Skip to page content or Skip to Accesskey List.

Work

Main Page Content

User Defined Window Targeting W Javascript

Rated 4.09 (Ratings: 11)

Want more?

  • More articles in Code
 
Picture of Jeff Howden

Jeff Howden

Member info

User since: 14 Dec 1998

Articles written: 21

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.

Possible Solutions

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.

  1. Add an onClick event handler to links that will be affected by the user's choice
    • Advantages
      • You can attach this to only those links you wish to have this functionality.
      • No calculations regarding targets is made until the link is clicked.

    • Disadvantages
      • You have to attach it to every link you want it to effect. This could be time-consuming depending on how many links we're talking about.
      • If you wished to have a mechanism to allow the user to affect all the links you would have no way of doing it without adding the function call to the onClick event handler for every link.

    • Application
      • This is best suited for those times when you only want this functionality to work on a few links in a page.

  2. We could alter the value of the target attribute for every link in the page.
    • Advantages
      • We don't have to alter any of the links on the page. We just call a function that handles the setting of the value of the target attribute of the link to the appropriate value depending on which choice is selected.

    • Disadvantages
      • Every link on the page would be affected.
      • There's no mechanism to turn off the behavior for certain links like on-site navigation.

    • Application
      • This is perfect for a page full of links and you want them all to be affected. This is especially nice when the links on the page are constantly being added/edited/removed since you don't have "attach" this functionality to the links individually.

  3. We could alter the value of the target attribute for only those links in the page that are marked for alteration.
    • Advantages
      • We could have different sets of links attached to different mechanisms.
      • We could have a mechanism that would affect all the links on the page.

    • Disadvantages
      • We'd have to alter those links we wanted to have use this functionality.
      • The function is altering all the marked links on the page whenever the selection is changed.

    • Application
      • Want ultimate flexibility? You've got it with this.

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.

Solution 1 - Using the onClick event handler of the link

The Options

This 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

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>

The Function

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>

The Result

[

]

[

]

[

]


Solution 2 - Changing the target Attribute for every link

The Options

This 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

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>

The Function

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>

The Result

[

]

[

]

[

]


Solution 3 - Changing the target attribute for certain links

The Options

This 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

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>

The Function

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>

The Result

[

]

[

]

[

]


Note:

  1. the value of the name attribute should not be used as an internal anchor in

    the page at any point
  2. the value of the name attribute must be the same value for all links
  3. the value of the name attribute for the links to be targeted by the user should

    exactly match the value of the name

    attribute of the group of radio buttons

    the developer wishes to tie to those

    same link(s)

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 controls

for all onsite links and another set for offsite links, or you could have

controls for all links in a sidebar (like list of blogs or some such). The

important thing to note is that they're all tied by the value of the name

attributes both on the radio buttons for the links and the name attribute of

the links to be affected themselves.

Good Luck!

.jeff

Jeff Howden (.jeff) is a web developer working for Vos & Howden, LLC in Portland, Oregon where he's partnered with long-time colleague, Anthony Vos. His skills include ColdFusion, JavaScript, CSS, XML, relational databases, and much, much more. His biggest professional accomplishments include, but are not limited to:

  • building a ColdFusion-based e-commerce solution for Mt. Bachelor that transacted over $1.62 million dollars in September 2001 with 0 (yes, that's zero) ColdFusion errors and then an almost completely rebuilt version transacted $2.86 million dollars in September 2002.
  • being asked to be a Technical Editor for the ColdFusion MX book, Inside ColdFusion MX from New Rider's Publishing company.
  • being asked by BrainBench to perform quality control on their JavaScript 1.5 certification test after receiving the highest beta test score out of 200 testees.
  • managing the server that hosts evolt.org and withstanding a slashdotting that brought over 1,000,000 hits to the site, over 10 gigs of data transfer, and an average in excess of 2300 unique visitor sessions per hour, all within a 24-hour period and the server never hiccuping once.

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.org Evolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.