Listen to everyone!
This may seem like a lot of code to add a listener to one link when it’s being clicked, mouseover’ed, or mouseout’ed. When you have multiple links which need to have the same functionality, or multiple elements which need to have the same event listener attached, this technique will be a life saver. From last week, we were able to select specific elements of a page, or groups of elements. Now we’ll do a real life example!
Let’s say we have a page full of terms which, to the untrained, would make no sense. Let’s add click handlers to each of these terms which will take the user to a google search for that particular term.
Consider the following markup:
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Hello there</title> </head> <body> <h1>This is the title</h1> <p class="terminology"><em>Lorem ipsum dolor sit amet</em>, consectetur adipiscing elit. <em>Nulla at leo quam</em>. Phasellus risus orci, molestie quis imperdiet nec, aliquam et tellus. Nam pulvinar odio vel massa feugiat fermentum. Donec eget ligula ut risus pellentesque faucibus nec ac libero. Morbi id elit vel nulla dignissim suscipit. Pellentesque nec augue ante, at viverra erat. In euismod mi vitae neque porttitor id viverra elit convallis. Mauris at massa quam, non ultricies arcu. Donec in libero risus, posuere iaculis velit. Aenean dignissim erat in augue malesuada nec cursus erat convallis. <em>Sed sem ligula</em>, luctus in semper vitae, vehicula sed nisi. Fusce quis magna ac turpis tempus porttitor a eget lectus. Mauris volutpat dolor laoreet felis bibendum volutpat. Ut facilisis convallis dui non ullamcorper. Curabitur eget euismod nunc. Phasellus at neque ac turpis sollicitudin consequat. Quisque adipiscing nunc ac erat commodo mattis. </p> <p class="terminology">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla at leo quam. Phasellus risus orci, molestie quis imperdiet nec, aliquam et tellus. Nam pulvinar odio vel massa feugiat fermentum. Donec eget ligula ut risus pellentesque faucibus nec ac libero. <em>Morbi id elit vel nulla dignissim suscipit</em>. Pellentesque nec augue ante, at viverra erat. In euismod mi vitae neque porttitor id viverra elit convallis. Mauris at massa quam, non ultricies arcu. <em>Donec in libero risus</em>, posuere iaculis velit. Aenean dignissim erat in augue malesuada nec cursus erat convallis. Sed sem ligula, luctus in semper vitae, vehicula sed nisi. <em>Fusce quis magna ac turpis tempus porttitor a eget lectus</em>. Mauris volutpat dolor laoreet felis bibendum volutpat. Ut facilisis convallis dui non ullamcorper. Curabitur eget euismod nunc. Phasellus at neque ac turpis sollicitudin consequat. Quisque adipiscing nunc ac erat commodo mattis. </p> </body> </html>
Here we have paragraphs of the class “terminology” and within the paragraphs, we have some emphasized text (<EM>). We want to change these all so that when someone clicks on them, a google search pops up in a new window/tab.
Once again we’re going to assume this code will be in the HEAD tag and the “domload” function exists for our pure JavaScript solution.
Example: Multiple listeners
- Pure Javascript
// our domload function from Week 1 initDOMLoad(function() { // check what kind of event listener function we need to call var m; window.addEventListener ? m = true : m = false; // select the link if (document.getElementsByTagName) { // first select all the paragraphs var objParagraphs = getElementsByClass('terminology',null,'p'); // select and update each EM in the paragraphs for (var i=0; i<objParagraphs.length; i++) { // select all child EMs var objEms = objParagraphs[i].getElementsByTagName('em'); for (var j=0; j<objEms.length; j++) { // update each em if (m) { objEms[j].addEventListener('click', doGoogleSearch, false); } else { objEms[j].attachEvent('onclick', doGoogleSearch); } } objEms = null; } } }); // helper functions function doGoogleSearch() { var search_terms = escape(this.innerHTML); if (search_terms === 'undefined') { search_terms = window.event.srcElement.innerHTML; } var w = window.open('http://www.google.ca/#q='+search_terms,'',''); } function getElementsByClass(searchClass,node,tag) { var classElements = new Array(); if ( node == null ) node = document; if ( tag == null ) tag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"); for (i = 0, j = 0; i < elsLen; i++) { if ( pattern.test(els[i].className) ) { classElements[j] = els[i]; j++; } } return classElements; } - Prototype
// listen on dom load document.observe('dom:loaded',function() { // select the link and listen on click $$('p.terminology em').invoke('observe','click',function(evt) { var w = window.open('http://www.google.ca/#q='+evt.element().innerHTML); }); }); - jQuery
// listen on dom load $(document).ready(function() { // select the link and listen on click $('p.terminology em').click(function() { var w = window.open('http://www.google.ca/#q='+this.innerHTML); }); });
Once again, you’ll notice the elephant in the room. Pure JavaScript without the help of any assisting frameworks is a lot more complex. Using Prototype or jQuery does simplify things. Using what we know about CSS, we can apply the same selector knowledge when using both frameworks. Otherwise, we’re stuck with pure JavaScript and will need to create loops within loops to find and select those particular elements required.
There is, of course, the unfortunate fact that there is overhead when using a framework. The libraries need to be downloaded even though your script may not utilize everything. Some programmers like to have a minimalistic mentality and only include what they require, so they use pure JavaScript. There is nothing wrong with that, it is just a lot more work. In this case we want to simplify the DOM manipulation for the sake of examining the practical implementation of event listening.
So, back to the matter at hand: multiple event listeners. This may seem like a mentally draining task, but in the future this code may be reused for any page. Designers with no programming knowledge at all can now utilize this functionality by creating paragraphs with EM tags around terms which may be useful to Google. They will never have to add “onclick” attributes anywhere, they just need to remember what HTML tags to use.
Review
This week gets us to a place which is more interesting: enabling us to interact with users! onMouseOver, onMouseOut, onClick are just the tip of the ice berg. Because this may be new to everyone, we should just start with the basic understanding of what events are, what makes them trigger, and how we can leverage our previous knowledge of selectors to add functionality without stressing out our designers.
Once again we go back to what this does for SEO. Absolutely nothing (yet). We can at least add more functionality to the page without adding more HTML to the page. Search crawlers will thank you as they don’t have to sift through script it can’t even read in the first place. As far as they’re concerned, we just provide them with a pure HTML page with great searchable terms embedded.