I'm wondering how can I detect whether all content inside dynamically appended HTML element is loaded. The element's content might be both text and images, maybe videos. I need to detect it to get a correct element's height value.
I believe that MutationObserver is not right solution for that as this only detects whether node has been changed or its attributes. I have to detect when element's content has been loaded.
Delegating load events to parent doesn't change anything.
Any suggestions?
You can do this by using a callback function on your AJAX call. Off the top of my head I can't remember how that works in vanilla javascript, but in jquery it would look like this:
$.ajax({
url: 'my-url'
}).done(function(){
// This only fires once the AJAX request / response has complete
populateElement();
fixElementHeight();
});
By doing it this way you ensure you have all the content before updating your element. Once the element has been updated, you are then able to measure its height. If part of the new content is an image, or some other content type which needs to be fetched, then I would do the fetching in the populateElement function:
var contentImage = new Image(imgWidth, imgHeight);
$(contentImage).click(function(event){
...
});
contentImage.src = 'source of image';
You will most likely need a javascript that has a constant setTimeout checking for the length of an element. (an element that is not loaded usually has a length of 0 or is invalid)
This is something we encountered awhile back and probably applies to your situation as well. It's for a youtube thing for detecting when certain elements have finished loading, but seeing your question, the concept applies as well.
http://www.gambit.ph/how-to-use-the-javascript-youtube-api-across-multiple-plugins/
I decided to use Javascript promises to handle images load events. I'm creating a new promise for each image and updating my app after all images are loaded.
So there's no other way round to make delegation on parent to detect whether all images were loaded.
Related
I am working with such kind of frame design. Consider this image as brief overview of more complex design.
I am recursively iterating each frame, so as to add event listeners to it.
For the very first $(window).load() , I am able to add listeners successfully.
But the real trick is;
Frame 2.1 is navigationFrame whereas Frame 2.2 is detailFrame.
As name suggests whenever we click any link of 2.1, Frame 2.2 is loaded again.
Due to this, it looses listeners attached.
Since new frame is loaded, I can't keep track of newly loaded frame.
Though I've tried
element.onunload = function(){
#add listeners recursively using element.parent
}
//where element is of type window
//created using
/*for(var i=0;i<window.frames.length;i++){
var element = window.frames[i];
}
*/
I've also tried ('frame').load, but didn't work.
I cant use #frameID since this work is generic to any web application (whether or not it use frame.)
Please suggest me any way to deal this kind of situation.
Assume that we know that an element (or a very specific selector) is going to appear on a page. Is it possible to set up beforehand, via JS or jQuery, an event that goes off when the browser gets to that element and parses it? This is NOT content loaded through AJAX but is present in the primary page's source.
The reason for this need is that I'm working with a hosted system that greatly limits where and when I can inject code to fix problems with the page. I can pretty much only place my code at the start and end of what is a really long page. Right now, the page has to load completely before it can inject any desired changes (yuck!). Plus, I cannot make the pages shorter in content.
This is basically the process I would like to happen:
Page begins loading
Listener set up to watch for .specialClass elements
...
.specialClass element gets parsed/added to DOM
Listener triggers function on that element
...
.specialClass element gets parsed/added to DOM
Repeat as before
...
Page finishes rendering
So, is this possible at all? Thanks in advance.
this is the situation.
I have a complex UI inside an iframe in which a user can perform several actions before submitting. During the process, the user can switch to another page (in the iframe) and come back. That means 2 postbacks inside the iframe.
Obviously, I don't want the user to lose everything but since all the actions have been done on the client-side, I can't reload the previous state from the server.
So now, I'm trying to move the first page content to the iframe parent and put it back in place when we come back. I'm half way there since the elements show back in the page but they lose their data attributes and event handlers.
I'm using this to move the content on the parent :
$("#resp").clone(true).attr("id", "refillResp").appendTo(window.top.$("#global"));
And this to put it back :
window.top.$("#global").find("#refillResp").clone(true).attr("id", "resp").appendTo($("#tdResp"));
Is there anyone who knows a way to do this ?
PS: I've tested how the content react when simply moved on the parent and data and events are already gone.
It is more a comment, but it does not fit in there.
Moving DOM element around different documents around is alway a little bit risky. Because it could lead to unexpected behavior (memory leaks, elements that behave strange). In current browsers it most of the time works, but i would not recommend it.
If you use jQuery you have another problem. jQuery has a cache for storing informations about data and event that are assigned to an Object, this cache is stored with the documents window. For further details please read this answer, to another question:
How to set jQuery data() on an iFrame body tag and retrieve it from inside the iFrame?
So if you move element with jQuery between different document, you will currently on the one hand loose these informations, on the other hand it could result in memory leaks.
With events it is even more complicate. e.g. if you have delegated events it could be become completely messy.
If you need to exchange data between iframe and parent you should think of some other logic.
I also mention this in a comment to the other answer of me, where i referred to this post:
How to set jQuery data() on an iFrame body tag and retrieve it from inside the iFrame?
Ajax sets up a scenario and jQuery then plays it out. The element does not exist before the page is loaded. I need a way to Animate something that was dynamically added to the page.
Something like:
$(document).on("animate", "div", function (){});
Does anything like this exist?
Okay, there seems to be some confusion, I am using queue() this isn't the issue creating it or doing something after I have the ajax return. After the Ajax the program builds and inserts imgs with specific IDs into the page. I need to reload the dom or something so that I can then animate the objects that were inserted into the page.
I have tested the animated on JSfiddle and they work fine, so my only assumption is that because these objects are not part of the initial dom they will not animate and thus I need the DOM to reload.
All you have to do is animate it with the proper function, like:
$("#nonexistent-element").animate({
right: '10%'
});
and it will animate once #nonexistent-element exists, regardless of whether it existed at page load. You only need to use on() when you want to bind an event to an element that does not exist on page load.
Working jsfiddle: http://jsfiddle.net/emFpw/26/
When the content is loaded via Ajax, we need to bind the events for them to work or we can use the live/on methods of jQuery which will bind the events to either parent/document depending on what we want.
Either of the two techniques ie binding when the content is loaded or using live/on should result in the event being triggered.
For ex: Once the content in inserted we can do as suggested by Lrdwhyt in the above answer.
Or we bind the element before its loaded like
$("#non-existing-elem").live("click",function(){
$(this).animate({right:'10'});
})
Im having an issue with scrollTo on newly created divs Im adding to the DOM via append(). For some reason I cant scroll to where I want from within the code, it only works from console command or if I add a button and call the scroll event that way.
Code:
$('#history').scrollTo('max');
Only works from console or attached to a button.
Edit: The history div has overflow:auto, not sure if that's causing it.
Just a guess, but are you calling "scrollTo" immediately after appending your new element to the DOM?
If that is the case, then the DOM layout likely hasn't had a chance to get recalculated. Relative offset values between elements aren't yet updated until after the current script processing finishes.
Two possible workarounds:
1. setTimeout("$('#history').scrollTo('max')", 1); // Call this after you append your element. This will allow the stack to unwind and update the DOM positions
2. $('#history').scrollTo(0, 9999); // Where "9999" is a value far larger than the actual height of the control.
This would indicate that you're trying to attach scrollTo() to elements which aren't actually existing at the time that you're calling the function on them. The fact that it works in the console would suggest this.
If that's the case, one way would be to use e.g. a library like livequery or then simply call the scrollTo() function on these elements once they have been appended.