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));
});
Related
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
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.
Only problem: jquery won't trigger the click event of my anchor link for rest of the ajax loaded pages except on first page.
There are already many answers found with this topic but none of them works for me.
Things Ive tried: (pls take a look..I might implement it in the wrong way)
1.) Wrapping with div data-role="page" first before the click event:
$('a[id^="preview"]').wrap('<div data-role="page" />');
//... click event code.. see below
2.) Using the body to capture event on specified link
$('body').on('click','a[id^="preview"]',function(e) {
//... click event code.. see below
3.) Tried putting the script on head or in body.
4.) Tried putting the the script externally or within body.
All of the things I've tried fails. Just working on the 1st page.
Here's my code for the click event and works perfectly on first load (1st page):
$('a[id^="preview"]').on('click',function(e) {
alert('preview clicked');
});
Note:
I'm using $('a[id^="preview"]') because the link are dynamically created with number suffix. e.g. preview1, preview2...etc.
Try to simplify your example and add this code to see if that works if it does expand fromt here.
Demo: http://jsfiddle.net/9hpaL/
$('button').click(function(){
$('body').append('<br><a href="#">Click me<a/>')
});
$('body').on('click', 'a', function(){
alert('It works!');
});
I have a script that hijacks all links with a certain REL tag and it will update the main content area for the JS version of my site. The problem is when I had it in its own JS file the pages loaded up in the content frame (div) would not execute the code even if it had a matching REL. I attached the script into those pages and a bug occurred that would make this script execute as many times as this script was found. So if I went through 3 pages of content link clicks would execute this 3 times. 5 pages would equal 5 executions. Spent half a day on this and would really like to know what I could do better.
Here is a snippet of what I am trying to use to hijack the links.
$("a[rel='linkMain']").click(function() {
var link = $(this).attr("href");
priFrame(link, 'main', 'true');
return false;
});
Here is a snippet of my priFrame so you know how I am trying to load the data.
function priFrame(page, frame){
$('#'+frame+'frame').load('/'+page).hide(0).scrollTop(0).fadeIn(1000);
$("html, body").animate({ scrollTop: 0 }, 600);
window.history.pushState(null, page, page);
}
This is a good case for event delegation. Try this instead (note: this script should be included once for the entire page, not for each page that is dynamically navigated to):
$(document).on("click", "a[rel='linkMain']", function() {
var link = $(this).attr("href");
priFrame(link, 'main', 'true');
return false;
});
The reason for the behavior you were seeing before is as follows:
When you simply had the script on the page once, it would bind click handlers to all the a[rel='linkMain'] elements that were already present on the page. Once you had dynamically brought new a[rel='linkMain'] elements onto the page, however, those new elements were not bound as well.
When you put the code into each page that was loaded dynamically, you were binding new handlers to a[rel='linkMain'] elements that had already had click event handlers bound to them previously.
The event delegation works because the click handler is only bound to the document once. Whenever a click event occurs, we simply make sure that the event originated from a a[rel='linkMain'] element, and then trigger the handler. This allows us to dynamically add/remove elements from the page without having to keep taps on which a[rel='linkMain'] elements do/don't have event handlers bound to them already.
#jmarr beat me to it :P
$("body").on('click', "a[rel='linkMain']", function() {
var link = $(this).attr("href");
priFrame(link, 'main', 'true');
return false;
});
I have a simple link:
Test Link
I want to get an alert whenever this link is pressed, so I add:
<script>
$('#test').click(function() { alert('clicked!'); } );
</script>
and it works fine, but when i move this code to a remote javascript file, it doesn't work..
any idea why?
I've also tried this code:
$(document).ready(function() {
$('#test').click(function() { alert('clicked!'); });
});
Your second example, using the ready function, should be working. Your first example should also work provided you include the script below the element with the ID "test" (the element has to already exist when your script runs, since you're not waiting for DOM ready). In both cases, your script must be included below (after) the jQuery script.
Example when you don't use ready
Example when you do use ready
I'd check that your external file is actually getting loaded (look for 404 errors in the browser console).
Update: From your comment below, the problem is that the "test" element doesn't exist when you're trying to hook up the handler. click only sets up the handler on the element if it already exists. If you're creating the element later, you have three options (two of which are really the same):
Use the code you already have, but run it after you've created the element (e.g., in the success callback of the ajax call you're making).
Use live, which basically hooks the click event document-wide and then checks to see if the element you tell it ("#test", in this case) was clicked.
Use delegate on the appropriate container (the element within which you're adding "test"). delegate is a more targeted version of live.
live and delegate are both examples of a technique called event delegation, which jQuery makes easy for you by providing those methods.
See the links for further information and examples, but for example, suppose you're going to be adding the "test" element to an element with the ID "target". You'd use delegate like this:
$("#target").delegate("#test", "click", function() {
alert("Clicked");
});
That hooks the click event on "target", but acts a lot like you've just magically hooked it on "test" as soon as "test" was added. Within your handler, this refers to the "test" element just as with click.