A member of thelist recently inquired about a JavaScript that would give the visitor of his webpage the choice of whether links should open in the same window, a new window for all, or new windows for each. I figured this was a fun opportunity to write the JavaScript to allow the user to choose the target of certain links on the page.
In order to address this problem with the best solution we should think of as many ways to solve it as possible. Which method is the best will depend on your needs.
onClick
event handler to links that will be affected by the user's choicetarget
attribute for every link in the page.target
attribute of the link to the appropriate value depending on which choice is selected.target
attribute for only those links in the page that are marked for alteration.No matter which method you decide to use, you need to give the user some means of triggering the choice. For simplicity let's make them a group of radio buttons. It could just as easily be links that change the value of a JavaScript variable with their onClick
event handler. Or, it could be a dropdown menu that calls a function with its onChange
event handler. It doesn't much matter, the end result is the same. With this information in mind, let's dig in.
onClick
event handler of the linkThis method assumes that the radio buttons won't actually affect anything when they're clicked. They will only serve as a mechanism to store and display the user's choice. With that in mind, here's the code for the radio buttons.
<form> [<input type="radio" name="target" id="target_self_0" value="_self" tabindex="1" title="Open links in this window" onClick="targetForm = this.form" checked> <label for="target_self_0" accesskey="s" title="Open links in this window" ><u>S</u>elf</label>] [<input type="radio" name="target" id="target_same_0" value="_same" tabindex="2" title="Open links in the same new window" onClick="targetForm = this.form"> <label for="target_same_0" accesskey="a" title="Open links in same new window" >S<u>a</u>me</label>] [<input type="radio" name="target" id="target_blank_0" value="_blank" tabindex="3" title="Open links in a new window for each link" onClick="targetForm = this.form"> <label for="target_blank_0" accesskey="n" title="Open links in a new window for each link" ><u>N</u>ew</label>]</form>
The links are where the action is initiated. So, we need to attach some onClick
event handlers to them. The onClick
event handler will call the function in such a way that the event handler will be expecting a value to be returned from the function before it can do anything. This will allow us to alter the value of the target
attribute before the browser follows the link.
<a href="http://www.evolt.org/" onClick="return setTarget_0(this)">evolt.org</a><a href="http://www.slashdot.org/" onClick="return setTarget_0(this)">/.</a><a href="http://www.microsoft.com/" onClick="return setTarget_0(this)">Microsoft</a><a href="http://www.netscape.com/" onClick="return setTarget_0(this)">Netscape</a>
To finish this up we're going to need a function that sets the value of the target
attribute of the clicked link to match the choice the user made with the radio buttons. After setting the target we'll then need to return a boolean value, true
, to the event handler so the browser will execute the click action of the user and follow the link.
[Note: See my article JavaScript: The Point of No Return?! for an explanation of how return statements affect event handlers that can have their action canceled.]
<script language="JavaScript" type="text/javascript"><!-- var targetForm = null;function setTarget_0(obj)
{ if(targetForm != null) { targetLen = targetForm.elements['target'].length; targetText = '_self'; for(t = 0; t < targetLen; t++) { if(targetForm.elements['target'][t].checked) { targetText = targetForm.target[t].value; break; } } obj.target = targetText; } return true; }// --></script>
[ ] [ ] [ ] |
target
Attribute for every linkThis method assumes that the links are clueless as to any JavaScript that's used to affect what window they're to target. Instead, the target
attributes will be altered when a radio button is clicked. With that in mind, here's the code for the radio buttons.
<form> [<input type="radio" name="target" id="target_self" value="_self" tabindex="1" title="Open links in this window" onClick="setTarget_1(this.value)" checked> <label for="target_self" accesskey="s" title="Open links in this window" ><u>S</u>elf</label>] [<input type="radio" name="target" id="target_same" value="_same" tabindex="2" title="Open links in the same new window" onClick="setTarget_1(this.value)"> <label for="target_same" accesskey="a" title="Open links in same new window" >S<u>a</u>me</label>] [<input type="radio" name="target" id="target_blank" value="_blank" tabindex="3" title="Open links in a new window for each link" onClick="setTarget_1(this.value)"> <label for="target_blank" accesskey="n" title="Open links in a new window for each link" ><u>N</u>ew</label>]</form>
The links are what could be considered "dumb" links in that they aren't aware in any way that they're being affected by JavaScript. So, unlike the last example, these links won't have any event handlers.
<a href="http://www.evolt.org/">evolt.org</a><a href="http://www.slashdot.org/">/.</a><a href="http://www.microsoft.com/">Microsoft</a><a href="http://www.netscape.com/">Netscape</a>
To finish up this example we're going to need a function that sets the value of the target attribute for all links to match the choice the user made with the radio buttons.
<script language="JavaScript" type="text/javascript"><!-- function setTarget2(target) { for(a = 0; a < document.links.length; a++) { document.links[a].target = target; } }// --></script>
[ ] [ ] [ ] |
target
attribute for certain linksThis method assumes that the links are clueless as to any JavaScript that's used to affect what window they're to target. Instead, the target
attributes will be altered when a radio button is clicked. The difference between this method and the last is that we'll "mark" certain links for alteration by adding the name
attribute and giving it the same value for all instances. With that in mind, here's the code for the radio buttons.
<form> [<input type="radio" name="target" id="target_self_2" value="_self" tabindex="1" title="Open links in this window" onClick="setTarget_2(this.value)" checked> <label for="target_self_2" accesskey="s" title="Open links in this window" ><u>S</u>elf</label>] [<input type="radio" name="target" id="target_same_2" value="_same" tabindex="2" title="Open links in the same new window" onClick="setTarget_2(this.value)"> <label for="target_same_2" accesskey="a" title="Open links in same new window" >S<u>a</u>me</label>] [<input type="radio" name="target" id="target_blank_2" value="_blank" tabindex="3" title="Open links in a new window for each link" onClick="setTarget_2(this.value)"> <label for="target_blank_2" accesskey="n" title="Open links in a new window for each link" ><u>N</u>ew</label>]</form>
The links are what could be considered "dumb" links in that they aren't aware in any way that they're being affected by JavaScript. So, like the last example, these links won't have any event handlers. However, unlike the last example these links will have name
attributes and a common value.
<a href="http://www.evolt.org/" name="target">evolt.org</a><a href="http://www.slashdot.org/" name="target">/.</a><a href="http://www.microsoft.com/" name="target">Microsoft</a><a href="http://www.netscape.com/" name="target">Netscape</a>
To finish up this example we're going to need a function that sets the value of the target
attribute for all "marked" links to match the choice the user made with the radio buttons. This function will differ from the previous one in that it will check to make sure the value of the name
attribute of the link it's going to change matches the name of the radio buttons the user is interacting with.
<script language="JavaScript" type="text/javascript"><!-- function setTarget_2(obj) { for(a = 0; a < document.links.length; a++) { if(document.links[a].name == obj.name) document.links[a].target = obj.value; } }// --></script>
[ ] [ ] [ ] |
Note:
Did I thoroughly confuse you?
In theory you could get fancy and have a different set of controls for
different portions of links on the site. You could have one set of controlsfor all onsite links and another set for offsite links, or you could havecontrols for all links in a sidebar (like list of blogs or some such). Theimportant thing to note is that they're all tied by the value of the nameattributes both on the radio buttons for the links and the name attribute ofthe links to be affected themselves.