On load instead of document ready with other javascript on page? - javascript

I currently have this bit of code going that looks for a certain class and adds the QTY text inside the class. I have to do it this way as I don't have access to the base HTML code for this portion of the site, but rather can do so via JS access.
The current code I have running is as follows:
$('.cart-product-qty').each(function() {
$(this).prepend("QTY: ");
});
But the problem I just ran into is when certain functions are performed in the shopping cart it doesn't refresh, so it ends up dropping the QTY text. Is there another method so that it keeps it there continuously even if the page "refreshes"?

Listen to the parent div underneath the products will be listed. So whenever the content changes, you can trigger your function.
DOMSubtreeModified event might be helpful.
var element = document.getElementById('div');
element.addEventListener('DOMSubtreeModified', updateQtyText);
function updateQtyText(e) {
$('.cart-product-qty').each(function() {
$(this).prepend("QTY: ");
});
}
Reference : fire a call when inner HTML changes.
This might help

Related

How do I make a JS function triggered in one HTML page edit elements defined in a second HTML page?

Basically I have two HTML pages, and both are connected to the same JS file. I want a function triggered by an event handler element in the first HTML to edit an element in the second HTML page, and then open it.
Here's a very basic example:
$("#p1").click(function() {
$("#p2el").text("TEST");
})
<button id="p1">CLICK</button>
In this example, the button p1 is defined in the first HTML, and the p2el element is defined in a second HTML page, both linked to the same JS file.
In the above example, I also used location.href inside the function. The idea being that, the element is edited, and automatically the second HTML page is loaded.
It's not working, and I don't know why. The second HTML page loads, but the element p2el is not edited.
I suspect this is has to do with data not transferring to the second HTML, but I am not sure why and what is happening exactly. I tried using localStorage inside the function, and then use the stored data as a condition that edits the element in the second HTML page...
function second() {
if(localStorage["key"] == "on") {
$("#p2el").text("TEST");
location.href = "secondpage.html"
}
}
$("#p1").click(function() {
localStorage["key"] = "on";
second()
})
... but It didn't work.
I hope somebody can help me out.
Navigating to a new page completely resets the "JavaScript envirionment".
Your JS files are reloaded, everything starts anew. Some things persist through page loads, such as local storage and cookies, but function calls certainly don't.
To do what you want to do, you'll need to:
Listen to the click event, and save the fact it was clicked somewhere.
(You're already doing this)
On page load, check the storage to determine whether or not the button was clicked at some time. If it was, do whatever you want. You will probably want to reset the stored value so this happens only once.
This will probably do the trick for you:
if(localStorage["key"] === true) {
localStorage["key"] = false; // reset the key.
$("#p2el").text("TEST");
}
$("#p1").click(function() {
localStorage["key"] = true;
location.href = "secondpage.html"
});

Cloning Objects in Google Optimize

I'm trying to clone a button in Google Optimize (or any other javascript/jQuery method) that adds an item into a shopping cart. My problem is that when I run the code or experiment in Optimize, the button doesn't trigger.
Here's my two different attempts. Method 1 via Optimizes' interface.
Select the button to copy, use the 'edit code' to get the html.
Use Insert HTML a the location of the new button, and insert the code.
Version 2 uses jQuery's clone();
$('#SOME-ID > PATH TO THE ELEMENT TO CLONE').clone().attr('id', 'ADD-ID-FOR-GTM-TRACKING').appendTo('#proPriceMobile');
What could the problem be?
Thanks in advance!
It's quite possible, that your experiment fires BEFORE your buttons loads on your page, in your actual browser.
Do you get an error message in console?
My tip would be to wait for your button to load, before applying the DOM changes. If possible, do this all via JavaScript.
For example, here you can wait for an element to load, via using a callback and setTimeout():
// FUNCTION WHICH WAITS FOR YOUR INITAL BUTTON to LOAD
function waitForElement(className, callBack){
window.setTimeout(function(){
// GRAB YOUR ELEMENT
var element = document.querySelectorAll(className)[0];
if(element) {
callBack(className, element);
console.log("Callback successfully fired and code executed...")
} else {
waitForElement(className, callBack);
console.log("This runs every second until your element is loaded on the page..")
}
},1000)
};
// EXECUTE THE CODE IN THIS FUNCTION, WHEN YOUR BUTTON LOADS IN THE DOM
waitForElement(".your-element-classname",function(){
console.log("Button has loaded in DOM...");
// NOW CLONE YOUR BUTTON
});
When I've cloned buttons in the past, I've lost all functionality on the cloned button. So you may need to rebuild that functionality on the cloned button.

Finding if `body` tag has class on Pop-up Window

I have a webpage where you can blow up the content into a pop up window using window.open.
The pop-up will have a class on its body called pop-up. Important to note, both windows use the same JavaScript file where it handles the click events.
I want to know if I am clicking in the pop-up or in the main (parent) window. Since the HTML is going to be basically the same.
Here is how I am attempting to do this. I maintain a global variable of the last clicked element and this seems to work:
$(document).click(function(event) {
window.lastElementClicked = event.target;
g_lastClicked = window.lastElementClicked;
});
I know this is good because when I check the tagName of the last clicked element it is always correct.
Then when I want to check "Where Am I" I wanted to do this:
var fromPopup = $(g_lastClicked).closest("body").hasClass("pop-up"); // the line in question
alert(fromPopup);
if (fromPopup) {
// unrelated; I need a check to do resizing if I am in the pop-up
var height = $(window).height();
$("#cvApplication").height(height - 120);
}
So it will check the last element, traverse up the DOM to the body and see if it has the class. I get false every time in the above alert. Is my logic wrong? Or is there a completely different way I need to be doing this?
They're separate windows, there's no need to track an "active" element. Each window has its own copy of the script and its own variables, event handlers, etc.
All you need in your code is
if ($(document.body).hasClass("pop-up")) { // Without the . before pop-up
// This code is running in the pop-up
} else {
// This code is running in the main window
}
I haven't checked the rest of your code, but you do not use a . when checking if an element has a class.
var fromPopup = $(g_lastClicked).closest("body").hasClass(".pop-up");
should be
var fromPopup = $(g_lastClicked).closest("body").hasClass("pop-up");

How to prevent adding elements to a DOM node?

I have a pretty disgusting issue. "Disgusting" because I do not have full control of the whole webpage and therefore have to hack my way to success.
Situation
I have my own script, which is loaded into the webpage, and a div container, that displays the pageĀ“s navigation. I want to add a link to that container and that container should only contain that single link.
Problem
There is a third party script, which also adds links to that container. It does that inside a AJAX callback function
What I have tried
1. Deleting all links but mine after document is completely loaded
This is not possible because third party script loads content via AJAX callback, so when page is fully loaded the unwanted links have not been rendered yet.
2. Renaming div container
After adding my link to the container I stripped the container completely naked, deleting class names, IDs etc. But the third party script still finds that container.
3. Attaching DOMNodeInserted event to the container
Works great in anything that I call a browser. But fails in IE. And the IE is the main browser the user of that page use.
What else can I try?
If the third party script uses jQuery then you can try ajaxComplete().
You can listen to DOMSubtreeModified event, and restore original div state.
var originalChildren = $('#content').children();
var setOriginal = function(e) {
$('#content').off('DOMSubtreeModified');
$('#content').empty().append(originalChildren);
$('#content').on('DOMSubtreeModified', setOriginal);
};
$('#content').on('DOMSubtreeModified', setOriginal);
Test it.
You could override/wrap the DOM methods the other script is using to add elements, such as appendChild(). Something like this (psuedocode)
var originalAppend = document.appendChild;
document.appendChild = function () {
if condition {
originalAppend.apply(document, arguments);
}
}

Global Javascript link handler

Here's what I have:
A web application that runs in a single HTML page (call it myapp.req), with content coming and going via AJAX
The application can be entered externally with a link such as myapp.req?id=123, and the application opens a tab with the item at id 123
The content on the page is mostly user's content, and many times has inner-application links to myapp.req?id=123
The problem is that clicking a link to myapp.req?id=123 reloads the browser, and removes any content or state that the user had loaded
What I want is to be able to catch link clicks whose destination is myapp.req?id=123, and instead of reloading the page, just open the tab for item 123, leaving anything else currently loaded alone. If the link is for an external website, though, obviously just let the browser leave.
So my question really: Can I have a global link handler that checks if I want to handle the link click, and if so, run some Javascript and don't leave?
I understand I could find all <a>s and add listeners, but my hope is that the solution would only require setting up the listener once, and not adding link handlers every time new content is loaded on the page. Since content can be loaded many different ways, it would be cumbersome to add code to all those places.
Does that make sense?
jQuery's live is what you need:
$('a').live("click", function () {
var myID = $(this).attr('href').match(/id=([a-zA-Z0-9_-]*)\&?/)[1];
if (myID) {
//run code here
alert(myID);
return false;
}
});
Any link will now have this click handler whether it's been added after this is called or not.
Sure you can. Add a clickhandler on the body. So you catch all clicks. Then you have to check if the target of the event or one of its parent is a link with your specific href. In this case stop the event and open the tab.
updated to use .live instead of .click
If you use jQuery, you can add a "live" click event handler to every a href at once:
<body>
click here
<br/>
whatever
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
$('a').live('click',function() {
var myID = $(this).attr('href').match(/id=([a-zA-Z0-9_-]*)\&?/)[1];
if (myID) {
//run code here
alert(myID);
return false;
}
});
</script>
This should extract the id from the href's query string and let you do whatever you want with it.

Categories