I have a page where the contents displayed from database using jquery and ajax. There are lot of processes in the page like Adding new content and image, Editing, Deletion etc and all are using ajax. But now some of event functions like click , mouseenter are not working in the content which where displayed from the database.
for example: This is how i display images in the page
for(var i=0;i<images.length;i++)
{
$("#content").append("<img src='"+images[i]+"' class='img' width='300' height='200' />");
}
Images are displayed properly. but when trying to do somthing on click event in images like this, its not working
$("#content .img").on('click',function()
{
//here comes my process, but its not working
}
Please help me to solve this problem.
Try:
$("#content").on("click", ".img", function() {
});
The problem is that $("#content img") creates a jQuery collection of elements that exist at the time it is run. When you start dynamically adding new elements, they don't have the event listener applied to them automatically.
What $("#content").on("click", ".img") does is provide for event delegation. So what's really happening is an event listener that is applied to $("#content") but only fired when that event comes from a descendant with a matching selector (.img in this case).
More info at http://api.jquery.com/on/.
Try like this
$(document).on('click', '#content .img',function()
{
...
});
This problem will always arise when you are trying to add some dynamic content. So,to resolve this always keep in mind some point.
All use some static element to reference the dynamic you are trying to apply event on.
Example : in your case try using
$("#content").on('click', 'img', function(){
//try using this way make your code works fine.!
});
Related
I have a problem.
I'm looking for document-wide click events, but large chunks of my site is loaded through a div with an innerHTML object.
<div id="contentHolder">
<script>
document.getElementById("contentHolder").innerHTML='<object type="text/html" id="content" data="article.html"></object>';
</script>
</div>
A listener like this:
$(document).on("click", function (event){
alert("Click");
});
Only registers clicks on elements outside of the ContentHolder.
I realise that the loaded content probably has its own document.
Do any of you know of a way I can refer to this content inside the Object? :)
I read up on jQuery delegation, but it didn't seem to offer a solution to my problem.
I set up a semi-working example on Codepen. It doesn't seem to allow loading external pages, understandably so - but the problem persists even without any actual loading. The example works locally.
Edit
I solved the problem myself. Instead of using an HTML Object for a container, you can use jQuery append and the listeners will remain active not only from the sub-document's events but also the parent's.
$.get('document.html', function(result) {
$('#container').append(result);
});`
You can try this:
$('#contentHolder').on('click', '.class-to-be-named', function() {
// do your click stuff
});
It will bind the click event on #contentHolder and whenever you click within #contentHolder it will lookup if element #contentHolder was clicked, when is it calls the callback.
I solved the problem myself. Instead of using an HTML Object for a container, you can use jQuery append and the listeners will remain active not only from the sub-document's events but also the parent's.
$.get('document.html', function(result) {
$('#container').append(result);
});
I have this jQuery code. What it does is when you click a div button (#logogo), it shows a resized image in the stage.
$(document).ready(function(){
$("#logogo").click(function(){
$(this).addClass("active");
$("#bannergo").removeClass("active");
$("#innerstage").html("<img id=\"magiclogogo\" src=\""+document.getElementById("logogo").title+"\">").hide().fadeIn('fast');
});
});
What I want to happen next is that when you click on the image (hence the magiclogogo id), it would be able to show (or to load) the image in its original size.
So far I tried putting an id and tried to make a jquery function for it but it does not work.
If it's not possible, is there any probable way to be able to zoom the image to its original size?
$(document).on("click", "#magiclogogo", function(){
// your code here
});
So, what I'm guessing is that somwhere else you have something like:
$('#magiclogogo').on('click', function() {
//More code here...
}
If the dom element isn't loaded yet, then it will not attach the event correctly. In other words, the event must be attached once the DOM element has been loaded or attach the event to the parent and look out for the source of the event (jquery has a shorthand for this, which is the other answer).
You can use the jQuery constructor to create the element and then attach the event.
var image = $("<img id=\"magiclogogo\" src=\""+document.getElementById("logogo").title+"\">");
image.on('click', function(){
//Your code here
});
You then can add it to your container with append.
$('#innerstage').append(image);
Im creating the same button in a loop as long as there is a certain condition, and I want to run the same jquery event handler for those buttons.
The problem is that the event handler only works for the first button generated.
My button is generated like this:
<?php while($row_c= mysqli_fetch_array($result_comments))
{ ?>
<button name="comment" id="comment" class="button_comment" value="Post">Post</button>
<?php } ?>
and the jquery im using is this:
$('.button_comment').click(function()
{
//some staff thats done here
});
What should do, so that the event handler works for all buttons that are generated?
Thank you
Your jQuery should work. Note that your buttons form invalid HTML/DOM: The id on an element must be unique. But since you're also using a class (which doesn't have to be unique), and that's what you're using in your jQuery selector, that works: Live Example | Source
Perhaps when you were trying it and it wasn't working, you were using $("#comment").click(...), which would not work, because of the id issue.
Check in firebug:
var buttoncomments = $('.button_comment');
console.log(buttoncomments);
Bind the control in question to a variable so you're certain that it's that one you're working with.
$('.button_comment').click(function()
{
var that = $(this);
"What should do, so that the event handler works for all buttons that are generated?"
A Fiddle would be a good way to show us the context of your problem ;)
Your code is valid because it will attach a handler to every element having 'button_comment' as a css class
Did you put this code inside a dom ready function ?
$(function(){
/* code here */
});
You can use event delegation
This mean you have to attach the event listener to the first common ancestor of those buttons. This is a good choice when many elements have to trigger the same routine an even more if some of them may be added to the DOM in the futur via AJAX (This keep the page from having to many event handlers attached to it)
Delegation syntax
// Event delegation
$( "#Ancestor").on("click", '.button_comment', function() {
alert( $( this ).val() );
});
Take the ID off from your php code. Remember ID's should be unique elements. Also, change your jquery from:
('.button_comment').click(function()
{
//some staff thats done here
});
to
('.button_comment').on('click', function()
{
//some staff thats done here
});
The on event will perform what you tell it to do at the time you tell it to do, so it does it pretty much at runtime. If you use your previous code, the element must exist at page load time for it to work.
I have a div that when the page is loaded is set to display:none;. I can open it up using this simple code:
$(".field-group-format-toggler").click(function()
{
$(".field-group-format-wrapper").css({'display':'block'});
});
Once it's opened, I'd like the user to be able to close it so I tried using the .is(':visible') function and then wrapping my original code in an if statment but this time using display:none;
if($('.field-group-format-wrapper').is(':visible')){
$(".field-group-format-toggler").click(function()
{
$(".field-group-format-wrapper").css({'display':'none'});
});
}
This does not seem to work though and I am not getting any syntax errors that I know of.
I also tried this:
if ($('.field-group-format-wrapper').is(':visible'))
$(".field-group-format-toggler").click(function () {
$(".field-group-format-wrapper").css({'display':'none'});
});
... but that did not work either.
You can just use the toggle function:
$(".field-group-format-toggler").click(function()
{
$(".field-group-format-wrapper").toggle();
});
This will show the '.field-group-format-wrapper' elements if they are currently hidden and hide them if they're currently visible.
FYI the reason your code snippet in your question wasn't working is because you're only checking the visibility of the elements on dom ready, rather than on each click - so the event handler to show the elements will never be attached.
I guess your function is only being called on page load at which time all divs are hidden.
Why not check the visibility in the click event handler?
$('.field-group-format-toggler').click(function(){
var $wrapper = $('.field-group-format-wrapper'); //Maybe $(this).parent()?
if($wrapper.is(':visible'))
$wrapper.hide();
else
$wrapper.show();
As already mentioned, you can use the toggle function to achieve what you want.
To add a bit of extra information, when attaching events like you're doing, you're actually using a subscription model.
Registering an event puts it in a queue of events subscribed to that handler. In this case, when you add the second event to change the CSS, you're adding an event, not overwriting the first one.
Whilst thing isn't actually causing your problem, it's worth being aware of.
I have a simple mouseover event that I am trying to work on elements that are loaded with ajax. For example I have a div that when you mouseover hide/show another div. When I load these divs through ajax they no longer work. For example :
<div class="block">
<div class="something">MOUSEOVER</div>
<div class="else" style="display: none" >HI</div>
</div>
$(document).ready(function(){
//using on hoping to catch the mouse events
$('.block').on('mouseenter',function(){
$(this).children('.else').fadeIn('fast');
});
$('.block').on('mouseleave',function(){
$(this).children('.else').fadeOut('fast');
});
});
This works fine straight up like this :
But when I load those elements from another page :
$j('#trigger').load( url + " .block");
The mouse events are no longer recognized. I thought this is what live, on, delegate were for. Can someone help me figure this out please.
One possibility is to change your code like:
var myFunc = function() {
$('.block').on('mouseenter',function(){
$(this).children('.else').fadeIn('fast');
});
$('.block').on('mouseleave',function(){
$(this).children('.else').fadeOut('fast');
});
}
$('#trigger').load(url + " .block", function() {
myFunc();
});
to make this functions like mouseenter or mouseleave in the loaded content possible.
The other possibility is $.live();. Like:
$('.block').live('mouseenter', function() {
//here your code
});
This is exactly what methods like on and delegate can be used for, but they have to be used correctly.
As events bubble from the element on which they originated up through the DOM you need to capture the event on an ancestor element that already existed:
$(".someAncestor").on("mouseenter", ".something", function() {
//Executed when .something triggers the mouseenter event
});
It looks like you are loading the entire .block element via AJAX, so you will need to bind the event somewhere higher up the DOM tree (probably the element inside which you append .block).
You can put the trigger event to load on AJAX success.