I know how trigger a function when an element loads in with jQuery but can't seem to figure it out in pure Javascript. I would like to do this is JS.
So I know how to fire a function in jQuery when an element loads but I want to do it in Javascript. I would like to do this is pure Javascript.
$('img').load(
function(){
//do stuff
})
From the MDN documentation of the load event:
The load event is fired when a resource and its dependent resources
have finished loading.
As mentioned in the comments, an input element has no dependent content to load, hence a load event for it will never trigger.
It's important to understand that all elements do need to be parsed into the Document's Object Model, but that is a process that must complete before you can programmatically interact with the element in the first place.
Once the client has finished parsing all the elements in the DOM, the client will fire off its "DOMContentLoaded" event (equivalent to the JQuery $(document).ready event shown in the W3 Schools example you linked to). It is at this point that it is safe to search through the DOM and locate elements to be worked with.
From there, different elements can/will have different events that can occur on them during their lifetime. An input element will respond to user input and interactions, so it has several different events to tie into them (input, change, keydown, keyup, keypress, mouseup, mousedown, focus, blur, etc.).
For a load event, you need to work with elements that contain content that needs to be loaded into them after the element itself has been created. Examples would be window, img, iframe, link. These are all elements that need external content for them to be of any use to anyone.
So, take an element like an img which needs to load an external resource and the pure JavaScript would use the native DOM API way to register event callbacks, which is with the element.addEventListener() method.:
// Get a reference to the DOM element.
// Make sure this is done AFTER the DOM has finished loading:
var img = document.getElementById("someImgageElementsID");
// Register a function to the image's load event handlers:
img.addEventListener("load", doLoad);
// Declare the callback function:
function doLoad(){
console.log("image loaded");
}
More on element events.
Related
So something I'm curious about, how the YUI3 PJAX works. For instance, when used, even if you inject an anchor into the page with the yui3-pjax class and click it - that will run the AJAX function.
My question is does that use a Promise or what to determine if the anchor, including injected anchors, has the class?
I have a function for observing mutations for a site and I call it on the click event for the yui3-pjax anchors already existing in the page, but I also want to have it run on yui3-pjax anchors that I dynamically load into the page without having to recall the function.
Using jQuery for the ease of sample code, a similar solution can be written in vanilla Javascript as well.
You can use .on() with a selector parameter. For example:
$('body').on('click', '.class', function(e) {
e.stopPropagation(); //Stop multiple possible triggers from the same click
//TODO: Rest of code
});
The downside obviously being that every click on your highest common ancestor will get processed. The upside is however that since the click is caught there (not on the elements themselves) you don't have to worry about rebinding events.
What happens in jQuery with .on() event if its element doesn't exist in the DOM?
For example, if I use this:
$(document).on('click', "#registerFormSubmit", function(){
// do something here
});
And I don't have #registerFormSubmit present on all pages, is the browser slowed down by the code, or is it not?
So why am I doing this anyway?
I don't want to split my javascript code to 10 .js files and include each depending on which is required on which page, as I believe the server/browser will transmit the data a lot faster if it's in 1 file (especially if the file is obfuscated and minified).
If the code slows down even pages not containing the element, would the following be a good solution to keep all the code in one file?
var page = window.location.pathname.split('/');
if (page[1] == 'contact'){
$(document).on('click', "#registerFormSubmit", function(){
// do something here
});
}
Remember that the .on() event attaches an event handler function for whatever element is in the DOM or will be in the DOM in the future. Therefore I believe it would slow the browser down even if the element isn't present at the moment.
However, the proposed if (page) solution should not attach the event if the page isn't matched, imo.
Can anyone shed some light on this, please?
Attaching many delegated event handlers near the top of the document tree can degrade performance. Each time the event occurs, jQuery must compare all selectors of all attached events of that type to every element in the path from the event target up to the top of the document. For best performance, attach delegated events at a document location as close as possible to the target elements. Avoid excessive use of document or document.body for delegated events on large documents.
jQuery can process simple selectors of the form tag#id.class very quickly when they are used to filter delegated events. So, "#myForm", "a.external", and "button" are all fast selectors. Delegated events that use more complex selectors, particularly hierarchical ones, can be several times slower--although they are still fast enough for most applications. Hierarchical selectors can often be avoided simply by attaching the handler to a more appropriate point in the document. For example, instead of $("body").on("click", "#commentForm .addNew", addComment) use $("#commentForm").on("click", ".addNew", addComment).
source: http://api.jquery.com/on/
I will suggest you to use above mentioned format instead of $(document).on('click', "#registerFormSubmit") and if you are not going to use the click event in all pages then simple answer is don't put it in all .js files. Load only the required .js files and handle registerFormSubmit click event in separate .js file.
I have a SPA ( single page application ) programmed in HTML/JavaScript/JQuery/CSS
Every time a navigation link is clicked the main div is loaded with a chunk of HTML/JavaScript/JQuery/CSS via the ajax command and the getScript function is used to load the JavaScript/JQuery portion of that chunk.
Once a user clicks on another link, the main div is removed via the remove() function and the new chunk with its JavaScript/Jquery replaces it.
HERE'S THE PROBLEM: when I load the content of the main div for the second, third, etc. time ( if a user clicks on another link but then comes back to this one ) do I run the getScript function again to load the JavaScript/JQuery? If so - wouldn't it bind the "on" and other events over each other, or does the remove() function take care of it and it's safe to do without any memory leak?
Thank you for your responses!
From http://api.jquery.com/remove/
Similar to .empty(), the .remove() method takes elements out of the DOM. Use .remove() when you want to remove the element itself, as well as everything inside it. In addition to the elements themselves, all bound events and jQuery data associated with the elements are removed. To remove the elements without removing data and events, use .detach() instead.
So all events bound on the div and its descendants will be removed and can be safely rebound. However if the JavaScript you are injecting binds events to things outside the div like the document, window, body etc.. multiple events will be bound which will likely cause problems if unintended.
As of jQuery 1.4, the same event handler can be bound to an element multiple times. This is especially useful when the event.data feature is being used, or when other unique data resides in a closure around the event handler function.
http://api.jquery.com/on/
If you absolutely must bind to higher level elements from the script that is run repeatedly then you should look in to using off() before you bind the events.
I'm just testing out replacing a whole page with another page using JavaScript and I found this answer with document.write. As to why document.write, I needed to replace the entire HTML, including scripts and styles using the same page.
It does what I want but i can't seem to have consistency with my event handlers. My handlers are all attached to document using:
$(document).delegate(...);
Currently, I have weird results. In a fiddle I made, it attaches a handler. When clicked, the event fires, rewrites the page, runs the function again - but it doesn't attach the handler.
However in my project, I'm doing the same routine (d.w(), then add handlers). It does reattach once and handlers work, but after doing a second routine (still on the same page), it doesn't attach anymore.
So my questions are:
When using d.w(), do existing handlers get erased from document?
Are window as well as document the same after subsequent d.w()s? or are they somehow "renewed"
Do scripts that are already parsed stay in memory and run after subsequent d.w()s? Or do they get erased as well?
(The following applies to google chrome)
Only the document is cleared, the scripts in memory still stay the same. You can easily test it by setting something to a variable and see if it exists after clearing out the document with .open.
The old native handler is therefore lost from the document, but jQuery still thinks that the handler exists in its own event model. You can see it by editing the log to:
console.log('patch', JSON.stringify($.cache ));
jQuery only ever attaches a single native handler per event, so if you have a "click" event registered on document, further handlers attached with jQuery don't attach a new native handler, instead the handler is pushed into the jQuery internal handlers array.
Now, because document.open removed the native handler, but doesn't clear javascript, jQuery still thinks the native handler exists, and further .delegate only goes to the jQuery internal handler array. If you replace your handler with plain old document.onclick you will see it starts working.
You can also keep using jQuery if you add $(document).unbind() (or more robust $.cache = {};, but this is internal and subject to change) before the .delegate, so that jQuery is again synced. Otherwise it won't be, since it has no idea you called document.open.
So:
Yes
They are still the same objects, can be tested by saving a reference and checking that agaist document after a .open
They stay in memory.
http://jsfiddle.net/wphzt/4/
The only reason it stops working from second time onwards is because in your function you have written
document.write('<span>'+(++i)+'</span>');
In which case, next time the document doesn't have the delegate function to increment the span value but has only what you have written in the code snippet I have highlighted above. Thus, as you doubted, yes they get erased as well. Hope this helps.
I am in the process of creating a huge web application, with a JavaScript based UI, and many events generated continuously.
To avoid bad performance due to the huge amount of the event listeners needed, I of course opted to use a single event listener which will catch all the events generated from the children elements (event bubbling).
The problem is, this application is designed in such a way that one or more modules can be loaded into the main JavaScript library I'm coding (which is responsible for controlling the UI and every other aspect of the program). Of course every module should be completely independent from each other, so you can choose which methods to load, without affecting the general functionality of the library, only adding or removing features.
Since every module can operate in different DOM elements, I need to have at least a single event listener for each module, since two modules can listen for events generated by html elements placed in different DOM branches.
http://jsfiddle.net/YRejF/2/
In this fiddle for example, the first button will let the first paragraph trigger an event, and its parent will catch it. The second button will let the second paragraph fire the event, but the div listening for the same event won't catch it, because it's not fired from one of its sons.
So my question is: is it possible to have a single event listener, able to listen also to events triggered from elements that are not its sons (elements placed everywhere on the page)?
I was thinking about having a js object, or a dom node, which store the data of the element which triggered the event, and the event itself, then a general event will be fired on the global event listener (no matter where it's placed in the dom), and it will then read the data to discover which element generated which event, and act accordingly.
Any help or suggestion about better ways of achieving this?
jQuery has a special binder for this kind of cases: live(). It let's all events bubble to the document and then handles them accordingly. However, if you use div or other containers for different panels etc, maybe using delegate() makes more sense. Don't worry too much about the number of bound elements. Believe me, it will run as well with 50 binds or 10 delegates as it will with 1 live.