I have an element with properties such as drag and drop and 1 click event handler. I have cloned this element, and find that the cloned element has the event handler working, as long as the original element is still in the DOM. The moment I remove the original from the DOM, however, the event handler is destroyed. My code goes:
el = $(#id).clone(true)
$('#container').packery('addItems', el)
el.appendTo('#container')
$('#container').packery('layout')
$('#lowerContainer > ' + #id).remove()
The event handler on el works as long as the last line is not added. However, adding $('#lowerContainer > ' + #id).remove() kills the handler. Does anyone know how I can keep the handler in cloned element even after removing the original? Thanks in advance!
You should define your click handler on container rather than on individual items:
$('#container').on('click', '.item', function() {...});
In this case it will handle clicks as on existing items as on ones added later.
Related
I know that for dynamic dom elements I need to use jQuery.fn.on or delegate, but if I 'move' the elements container appending to another elements in the dom, the click doesn't work anymore.
Here is the the jsFiddle to reproduce the issue:
http://jsfiddle.net/j0L7c51f/
Currently I'm using the following bind method:
$('#commoditySelector').on( 'click', 'li.available', function() {
var cmID = $(this).attr('data-cmid');
$('#debug').html('commoditySelected: '+ cmID);
});
If I comment out the code line where I move the ul element using appendTo(), the click event bound works fine.
The issue is caused by your use of mousemove, not the delegated event handler, as the HTML is being re-built every single time the mouse moves. This means that the delegated event handler is correctly fired on a clicked element, but that element is immediately removed from the DOM, so the event is cancelled before it propagates up the DOM to be processed.
To fix this issue, use the mouseenter event on the a instead:
$('#commodityCategories li a').mouseenter(function(e) {
// your code...
});
Updated fiddle
I have a table where i have bound all my elements with class="shift" to a click function.
Now, because I also need to use another click event on part of the element, I would like to unbind the click event on element when the mouse enters the element and rebind when i leaves (meant for some touch events and whatnot)
Now, I bind like this
$("table").on("touchstart mousedown",".shift", function(e){ ... })
But when i try to unbind on a specific element, say it has a class="selected" added to distinguish the current element i use:
$("table").off("touchstart mousedown",".shift.selected")
which does not work....
I can remove all the handlers at once, but it would be wasteful to remove all the handlers and reinsert them as soon as the mouse leaves.
So, is there a way to remove the handler on a single element after the event is bound to all current and future elements?
Thanks in advance!
You don't need to unbind the click event on the element when the mouse enters. I know, the element click event will trigger when you click an inner element with the click event bound, right ? you can stop that:
The click handler of the inner element must look like this:
$("some inner element").click(function(event) {
//That's what are you looking for ;)
event.stopPropagation();
//You code here
});
event.stopPropagation() will prevent the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
Is it possible to trigger an event on some object with a custom event object?
i.e.
$('#Element1').click(function(event){
console.log('Element1 clicked', event);
}
$('#Element2').click(function(event)
{ //handle click on one element
//optionally modify the event object
event.target=Something;
//Trigger the event handler(s) on some other element using modified event object
$('#Element1').click(event);
});
A bit of background:
In my instance Element2 is an almost identical clone of Element1 but with different position. When Element2 is clicked that click should be forwarded to Element1.
I already have code to identify the correct child of Element1 according to which child of Element2 was clicked but the click event handler on the child of element 1 requires the pageX and pageY properties to be set correctly and .click() omits these properties entirely.
It does not suffice in my example to do a deep clone and include the event handlers because the target property is incorrectly set.
One workaround in my instance would be for the cloned element to retain a reference to the original element (and for every child) and the handler to check for that reference, however, I would prefer a solution where the handler has no knowledge of the cloning process - not least because there are a LOT of handlers to modify!
I am not understand well your background logic, but you can try with trigger from jQuery. You can trigger event reusing the event object:
$('#Element1').click(function(event){
console.log('Element1 clicked with changed event: ' + event.something);
});
$('#Element2').click(function(event){
event.something = "Something";
$('#Element1').trigger(event);
});
You can try with .trigger() it accepts an event object as the argument
$('#Element1').trigger(event);
Demo: Fiddle
When I access <div> or <p> elements by class with jQuery for a click function, it repeats the event by how many elements are in the array or stack. So, if I have 3 <div> elements on top of each other or next to each other, the one on the bottom, or the one to the right, will go through the event once and the one on the top or the left will go through the event 3 times.
Am I doing something wrong? Or is this not meant to be done with jQuery?
[revision]
sorry if i worded this in a confusing way. here is a link... you will better understand my problem there. just add a couple new elements via the form and click on them.
http://jsfiddle.net/rNj6e/
Now that you've posted a fiddle showing the problem, I can actually answer. The problem is that you bind the click event handler to .dp inside the click event handler bound to #add. So what happens is this:
You fill in the form and click #add, which creates a new element with class dp and appends it
It then binds a click event handler to every element with class dp (there's only 1, the 1 we just added)
You fill in the form again, click #add, which repeats steps 1 and 2, so it binds another click event listener to the first .dp element, and binds one to the new element.
Repeat as necessary, binding more and more event handlers to the existing elements every time you click #add!
To fix this, you need to bind the event handler to .dp outside of the #add event handler. The problem is that you're creating new .dp elements on the fly, so just using .click won't bind to elements that are not in the DOM yet. To solve that, you can use delegate, which binds an event handler to elements matching the selector now and in the future:
$("#preview").delegate(".dp", "click", function(event){
alert(this.id);
});
Here's an updated fiddle.
Try:
$(".some_class").click(function(event){
alert(event.target.id);
}).children().click(function(event) {
return false;
});
This should prevent the click event from bubbling through the children, this happens when you click on the children contained in the div.
You are recieving a blank ID because the target of your clicks is most likely the child you clicked and you haven't given it an ID.
To prove this try...
$(".some_class").click(function(event){
alert(event.target.nodeName);
});
which alerts you the nodeName (the name of the html tag) you just clicked.
Change it to this:
$(".some_class").each( function () {
jQuery(this).click(function(event){
alert(event.target.id);
});
});
Im trying to remove a row. But i can't figure it out really.
First of all I've got a button that'll add a new row, that works.
But I want to give the user the possibility to remove the just added row.
The row has an 'div' inside what acts as an deletebutton. But the deletebutton doesn't work?
I'm I missing something?
Greet,
Juki
function addrow() {
$("#container").append("<div id=\"row_added\"><div class=\"deletebutton\" id=\"delbuttonnumber\"></div><div id=\"addedcolor\" class=\"colorcube\"></div></div>");
}
// deleterow the row
$(".deletebutton").click(function() {
rowclrid = "#" + $(this).parent().attr("id");
$(rowclrid).remove();
});
My guess is that you have assigned the click handler before adding the new content, so the handler is not attached to this particular element. You can use .delegate() to listen for events on all elements below a particular parent element, whether or not they already exist:
$('#container').delegate('.deletebutton', 'click', function(){
$(this).parent().remove();
});
This listens for all click events that happen inside the element #container using a feature of the DOM called event bubbling, then checks to see if they happened on a .deletebutton element, and, if so, calls the handler.
Note also the simplified code inside the handler.
I think what you need to do is use the live method. This will add the events for any new item that is added to the DOM, not just the ones that exist when you set the click handler.
// deleterow the row
$(".deletebutton").live('click', function() {
$(this).parent().remove();
});
You also don't need to get the row by getting the ID - it's simpler in the way above.