I am creating some elements and appending it, and its working fine but when I want to call any function or want to call any jquery that not work, but when i put that elements directly instead of appending then it works properly. In all to say that appending element does not call any function or anything.
JQUERY CODE:
var cart_content = jQuery($.create('li', {}, [])).append($.create('span',{}, [av_title]),$.create('img', {"src":"images/delete_icon.png", "class":"cart_content", "alt":"delete", "title":"Delete"}, []));
$(".advertise_cart").append(cart_content);
$(".cart_content").click(function(){ alert("Hello"); });
<ul class="advertise_cart" id="advertise_cart_id">
<li>
<span>Inner Content 1</span>
<img src="images/delete_icon.png" class="cart_content" alt="delete" title="Delete"> <!------ On clicking on this will show alert box, but on clicking on appended element will not call alert box or anything ----->
</li>
</ul>
Thanks in advance
The problem you're experiencing is the result of the elements not being present in the DOM when the events are bound. To work around this, you can use delegate() or live():
$('body').delegate('.cart_content','click',
function(){
alert('hello');
});
JS Fiddle demo.
References:
live().
delegate().
Do not use .click function.
Use live function it work for newly added element in DOM
like this :
$(".cart_content").live(function(){ alert("Hello"); });
Using the live function to handle your event might help.
The only thing I'd add is that the live function means that the handler will continue to be applied to content that matches the selector at any point in the future (until and unless you call unbind). That is probably what you want here. If it isn't, you could write could that would add the click handler after a brief delay (say, 1.5 seconds). Or to be a little more sure, you could write code that would check for the presence of .cart_content every 100 milliseconds until it's found, and then add the click handler. So this approach would add the click handler only once. If something caused another .cart_content were added later, the click handler would not automatically be added.
Related
I use the following jquery in my page.
var j = jQuery.noConflict();
j(document).ready(function(){
console.log(j("#label_19"));
j("#label_19").on("click",function(){
alert("Clicked");
});
});
When document loads, the element (it's a checkbox) appears in the console. But when I click the checkbox, the alert is not thrown. But when I copy the same code (as below)
j("#label_19").on("click",function(){
alert("Clicked");
});
in console panel and press run. Now when I click the checkbox, the alert is thrown. What could be the issue in this case?
Updated:
What I observe in console is:
Object[input#label_19.document_label attribute value = "Check-In"]
The HTML markup is
<input id="label_19" class="document_label" type="checkbox" value="Check-In" name="label[19]">
The only explanation that fits the facts you've presented is that there is code running after your ready callback but before you click the element that replaces the element in question. Some kind of ajax callback or similar.
You'll need to look through your code to find the place where that's happening. Things to look for are any html calls on elements that contain the #label_19 element, or (if there's a mix of jQuery and non-jQuery code) assignments to innerHTML.
You can use event delegation to solve this, which may or may not be the best answer depending on what your code is doing. That looks like this:
var j = jQuery.noConflict();
j(document).ready(function(){
console.log(j("#label_19"));
j(document).on("click", "#label_19", function(){ // This is the changed line
alert("Clicked");
});
});
There, instead of hooking click on the actual element, we're hooking it on document but then asking jQuery to only tell us about clicks that pass through elements matching the selector we give it as they bubble. That way, the fact that something is destroying and recreating the #label_19 element doesn't matter, because we're not hooking a handler on that element. We're hooking the handler on document and checking, when the event occurs, if it passed through something that matches that selector.
But I wouldn't just blindly use event delegation, I'd find out what's really happening with that element.
Without seeing the rest of your code—including HTML and related DOM elements—have you considered using j(window).load() instead of j(document).ready()
var j = jQuery.noConflict();
j(window).load(function(){
console.log(j("#label_19"));
j("#label_19").on("click",function(){
alert("Clicked");
});
});
As explained here:
The window load event executes a bit later when the complete page is fully loaded, including all frames, objects and images. Therefore functions which concern images or other page contents should be placed in the load event for the window or the content tag itself.
I had a similar issue, it got resolved after i wrapped it in a window.load
(function ($) {
$(window).on('load', function () {
//MY click calls inside here
});
})(jQuery);
Hope it helps!
Consider the HTML
<ul>
<li>Default item</li>
<li>Default item</li>
</ul>
<button>Append</button>
and the jQuery code
$('button').live('click', function(){ //This action is done by an external script.
$('ul').append('<li>Added item</li>');
});
$('ul li').append('<b> x</b>'); // This action is done by me
The thing is, I need to append the "x" mark to all newly added elements to the dom.
In this case only default elements are appended with the "x" mark.
Newly added elements are not appended by "x".
I am sure the work will be simple, but cant get it right !!
Live example - http://jsfiddle.net/vaakash/LxJ6f/1/
Your code is running right away, and so of course it only has access to the elements that already exist. The code adding new list items is running later, when the user clicks something. You'll have to hook into that process as well.
One way is to hook the same event they are, and run your code from the event handler. Be sure to hook the event after they do.
Their code:
$('button').live('click', function(){
$('ul').append('<li>Added item</li>');
});
Your code (after theirs):
$('button').live('click', markButtons);
markButtons();
function markButtons() {
$('ul li:not(.marked)')
.addClass("marked")
.append('<b> x</b>');
}
Updated fiddle
The reason I said your code needs to do its hookup after their code is that jQuery guarantees the order of the calls to event handlers: When the event occurs, the handlers are called in the order in which they were attached. By attaching your handler after they attach theirs, you guarantee that your handler is called after theirs has done its thing.
If you're worried about the order getting mixed up, you could always delay your code slightly:
$('button').live('click', function() {
setTimeout(markButtons, 0);
});
That way, your code is guaranteed to run after all of the event handlers hooked to the click have been run.
You have to repeat the "x" code in the event handler:
$('button').live('click', function(){ //This action is done by an external script.
$('ul').append(
$('<li>Added item</li>').append('<b>x</b>')
);
});
Of course you could also just put the bolded "x" right in the <li> when you append it ...
edit If you can't change the click handler, then the only thing you can do is either poll the DOM, or else try something like what #T.J. Crowder suggests (which I think should work just fine).
Why not just do it in the initial append?
$('button').live('click', function(){ //This action is done by an external script.
$('ul').append('<li>Added item<b> x</b></li>');
});
Since it sounds like you don't have access to the script that is doing the append, you could bind your own handler.
$('button').live('click', function(){ //This action is done by an external script.
setTimeout(function() {
$('ul li:not(li:has(b))').append('<b> x</b>');
}, 10);
});
This will select li elements that do not currently have a nested b element, and it will append one.
I placed it in a setTimeout since you may not be able to guarantee the order of execution of the handlers.
If you prefer valid CSS selectors, do this instead:
$('ul li').not($('li b').closest('li')).append('<b> x</b>');
or this:
$('ul li').not(function() { return $(this).find('b').length; }).append('<b> x</b>');
JSFIDDLE DEMO showing the two separate handlers.
I have a problem that happens only on a specific computer(FFX 3.6.13,Windows 7,jQuery 1.4.3).
Sometimes document.ready is fired but when trying to get elements to attach the event handlers,the elements don't exist!
the code goes something like this:
$(function(){
window.initStart = true;
$("#id_of_element").click(function()...);
window.initEnd = $("#id_of_element");
});
the window.initStart/End are there for debugging,sometimes this code runs just fine,but sometimes window.initEnd is just a empty jQuery set(length == 0).
What this means is that document.ready is always fired,but sometimes it is fired before elements are available.
Does anybody had this problem? what could the problem be?
One way that you could try to get around this would be with using .live instead of .click. The following code
$('#idOfDiv').live('click', function() { doStuff(); });
will attach the input function to the click event of everything that is dropped on the page with an id of 'idOfDiv' as soon as it makes it to the page. Whereas .click executes immediately, this should be attached no matter what time the divs make it to the page.
Cheers
There's an article on SitePoint that demonstrates how to sense when certain dom elements are available.
Also I know this is a version specific issue, but if you were on Jquery 1.5 the deferred objects stuff would be useful here.
It seems that this code:
$(function(){
$('.show_hide_login').toggle(
function (){
alert('show');
$("div#fullpage").show();
$("div#loginbox").show();
},
function (){
alert('hide');
$("div#loginbox").hide();
$("div#fullpage").hide();
}
); });
Any idea on why it would be running twice when I click on either link (two, one is a div and one is an anchor)?
How many elements do you have with the .show_hide_login class? I'll guess you have two of those. In which case, $('.show_hide_login') result contains two elements, and toggle() is executed for each of them.
This isn't an answer to your question, but you could clean up your code a bit like so:
$(function() {
$('.show_hide_login').toggle(
function() {
alert('show');
$("#loginbox,#fullpage").show();
}, function() {
alert('hide');
$("#loginbox,#fullpage").hide();
});
});
As to your actual problem, I suspect Nick's guessed the culprit. Check out this demo to see the result of binding the same event twice: http://jsfiddle.net/9jPLv/
In addition to adding an alert prior to the binding of the toggle event, you could add in an unbind() and see if that solves the problem, like so:
$('.show_hide_login').unbind().toggle(
If that solves it, the toggle binding is definitely being run twice, so you'd just have to figure out why.
my answer is just a kind of checkpoint,i had the same issue but for different reason. I did include the script file in base page as well as child page. this resulted in toggle running twice if you have this problem check that the script is added only once.
It might be the same issue i was having.
so if you got an element with a script tag in it - then you move that containing element or wrap it with another tag in jquery - then the ready function in jquery is executed again - thus binding a second toggle function to your element.
as suggested $('.show_hide_login').unbind().toggle( is a workaround that does work, but better to try moving your javascript code to the head or bottom of the page.
I have a code chunk of html:
<div id="chunk-1" class="chunk">
<div class="chunkText">Text<div>
<button class="addChunk">Click Me</button>
</div>
<script>
$(".addChunk").click(function(){create_chunk(this.parentNode)})
function create_chunk(after_this){
$(after_this).after(chunk_html)
var i = 0
$("div.chunk").each(function(){$(this).attr('id', "chunk-" + i++)})
}
</script>
Now, this works, but only for the .chunk that is statically rendered on the page. When I press the button a second chunk appears, but that button does not work. If I add the html for two or more chunks to be rendered, each one works, but the buttons for the chunks it creates do not. What should I do?
The event handler in the below line attaches the click event to the element matching the selector when you add the handler.
$(".addChunk").click(function(){create_chunk(this.parentNode)})
you can use the live handler to do this. the following code will solve your problem
$(".addChunk").live('click'. function(){create_chunk(this.parentNode)});
Use the "live" jQuery function.
$(".addChunk").live('click'. function(){create_chunk(this.parentNode)});
The problem is that you're binding to a single element. The "live" option will monitor the document for any clicks on elements that have the ".addChunk" class.
replace
.bind()
with
.live()
or even better use
.delegate()
which is in your case:
$('#chunk-1').delegate('.addChunk', 'click', function(){create_chunk(this.parentNode);})
furthermore, go to www.jquery.com and read the documentation.