Back button / backspace does not work with window.history.pushState - javascript

I have made a solution for my website which includes using ajax to present the general information on the website. In doing this, I am changing the URL every time a user loads some specific content with the window.history.pushState method. However, when I press backspace or press back, the content of the old url is not loaded (however the URL is loaded).
I have tried several solutions presented on SO without any luck.
Here is an example of one of the ajax functions:
$(document).ready(function(){
$(document).on("click",".priceDeckLink",function(){
$("#hideGraphStuff").hide();
$("#giantWrapper").show();
$("#loadDeck").fadeIn("fast");
var name = $(this).text();
$.post("pages/getPriceDeckData.php",{data : name},function(data){
var $response=$(data);
var name = $response.filter('#titleDeck').text();
var data = data.split("%%%%%%%");
$("#deckInfo").html(data[0]);
$("#textContainer").html(data[1]);
$("#realTitleDeck").html(name);
$("#loadDeck").hide();
$("#hideGraphStuff").fadeIn("fast");
loadGraph();
window.history.pushState("Price Deck", "Price Deck", "?p=priceDeck&dN="+ name);
});
});
Hope you guys can help :)

pushState alone will not make your page function with back/forward. What you'd need to do is listen to onpopstate and load the contents yourself similar to what would happen on click.
var load = function (name, skipPushState) {
$("#hideGraphStuff").hide();
// pre-load, etc ...
$.post("pages/getPriceDeckData.php",{data : name}, function(data){
// on-load, etc ...
// we don't want to push the state on popstate (e.g. 'Back'), so `skipPushState`
// can be passed to prevent it
if (!skipPushState) {
// build a state for this name
var state = {name: name, page: 'Price Deck'};
window.history.pushState(state, "Price Deck", "?p=priceDeck&dN="+ name);
}
});
}
$(document).on("click", ".priceDeckLink", function() {
var name = $(this).text();
load(name);
});
$(window).on("popstate", function () {
// if the state is the page you expect, pull the name and load it.
if (history.state && "Price Deck" === history.state.page) {
load(history.state.name, true);
}
});
Note that history.state is a somewhat less supported part of the history API. If you wanted to support all pushState browsers you'd have to have another way to pull the current state on popstate, probably by parsing the URL.
It would be trivial and probably a good idea here to cache the results of the priceCheck for the name as well and pull them from the cache on back/forward instead of making more php requests.

This works for me. Very simple.
$(window).bind("popstate", function() {
window.location = location.href
});

Have same issue and the solution not working for neither
const [loadBackBtn, setLoadBackBtn] = useState(false);
useEffect(() => {
if (loadBackBtn) {
setLoadBackBtn(false);
return;
} else {
const stateQuery = router.query;
const { asPath } = router;
window.history.pushState(stateQuery, "", asPath);
},[router.query?.page]

Related

How to detect a window url change? [duplicate]

How can I check if a URL has changed in JavaScript? For example, websites like GitHub, which use AJAX, will append page information after a # symbol to create a unique URL without reloading the page. What is the best way to detect if this URL changes?
Is the onload event called again?
Is there an event handler for the URL?
Or must the URL be checked every second to detect a change?
I wanted to be able to add locationchange event listeners. After the modification below, we'll be able to do it, like this
window.addEventListener('locationchange', function () {
console.log('location changed!');
});
In contrast, window.addEventListener('hashchange',() => {}) would only fire if the part after a hashtag in a url changes, and window.addEventListener('popstate',() => {}) doesn't always work.
This modification, similar to Christian's answer, modifies the history object to add some functionality.
By default, before these modifications, there's a popstate event, but there are no events for pushstate, and replacestate.
This modifies these three functions so that all fire a custom locationchange event for you to use, and also pushstate and replacestate events if you want to use those.
These are the modifications:
(() => {
let oldPushState = history.pushState;
history.pushState = function pushState() {
let ret = oldPushState.apply(this, arguments);
window.dispatchEvent(new Event('pushstate'));
window.dispatchEvent(new Event('locationchange'));
return ret;
};
let oldReplaceState = history.replaceState;
history.replaceState = function replaceState() {
let ret = oldReplaceState.apply(this, arguments);
window.dispatchEvent(new Event('replacestate'));
window.dispatchEvent(new Event('locationchange'));
return ret;
};
window.addEventListener('popstate', () => {
window.dispatchEvent(new Event('locationchange'));
});
})();
Note, we're creating a closure, to save the old function as part of the new one, so that it gets called whenever the new one is called.
In modern browsers (IE8+, FF3.6+, Chrome), you can just listen to the hashchange event on window.
In some old browsers, you need a timer that continually checks location.hash. If you're using jQuery, there is a plugin that does exactly that.
Example
Below I undo any URL change, to keep just the scrolling:
<script type="text/javascript">
if (window.history) {
var myOldUrl = window.location.href;
window.addEventListener('hashchange', function(){
window.history.pushState({}, null, myOldUrl);
});
}
</script>
Note that above used history-API is available in Chrome, Safari, Firefox 4+, and Internet Explorer 10pp4+
window.onhashchange = function() {
//code
}
window.onpopstate = function() {
//code
}
or
window.addEventListener('hashchange', function() {
//code
});
window.addEventListener('popstate', function() {
//code
});
with jQuery
$(window).bind('hashchange', function() {
//code
});
$(window).bind('popstate', function() {
//code
});
EDIT after a bit of researching:
It somehow seems that I have been fooled by the documentation present on Mozilla docs. The popstate event (and its callback function onpopstate) are not triggered whenever the pushState() or replaceState() are called in code. Therefore the original answer does not apply in all cases.
However there is a way to circumvent this by monkey-patching the functions according to #alpha123:
var pushState = history.pushState;
history.pushState = function () {
pushState.apply(history, arguments);
fireEvents('pushState', arguments); // Some event-handling function
};
Original answer
Given that the title of this question is "How to detect URL change" the answer, when you want to know when the full path changes (and not just the hash anchor), is that you can listen for the popstate event:
window.onpopstate = function(event) {
console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
Reference for popstate in Mozilla Docs
Currently (Jan 2017) there is support for popstate from 92% of browsers worldwide.
With jquery (and a plug-in) you can do
$(window).bind('hashchange', function() {
/* things */
});
http://benalman.com/projects/jquery-hashchange-plugin/
Otherwise yes, you would have to use setInterval and check for a change in the hash event (window.location.hash)
Update! A simple draft
function hashHandler(){
this.oldHash = window.location.hash;
this.Check;
var that = this;
var detect = function(){
if(that.oldHash!=window.location.hash){
alert("HASH CHANGED - new has" + window.location.hash);
that.oldHash = window.location.hash;
}
};
this.Check = setInterval(function(){ detect() }, 100);
}
var hashDetection = new hashHandler();
Add a hash change event listener!
window.addEventListener('hashchange', function(e){console.log('hash changed')});
Or, to listen to all URL changes:
window.addEventListener('popstate', function(e){console.log('url changed')});
This is better than something like the code below because only one thing can exist in window.onhashchange and you'll possibly be overwriting someone else's code.
// Bad code example
window.onhashchange = function() {
// Code that overwrites whatever was previously in window.onhashchange
}
this solution worked for me:
function checkURLchange(){
if(window.location.href != oldURL){
alert("url changed!");
oldURL = window.location.href;
}
}
var oldURL = window.location.href;
setInterval(checkURLchange, 1000);
None of these seem to work when a link is clicked that which redirects you to a different page on the same domain. Hence, I made my own solution:
let pathname = location.pathname;
window.addEventListener("click", function() {
if (location.pathname != pathname) {
pathname = location.pathname;
// code
}
});
Edit: You can also check for the popstate event (if a user goes back a page)
window.addEventListener("popstate", function() {
// code
});
Best wishes,
Calculus
If none of the window events are working for you (as they aren't in my case), you can also use a MutationObserver that looks at the root element (non-recursively).
// capture the location at page load
let currentLocation = document.location.href;
const observer = new MutationObserver((mutationList) => {
if (currentLocation !== document.location.href) {
// location changed!
currentLocation = document.location.href;
// (do your event logic here)
}
});
observer.observe(
document.getElementById('root'),
{
childList: true,
// important for performance
subtree: false
});
This may not always be feasible, but typically, if the URL changes, the root element's contents change as well.
I have not profiled, but theoretically this has less overhead than a timer because the Observer pattern is typically implemented so that it just loops through the subscriptions when a change occurs. We only added one subscription here. The timer on the other hand would have to check very frequently in order to ensure that the event was triggered immediately after URL change.
Also, this has a good chance of being more reliable than a timer since it eliminates timing issues.
Although an old question, the Location-bar project is very useful.
var LocationBar = require("location-bar");
var locationBar = new LocationBar();
// listen to all changes to the location bar
locationBar.onChange(function (path) {
console.log("the current url is", path);
});
// listen to a specific change to location bar
// e.g. Backbone builds on top of this method to implement
// it's simple parametrized Backbone.Router
locationBar.route(/some\-regex/, function () {
// only called when the current url matches the regex
});
locationBar.start({
pushState: true
});
// update the address bar and add a new entry in browsers history
locationBar.update("/some/url?param=123");
// update the address bar but don't add the entry in history
locationBar.update("/some/url", {replace: true});
// update the address bar and call the `change` callback
locationBar.update("/some/url", {trigger: true});
To listen to url changes, see below:
window.onpopstate = function(event) {
console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
Use this style if you intend to stop/remove listener after some certain condition.
window.addEventListener('popstate', function(e) {
console.log('url changed')
});
The answer below comes from here(with old javascript syntax(no arrow function, support IE 10+)):
https://stackoverflow.com/a/52809105/9168962
(function() {
if (typeof window.CustomEvent === "function") return false; // If not IE
function CustomEvent(event, params) {
params = params || {bubbles: false, cancelable: false, detail: null};
var evt = document.createEvent("CustomEvent");
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
}
window.CustomEvent = CustomEvent;
})();
(function() {
history.pushState = function (f) {
return function pushState() {
var ret = f.apply(this, arguments);
window.dispatchEvent(new CustomEvent("pushState"));
window.dispatchEvent(new CustomEvent("locationchange"));
return ret;
};
}(history.pushState);
history.replaceState = function (f) {
return function replaceState() {
var ret = f.apply(this, arguments);
window.dispatchEvent(new CustomEvent("replaceState"));
window.dispatchEvent(new CustomEvent("locationchange"));
return ret;
};
}(history.replaceState);
window.addEventListener("popstate", function() {
window.dispatchEvent(new CustomEvent("locationchange"));
});
})();
While doing a little chrome extension, I faced the same problem with an additionnal problem : Sometimes, the page change but not the URL.
For instance, just go to the Facebook Homepage, and click on the 'Home' button. You will reload the page but the URL won't change (one-page app style).
99% of the time, we are developping websites so we can get those events from Frameworks like Angular, React, Vue etc..
BUT, in my case of a Chrome extension (in Vanilla JS), I had to listen to an event that will trigger for each "page change", which can generally be caught by URL changed, but sometimes it doesn't.
My homemade solution was the following :
listen(window.history.length);
var oldLength = -1;
function listen(currentLength) {
if (currentLength != oldLength) {
// Do your stuff here
}
oldLength = window.history.length;
setTimeout(function () {
listen(window.history.length);
}, 1000);
}
So basically the leoneckert solution, applied to window history, which will change when a page changes in a single page app.
Not rocket science, but cleanest solution I found, considering we are only checking an integer equality here, and not bigger objects or the whole DOM.
Found a working answer in a separate thread:
There's no one event that will always work, and monkey patching the pushState event is pretty hit or miss for most major SPAs.
So smart polling is what's worked best for me. You can add as many event types as you like, but these seem to be doing a really good job for me.
Written for TS, but easily modifiable:
const locationChangeEventType = "MY_APP-location-change";
// called on creation and every url change
export function observeUrlChanges(cb: (loc: Location) => any) {
assertLocationChangeObserver();
window.addEventListener(locationChangeEventType, () => cb(window.location));
cb(window.location);
}
function assertLocationChangeObserver() {
const state = window as any as { MY_APP_locationWatchSetup: any };
if (state.MY_APP_locationWatchSetup) { return; }
state.MY_APP_locationWatchSetup = true;
let lastHref = location.href;
["popstate", "click", "keydown", "keyup", "touchstart", "touchend"].forEach((eventType) => {
window.addEventListener(eventType, () => {
requestAnimationFrame(() => {
const currentHref = location.href;
if (currentHref !== lastHref) {
lastHref = currentHref;
window.dispatchEvent(new Event(locationChangeEventType));
}
})
})
});
}
Usage
observeUrlChanges((loc) => {
console.log(loc.href)
})
I created this event that is very similar to the hashchange event
// onurlchange-event.js v1.0.1
(() => {
const hasNativeEvent = Object.keys(window).includes('onurlchange')
if (!hasNativeEvent) {
let oldURL = location.href
setInterval(() => {
const newURL = location.href
if (oldURL === newURL) {
return
}
const urlChangeEvent = new CustomEvent('urlchange', {
detail: {
oldURL,
newURL
}
})
oldURL = newURL
dispatchEvent(urlChangeEvent)
}, 25)
addEventListener('urlchange', event => {
if (typeof(onurlchange) === 'function') {
onurlchange(event)
}
})
}
})()
Example of use:
window.onurlchange = event => {
console.log(event)
console.log(event.detail.oldURL)
console.log(event.detail.newURL)
}
addEventListener('urlchange', event => {
console.log(event)
console.log(event.detail.oldURL)
console.log(event.detail.newURL)
})
for Chrome 102+ (2022-05-24)
navigation.addEventListener("navigate", e => {
console.log(`navigate ->`,e.destination.url)
});
API references WICG/navigation-api
Look at the jQuery unload function. It handles all the things.
https://api.jquery.com/unload/
The unload event is sent to the window element when the user navigates away from the page. This could mean one of many things. The user could have clicked on a link to leave the page, or typed in a new URL in the address bar. The forward and back buttons will trigger the event. Closing the browser window will cause the event to be triggered. Even a page reload will first create an unload event.
$(window).unload(
function(event) {
alert("navigating");
}
);
window.addEventListener("beforeunload", function (e) {
// do something
}, false);
You are starting a new setInterval at each call, without cancelling the previous one - probably you only meant to have a setTimeout
Enjoy!
var previousUrl = '';
var observer = new MutationObserver(function(mutations) {
if (location.href !== previousUrl) {
previousUrl = location.href;
console.log(`URL changed to ${location.href}`);
}
});
Another simple way you can do this is by adding a click event, through a class name to the anchor tags on the page to detect when it has been clicked, then you can now use the window.location.href to get the url data which you can use to run your ajax request to the server. Simple and Easy.

Popstate event not triggered after pushing twice to history using history.pushState()

I’m working on an eshop where items are opened on top of a page in iframes. I’m using
history.pushState(stateObj, "page 2", http://localhost:8888/product-category/tyger/vara-tyger/?view=product&item=test-4);
in order to let customers copy the current url and use it to go to the current page with the item opened in an iframe. In addition, I’m using
window.addEventListener('popstate', manageHistory);
function manageHistory(event) {
if (!has_gone_back) {
var iframeOpen = false;
has_gone_back = true;
}
else {
var iframeOpen = true;
has_gone_back = false;
}
}
in order to let customers use their browser’s back and forward buttons for navigation (closing and opening the iframe).
However, when opening one product (calling history.pushState once), using the browser’s back button, and opening another product (calling history.pushState again), and going back again, manageHistory() is not called. The customer is taken to the first opened product but if pressing back again, manageHistory() is called.
I want manageHistory() to be called when pressing back on the product page opened second in order to add code to redirect customers to the category's start page when pressing back.
I’ve tried both adding Event Listeners for both opened products and also for only the first one. Any ideas what the problem may be?
From https://developer.mozilla.org/en-US/docs/Web/Events/popstate
Note that just calling history.pushState() or history.replaceState() won't trigger a popstate event. The popstate event is only triggered by doing a browser action such as a click on the back button (or calling history.back() in JavaScript).
You can overwrite popState and replaceState, but what is generally a better idea is to create a wrapper which sets the url and then triggers your handler function.
Something like this...
function urlChangeHandler() {
var url = window.location.href;
// Whatever you want to do...
}
// Handle initial url:
urlChangeHandler();
window.addEventListener('popstate', urlChangeHandler);
var urlState = {
push: function(url) {
window.history.pushState(null, null, url);
urlChangeHandler();
},
replace: function(url) {
window.history.replaceState(null, null, url);
urlChangeHandler();
}
}
I have a similar file in one of my projects which updates the datastore based on the #hash...
import tree from './state'
// No need for react-router for such a simple application.
function hashChangeHandler(commit) {
return () => {
const hash = window.location.hash.substr(1);
const cursor = tree.select('activeContactIndex');
const createCursor = tree.select('createNewContact');
cursor.set(null);
createCursor.set(false);
(() => {
if(!hash.length) {
// Clean up the url (remove the hash if there is nothing after it):
window.history.replaceState(null, null, window.location.pathname);
return;
}
if(hash === 'new') {
createCursor.set(true);
return;
}
const index = parseInt(hash, 10);
if(!isNaN(index)) {
cursor.set(index);
}
})();
commit && tree.commit();
}
}
// Handle initial url:
hashChangeHandler(true)();
// Handle manual changes of the hash in the url:
window.addEventListener('hashchange', hashChangeHandler(true));
function createHash(location) {
return (location !== null) ? `#${location}` : window.location.pathname;
}
module.exports = {
push: (location, commit=true) => {
window.history.pushState(null, null, createHash(location));
hashChangeHandler(commit)();
},
replace: (location, commit=true) => {
window.history.replaceState(null, null, createHash(location));
hashChangeHandler(commit)();
}
}

Fix back button issue on load more pagination style

HTML
<div class="moreButton">
<a class="more" id="<?php echo htmlspecialchars($page);?>">More</a>
</div>
AJAX
$(function(){
$('.more').live('click', function(){
var page = $(this).attr('id'); //get the last id
$.ajax({
type : 'GET',
url : 'functionality/js/paginate.php',
data : { page : page, per_page : per_page, last_page : last_page },
beforeSend: function(){
$('.more').html(img);
if(history.pushState){
history.pushState(null, null, '#' + page);
}else{
location.hash = '#' + page;
}
},
success: function(data){
$('.more').remove();
$('.main-content').append(data);
}
});
});
});
I've implemented a load_more style of pagination. The problem here is the usual for infinite scrolls, when a user clicks a post and comes back with back button, he/she should get the previous number of loaded posts, but only initial posts are loaded. I'm trying to integrate the history.pushState functionality based on what I found googling, but doesn't seem to get it working. What am I missing here?
There are two key parts to saving states using browser history. The pushState function allows you to add to the history stack (essentially like going to a new page). It also allows you to store a javascript object as the "state". This will come in handy when the state is "popped" off the stack (e.g. the browser's "back" button is pressed).
Browsers throw a popstate event which you can use to determine if the browser is going back to a previous state. You can access it with window.onpopstate. To watch for a hash change you can use window.onhashchange.
if ("onpopstate" in window) {
window.onpopstate = function (event) {
if (event.state && event.state.pageID) {
fetchData(event.state.pageID);
}
};
}
if ("onhashchange" in window) {
window.onhashchange = function () {
if (location.hash) {
fetchData(location.hash.substr(1));
}
};
}
function fetchData(pageID) {
// Load some content
}
function saveState(pageID) {
if (history.pushState) {
history.pushState({ pageID: pageID }, null, "/page/" + pageID);
} else {
location.hash = pageID;
}
}
Here you need to define a function to check hash update as if hash updates(User clicks on back/forward button) it should update data of the page according to URL.

getting my back and forwards buttons to work with ajax

My site is working much quicker thanks to some code I painstakingly modified, but I would love if the browsers' back/forwards buttons worked. Right now, with my code below, the browser address bar never changes. When someone clicks 'Back', it takes them out of the application.
Would there by any easy way of changing this so the browser's back/forward button worked? Or else if someone could point me in the right direction. Thanks for any help.
$(document).on("ready", function () {
//I want to load content into the '.page-content' class, with ajax
var ajax_loaded = (function (response) {
$(".page-content")
.html($(response).filter(".page-content"));
$(".page-content .ajax").on("click", ajax_load);
});
//the function below is called by links that are described
//with the class 'ajax', or are in the div 'menu'
var history = [];
var ajax_load = (function (e) {
e.preventDefault();
history.push(this);
var url = $(this).attr("href");
var method = $(this).attr("data-method");
$.ajax({
url: url,
type: method,
success: ajax_loaded
});
});
//monitor for clicks from menu div, or with
//the ajax class
//why the trigger?
$("#menu a").on("click", ajax_load);
$(".ajax").on("click", ajax_load);
$("#menu a.main").trigger("click");
});
Here is a way of detecting what you are asking.
Bear in my playing with the back and forward buttons is a risky task.
window.onload = function () {
if (typeof history.pushState === "function") {
history.pushState("someState", null, null);
window.onpopstate = function () {
history.pushState("newState", null, null);
// Handle the back (or forward) buttons here
// Will not handle refresh, use onbeforeunload for this.
};
}
}
You could use the jquery address plugin (http://www.asual.com/jquery/address/).
It has an event that detects when the user presses the back/forward button.
$.address.externalChange(function() { console.log('back/forward pressed'); });
As far as I know there is no way of differentiating between back and forward.
You should definitely check History.js
Here's some sample code:-
(function(window,undefined){
// Prepare
var History = window.History; // Note: We are using a capital H instead of a lower h
if ( !History.enabled ) {
// History.js is disabled for this browser.
// This is because we can optionally choose to support HTML4 browsers or not.
return false;
}
// Bind to StateChange Event
History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate
var State = History.getState(); // Note: We are using History.getState() instead of event.state
//History.log(State.data, State.title, State.url);
var goto_url = State.url;
$.ajax({
url: goto_url,
dataType: "script"
});
});
})(window);

How to use jQuery click event to change href value asynchronously, based on a JSON query

I'm using the bit.ly url shortening service to shorten certain url's being sent to a "share on twitter" function. I'd like to load the bit.ly url only when a user actually presses the share button (due to bit.ly's max 5 parallel reqs limitation). Bit.ly's REST API returns a JSON callback with the shortened url, which makes the whole scenario async.
I've tried the following to stop the click event, and wait for the JSON call to return a value before launching the click.
I have the following simplified code in jQuery(document).ready():
Updated code (oversimplified)!
jQuery("#idofaelement").click(function(event) {
event.preventDefault(); //stop the click action
var link = jQuery(this);
bitlyJSON(function(shortUrl) {
link.attr("href", function() {
//process shortUrl
//return finalized url;
}).unbind().click();
});
});
And the following code to handle the bitly shortening (works just fine):
function bitlyJSON(func) {
//
// build apiUrl here
//
jQuery.getJSON(apiUrl, function(data) {
jQuery.each(data, function(i, entry) {
if (i == "errorCode") {
if (entry != "0") {
func(longUrl);}
} else if (i == "results") {
func(entry[longUrl].shortUrl);}
});
});
} (jQuery)
The href gets its value changed, but the final .click() event never gets fired. This works fine when defining a static value for the href, but not when using the async JSON method.
As you outlined yourself:
event.preventDefault(); //stop the click action
That means, BROWSER IS NOT GOING TO THAT URL, if you wish to actually go forward to the long-url location, simply do something like:
document.location.href = longurl;
iirc, jquery doesn't trigger "click" on A elements. I'd try old good "location.href=whatever" in the callback.
bitlyJSON(function(shortUrl) {
link.attr("href", function() {
//process shortUrl
//return finalized url;
});
location.href = link.attr("href");
});
I think what you actually want is to return false; from the click event, to prevent the actual following of the href, right?
Like:
jQuery("#idofaelement").click(function(event) {
//event.preventDefault(); //stop the click action
var link = jQuery(this);
bitlyJSON(function(shortUrl) {
link.attr("href", function() {
//process shortUrl
//return finalized url;
}).unbind().click();
});
return false;
});
#Tzury Bar Yochay pointed me in the right direction by suggesting I use location.href to update the url. Also #Victor helped with his answer.
I got things kinda working combining the answers, but had issues with the history in firefox. Seems that updating window.location indeed redirected the user, but also removed the "source page" from the history. This did not happen in chrome, safari, ie8, ie8-compatibility or ie7.
Based on this response to another question I was able to create a workaround giving the following working code + made a few changes:
jQuery("#idofaelement").one("click", function(event) {
bitlyJSON(function(shortUrl) {
jQuery("#idofaelement").attr("href", function() {
//process shortUrl
//return finalized url;
});
setTimeout(function() {
window.location = jQuery("#idofaelement").attr("href");
}, 0);
});
return false;
});
Thanks for all the help!

Categories