$('a').click(function() {
_link = $(this).attr('href');
loadContent(_link);
return false;
});
function loadContent(href){
$('#content').load(href + ' #content > *)
}
I have all <a> binded with a .click() that will only change the contents of #content. However, new <a> from the new #content arent working with the previous .click() function. How can I rebind it?
Adding the function again after the .load() seems to work
function loadContent(href){
$('#content').load(href + ' #content > *);
$('a').click(function() {
_link = $(this).attr('href');
loadContent(_link);
return false;
});
}
But would this mess up the `s' that were already binded and cause it to run it on a loop?
Use event delegation to bind events to dynamically added elements (in this case as):
$(document).on('click', 'a', function() {
_link = $(this).attr('href');
loadContent(_link);
return false;
});
Event delegation works by listening for events bubbling up to a non-changing ancestor (document is the best default if none is handy, do not use 'body' as it has click bugs relating to styling). It then applies the jQuery selector to the elements in the bubble chain, it then applies your function to the matching element(s) that caused the event. The advantage is that the elements only need to exist at event time and now when the handler was registered.
When you initially add the click event listener, it is only bound to the existing anchor tags. The code to bind the event listener is run once and does not run again for any new anchor tags.
You can try attaching a listener to the body for click events on any anchor tags.
$('body').on('click', 'a', function() {...});
Related
first i created navigation click event
$('#inner-navigation li a')
.on('click', function (e) {
e.preventDefault();
AjaxNavUrl.checkURL(this.hash);
});
then it conducts ajax call and response html data
based on navigation key
$(".panel-body").html(data);
first ajax click working nicely..
then whithin that responese html data there is rest of click event and ajax call like
$(document.body).on('click', '.page-demos .page-wrapper', function (e) {
e.preventDefault();
and this
$(document.body).on('click', '.button-next', function (e) {
e.preventDefault();
but it seems like click event or e.preventDeafult() function is not working
I got the answer from jQuery doc here is what I learned,
Event Propagation
Understanding how events propagate is an important factor in being able to leverage Event Delegation. Any time one of our anchor tags is clicked, a click event is fired for that anchor, and then bubbles up the DOM tree, triggering each of its parent click event handlers:
<a>
<li>
<ul #list>
<div #container>
<body>
<html>
document root
This means that anytime you click one of our bound anchor tags, you are effectively clicking the entire document body! This is called event bubbling or event propagation.
Since we know how events bubble, we can create a delegated event:
$("#list").on("click", "a", function(event) {
event.preventDefault();
console.log($(this).text());
});
Notice how we have moved the a part from the selector to the second parameter position of the .on() method. This second, selector parameter tells the handler to listen for the specified event, and when it hears it, check to see if the triggering element for that event matches the second parameter. In this case, the triggering event is our anchor tag, which matches that parameter. Since it matches, our anonymous function will execute. We have now attached a single click event listener to our <ul> that will listen for clicks on its descendant anchors, instead of attaching an unknown number of directly bound events to the existing anchor tags only.
linkUsing the Triggering Element
What if we wanted to open the link in a new window if that link is an external one (as denoted here by beginning with "http")?
// Attach a delegated event handler
$("#list").on("click", "a", function(event) {
var elem = $(this);
if (elem.is("[href^='http']")) {
elem.attr("target", "_blank");
}
});
This simply passes the .is() method a selector to see if the href attribute of the element starts with "http". We have also removed the event.preventDefault(); statement as we want the default action to happen (which is to follow the href).
We can actually simplify our code by allowing the selector parameter of .on() do our logic for us:
// Attach a delegated event handler with a more refined selector
$("#list").on( "click", "a[href^='http']", function(event) {
$(this).attr("target", "_blank");
});
The click binding adds an event handler so that your chosen JavaScript function will be invoked when the associated DOM element is clicked. This is most commonly used with elements like button, input, and a, but actually works with any visible DOM element.
Example
<div>
You've clicked <span data-bind="text: numberOfClicks"></span> times
<button data-bind="click: incrementClickCounter">Click me</button>
</div>
<script type="text/javascript">
var viewModel = {
numberOfClicks : ko.observable(0),
incrementClickCounter : function() {
var previousCount = this.numberOfClicks();
this.numberOfClicks(previousCount + 1);
}
};
</script>
Each time you click the button, this will invoke incrementClickCounter() on the view model, which in turn changes the view model state, which causes the UI to update.
I have a start script
<script>
$(function() {
$('.full-info').on('click',loadFull);
function loadFull(e) {
e.preventDefault();
$.get($(this).attr('href'), function(data) {
$('#pop-up').html(data).show();
});
};
});
</script>
<div class="Generalwrapper" >
<div class="wrapper pop-up" id="pop-up" style="display:none;" ></div>
</div>
After Get response i got data in Html format
<a href='#' class='close pop-up'></a>
So how to hide #pop-up div on .close pop-up click ?
As from start script .close pop-up is not accessible and also from output data #pop-up div is not accessible
The event handler for the click event can only be assigned after this line of code:
$('#pop_up').html(data).show();
The HTML is not loaded into the DOM until this line is executed.
Use Event Delegation using .on() delegated-events approach and bind event as
$('#pop-up').on('click', '.close.pop-up', function(){
e.preventDefault();
$('#pop-up').hide();
});
The 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, we can use delegated events to bind the click event to dynamically created elements and also to avoid the need to frequently attach and remove event handlers.
$('#pop-up').on("popupbeforeposition", function(event, ui) {
// bind events like below
//$('.close.pop-up','#pop-up').off('click');
//$('#pop-up').on('click', '.close.pop-up', function(){
// e.preventDefault();
// $('#pop-up').hide();
//});
}
use below code . add below code in your $(function() { });
Learn about event delegation
Event delegation allows us to attach a single event listener, to a
parent element, that will fire for all descendants matching a
selector, whether those descendants exist now or are added in the
future.
$(function() {
$(document).on('click','.close',function(e){
e.preventDefault();
$('#pop-up').hide();
});
$('.full-info').on('click',loadFull);
function loadFull(e) {
e.preventDefault();
$.get($(this).attr('href'), function(data) {
$('#pop-up').html(data).show();
});
};
});
Second Option.( with nearest static parent )
$('.Generalwrapper').on('click','.close',function(e){
e.preventDefault();
$('#pop-up').hide();
});
You can use below code:
$(".close").click(function(){
e.preventDefault();
$("#pop-up").hide();
});
Let me know if you face any query/concern regarding this.
Thanks!
I'm using
$(document).on('click', '.mySelector', function () {
//do something
});
To delegate events to buttons.
Next I'm using .clone(true) to copy div which containing few buttons with delegated in to it events.
My question is how do I remove events form selected new created buttons?
I'm tried:
$(document).unbind('click', $(myNewDiv).find('.mySelector'));
Somehow it's removing events from all $('.mySelector') in whole document not only from this inside 'myNewDiv' object.
I have seen documentation of jQuery .off() and .undelegate() and they accept only string like selector (my div can't have any unique ID).
Is any option to remove events from selected elements inside jQuery object when they are delegated to document?
You can add a class to your clones:
var $clone = $original.clone(true).addClass("clone");
And reject that class in your delegated handler:
$(document).on("click", ".mySelector:not(.clone)", function() {
// Do something...
});
$(document).on('click', '.mySelector', function(){
//do something
});
the code above means, "attach a click handler to the document, so whenever any element that corresponds to the '.mySelector' selector is clicked, fire the handler".
whenever you clone an element, you clone its class as well, therefore it will suit the '.mySelector' too.
the handler that you have delegated is attached to the document and not to the elmenets themselves. in order for the new elements to not fire the handler, you must make them not fit the selector. so either change their class to '.mySelector2' after cloning, or whatever.
I have a few generated div's on my page listing events on a calender, they all have the same class "fc-event-inner". I would like to add a onclick to these div's but am struggling to get this right.
This is what iv tried, no onclick is added and no errors on page.
$(document).ready(function () {
$('.fc-event-inner').each(
function (element) {
Event.observe("click", element, EventClick);
}
);
function EventClick() {
alert("You clicked an event")
}
});
This is an example of a generated event div:
<div class="fc-event-inner">
<span class="fc-event-title">Requested<br>by Santa</span>
</div>
Use the delegate version of on
$(document).on("click", ".fc-event-inner", function(){
/// do your stuff here
});
This catches the click at the document level then applies the class filter to see if the item clicked is relevant.
Example JSFiddle: http://jsfiddle.net/BkRJ2/
In answer to comment:
You can access the clicked element via this inside the event function. e.g.
$(document).on("click", ".fc-event-inner", function(){
var id = this.id; // Get the DOM element id (if it has one)
var $this = $(this); // Convert DOM element into a jQuery object to do cool stuff
$this.css({'background-color': 'red'}); // e.g. Turn clicked element red
});
*Note: You should never have to run an Each in order to catch events on multiple items that have a common class.
You do not need each() to bind event to elements with specific class, just selector is enough. Use jQuery on() with event delegation it will bind event to those which are generted after the binding code.
$(document).on("click", ".fc-event-inner", function(){
alert("click");
});
Delegated events
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, jQuery doc.
<div class="fc-event-inner">
<span class="fc-event-title">Requested<br />by Santa</span>
</div>
Your JS:
<script>
$(document).ready(function () {
$('.fc-event-inner').on("click", EventClick);
function EventClick() {
alert("You clicked an event")
}
});
</script>
http://jsfiddle.net/UBhk9/
Some explanation:
Because you are using a class(it may be used multiple times, in contrast to an id) it will work for all the elements with this class name. The .on method will attach the event handler(in this example "click") to the selector(the class .fc-event-inner). If you want to remove events bounds you've to use the .off() method and if you only want to attach the event once you can use the .one() method.
I have a div and within the div there is a child img element.
Both div and img have their very own javascript click handler.
My objective is to have when I click on the img, only the img click is triggered.
But currently the div click handler is responding before the img click handler.
Here's the example: http://jsfiddle.net/5j73w/
I'm not sure if parent's position: relative is the culprit. But that's a compulsory style.
I also tried with z-index for img but no avail.
Thanks in advance!
Replace the deprecated .live() by .on() as you're using jQuery 1.7+.
$('#parent > img').on('click', function(e) {
Fiddle
Or, if you need the event delegation (e.g. in case you're adding content dynamically to #parent):
//run this line when #parent is in the DOM
$('#parent').on('click', '> img', function(e) {
Fiddle
.live bubbles the event all the way up to the document to then check if the given selector matches the target element, by then you can't stop the event propagation anymore. From the docs:
Calling event.stopPropagation() in the event handler is ineffective in stopping event handlers attached lower in the document; the event has already propagated to document.
Also, to answer the "parent takes precedence" question, that's not case. When you call .live, you're actually attaching a handler to the document.
In this case, the handler attached through .click(function(){}) (which in jQuery 1.7+ is a shorthand for .on('click'[, null], function(){}), executes before the handler attached to the document, which is the expected event propagation bubbling behavior.
Was able to fix by doing the following:
$('#parent').click(function(e)
{
console.log("parent click");
});
$('#child').click(function(e)
{
console.log("child click");
e.stopPropagation();
});
Here's the Fiddle.