1

I'd like to have code executed when a particular element and all of it's children are in the DOM. I know how to poll for the desired element's existence, or even better, to use a MutationObserver, but the desired element is itself rather large and I can't be sure that all of it's children are fully loaded simply based on it existing.

I could wait for ready which is called when all the DOM is loaded, but the page usually takes a rather long time to load. In the interests of speed i'd like to know without necessarily waiting for $(document).ready().

I did find the on function, I love the fact that it will be called for elements which don't even exist yet:

$(document).on('SomeEvent', '#desiredElem', handler);

...however I don't know of an event which is fired for an html element being fully in the DOM.

My script is being injected into the browser, and I know from logging that it's running a long time before $(document).ready() or DOMContentLoaded. Basically i'd like to take advantage of that. I can't add <script> tags to the HTML, unfortunately.

On a side note, an event for an object existing would be interesting. It would save me from having to use MutationObserver.

iPherian
  • 908
  • 15
  • 38
  • If its something regarding like, all of the elements inside a particular parent element, say for example, all textboxes inside a div ( say id div1) gets loaded, you could check it using jQuery through getting the counts of inputs inside the div1 as `var cnt = $('div1').find(input);` If it returns your desired counts of the elements, you can fire the required event. – Vinit Sharma Dec 16 '15 at 04:52
  • You can try your statement inside $(window).load = function() { //statements }); This is event after page is loaded completely. – yjs Dec 16 '15 at 04:53
  • What do you mean "the desired element is itself rather large"? What makes it large? An element is either present or not. It's never half present. Is this element part of the page HTML or is it dynamically added to the page? If it's dynamically inserted into the page, can you share the code that inserts it? – jfriend00 Dec 16 '15 at 04:58
  • If you're trying to load piece by piece use `$(selector).load('anotherPage.php #someId', function(){ /* load more */})`. – StackSlave Dec 16 '15 at 05:03
  • _"would save me from having to use `MutationObserver`"_ `MutationObserver` not return expected results ? Can include example `html` at Question ? Tried adding `
    ` element at close of loaded `html` ?
    – guest271314 Dec 16 '15 at 05:03
  • @jfriend00 I mean when *all* of the element's children are loaded. It's part of the main HTML. Updated the question to be more clear. – iPherian Dec 16 '15 at 05:04
  • Images have a onload Event naturally, by the way. You can always test if something is loaded in the DOM by querying it. Of course, `$(document).ready()` or its likeness should be used to make sure you have access to your Elements, including your script tags. – StackSlave Dec 16 '15 at 05:07
  • @guest271314 That would work, but I don't control the html source. – iPherian Dec 16 '15 at 05:07
  • @iPherian _"That would work, but I don't control the html source."_ ? How is "rather large" `html` source appended to `document` ? – guest271314 Dec 16 '15 at 05:08
  • I think you still want to use `$(document).ready()` or its likeness. That just makes sure your HTML is loaded. [Check this out](http://stackoverflow.com/questions/544993/official-way-to-ask-jquery-wait-for-all-images-to-load-before-executing-somethin) . – StackSlave Dec 16 '15 at 05:17
  • If you want to Asynchronously load things on your page. Use `$(selector).load(fromPageAndSelector, completeFunc)`. Inside `completeFunc` load another Element. – StackSlave Dec 16 '15 at 05:24
  • @iPherian What is expected result ? Can reproduce example `html` , `js` at stacksnippets, jsfiddle http://jsfiddle.net ? – guest271314 Dec 16 '15 at 05:28
  • Cant' you use $('body').on('load','your element', function(){}); ? – Jules Dec 16 '15 at 05:48
  • @Jules I tried, but it never fires. Based on the documentation It seems that's only for external resources. (css, images, etc). – iPherian Dec 16 '15 at 05:59

2 Answers2

2

Since you've said that what you're trying to discern is when an element and all of its children that are present in the source HTML of the page are loaded, there are a couple things you can do:

  1. You can test for the presence of any known element after the last child. Since HTML elements are loaded serially in order, if the element after the last child is present, then everything before it must already be in the DOM because page HTML is inserted only in the order it appears in the page HTML source.

  2. If you put a <script> tag after the relevant HTML in the page, then all HTML before that <script> tag will already be in the DOM when that script tag runs.

  3. You can either poll or use a mutation observer, but chances are this won't really help you because no scripts run while the DOM parser is in the middle of inserting a bunch of HTML into the page. So, your scripts or mutation events would only run after the whole page DOM was inserted anyway or when the page pauses in order to load some other inline resource such as a <script> tag.

  4. You can fallback to the DOMContentLoaded event which will tell you when the whole DOM is loaded.

For more concrete help, we need to understand much more about your specific situation including an example of the HTML you're trying to watch for and a full understanding of exactly what constraints you have (what you can modify in the page source and where in the page you can insert or run scripts).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • My script is being injected by GreaseMonkey. Based on logging, my script is running a long time before `DOMContentLoaded`, so I thought I would try to take advantage of that. – iPherian Dec 16 '15 at 05:22
0

You need to setup a timer and keep observing the DOM checking if the element exists or not

function checkIfLoaded( callBack, elementSelector )
   setTimeout( function(){

     $( elementSelector ).size() == 0 )
     {
        //continue checking
       checkIfLoaded( callBack, elementSelector )
     }
     else
     {
        callBack();
     }
   }, 1000 );
)

checkIfLoaded( function(){ alert( "div loaded now" ) }, "#divId" );
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
  • 1
    This "polling" method would be an inefficient way to do this. When the OP explains more about what the actual element is and how it is added to the page, we can offer ideas on whether there are more efficient ways to do it than this. – jfriend00 Dec 16 '15 at 04:59
  • @AlexanderO'Mara thanks. Learnt this new thing today :). But it seems it may not work for older browser. – gurvinder372 Dec 16 '15 at 05:08