开发者

jQuery: insert html with javascript, waiting for it to run

开发者 https://www.devze.com 2023-03-17 16:59 出处:网络
I\'m using $.ajax method to pull some html code and insert it into a \'div.listbox\' element, using $(\'div.listbox\').html() method.

I'm using $.ajax method to pull some html code and insert it into a 'div.listbox' element, using $('div.listbox').html() method.

I'm aware that .html will insert all HTML code, and execute all javascript code found under the HTML code.

What is actually happening:

$.ajax({
async: false,
url: 'ReturnSomeDataAsJSON',
data: {some_needed_data},
dataType: 'json',
success: function(data){
  $('div.listbox').html(data.body)}
})

This data.body has a javascript that will make a call to an asynchronous function th开发者_C百科at will update an element inside the HTML under data.body.

Putting a .live function on the 'div.listbox' element, in order to listen to DOMNodeInserted event, I could see that the javascript method executed by the $...html(data.body) call updated 'div.listbox' element 6 times.

As this number could change, I can't just treat this as my solution, waiting to the element to change 6 times and then do what I want.

So I'm asking if it's possible to wait untill all javascript inside that .html call is executed before continuing to other javascript methods after the $.ajax call.


The only way would be to use a callback function inside your ajax-generated javascript, so you'd have:

//(ajax generated code)
<script>
   ...   
   $('div.listbox').css("color", "blue"); //For example, let's assume this code executes asynchronously
   div_changed(); //This is the callback function
</script>

Then, in your main script you should have:

$.ajax({
  async: false,
  url: 'ReturnSomeDataAsJSON',
  data: {some_needed_data},
  dataType: 'json',
  success: function(data){
    $('div.listbox').html(data.body)
  }
})

function div_changed(){
   //Here put the code you want to be executed after changes are made
}

This is the only way, note that this is asynchronous.

Hope this helps. Cheers


JavaScript is a functional programming language meaning that you almost everywhere work with functions and can also pass functions as parameters. Let's describe your scenario: In scope A (parent element) you want to do something, but just when in scope B (child element) something happens and finishes. Only scope A knows what it wants to do, and only scope B knows when it finishes its job. So what do you do? Here are some solutions:

  1. Hardcoding your logic of scope A in scope B (spaghetti code)
  2. Get the function back from scope B and execute it in scope A (bad idea)
  3. Pass the logic of scope A as a function to the scope B and let B be the agent to decide when to execute that.

The best method is the third item and this is the spirit of functional programming.


Solve by adding a listener to DOMSubtreeModified event, by doing:

$.ajax({
async: false,
url: 'ReturnSomeDataAsJSON',
data: {some_needed_data},
dataType: 'json',
success: function(data){
  external_data = $(data.body)
  var data_html = $(data.body)[0]
  var data_script = $(data.body)[1].text

  listbox_container = $('form#main_form div.listbox-container:nth(0)')
  //fill body
  listbox_container.html(data_html);
  // attach listener
  listbox_container.live('DOMSubtreeModified', check_listbox)
  // eval script
  eval(data_script)

  // this script will (some time, asynchonously) update listbox_container
  // by adding some data, that I need to deal with

}
})

function check_listbox() {
    listbox_internal_ container = $('form#main_form div.listbox-container:nth(1)')
    if (listbox_internal_container.length >= 1) {
        // do what I want (deal with new data filled), 
        // because internal container (that will be created
        // by the $.ajax call) now exists with some data filled by the
       // eval(...) of the script
    };
}
0

精彩评论

暂无评论...
验证码 换一张
取 消