Reputation: 1140
When i append a javascript script to a div at the first time it work and populate my div with external data and layout. But when i do it again at the same instance with the same javascript... noting happens
$('#JsModelSubmit').on('click',function(e){
e.preventDefault();
$('.poptin-popup .js-container').empty();
$('#os-widget-jssdk').remove(); // Delete the script from the DOM
setTimeout(function(){
$('.poptin-popup .js-container').append($('#AddJsInput').val());
},300)
$('.poptin-popup .js-container').attr('data-script',$('#AddJsInput').val());
$(".poptin-popup .thumbnail-js").attr('src','').fadeOut();
$("#addJsModel").fadeOut();
});
And example script that i append is:
<script type="text/javascript">
(function(d, s, id){
var js,
fjs = d.getElementsByTagName(s)[0],
r = Math.floor(new Date().getTime() / 1000000);
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id; js.async=1;
js.src = "https://www.opinionstage.com/assets/loader.js?" + r;
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'os-widget-jssdk'));
</script><div class="os_widget" data-comments="false" data-of="outbraininteractive" data-path="/outbraininteractive/quiz-novice-or-wiz-test-your-digital-marketing-skills" id="os-widget-39833"></div>
First time
This is the result that i'm getting:
Second time and so on this is the result that i'm getting:
Here is the jsfiddle:
https://jsfiddle.net/86c9vkog/3/
Please help! Thank!
Upvotes: 2
Views: 2449
Reputation: 2974
Once the JavaScript is loaded and executed, there is no link between it and the script element that loaded it at all. So, we cannot remove it.
But, by using iFrame
we can bypass this behavior.
See the demo here.
Why iFrame
works?
By definition, iFrame
embeds a new document context
. So, the original page context
and the iFrame
page context are different. Whatever attached to the iFrame
belongs to its own context.
The HTML element represents a nested browsing context, effectively embedding another HTML page into the current page. In HTML 4.01, a document may contain a head and a body or a head and a frameset, but not both a body and a frameset. However, an can be used within a normal document body. Each browsing context has its own session history and active document. The browsing context that contains the embedded content is called the parent browsing context. The top-level browsing context (which has no parent) is typically the browser window.
Learn more here.
$(document).on('click','#JsModelSubmit',function(e){
e.preventDefault();
$('#js-container').empty();
iframe($('#AddJsInput').val());
});
function iframe(script){
var iframe = document.createElement('iframe');
iframe.setAttribute('id', 'iframeId');
iframe.setAttribute('src', 'about:blank');
var adContainer = document.getElementById('js-container');
adContainer.appendChild(iframe);
var doc = iframe.contentWindow || iframe.contentDocument;
if (doc.document){
doc = doc.document
}
doc.open();
doc.write(script);
doc.close();
}
#js-container{
background:red;
width:960px;
heigth: 750px;
}
iframe{
width: 100%;
height: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div id="js-container">asdasdasd</div>
<textarea id="AddJsInput" rows="10" cols="1000"></textarea>
<button id="JsModelSubmit">Append</button>
<!-- Append this js code
<script type="text/javascript">
(function(d, s, id){
var js,
fjs = d.getElementsByTagName(s)[0],
r = Math.floor(new Date().getTime() / 1000000);
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id; js.async=1;
js.src = "https://www.opinionstage.com/assets/loader.js?" + r;
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'os-widget-jssdk'));
</script><div class="os_widget" data-comments="false" data-of="outbraininteractive" data-path="/outbraininteractive/quiz-novice-or-wiz-test-your-digital-marketing-skills" id="os-widget-39833"></div>
-->
Upvotes: 1
Reputation: 31
Actually the problem is that when loader.js
is loaded the first time it creates the OpinionStage
object and when it's loaded the second time it doesn't do the initialization again because OpinionStage
object already exists.
To make the snippet work you need to add window.OpinionStage = null
before creating the script element.
<script type="text/javascript">
(function(d, s, id){
var js,
fjs = d.getElementsByTagName(s)[0],
r = Math.floor(new Date().getTime() / 1000000);
if (d.getElementById(id)) {return;}
window.OpinionStage = null;
js = d.createElement(s); js.id = id; js.async=1;
js.src = "https://www.opinionstage.com/assets/loader.js?" + r;
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'os-widget-jssdk'));
</script><div class="os_widget" data-comments="false" data-of="outbraininteractive" data-path="/outbraininteractive/quiz-novice-or-wiz-test-your-digital-marketing-skills" id="os-widget-39833"></div>
Upvotes: 1