jQuery Dynamic Element click event not firing - javascript

I have a dynamic page that gets loaded in. Inside that page there is a script that gets loaded in as well.
i.e. Page 1 loads Page 2. Page 2 looks like below -
<script src="someScript.js"></script>
<!-- HTML content below -->
<a class="myElement">with click event</a>
There are things in the script that run -
I run a bunch of if statements checking to make sure the right elements exists, and if not to add them.
//all of these statements fire and load in jquery as well as the missing elements
if (jQuery version is less than 1.7) load in jquery
if (certain elements dont exist) add elements
$('.myElement').each( add something to each myElement )
$(document).on('click', '.myElement', function() {
//Click event never fires for myElement
});
What could be the reason that the click event is not firing?
Cannot be reproduced with a fiddle, but you can take a look here - https://www.metsales.com/MetropolitanSales/ConstantContact/MMF/Home.aspx
Complete script can be found - https://www.metsales.com/MetropolitanSales/Script/viewFrame.js
The issue involves the Data Sheet button

Related

jQuery Mobile: Navigation does not open after page change

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.

Click event on dynamically added elements from chrome content script

I am working on building a chrome extension to be used to simplify some of the eCommerce related tasks that we perform. A content script is loaded into every page with jQuery as a dependency mentioned in the manifest.json file. The main objective is to pick out the element being clicked on the loaded page.
While the above logic works in most of the scenarios, there is a couple of websites(one mentioned below that does not seem to register the click event for a few dynamically loaded elements. For example I click on the color swatch and the content script event is triggered, however clicking on the size swatch which has been modified yields nothing).
http://www.solesociety.com/opal-crystal-blue.html
Sample Content script code
$(window).load(function(){
console.log('Content Script Loaded!');
$('body').on('click', function(e){
console.log($(e.target));
});
});
I have gone through several stackoverflow questions that suggest adding the selector as the second parameter to the on function will take in consideration the dynamically elements, but I cannot opt for that as my code relies on any element of the body to be clicked.
Additionally I also did a check to see if mentioning the element as the second parameter gave any results but the outcome was the same.
$('body').on('click', '.sizes li a', function(e){
console.log($(e.target));
});

Losing click even when page is loaded with ajax [duplicate]

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.

how to use jQuery on() in dynamically loaded scripts

If I have the following html:
<html>
<div id="main_content">
<button>click me</button>
<script src="main.js" ></script>
</div>
</html>
And main.js:
$('#main_content').on('click', 'button', function() {
console.log('you clicked');
});
If I do a full page load, then clicking the button only registers one console message. If, however I subsequently re-load main_content's contents via an AJAX request then each button click gives 2 console messages. It will give 3,4,5... messages for each subsequent AJAX load, but always one for a full page reload.
Might someone explain this behavior and suggest possible solutions?
That's because you are loading multiple copies of main.js and thus you are attaching one more event handler each time.
Every time you load the <script> one more handler is attached
<button>click me</button>
<script src="main.js" ></script>
The lesson here is that script loaded by ajax are parsed and so if you have handlers in them they are attached
If you really need to reload that script all the time, then do this in it:
$('#main_content').off("click").on('click', 'button', function() {
console.log('you clicked');
});
Otherwise put it somewhere else obviously.
I suppose you placed that script into the reloaded content and not within the head section, where all scripts usually reside, because event handler becomes detached from the #main_content each time it's reloaded? Well, there's another way:
$(function(){
...
$('body').on('click', '#main_content', function() { console.log('You clicked!'); });
});
You can place, load and execute this code just once - and won't need to reattach the event each time the block in question is reloaded.
Take note, though, that body in my code is better be replaced with a more specific element - in a perfect world, direct parent of #main_content element.
UPDATE: this is so called event delegation, and it's very well described in the .on docpage. In the previous versions of jQuery, you had to use either .live or .delegate methods.
As has already been said, main.js is getting reparsed and rerun each time you do a .load().
You have a couple of options to solve this:
Move main.js outside of the dynamically loaded content so it isn't reparsed and run each time you do a .load().
Modify main.js so the whole script only executes once.
Modify main.js to aware of being loaded multiple times so it protects against repeatedly installing the same event handlers.
These are presented in order of simplicity of implementation.
For option 2, you could put all of main.js in an if statement like this so that it only ever gets executed once:
if (!window.__main__js__defined) {
window.__main__js__defined = true;
// rest of main.js code here
}
For option 3, you'd have to protect each individual event handler that you wanted anti-dup protection with, probably using .data() on each object to set a flag that you'd already installed a given event handler.

Locating an element in a 'Facebox' box

Heres my link:
http://tinyurl.com/6j727e
If you click on the link in test.php, it opens in a modal box which is using the jquery 'facebox' script.
I'm trying to act upon a click event in this box, and if you view source of test.php you'll see where I'm trying to loacte the link within the modal box.
$('#facebox .hero-link').click(alert('click!'));
However, it doesn't detect a click and oddly enough the click event runs when the page loads.
The close button DOES however have a click event built in that closes the box, and I suspect my home-grown click event is being prevented somehow, but I can't figure it out.
Can anyone help? Typically its the very last part of a project and its holding me up, as is always the way ;)
First, the reason you're getting the alert on document load is because the #click method takes a function as an argument. Instead, you passed it the return value of alert, which immediately shows the alert dialog and returns null.
The reason the event binding isn't working is because at the time of document load, #facebox .hero-link does not yet exist. I think you have two options that will help you fix this.
Option 1) Bind the click event only after the facebox is revealed. Something like:
$(document).bind('reveal.facebox', function() {
$('#facebox .hero-link').click(function() { alert('click!'); });
});
Option 2) Look into using the jQuery Live Query Plugin
Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the DOM updated.
jQuery Live Query will automatically bind the click event when it recognizes that Facebox modified the DOM. You should then only need to write this:
$('#facebox .hero-link').click(function() { alert('click!'); });
Alternatively use event delegation
This basically hooks events to containers rather than every element and queries the event.target in the container event.
It has multiple benefits in that you reduce the code noise (no need to rebind) it also is easier on browser memory (less events bound in the dom)
Quick example here
jQuery plugin for easy event delegation
P.S event delegation is pencilled to be in the next release (1.3) coming very soon.

Categories

Resources