Dani Banai
Dani Banai

Reputation: 1140

Run JavaScript again after div content change

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

enter image description here

This is the result that i'm getting:

enter image description here

Second time and so on this is the result that i'm getting:

enter image description here

Here is the jsfiddle:

https://jsfiddle.net/86c9vkog/3/

Please help! Thank!

Upvotes: 2

Views: 2449

Answers (2)

James
James

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

TNian145
TNian145

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

Related Questions