问题
I have the below code:
<HTML>
<HEAD>
<SCRIPT>
function myFunction(atlasTrackingURL)
{
var atlasURL = atlasTrackingURL;
if (!atlasURL) return;
//Build a cache busting mechanism
var timestamp = new Date();
var queryString = "?random=" + Math.ceil(Math.random() * 999999999999) + timestamp.getUTCHours() + timestamp.getUTCMinutes() + timestamp.getUTCSeconds();
//Build the final URL
atlasURL = atlasURL + queryString;
if (!document.getElementsByTagName || !document.createElement || !document.appendChild)
{return false;}
else
{ //Activate the JACTION call
var script = document.createElement("script");
script.type = "text/javascript";
script.onload = function()
{
document.getElementsByTagName("head")[0].appendChild(script);
};
script.src = atlasURL;
return false;
}
}
</SCRIPT>
</HEAD>
<BODY>
<a href="http://www.microsoft.com" onclick = "myFunction('http://view.atdmt.com/jaction/adoakb_PiggybackJSTest_1')">Test - Click Me</a>
</BODY>
</HTML>
It works in Internet Explorer every time, but rarely works in Chrome and Firefox. Why would this be?
What's interesting is that if I replace the URL (microsoft.com) with a #, it does execute properly. I'm wondering if there is a race condition of some kind where the href evaluates before the onclick function loads. Adding a # prevents the href from executing, and so the onclick function is given time to fire off. Is there any way to fix this?
I am trying to help a client figure out why one of their tracking tags are not firing off all the time on click in these browsers. There is supposed to be a javascript file that gets executed on click (the view.atdmt.com URL), but it only works in IE and doesn't fire off in FF and Chrome.
I am almost positive there is nothing wrong with the actual code - so hence I believe these browsers can't execute the onclick fast enough and the landing page executes first. Once the landing page is reached, the onclick function can no longer be called....
Thanks,
回答1:
As you are returning true
from the function, the default action of the link is allowed and the browser goes on to navigating to the page.
Exactly what happens with changes to the document and queued requests may differ, as it's up to the implementation of the browser to do something that is reasonable, and both requesting the script and not doing it are within what's reasonable.
As you are navigating away from the page, you can't expect the browser to actually do anything more in the current page. Some browsers may go on as nothing happens until the new page starts to arrive, some may suspend some actions as they would request data for a page that isn't supposed to be there any more when the response arrives.
To make it work in any browser you should return false
from the function to keep the link from being activated, and wait for the script to load before you navigate to the new page.
Edit:
Add a paramter to the function to handle the URL:
function myFunction(url, atlasTrackingURL)
Use the onload
event to navigate to the URL when the script has loaded:
var script = document.createElement("script");
script.type = "text/javascript";
script.onload = function() {
window.location.href = url;
};
script.src = atlasURL;
document.getElementsByTagName("head")[0].appendChild(script);
return false;
Return the result in the event handler to stop the link from being activated:
<a href="http://www.microsoft.com" onclick = "return myFunction(this.href, 'http://view.atdmt.com/jaction/adoakb_PiggybackJSTest_1')">Test - Click Me</a>
回答2:
Try waiting for the script to load before appending it:
script.onload = function()
{
document.getElementsByTagName("head")[0].appendChild(script);
};
script.src = atlasURL;
来源:https://stackoverflow.com/questions/22864809/possible-race-condition