getElementsByTagName noob help!

Hi everybody!
I am stuck at a basic noob js problem, and really need help.

My assignment is fallowing;
I need to assign my links a pop-up window, that will say “Are you sure you want to leave?”

I am supposed to do this with getElementsByTagname(), and use an external file.
I’ve tried putting a class=a into the html code, but when I click the link it goes through without the pop-up. Really appreciate the help!

JS:

<script type="text/javascript">
function changeLink() {
	var links = document.getElementsByTagName("a");


	for(var i=0;i<links.length;i++) {

		links[i].onclick = function() { alert('I have been clicked')};
	}
}
</script>

HTML:

    <html>
         <head>
             <script script type="text/JavaScript" src="2.js"></script>
        </head>


  <body>
 <ul>
    <li>
        <a href="http://www.bajs.com">link1</a>
    </li>
     <li>
       <a href="http://www.kiss.com">link2</a>
    </li>
</ul>


</body>
</html>

add to the “body” tag, the attribute onload=“changeLink()” as follows:

<body onload="changeLink()">

Since you want all the JavaScript in the separate file add the following to the end of the JavaScript instead:

window.onload = changeLink;

The simplest solution is to remove the changeLink function part, so you only have what’s inside of it as the entire script.

2.js


var links = document.getElementsByTagName("a");
for(var i=0;i<links.length;i++) {
    links[i].onclick = function() {alert('I have been clicked')};
}

And to have that script load from the end of the body, just before the </body> tag.


<html>
<head>
</head>

<body>
<ul>
    <li>
        <a href="http://www.bajs.com">link1</a>
    </li>
    <li>
       <a href="http://www.kiss.com">link2</a>
    </li>
</ul>
<script src="2.js"></script>
</body>
</html>

There are several improvements that can be made to this script.


var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++) {
    links[i].onclick = function() {alert('I have been clicked')};
}

A completely new function is assigned to each onclick event. It uses less resources to have only the one function, and to assign to the onclick event a reference to that function.


[color="green"]function linkClickHandler() {
    alert('I have been clicked');
}[/color]
var links = document.getElementsByTagName("a");
for(var i = 0; i < links.length; i++) {
    links[i].onclick = [color="green"]linkClickHandler[/color];
}

Calculate the length outside of the for loop. That way it doesn’t need to be calculated over and over again whenever the for loop loops around again.

Also, using += 1 instead of ++ makes it easier for you to specify different types of increments later on.


function linkClickHandler() {
    alert('I have been clicked');
}
var links = document.getElementsByTagName("a");
[color="green"]var linksLen = links.length;[/color]
for (var i = 0; i < [color="green"]linksLen; i += 1[/color]) {
    links[i].onclick = linkClickHandler;
}

Having var assignments scattered throughout the code is not a good idea. Always ensure that var assignments are at the start of a function or block of code.


function linkClickHandler() {
    alert('I have been clicked');
}
[color="green"]var links = document.getElementsByTagName("a");
var linksLen = links.length;
var i;[/color]
for (i = 0; i < linksLen; i += 1) {
    links[i].onclick = linkClickHandler;
}

You can (and should) combine multiple var statements to just one comma-separated var statement.


function linkClickHandler() {
    alert('I have been clicked');
}
[color="green"]var links = document.getElementsByTagName("a"),
    linksLen = links.length,
    i;[/color]
for (i = 0; i < linksLen; i += 1) {
    links[i].onclick = linkClickHandler;
}

Finally, instead of assigning onclick events to every single link on the page, you can instead monitor all clicks on the page, and take action when the click occurs on a link.

The benefit of this is that only one event handler is being added to the page.


document.body.onclick = function (evt) {
    evt = evt || window.event;
    var targ = evt.target || evt.srcElement;
    if (targ.nodeType === 3) { // handle Opera bug
        targ = targ.parentNode;
    }
    if (targ.nodeType === 1 && targ.nodeName === 'A') {
        alert('I have been clicked');
    }
}

That might be reaching too far beyond what you’re being taught though.

@ Amit Yaron, felgall Thanks guys! I did try both of your suggestions but (guess from my part) it didn’t work.

@ paul_wilkins All I can say is that was amazing. I have been dealing with this assignment for a ridiculous long time. Be amazed, a month. For you to show me this is just wonderful and I’m unbelievable grateful for it. Also the way you have shown the build up for the code is highly pro, I have been scanning all kind of JS books, from Keits DOM Scripting to The JavaScript Anthology and none of them had this specific code. They all explained the difference between GetElementsByTagId and GetElementsByTagName. They also explained about the loop inside the GetElementByTagName but that was it. I really feel that the hands on examples lack immensely. The books for HTML and CSS are milestones way ahead of explaining for beginners.

I will definitely look through your suggestion and study it.