I have some javascript that I inherited for my job. In this javascript we have a side bar that is constantly updated(every 1 - 10 or so minutes). In the script we parse and process the AJAX from the server and then we call an interesting function.
function renewClicks(){
$('.classElem').unbind('click');
$('.classElem2').unbind('click');
$('.classElem3').unbind('click');
$('.classElem').click(elm1funct);
$('.classElem2').clikc(elm2funct);
$('.classElem3').click(elm3funct);
}
Where .classElem is a css class selector that is appended to each image that is added to the page. And elmfunct is a function that is written to handle the click. This runs on each update (deauthorizing valid already added elements and then re adding them all). I want to know if there is a way I can possibly attach a listener on the body element in the DOM so that all of the image elements added to the page and that inherit the css class will already be handled and therefore not unregistered and re-registered on each update.
Thank you for any info you can provide.
You could try this:
$('body').on('click','.classElem',elm1funct)
.on('click','.classElem2',elm2funct)
.on('click','.classElem3', elm3funct);
From jQuery's docs:
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers.
As #crush mentioned, use an event delegated approach to avoid unbinding and re-binding events:
$(document).on('click', '.classElem', elm1funct);
Related
Currently, my page has a top navigation bar.
When clicking, the page currently does a full reload which causes a flickering effect.
To avoid this, I'm planning to use the jQuery html function to just replace the main body of the page and leave the header intact.
But this appears to stop JavaScript function from running on the main body of the page.
Is there a way I can use the jQuery html function and still get my JavaScript to work on the HTML elements in the body?
You can use event bubbling to listen to the events on document, and based on the target element, execute appropriate event handling logic.
jQuery makes it easier to register such event handlers by simplifying the logic around identification of the target element. The syntax for registering such an event handler would be: $(document).on(events, selector, handler).
These are called Delegated Event Handlers in jQuery's documentation:
Delegated event handlers have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers.
I have illustrated an example in the snippet below. Notice how you do not need to re-register the event listener even after replacing the HTML content.
$(document).on("click", "#clickMe", function() {
alert("Element clicked.");
});
// Change the innerHTML after 10 seconds.
setTimeout(function() {
$(document.body).html(`
<div id="clickMe">[New] Click Me</div>
`);
}, 10000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="clickMe">Click me</div>
You can read more about event bubbling here and more about jQuery's event handling syntax here.
Note: In my opinion, you need to rethink your architecture. While the suggested approach works, given the unconventional nature of your architecture, you may run across other challenges in future.
I have created a dynamic page in which i am loadin 10 element by default. after that if user scroll doun i am apppending more element to this page by js (appending data by ajax).
and on click of a tag i am doing some js work
I am using
$('.atnd_modal').click(function(){
alert("dsfds");
});
not
onclick ="function()" and i dont want to do that onclick.
Problem i am facing that this js is working perfectely for first 10 result but after that it stop working for the block i have appended by js.
how can to do it working for both the cases ??
Try jquery on() for event delegation. It will work on dynamic loaded element on DOM also.
$('body').on('click','.atnd_modal', function(){
alert("dsfds");
});
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time.
Your click event is not working because when you use click() it will attach this handler to all elements having atnd_modal class, but when new element loading in DOM that event is not attached automatically with new element. For previous elements it will work fine but for new element it won't. So here comes Delegated events. We shall attach event to parent element with on() or delegate()
If you want to bind an event to the dynamically added new elements you have to use event delegation :-
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers.
Change your code like this, use Jquery On
$('body').on('click','.atnd_modal', function(){
alert("dsfds");
});
How come the second code better than the first? Why not grab the .vote a directly, instead of grabbing the body tag? I'm creating a voting system using AJAX/JSON/PHP:
$('.vote a').click(function() {});
$('body').on('click','.vote a',function(){});
The second example is a delegated event handler. It is attaching the click event to the body so that it can be applied to any .vote a element which are appended to the DOM after the page has loaded.
You may also see a performance increase from using the delegated model even when there are no elements appended after DOMReady, if there are a lot of elements you need to attach the same event handler to.
That kind of doing is called as event-delegation. And that would be useful when binding events for the elements which are created at run time(dynamically).
I've got an event handler set on document, listening for submit and change events, delegated to any form elements on the page. The idea is to update the server when an input is altered (since the event bubbles up to the form), while also allowing for submitting an entire form. I have a few overrides in place for inputs that need special handling, and this works great (since they're placed higher up in the code, I can block the main event handler with .stopImmediatePropagation() - all these handlers are on document.)
What I'm trying to do now is intercept the change event on a specific input, then instead of preventing, I want to re-trigger the primary handler, passing in some additional data (using jQuery's .trigger(event, [data]) syntax.)
To give a simplified example: http://jsfiddle.net/rrEmq/3/
My goals are to:
Maintain delegated events (the forms are loaded in dynamically, the JS is loaded once)
Avoid duplicating code
Avoid breaking out the main handler's functionality into separate functions
That third item is my initial approach, and I understand that it will get the job done, but I'd love to find a way to solve this without rewriting the main handler. Obviously, the real kicker is that, since everything's delegated to the same element, and since I'm using e.target, I can't simply trigger a handler higher up in the DOM tree.
Create a custom event and trigger with the extra data
Instead of
$(this).trigger("change", data);
Call
$(this).trigger("changemodified", data);
And create a handler for this event.
You can reuse handlers
var handleChange = function(e) { };
$("something").on("change", handleChange);
$("something").on("changemodified", handleChange);
I dynamically generate some markup and inject it into the DOM like this:
content+='<td><a class="reportLink" onclick="showReport();return false;" href="'+layerResults.features[i].attributes['Information_External']+'">Info</a></td>';
I know it would be better to use jQuery to attach the click handler instead of using an inline handler.
The problems are, even using an inline handler and a function like this:
function showReport() {
console.log('stopped');
}
Still doesn't prevent the link from navigating away from my page.
The second problem is, when I try using
jQuery('.reportLink'.on('click', function(e) {
e.preventDefault();
console.log('clicked');
});
The event never gets attached. I'm using jQuery 1.7.2.
This is driving me a bit insane as it's a simple task I've done about a zillion times in jQuery <= 1.5.
Delegate the event handler to a parent element that exists at the time the dom is loaded. You can replace body with that parent.
jQuery('body').on('click','.reportLink', function(e){
e.preventDefault();
console.log('clicked');
});
from jquery docs .on()
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.
In addition to their ability to handle events on descendant elements not yet created, another advantage of delegated events is their potential for much lower overhead when many elements must be monitored. On a data table with 1,000 rows in its tbody, this example attaches a handler to 1,000 elements:
to prevent it from navigating away, enter this right after "console.log('stopped');
return false;
for the second one, i usually use this syntax, maybe it'll help:
jQuery(".reportLink").click(function() {
//do something
});