This question already has answers here:
Events triggered by dynamically generated element are not captured by event handler
(5 answers)
Closed 8 years ago.
I have a page with a left nav which has two links and a main div. The main div is updated with content from the server whenever user clicks a link in the left nav. I use pjax for this.
When user initially comes to this page, the main div has a link with id somelink that shows an alert box when the user clicks the hyperlink. This is accomplished by this code:
$(document).ready(function() {
.....
$('#somelink').click(function (event){
alert("here");
});
....
});
When the second link on the nav bar is clicked, I load content from the server and update the main div. When user clicks first link, again I load content from the server and update the main div. However, this time when I click somelink nothing happens. Its as if jQuery isn't able to detect that there is a link with id somelink because it was loaded via ajax.
Is there a way to overcome this?
You need to use .on and delegate the click handler to a higher level element that isn't being replaced since it's loaded with AJAX.
$(main).on('click', '#somelink', function() {
alert("here");
});
The reason being that when you do $('#somelink'), it goes through the DOM and finds each one as it is. So, when you remove it by replacing, you either need to add that again or use .on
You've replaced the elements and so the attached events. You need to add them differently to make them automatically available after dom updates.
Try the on function:
$('#somelink').on('click', function() {});
Older jQuery versions do the with the "live" function and with even more older version you have to bind your events again after every dom update.
Related
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 4 years ago.
I create a span using PHP like this.
if ($subnetkey == 1 ) { echo ("<span class='subnetkey'>S/N of: $subnetnum</span> ");}
It works, and shows the correct data on screen. Additionally if I look at it using 'Inspect Element' its properly formatted.
<span class="subnetkey">S/N of: 780</span>
I have this script at the top of the page. I've also tried it at the bottom.
<script>
$(document).ready(function(){
$(".subnetkey").click(function() {
alert("subnet click mode");
});
});
</script>
When I click the span, nothing happens. I get no errors, and of course I don't see the alert fire.
It seems like this is a timing issue between building the page dynamically and using the page. But in case thats not it, what can I do to make the function fire?
JQuery Event Methods like click(), dblclick(), mouseenter() etc. work only for elements already created when DOM is rendered. For dynamically created elements you use on() method with the below syntax (see previous post):
$(staticAncestors).on(eventName, dynamicChild, function() {});
Since it is a dynamically created element your code won't work. Try:
$(document).on('click', '.subnetkey', function() {
alert("subnet click mode");
});
jQuery is only aware of the elements in the page at the time it runs, so new elements added to the DOM are unrecognized by jQuery. To combat the problem use event delegation, bubbling events from newly added items up to a point in the DOM which was there when jQuery ran on page load. Many people use document as the place to catch the bubbled event, but it isn't necessary to go all the way up the DOM tree. Ideally you should delegate to the nearest parent existing at the time of page load.
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 6 years ago.
I'm using Icegram (an "exit intent" modal popup plugin) on a page. We have click-to-call links on the page, and the problem is that anytime someone clicks to call, the browser sees it as leaving the page so our exit intent popup shows while people try to call, which is definitely not what we want.
So, I've tried adding a jQuery function to the call links, like this:
<style>
.hide-icegram {display:none !important}
</style>
8888888888
<div class="icegram-popup"></div> <!--div inserted dynamically by icegram's script-->
<script>
jQuery(".clicktocall").click( function() {
jQuery(".icegram-popup").addClass("hide-icegram");
});
</script>
But no matter what I do, the "hide-icegram" class does NOT get applied to the icegram popup, so it stays visible.
I noticed that <div class="icegram-popup"> is inserted in the page only when it's activated. So I'm wondering if the addClass isn't working because it's looking for the "icegram-popup" div, but it doesn't exist on page load so maybe that's the issue?
I just want the "hide-icegram" class applied to <div class="icegram-popup"> anytime someone clicks the call links. Any ideas?
If the element with icegram-popup class is dynamically inserted, for sure, your script can't identify it onload.
Try event delegation:
$("body").on("click", ".clicktocall", function() {
$(".icegram-popup").addClass("hide-icegram");
});
jQuery will start from body and look for a .clicktocall to delegate the event on click.
In my jQuery Mobile project I have an element #sidebar with a toggle icon.
In my base file, just under the #sidebar div I use the following code:
Toggle sidebar
<div id="sidebar"> ... </div>
$('#toggle-sidebar').on('click', function() {
$('#sidebar').toggleClass('visible');
});
When my page loads for the first time, toggling works perfectly fine. However, when I change pages via my main navigation the toggling does not work anymore. I put an alert inside the click function and realized that AFTER page change the alert gets executed multiple times, namely as many times as I changed the page before.
The toggling works again when I move to the other page by entering the URL in my browser and loading the page.
How can I solve this problem?
If the alert executes many times on click after changing the page it may suggest that you have new click event listener bound on every page change. Try to unbind the click event listeners on that element before binding your click listener, to avoid such situation. Sth like that:
$('#toggle-sidebar').off('click');
$('#toggle-sidebar').on('click', function() {
$('#sidebar').toggleClass('visible');
});
It may resolve the issue.
You may also take a look at jQuery event namespaces https://api.jquery.com/event.namespace/. And add namespace to your click event so it won't unbind other click events on that element that may possibly appear in the code someday.
Have a really strange issue that a colleague was facing which I managed to work around, but for the life of me cannot understand why his initial code did not work! - we have a legacy asp.net web application that is using MasterPages/Content controls and has jQuery mixed all over the web application providing some client interactivity.
Essentially there is a web form view that has a div containing a button which is initially hidden (display: none), upon clicking another menu item, this div is shown using jQuery BLOCKUI Plugin, blocking the rest of the UI and rendering the popup div into place - the user can then click the button, clicking the button should hide the containing div, and show another div that contains another two buttons - all should be simple.... but this is where it got funky:
Bear in mind none of this content is dynamically generated, all HTML elements are present within the .aspx view up front after the page is finished loading.
var blockUiRenderFrame = function (html, width, height) {
window.parent.$.blockUI({
message: html,
css: {
top: ($(window.parent).height() - height) / 2 + 'px',
left: ($(window.parent).width() - width) / 2 + 'px',
width: width
}
});
};
<div id="anotherContentFrame">
<p>some text</p>
</div>
<div id="contentFrame" style="display:none;">
<div id="myButtonContainingDiv">
<button id="aButton" />
</div>
<div id="myOtherButtonsContainingDiv"></div>
</div>
$(document).ready(function() {
$("#myButton").click(function() {
$("#myButtonContainingDiv").hide();
$("#myOtherButtonsContainingDiv").show();
});
});
<!-- A Button on the page calls this code -->
blockUiRenderFrame($("#contentFrame"), 200, 200);
What I observed occurring was what appears to be a complete loss of context, or executing the event under a different context all together... during the handling of the click event, the div elements, or indeed anything within the HTML div contentFrame all return undefined.
At any other time if I use the console/debugger, I can successfully return an element using say $("#myButtonContainingDiv").
The click event has its correct event element, I can use $(this) to get the button I clicked on, but even trying to select $("#myButton") within the actual click event handler code itself returns 'undefined'.
I can access $("anotherContentFrame") perfectly fine, at any time, including during the handling of the click event of #myButton.
The workaround I had to use in order to get this code to work was:
During the click event handler, use the following:
$(this).closest('div').hide()
$(this).closest('div').next().show()
As this was the only way I could get any reference to the DOM elements on the page to successfully hide/show them.
I can try to give out some more information if anyone wishes, I am not sure if anyone has ever seen an issue like this.
Thanks in advance!
Where's the code showing your button?
When you call $(element).click() it will try to bind to your element on the DOM that is already loaded (no async elements!). If you're loading the #myButton via a async call, you need to bind the click on a parent element and then filter the function call to your #myButton like this:
$(document).on('click', '#myButton', function(){});
This way you're sure that the element (in this case, document) existing when jQuery tries to bind the click event and it will only fire it when clicking on the filter you specified as the 2nd parameter to the .on() call, in this case, your #myButton element
Your event is not firing because jQuery doesn't know the element, because its state changed dynamically. In order to be sure to fire your click event, no matter the context, you can use
$(document).on('click', '#myElement', function(){});
By doing that, you are refering to the easiest "non dynamically generated" element, and jQuery will always be able to find your element.
You can then access your element properties with :
$(this)
This question already has answers here:
jQuery find events handlers registered with an object
(16 answers)
jQuery 1.8 find event handlers
(2 answers)
Closed 8 years ago.
I have some links that have events bound to them and some links that do not.
These links are having their click event triggered by a change in a select box.
See this fiddle
Is there a way for jquery to visit a link if there is no event bound that link?
I do not want to reference the url within the select box vlaue attribute, I want to reference the url in the anchor tag.
something like (pseudo code) -
if (link.hasEventHandler('click')){
trigger click
} else {
window.location = link.attr('href')
}
EDIT - There's a plugin that does exactley what I need to do here - https://github.com/sebastien-p/jquery.hasEventListener
File size is an issue, so I'd like to avoid using it.
I'm using the latest jquery so cannot use .data('events')
As far as I am aware you can't 'fake click' in JS. The click event trigger simply triggers the onClick JS event, and does not simulate clicking on a link in the browser, entirely. However, all you need to do is grab the href and redirect to that page using JS. I updated your fiddle with a couple of lines that do this.
http://jsfiddle.net/9j8QS/1/
$('a:not(.event-bound)').click(function(event) {
window.location.href = $(this).attr('href');
});
The selector selects all anchor tags that don't have the class event_bound.
You could implement something the Dropdown button from Twitter Bootstrap (http://twitter.github.com/bootstrap/components.html#buttonDropdowns). Bootstrap also allows you to customize your download. When you select only dropdown, it comes out to ~40kb. It doesn't even require jQuery because it's all CSS.
Looking at your code, you have to select the link with the href attribute which is same with the selected value in your combobox. Something like:
$('#nav').on('change', function(event) {
var targetHref = $(this).find("option:selected").val();
$('a[href="'+targetHref+'"]').each(function() {
$(this).trigger('click');
});
});
Assuming you have a click event for your links. If not, just give your links the same class and write a click event for that class to set the window location to the href attribute of the object.