Jump to content
Larry Ullman's Book Forums

Recommended Posts

On page 43, you strongly recommend eliminating embedded Javascript within the HTML page. I am guilty of adding JavaScript to my web pages by embedding. Mainly because I didn't know any better. So following your good example, I am rewriting my JavaScript content.

 

But I don't know how to eliminate one of the examples you show: <a href="javascript:createWindow():">A Link</a>

 

I'd like the 'A Link' to show a popup window for those with javascript and a new window for those without javascript.

 

Any tips are welcome.

 

Thank you for writing Modern Javascript. It has so many good tips for improved JavaScript scripting. And the book starts basic enough to gently educate. Especially a self-taught webmaster like me. I'll try to improve!

Link to comment
Share on other sites

martinb, the main way to separate the JS from HTML and still do what you want to do is to use something like the getElementById method. I think you have a couple of options here. If you are only concerned about one link, then you can do something like the following:

 

<body>

 

<a href="some-page-name-here.html" id="newWindow" target="_blank">Click me to open a new window</a>

 

<script>

 

document.getElementById('newWindow').onclick = function () {

 

window.open(this.getAttribute('href'));

 

return false;

 

};

 

</script>

 

</body>

 

The return false at the end of the anonymous function reference used for the onlick event handler will force the browser to not follow the href value in the a tag. As such, if JS is enabled, the window.open method will open a new window with the specified URL (see http://www.w3schools.com/jsref/met_win_open.asp for details), and if JS is not enabled, the standard HTML link will be used. Note that the target attribute will force the linked page to be opened in a new window/tab in the browser.

 

If you want to do the above for multiple links, then you'll want to use the getElementsByTagName method and for through all of the returned DOM elements. Be careful of the closure gotcha in JS when you're doing this though. The easiest way to avoid that is something like the following:

 

<body>

 

<a href="some-page-name-here-1.html" target="_blank">Click me to open a new window 1</a>

 

<a href="some-page-name-here-2.html" target="_blank">Click me to open a new window 2</a>

 

<a href="some-page-name-here-3.html" target="_blank">Click me to open a new window 3</a>

 

<script>

 

var aElems = document.getElementsByTagName('a');

 

for (var i = 0, aElemsLen = aElems.length; i < aElemsLen; i++) {

 

aElems.onclick = openNewWindow;

 

}

 

function openNewWindow() {

 

window.open(this.getAttribute('href'));

 

return false;

 

}

 

</script>

 

</body>

 

Well, hope that helps. Please ask if you have any questions.

Link to comment
Share on other sites

Thats really helpful. Thank you for answering my question. I can understand what you scripted.

 

Meanwhile I scrolled the internet and found this solution. It seems close to your suggestion but I'm not sure if it follows your logic.

<script type="text/javascript">

function changeLinks()

{

var as,i,islink;

// grab all links, loop over them;

as=document.getElementsByTagName('a');

for(i=0;i<as.length;i++)

{

// check which link has a target attribute, and send this one to popup

if(as.getAttribute('target')!='')

{

as.onclick=function(){return(popup(this));};

//as.onkeypress=function(){return(popup(this));};

}

}

}

function popup(o)

{

// open a new window with the location of the link's href

window.open(o.href,'newwin','height=400,width=400');

return false;

}

 

// if the browser can deal with DOM, call the function onload

if(document.getElementById && document.createTextNode)

{

window.onload=changeLinks;

}

 

</script>

Link to comment
Share on other sites

Yeah, that's more or less the same thing, although their script is a bit overly complex and it has a few inefficiencies in it.

 

For one, using array.length in a for loop end condition is inefficient because the length value has to be recalculated each time through the loop. It's better to store the length in a variable ahead of time, like I did in my code.

 

Also, the script does avoid the closure gotcha by returning a reference to the popup function with the provided argument, but it also is stacking a bunch of function definitions up in memory. For example, if there are 100 valid links on the page, then there will be 100 anonymous function definitions stacked up in memory, which is inefficient. With my code, because an existing function (i.e., openNewWindow) is referenced by name, there's only one function definition in memory.

 

Lastly, I don't like the DOM-object.href syntax. I think DOM-object.getAttribute('href') is better because it's more widely supported.

 

One thing I will compliment the code on is for testing whether each link has a target attribute or not. That's a good idea. An equally good idea would be to assign a class to all the links you want to have pop-ups for. For example:

 

<a href="#" class="popup">

 

<a href="#" class="popup">

 

<a href="#">

 

<a href="#">

 

<a href="#" class="popup">

 

<script>

 

var aElems = document.getElementsByTagName('a');

 

for (var i = 0, aElemsLen = aElems.length; i < aElemsLen; i++) {

 

if (aElems.className === 'popup') {

 

// Code here

 

}

 

}

 

</script>

 

Also, if you have multiple classes assigned to some links, you could use the indexOf method or a regex to test whether the popup class is present.

Link to comment
Share on other sites

Can popups.js (Chapter 9) work when images are used for the link? Using popups.js and popups.html:

<a href="popupA.html id="link" target="PopUp">B Link</a> works fine.

<a href="popupA.html id="link" target="PopUp"><img src="NSCF.gif" alt="image"></a> results in a popup window that does not recognise the page.

Link to comment
Share on other sites

martinb, I'm not sure what the problem with your code is. By wrapping an img tag in an a tag, you're not so much making an image a link as you are just wrapping in img tag in an a tag.

As such, if the a tags in your HTML and your JS sync up properly, your code should work properly, as if there were no img tags at all.

Link to comment
Share on other sites

 Share

×
×
  • Create New...