This question is kind of a duplicate, but the answer provided doesn't actually solve the issue. Here's the related question:
Why jQuery click doesn't work when included in a separate file
I've got a php template that has an overlay div I am dynamically populating with different content, depending upon which link is clicked. So for example, I have this in my template:
<a class="icon-search" href="#"></a>
<div id="overlay" class="hidden"></div>
In my global.js file, I have these functions:
$(document).ready(function(){
$("a.icon-search").click(function () {
$("#overlay").load("inc/search.php");
$("#overlay").toggleClass('show hidden');
});
$("#cancel").click(function() {
$("#overlay").toggleClass('show hidden');
});
});
The cancel button is in "inc/search.php"
When you click "icon-search", the overlay toggles properly, and the content of search.php gets loaded, but pressing the cancel button doesn't work, unless I move that function into the search.php file. I really hate doing this, because it makes the html really messy, and it makes reusing things difficult. Is there any way to overcome this issue, so that functions will work on elements that are included?
You need to use event delegation in order to have generated content fire events.
Lookup the .on() method in the jQuery documentation (http://api.jquery.com/on/)
Try this instead:
$(document).ready(function(){
$("a.icon-search").click(function () {
$("#overlay").load("inc/search.php");
$("#overlay").toggleClass('show hidden');
});
$(document).on('click','#cancel',function() {
$("#overlay").toggleClass('show hidden');
});
});
Using .on() will delegate click events on the document to the elements with the specified selector and this will work for all current elements (which are in the DOM when this code runs) and future elements (like those which are appended using AJAX, like when you use the .load() method).
The event handlers like you are using (which I call static event handlers), must be attached directly to the DOM object they are handling events for. That means that when you run the code to attach the event handler, the DOM object you want to attach to must already exist.
If you are running this code on .ready(), but your dynamically loaded content has not yet been loaded, then no event handler will be attached because there's no DOM object yet to attach it to.
There are two general approaches to solving this type of issue:
Run the code AFTER you've loaded the dynamic content (this is what putting the script into your dynamically loaded PHP content does).
Switch to using delegated event handling. In delegated event handling, you attach an event handler to a parent of the dynamic content that is itself not dynamically loaded and thus it already exists. Then, when a click happens on the dynamic content, that click will "bubble" up through it's parents and encounter the click handler you have. jQuery automates a lot of this for you when using the delegated form of .on() which is of this form $("#staticParent").on("click", "#dynamicChild", fn). You can read the details about using the delegated for of .on() in these references:
Does jQuery.on() work for elements that are added after the event handler is created?
jQuery .live() vs .on() method for adding a click event after loading dynamic html
jQuery .on does not work but .live does
Related
The problem is this:
I have a simple, two fields form which I submit with Ajax.
Upon completion I reload two div's to reflect the changes.
Everything is working perfect except a jQuery plugin. It's a simple plugin that can be called with simple
function(){
$('.myDiv').scrollbars();
}
It's simple and easy to use, but it doesn't work on Ajax loaded content. Here is the code I use to post form and reload div's:
$(function() {
$('#fotocoment').on('submit', function(e) {
$.post('submitfotocoment.php', $(this).serialize(), function (data) {
$(".coment").load("fotocomajax.php");
}).error(function() {
});
e.preventDefault();
});
});
I've tried creating a function and calling it in Ajax succes:, but no luck. Can anyone show me how to make it work ? How can that simple plugin can be reloaded or reinitialized or, maybe, refreshed. I've studied a lot of jQuery's functions, including ajaxStop, ajaxComplete ... nothing seems to be working or I'm doing something wrong here.
If you're loading elements dynamically after DOM Document is already loaded (like through AJAX in your case) simple binding .scrollbars() to element won't work, even in $(document).ready() - you need to use "live" event(s) - that way jQuery will "catch" dynamically added content:
$(selector).live(events, data, handler); // jQuery 1.3+
$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
$(document).on(events, selector, data, handler); // jQuery 1.7+
Source: jQuery Site
Even if I am totally against using such plugins, which tries to replicate your browser's components, I'll try to give some hints.
I suppose you are using this scrollbars plugin. In this case you may want to reinitialize the scrollbars element, and there are many ways to do this. You could create the element again like in the following example
<div class="holder">
<div class="scrollme">
<img src="http://placekitten.com/g/400/300" />
</div>
</div>
.....
$('.scrollme').scrollbars();
...
fakedata = "<div class='scrollme'>Fake response from your server<br /><img src='http://placekitten.com/g/500/300' /></div>";
$.post('/echo/html/', function(response){
$('.holder').html(fakedata);
$('.scrollme').scrollbars();
});
If you want to update the contents of an already initialized widget instead, then things gets more complicated. Once your plugin initialize, it moves the content in some custom wrappers in order to do its 'magic', so make sure you update the correct element, then trigger the resize event on window, pray and hopefully your widget gets re-evaluated.
If it doesn't help, then try to come up with some more details about your HTML structure.
I want to thank everyone of you who took their time to answer me with this problem I have. However, the answer came to me after 4 days of struggle and "inventions" :), and it's not a JS or Jquery solution, but a simple logic in the file.
Originally, I call my functions and plugins at the beginning of the document in "head" tag, like any other programmer out here (there are exceptions also ).
Then my visitors open my blog read it and they want to post comments. But there are a lot of comments, and I don't want to scroll the entire page, or use the default scroll bars, simply because they're ugly and we don't have cross browser support to style that, just yet.
So I .post() the form with the comment, and simply reload the containing all of them. Naturally .scrollbars() plugin doesn't work. Here come the solution.
If I put this :
<script>$('.showcoment').scrollbars();</script>
in the beginning of my loaded document (with load() ), will not work, because is not HTML and it's getting removed automatically. BUT !!! If i do this:
<div><script>$('.showcoment').scrollbars();</script></div>
at the same beginning of loaded document, MAGIC .... it works. The logic that got me there I found it in the basics of javascript. If your script is inside an HTML element, it will be parsed without any problem.
Thank you all again, and I hope my experience will help others.
If I understand you correctly, try this:
var scrollelement = $('.myDiv').scrollbars();
var api = scrollelement.data('jsp');
$(function () {
$('#fotocoment').on('submit', function (e) {
$.post('submitfotocoment.php', $(this).serialize(), function (data) {
$(".coment").load("fotocomajax.php");
api.reinitialise();
}).error(function () {
});
e.preventDefault();
});
});
reinitialise - standart api function, updates scrolbars.
I have a page with dynamic content from PHP and I want to use jQuery's load function to periodically refresh the div container which contains the dynamic content so that new content is displayed on top of the old content.
I using a jQuery function as follows:
setInterval(function() {
$("#ContentWrapper").load("Livefeed.php #ContentWrapper");
}, 10000);
to refresh the content container's wrapper every 10 seconds
My problem is that after the load function is executed. Click events and hover events do no properly work on the page. Initially they did not fire at all so I used Jquery live function on all click and hover events within the content wrapper and it solved the problem.
However, when the page reloads the hovers reload as well and all hidden divs with are made visible by jQuery's .show method hide. Is there any way to prevent the hover from reloading and also for the visible hidden divs to remain visible every time the .load function is called.
I'm using click and hover functions like so:
$('selector').live("click",function(){
});
and
$('selector').live("hover",function(){
});
Any help is appreciated.
Using jQuery.live is deprecated now. So don't use it. Use jQuery.on from now on. Also, .hover event is being taken down. You should use separate mouseenter and mouseleave events.
You can fix this issue by replacing .live with:
/*
If click happens inside contentwrapper, check if click target was yourSelector, if true execute this function
*/
$("#ContentWrapper").on("click", "#yourSelector", function(){
//do whatever u wanna do on click
});
To keep track of all divs that were hidden and all those weren't you need to set unique id for each div. And before you reload with .load() you loop through all divs and save their current state (hidden or visible) in an Object Array in [{ id : state },..] format. Once ajax request finishes, loop through Object array via $.map and set states for each div
You can use JQuery delegate,its primary intention is dynamically driven content:
http://api.jquery.com/delegate/
$("#Parent").delegate("selector","click", function() { });
I have my code here.
// HTML Code
<div class="article"></div>
// jQuery
$('.article').append('Toggle div');
Is it possible to use that newly created href link and toggle a div like this:
// jQuery
$('.toggle').click(function() {
$('.article').toggle('slow');
});
I have tried the above with no luck. I just get redirected to index page.
Don't use click(): it's deprecated and wouldn't work even if it weren't. Use on():
$('.toggle').on('click', function() {
$('.article').toggle('slow');
});
Also, change your a tag to Toggle div.
As to the reason why on() works and click() doesn't, you need to read jQuery's documentation. In short, the click event has been bound to an element on the page; this scope does not cover future elements that are added to the DOM. On(), however, is a delegated event:
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.
I have a problem with jQuery being lost after .load() function.
I have a element built up with jQuery UI. The problem is that when I load it from separate page like this:
$("#mydiv").load("getgroup.php?group=" + selectedGroup).html();
The getgroup.php generates something like this, depending on the GET parameter:
<select>
<option>something</option>
<option>something</option>
</select>
When loading it with load() (or post, ajax, get) the element returns unformatted... I have tried including jquery and jquery-ui plugin also in the getgroup.php file but with no luck...
Thank you
The problem is, your jquery code isn't executed automatically on dynamically loaded elements.
What you should do is, put all your jquery ui code in a function. For instance, let's say you want to call the button() jQuery UI function on the newly loaded submit elements:
function launchUiWidgets(target) {
$(target).find('input:submit').button();
}
Then, you use this function as a success callback when you load new elements - giving it target as an argument to avoid rerunning the code on all of your DOM. Let's suppose you're loading the data in a div of id "container":
$.get(
"whatever.html?name=val",
function(data){
$('#container').html(data);
launchUiWidgets('#container');
},
"html");
If my understanding is correct and the element is being inserted, but with no CSS, you may need to run .addClass after the element is loaded to apply your chosen CSS class once the element is present. However, if in your CSS you have default values for the element type predefined, e.g. select{color:#000000;width:... these should also be loaded automatically.
Per the comment below- if you are looking at your predefined handlers still being relevant for content injected by AJAX/load() calls, you can use the .live() method:
http://api.jquery.com/live/
How can I run jquery function for a .click() event on a element created by an ajax request ?
For a normal element it works, but I want to do this for an element created by the ajax request. And it's not working ...
$(".links").click(function(){alert("aaaa");})
a class="links" >1</a;
I've also tried with "links" as id.
I need it for a pagination system.
Please help :(
You need to run the code again to bind the click event handler, after the new element is inserted into the DOM. Alternatively, you may want to use .live().
use jquery live
use jquery live,
$(".links").live('click', function(){
//user code here
});
to deal with dynamically loaded doms, you should use live function.
jquery do not load page doms automatically after page loaded.
You should use live() like this:
$(".links").live('click', function(){alert("aaaa");})
This also works with elements added to document
for an onclick to every <a> element you must do like this (if this is what you mean:
$("a").live('click', function(){
alert($(this).attr("id"));
})
This attaches event to all <a> elements and also to those added afterwards.
EDIT - now the alert shows the id of the link: 'this' in this case refers to the <a> that has been clicked