Following is a piece of jquery code that is driving me nuts
var count = 0;
$('#some-element-id').click(function(){
var currentElement = '#new-div-id-'+count;
$(currentElement).after($('<div id="new-div-id-'+(++count)+'">Hello World!<span class="delete_me">x</span></div>'));
});
$(".delete_me").click(function () {
alert('Deleting!');
});
Now accordingly when I click on element with id some-element-id a new div is inserted and I see the x character. But clicking x doesn't do any thing. No error. As per http://api.jquery.com/after I can insert elements this way which is working fine. I can ee the new elements in DOM tree using Firebug. Now why no event is fired when I click on span? For some unknown reason I am forced to use jQuery 1.3.2 but that should not be a problem.
Update 1
I understand that I am trying to bind an even to an element that doesn't exist in the DOM. But please note that even is not fired, the event will be fired after the element is embedded in the DOM. I used following code and even it doesn't work
$("span.delete_me").live('click',function () {
alert('Deleting!');
});
There is no error on the console.
Update 2
Here is the actual rendered code http://jsfiddle.net/8sjcZ/
See http://jsfiddle.net/vKwm6/
Use the live method:
$(".delete_me").live("click", function () {
alert('Deleting!');
});
At the time you call the .click method in your post, the "x" doesn't exist.
try
$(".delete_me").live('click',function () {
alert('Deleting!');
});
your .click() is not working because the .delete_me class is not in DOM at time you call .click() so binding never takes place. .live() ensures that binding takes place for elements which are created at runtime.
hmmm you need to do it with live()
$(".delete_me").live('click',function () {
alert('Deleting!');
});
live() will apply to dynamically added objects
http://api.jquery.com/live/
Related
I'm new to jQuery and wrote the following code. Strangely, the jQuery code somehow works even after the time delay. alert() gets called onclick after the time delay. The same thing in javascirpt with .addEventListener() would give error since the element doesn't exist. Can someone explain me how and why jQuery does this?
<div id="outerId" class="outerHolder">
<div class="innerHolder"></div>
</div>
JS Code:
$("#outerId").on("click touchstart", "#newTag", function (e) {
alert("OK");
});
setTimeout(function() {
var tag = '<div id="newTag">Hello World</div>';
$("#outerId").append(tag);
}, 5000);
Here is a jsFiddle of the same: https://jsfiddle.net/jb6pmovb/
My guess is that your query is about the way on() is binding to to the object. When on() is first ran, #newTag does not exist, so you might be wondering why it still triggers when appended after a delay.
This is because #outerId is the object being bound to, which does exist the time on() is called. When you append #newTag, it doesn't alter the outer binding, it simply looks over the children when it is clicked.
With regular js I assume you are using addEventListener, which requires you bind the event to the specific object. If you do try and use that directly on #newTag before it exists, it obviously won't work.
You can see by the docs for on():
selector
Type: String
A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element.
If you are wondering how the click works on an element which is not there at the time of page load, then that's because you are attaching the listener on the outerDiv and using .on
Check out this for the difference between using .on and .click
I am using jquery 1.8.3 so trying to change from using .live() to the .on()
Like many others on SO - cant get it worrking - what am i doing wrong? If its so wrong to use .live()
why does it work so consistently well!
( txtbxhost is a textbox NOT added dynamically its already in the DOM )
$('#txtbxhost').live('input', function() {
// works everytime
});
$('#txtbxhost').on('change', 'input', function() {
// fails everytime
});
and
$('#txtbxhost').on('change', '#txtbxhost', function() {
// fails everytime
});
and
$(document).on('change', '#txtbxhost', function() {
// fails everytime
});
i'm out of ideas here ... help ...
You probably want:
$(document).on('input', '#txtbxhost', function() {
// code here
});
Check this fiddle
Also, change works only when you blur - In other words click elsewhere after you change text in the texbox.
So, this should work too
$(document).on('change', '#txtbxhost', function() {
// fails everytime
});
Check the updated fiddle
You need to understand how on() differs in behavior to live().
There are really two main approaches to using on(). If the element you are interested in exists on the page at load, you can consider directly binding the event like this:
$('#txtbxhost').on('input', function () {
// some function
});
This would work in much the same way as change() would.
If the element may not exist at page load then you need to work with delegated events. To do this, you must attach the on() to an element that does exist at page load. This can be document or would typically be the closest ancestor to the element the you are interested in that exists on page load. This delegation works by looking at the event bubbling up the DOM element stack to the element to which you bind on(), you then look for a selector within that element to apply the callback to. This looks like this:
$('#some_static_ancestor').on('input', '#txtbxhost', function () {
// some function
});
$(function(){
$('#txtbxhost').on('input', function() {
// do stuff
});
});
That should do it.
In your case you don't really need to use .on(), it's main purpose is to deal with dynamically created elements.
First off, I don't want another plugin to do this... jQuery already has the functionality to do 99% of what I want with the live() method.
Basically, I want to change this:
$(".some-button").live("click", function() { alert('yay!'); });
into this:
$(".some-button").live(function() { alert('yay!'); });
So, what I'm saying is that I want to fire a method right away when an element is added to the page... jQuery can already do this SOOO close because that's how it adds the "click" even in my example above!
How can I achieve this without adding another plugin, but rather, just by using the same functionality as the "live" and "die" methods do?
Here's some code I've copied and pasted that seems to work in fiddle, at least on FF: http://jsfiddle.net/KQBzn/
$(document).bind('DOMNodeInserted', function(event) {
alert('inserted ' + event.target.nodeName + // new node
' in ' + event.relatedNode.nodeName); // parent
});
source: http://forum.jquery.com/topic/how-to-get-notified-when-new-dom-elements-are-added
There isn't any cross-browser way to do this, and there's nothing in jQuery itself that allows it.
You'd have to use a plugin, or just manage invoking code for your new elements manually.
The the live()[docs] method and the delegate()[docs] method are only for event handling. The code you give them will only respond to browser events, not to DOM manipulation.
The reason .live() won't do this is because it does not run any code when adding new elements to the DOM. It isn't monitoring any DOM changes. Rather it is responding to events that bubble to the document, and invoking the handler if it matches the selector you gave it.
You can't do it with the .live() method.
It seems jQuery should add a feature to the .live() method so that if its used with a specific keyword like 'created' instead of an event name then it will let you execute a function for the created element. That'd be cool! For example, the ideal scenario would be like this:
$('.foobar').live('created', function() {
// do something with each newly created .foobar element here.
});
I am trying to use SimpleBox jQuery plug-in on my website. I have the code such that everytime the user clicks on a div of class "link", a SimpleBox is invoked.
I also have another button that uses javascript to dynamically create divs of class "link" to my page. However, when I try to click these divs, the SimpleBox is not invoked.
<script type="text/javascript">
function createLinkDiv()
{
var parentDiv = document.getElementById ("right");
var linkDiv = document.createElement("div");
numDivs++;
linkDiv.setAttribute("class","link");
linkDiv.setAttribute("id",numDivs);
parentDiv.appendChild(linkDiv);
}
$().ready(function() {
$(".link").click(function(event) {
event.preventDefault();
$("#simplebox").simplebox();
});
$(".close_dialog").click(function() {
event.preventDefault();
$("#simplebox").simplebox('close');
});
});
</script>
Any idea why? Any help would be appreciated! Thanks!
For Dynamically added items use .live() or .delegate() to attach event handlers
$(".link").live("click",function(event) {
event.preventDefault();
$("#simplebox").simplebox();
});
Or
$("#right").delegate(".link","click",function(event) {
event.preventDefault();
$("#simplebox").simplebox();
});
Out of context
I suppose you've placed the the createLinkDiv function since you're calling it through inline javascript. Calling functions via inline javascript is a bit of out of fashion these days. Binding those events in code helps to keep your javascipt code easily maintainable.
$("#createLink").click(function(){
$('<div/>').attr({"class":"link","id":"link_" + $(".link").size() })
//Id shouldn't start with a number (not in HTML5)
.click(linkClick)
//Now you don't have to use live
.appendTo("#right");
});
As a side note, the $().ready() syntax is deprecated; it's better to use $(document).ready or just call $ with a function as a parameter.
To answer your main question, the .click method only binds to elements that exist when it's called. So when you add elements to the DOM later, you're not launching the simplebox on click because the handler hasn't been bound. You could either use .delegate to attach event handlers, or you could add the onclick directly in the creation of the DOM element.
The accepted answer is out of date now. The live() method has been removed from jQuery 1.9 and replaced with the on() method.
The syntax for on() is
$(element).on(event, selector, handler)
So in #jnfr's case, one of his handlers could be re-written as
$(document).on("click",".link",function(event) {
event.preventDefault();
$("#simplebox").simplebox();
});
Hopefully this will be of use to anyone arriving here and getting errors when using live().
I have an group of checkboxes with id's starting with somename and I want catch the click event of these checkboxes. Previously I have done this through jQuery. i.e.:
$("input[id^='somename']").click(function(){
// my code follows here
})
but this is not working this time around. Why?
P.S. The element is created via JavaScript after the page is fully loaded after making some ajax request. I don't know if this may be the problem?
just use live if elements are created after the page is loaded.
$("input[id^='somename']").live('click', function(){ // my code follows here })
P.S : Your search selector is "somename" but you search it on the attribute ID, are you sure that you don't want :
$("input[name^='somename']").live('click', function(){ // my code follows here })
instead?
This indeed could be the problem. Replace .click with .live()
$("input[id^='somename']").live('click', function(){ // my code follows here })
and you should be fine.
Since a call to .click is just a shortcut for .bind('click', fnc), this will not work if the element is not in the DOM when calling this. Even better than using .live() would be to use .delegate(). Have a read:
.live(), .delegate()
Using the standard binding functions only works on elements that exist at the time of the bind. You need to use something called event delegation, where elements further up the DOM tree are notified of events on descendant elements. The best way to do this is with .delegate():
$('#containingElement').delegate("input[id^='somename']", 'click', function(){
// your code here
});
This assumes that you have an element #containingElement that contains all the elements that you want to capture the events on.
NB that other answers recomment live. live and delegate use the same backend code, but for various reasons delegate is more efficient.
I believe that because you want this applied to dynamically created elements in the DOM you are going to have to use the the jQuery .live() method:
$("input[id^='somename']").live('click', function(e) {
// Your code
});
Instead of .click() try .change() event.