Chapter 6: Advanced JavaScript

Loops

The for() statement is one way to run a loop. Try running the code below in the console. What happens if you change the initial value of i to 2?

for(var i = 0; i < 5; i++) {
	console.log(i);
}

Below is the sample results list described in the section on Loops in Chapter 6.

Article Journal Database Name 1 1986-present
Article Journal Database Name 2 1991-1999
Show Markup
<div id="linkresolver" class="sample">
    <table>
      <tr class="row">
        <td>
          <table>
            <tr>
              <td class="article"><a href="#article1">Article</a></td>
              <td class="journal"><a href="#journal1">Journal</a></td>
              <td class="database"><a href="#database1">Database Name 1</a></td>
              <td class="dates">1986-present</td>
            </tr>
          </table>
        </td>
      </tr>
      <tr>
        <td>
          <table>
            <tr class="row">
              <td class="article"><a href="#article2">Article</a></td>
              <td class="journal"><a href="#journal2">Journal</a></td>
              <td class="database"><a href="#database2">Database Name 2</a></td>
              <td class="dates">1991-1999</td>
            </tr>
          </table>
        </td>
      </tr>
    </table>
   </div>

The code below will scrape the text from the various table cells to create a set of arrays, and then echo the contents of those arrays into the console.

var articleLinks = new Array(), journalLinks = new Array(), databaseLinks = new Array(), databaseNames = new Array(), dates = new Array();
var links = document.getElementById('linkresolver').querySelectorAll('tr.row');
for(var i = 0; i < links.length; i++) {
    articleLinks[i] = links[i].querySelector('td.article a').href;
    journalLinks[i] = links[i].querySelector('td.journal a').href;
    databaseLinks[i] = links[i].querySelector('td.database a').href;
    databaseNames[i] = links[i].querySelector('td.database a').textContent;
    dates[i] = links[i].querySelector('td.dates').textContent;
}
console.log(articleLinks); 
console.log(journalLinks); 
console.log(databaseLinks); 
console.log(databaseNames); 
console.log(dates);

Try replacing the entire arrays in the console.log() methods with an array key. What happens if you log databaseNames[1]?

Now let's try scraping data from HTML markup and then building new HTML with JavaScript to replace the old. The code below is the code above, plus a series of statements to build a semantic list with a <ul> element rather than a table. After running the code in the console, look at your Elements Browser. Can you see how the markup in the DOM has changed?

var articleLinks = new Array(), journalLinks = new Array(), databaseLinks = new Array(), databaseNames = new Array(), dates = new Array();
var links = document.getElementById('linkresolver').querySelectorAll('tr.row');
for(var i = 0; i < links.length; i++) {
    articleLinks[i] = links[i].querySelector('td.article a').href;
    journalLinks[i] = links[i].querySelector('td.journal a').href;
    databaseLinks[i] = links[i].querySelector('td.database a').href;
    databaseNames[i] = links[i].querySelector('td.database a').textContent;
    dates[i] = links[i].querySelector('td.dates').textContent;
}

var linkContainer = document.createElement('ul');
for(var i = 0; i < links.length; i++) {
  var newListItem = document.createElement('li');
    newListItem.innerHTML = '<a href="' + articleLinks[i] + '" class="article">Full Text Online</a> '
		+ 'from <a href="' + databaseLinks[i] + '" class="database">' + databaseNames[i] + '</a>.<br />' 
		+ '<span class="dates">Coverage: ' + dates[i] + '</span>'
		+  ' <small>(<a href="' + journalLinks[i] + '">Browse Journal</a></small>)';
  linkContainer.appendChild(newListItem);
}
// Remove the old table
var oldTable = document.querySelector('#linkresolver > table');
document.getElementById('linkresolver').removeChild(oldTable);
// Add the new list
document.getElementById('linkresolver').appendChild(linkContainer);

Now, to add new styles to this list, run the code below after you've changed the <table> into a <ul>:

var newStyles = document.createElement('link');
newStyles.rel = 'stylesheet';
newStyles.type = 'text/css';
newStyles.href = '//mreidsma.github.io/vendor_tools/css/chapter6.css';
document.head.appendChild(newStyles);

Event Listeners

Often we need to run a script after a user has interacted with our site, or after another event has occured (like the page is done loading). Event Listeners are a great way to do this in JavaScript. Below you will find the sample results list described in the section on Event Listeners.

Full Text Online from Academic Search Database
Coverage: 1996-present Browse the journal

Show additional results

Show Markup
<div class="first-result">
	<a href="#" class="article">Full Text Online</a> from <a href="#" class="database">Academic Search Database</a><br />
	<span class="dates">Coverage: 1996-present </span>
	<small><a href="#">Browse the journal</a></small>
</div>
<p id="results-toggle">Show additional results</p>
<ul id="additional-results">
	<li><a href="#">Full Text Online</a> from Database.</li>
	<li><a href="#">Full Text Online</a> from Database.</li>
	<li><a href="#">Full Text Online</a> from Database.</li>
</ul>

The following code will hide the additional results by default, and then show them when the "Show additional results" link is clicked.

document.getElementById('additional-results').style.display = 'none';
document.getElementById('results-toggle').style.color = 'blue';
document.getElementById('results-toggle').style.textDecoration = 'underline';
document.getElementById('results-toggle').style.cursor = 'pointer';
document.getElementById('results-toggle').addEventListener('mousedown', function() {
	if(this.textContent == 'Show additional results') {
		document.getElementById('additional-results').style.display = 'block';
		this.textContent = 'Hide additional results';
	} else {
		document.getElementById('additional-results').style.display = 'none';
		this.textContent = 'Show additional results';
	}
});