PDA

View Full Version : Help With My Script



richmurphy
04-09-2010, 08:55 PM
I have a really simple request, or so I think. I cannot find the answer or at least one that makes sense for me. The script below checks to see if the user is trying to go to an external site. The problem is that the script is on a website that uses two different domains therefore when the script is confronted with the other domain it executes thinking it is an external site.

Please help! Thanks!



var lnk;

for(var i in document.links)
if( (lnk = document.links[i] ).href && lnk.href.indexOf( document.domain ) > -1 )
lnk.onclick = function(){ window.onbeforeunload = null; }

})();

jscheuer1
04-10-2010, 01:07 AM
Here:


if( (lnk = document.links[i] ).href && lnk.href.indexOf( document.domain ) > -1 )

is where the determination is made. In general this is known as a test. What you probably need is an expanded or altered test that will include these sub-domains that you speak of. One fairly easy way to do this is via a regular expression.

The best way though is to use indexOf() like you have it. But obviously document.domain isn't cutting it for what you want. Most sub-domains do contain the domain name, do yours? If so we may use the literal domain name, ex:


if( (lnk = document.links[i] ).href && lnk.href.indexOf( 'mydomain' ) > -1 )

That's like if the main domain is mydomain.com or dot something, and all sub-domains contain the text 'mydomain' in them.

If not a regular expression would probably be best.

In other words, if this doesn't solve it for you, I need to know the domain name and all of the sub-domain names involved.

richmurphy
04-10-2010, 04:17 AM
Our domains are completely different.

They are not subdomains.

Such as one.com and two.com.

djr33
04-10-2010, 05:56 AM
In that case, I believe you could just add another statement to allow another domain:

if( (lnk = document.links[i] ).href && ( lnk.href.indexOf( 'mydomain1' ) > -1 || lnk.href.indexOf( 'mydomain2' ) > -1 ))

jscheuer1
04-10-2010, 01:03 PM
That won't work because it requires that a link be to both domains, an impossibility really, in order to pass the test. You could use || (logical or). But, if there are very many domains, your test would get quite long and unwieldy. It's already fairly inefficient using for in instead of for, adding all those indexOf() methods to it would bloat it even more.

Here's a fairly easy way to set things up that would be about as efficient as is possible for this. You need to configure the domains:


(function(){
var domains = ['one.com', 'two.com'],
lnks = document.links, i = lnks.length - 1, lnk;

domains = new RegExp( domains.join('|').replace(/\./g, '\\.') );
for (i; i > -1; --i){
if( (lnk = lnks[i] ).href && domains.test(lnk.href) ){
lnk.onclick = function(){ window.onbeforeunload = null; };
}
}
})();

You can add as many domains as you like to the array, ex:


var domains = ['one.com', 'two.com', 'three.com', 'four.com'],

richmurphy
04-10-2010, 04:25 PM
Perfection! Thank you so much! You are a life saver!

djr33
04-10-2010, 05:18 PM
I fixed my code above. Right, I see that now. The combination of three elements + and/or is sometimes hard to read. (I saw it as 'if this fails and this fails' somehow missing the fact that it wasn't checking for failure :rolleyes:). The array approach is more flexible, too, though my fixed version above is one line if that's easier to use for someone.

richmurphy
04-15-2010, 02:03 PM
Alright so I thought everything was working great, and it is, except for when the user submits a form. It still submits the form to the same domain but it executes the popup script anyways.

So for example the domain is site1.com and the form is located on a page and points to a page that is on site1.com.

Any ideas???

jscheuer1
04-15-2010, 03:51 PM
A form submission isn't an onclick event of an anchor link. The anchor links (document.links) are all that were covered by our code.

How many forms to you have? Do they all submit to one of the approved domains? If so we can just disable the beforeunload for all form submissions, if not we will have to make a test of each form's action attribute similar to how we tested each link's href attribute. But the event shouldn't be onclick, rather onsubmit. If that's already in use by one of the exempt forms it gets a little more complicated. If you submit any of your forms via javascript, their onsubmit event might not fire as expected. Also the action attribute of a form, unlike the href attribute of a link might not automatically include the domain even when it isn't literally specified (not sure on that one). This last will only come into play if we have to test each form's action attribute. But if need be it could be spelled out literally in the action attribute. I suspect that if this is an issue, it would vary by browser.

With all that in mind, if all forms are exempt and none of the other extenuating circumstances I've imaged (perhaps others) apply, we could simply do:


(function(){
var domains = ['one.com', 'two.com'],
lnks = document.links, i = lnks.length - 1, lnk, frms = document.forms;

domains = new RegExp( domains.join('|').replace(/\./g, '\\.') );
for (i; i > -1; --i){
if( (lnk = lnks[i] ).href && domains.test(lnk.href) ){
lnk.onclick = function(){ window.onbeforeunload = null; };
}
}
for (i = frms.length - 1; i > -1; --i){
frms[i].onsubmit = function(){ window.onbeforeunload = null; };
}
})();

Another important thing to remember is that the beforeunload only works in IE, perhaps one or two others, and only when javascript is enabled on the user's end. So if whatever this beforeunload thing you have that you are canceling for certain domains is very important, you need to find another way of doing it. If it is not, you may be better off skipping it. Users often find it obnoxious to see an alert or confirmation when leaving a site. Another approach is simply to make all off site links open in a new window/tab. It's still a bit obnoxious, but less so, will keep your site in the user's browser, and works in virtually all browsers, subject to pop up blocking, but only if pop up blocking is set to its strictest setting, which it almost never is. Even when it is strict, it will still keep your site in the user's browser, just not let them open the off site link unless they "approve the pop up".

richmurphy
04-22-2010, 02:16 PM
Thank you for the feedback John.

Is there anyway to code this script to suppress when hitting the "BACK" and "FORWARD" buttons in the browser, and also the "REFRESH" button?

jscheuer1
04-22-2010, 05:16 PM
I really don't think so. The beforeunload event is proprietary to IE. This isn't so much because IE is more advanced than other browsers, more a case of of it having poor garbage collection routines. You may use this event in IE to clean up any DOM generated elements and the events associated with them before the page unloads, otherwise they can cause memory leaks. Other browsers do this automatically.

If what you are doing is popping up a "Are you really sure you want to leave?" message, there is no way I've ever heard of to restrict this from the browser's internal back, forward and refresh buttons. It's not what this event was designed for. These browser functions (back, forward and refresh) cannot be disabled via javascript either. Where form data is involved, server side code can be used to prevent duplicate submissions. The functions (back, forward and refresh) can be disabled if you control the install of the browser, like over a closed network that you have administrative privileges for.