GithubHelp home page GithubHelp logo

javascript-hide-and-seek's Introduction

JavaScript Hide and Seek

Objectives

  1. Use document.querySelectorAll to find nested nodes
  2. Change the value of the correct DOM nodes

Introduction

In this lab, we're going to practice finding elements in the DOM. To do so, we're going to make use of two methods that are immensely useful for navigating the DOM.

If you are using the in-browser IDE, call httpserver in your IDE terminal or call open index.html if you are coding in a local environment. Use the browser as a visual aid while solving this lab. Use learn to run the tests.

querySelector()

querySelector() takes one argument, a string of selectors, and returns the first element that matches these selectors. Given a document like

<body>
  <div>
    Hello!
  </div>

  <div>
    Goodbye!
  </div>
</body>

If we called document.querySelector('div'), the method would return the first div (whose .innerHTML is "Hello!").

Selectors aren't limited to tag names, though (otherwise why not just use document.getElementsByTagName('div')[0]?). We can get very fancy.

<body>
  <div>
    <ul class="ranked-list">
      <li>1</li>
      <li>
        <div>
          <ul>
            <li>2</li>
          </ul>
        </div>
      </li>
      <li>3</li>
    </ul>
  </div>

  <div>
    <ul class="unranked-list">
      <li>6</li>
      <li>2</li>
      <li>
        <div>4</div>
      </li>
    </ul>
  </div>
  <script>
    // get <li>2</li>
    const li2 = document.querySelector('ul.ranked-list li ul li')

    // get <div>4</div>
    const div4 = document.querySelector('ul.unranked-list li div')
  </script>
</body>

In the above example, the first query says, "Starting from document (the object we've called querySelector() on), find a ul with a className of ranked-list (the . is for className). Then find an li that is a child of that ul. Then find a ul that is a child (but not necessarily a direct descendant) of that li. Finally, find an li that is a child of that (second) ul."

NOTE: The HTML property class is referred to as className in JavaScript. It's... unfortunate.

What, then, does the second call to querySelector() say? Puzzle it out for a bit, and then read on.

Puzzle a bit longer!

Just a bit longer!

Okay, the second call says, "Starting from document, find a ul with a className of unranked-list. Then find an li descended from ul.unranked-list and a div descended from that li."

Interlude: Selectors

Now is probably a good time to read up on selectors. They're super important and relatively straightforward to pick up. Play around on the MDN page while you're getting the hang of it! Then come back when you're ready.

querySelectorAll()

querySelectorAll works a lot like querySelector() -- it accepts a selector as its argument, and it searches starting from the element that it's called on (or from document) -- but instead of returning the first match, it returns a NodeList (which, remember, is not an Array) of matching elements.

Given a document like

<main id="app">
  <ul class="ranked-list">
    <li>1</li>
    <li>2</li>
  </ul>

  <ul class="ranked-list">
    <li>10</li>
    <li>11</li>
  </ul>
</main>

If we called document.getElementById('app').querySelectorAll('ul.ranked-list li'), we'd get back a NodeList of <li>1</li>, <li>2</li>, <li>10</li>, <li>11</li>.

We could change the .innerHTML of these lis like so:

const lis = document
  .getElementById('app')
  .querySelectorAll('ul.ranked-list li');

for (let i = 0; i < lis.length; i++) {
  lis[i].innerHTML = (i + 1).toString();
}

Now our lis, even though they're children of two separate uls, will count up from 1 to 4.

Using this loop construct, we could even, say, call querySelector() or querySelectorAll() on these children to look deeper and deeper into a nested structure... (hint!).

Instructions

Instructions for In-Browser Learn IDE Users

If you are using the Learn IDE available in your browser, you will automatically clone down the files you need when you click 'Open IDE', but in order to view index.html, you will need to use httpserver to serve the HTML page temporarily. In the terminal, type httpserver and press enter. You will see that Your server is running at ... followed by a string of numbers and dots. This string is a temporary IP address that is hosting your index.html file. Copy this string of numbers, open a new tab and past the string in to the URL bar.

Instructions for Students Using an Stand Alone Text-Editor

If you are using an standalone text editor such as Sublime or Atom, before we get started, follow these instructions to manually fork and clone the lesson repository on GitHub. In your forked and cloned copy, you'll find the index.html file, which you can then manually open up in the browser. (For instructions on opening HTML files in the browser from the Learn IDE, see this Help Center article.)

In index.html, you'll see that we've set up a basic document for you. We'll be testing against this document, but you should still write your code in index.js. We'll handle loading everything up for you.

  • Define a function getFirstSelector(selector), which accepts a selector and returns the first element that matches.
  • Define a function nestedTarget() that pulls a .target out of #nested (# is used for IDs in selectors — but you knew that because you read the docs, right? :) ). (Note that in index.html #nested and .target just happen to be divs. This method should work with arbitrary elements.)
  • Define a function increaseRankBy(n) that increases the ranks in all of the .ranked-lists by n. (You might need to make use of parseInt()
  • Define a function deepestChild() that pulls out the most deeply nested child element from div#grand-node. (Remember, you can iterate over elements and call querySelector() and querySelectorAll() on them. This is challenging to implement correctly, but not beyond your ability!)

HINT 1: Your solution for deepestChild() does not need to be totally generic; we don't expect it to work in every case. For example, we know that div#grand-node has only one node at each level — for this lab, you can solve for that case, and not worry about a case where there are sibling nodes.

HINT: Remember learning about breadth-first search? A similar technique might come in handy here.

Have fun, and good luck!

Resources

javascript-hide-and-seek's People

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

javascript-hide-and-seek's Issues

How to restore // ♥ prompt to terminal after creating server with "httpserver"?

Hello

the section "Instructions for In-Browser Learn IDE Users" in this lesson seems incomplete (unless I'm missing something?)

It's simple enough to follow the instructions to get the server's IP address and then open that in another window... but then we are not shown how to escape the resulting "ready for changes" server mode and return to the familiar Learn terminal prompt " //♥ " in order to be able to use "learn test" and "learn submit" ... unless we're not supposed to? It's not explained...

There must be a simple way to get the //♥ prompt back – if so, what is it? – and shouldn't that be part of the instructions?

I was able to get "httpserver &" to work, to start the server as a background process, only after a combination of finding this article and some experimentation with exiting and re-entering the lesson.

Side note - there's also some nonfunctioning links in the "Instructions for Using an Stand Alone Text-Editor" section

Thank you!

open index.html command doesn't word in the ide's command line

For this lab it istructs you to call "open index.html" in terminal and "mocha.run()" in the developer console.
One of the TA's pointed out i should instead call "httpserver".

I then realized putting number returned after "Your server is running at" into my browser would show me the resulting webpage where i could open the developer console and then mocha.run().

I'm just thinking since the program suggests to use the IDE that there be a bit about that in the writeup to make it easier for other student.

Cheers 🍻

div#grand-node

Define a function deepestChild() that pulls out the most deeply nested child from div#grand-node. (Remember, you can iterate over elements and call querySelector() and querySelectorAll() on them. This is challenging to implement correctly, but not beyond your ability!)

This question has confusing wording.

issues with test, swap var for let

tests weren't working. removed 'let' from the variable declarations and replaced with 'var'. tests worked.

error message:

[email protected] test /Users/jonalexander/Development/code/javascript-hide-and-seek-web-0616
mocha -R mocha-multi --reporter-options nyan=-,json=.results.json

/Users/jonalexander/Development/code/javascript-hide-and-seek-web-0616/test/index-test.js:40
let children = firstList.children
^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:387:25)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at /Users/jonalexander/Development/code/javascript-hide-and-seek-web-0616/node_modules/mocha/lib/mocha.js:220:27
at Array.forEach (native)
at Mocha.loadFiles (/Users/jonalexander/Development/code/javascript-hide-and-seek-web-0616/node_modules/mocha/lib/mocha.js:217:14)
at Mocha.run (/Users/jonalexander/Development/code/javascript-hide-and-seek-web-0616/node_modules/mocha/lib/mocha.js:469:10)
at Object. (/Users/jonalexander/Development/code/javascript-hide-and-seek-web-0616/node_modules/mocha/bin/_mocha:404:18)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:142:18)
at node.js:939:3
npm ERR! Test failed. See above for more details.
/Users/jonalexander/.rvm/gems/ruby-2.2.3/gems/learn-test-2.4.0/lib/learn_test/strategies/mocha.rb:49:in results': undefined method[]' for nil:NilClass (NoMethodError)
from /Users/jonalexander/.rvm/gems/ruby-2.2.3/gems/learn-test-2.4.0/lib/learn_test/runner.rb:68:in push_results' from /Users/jonalexander/.rvm/gems/ruby-2.2.3/gems/learn-test-2.4.0/lib/learn_test/runner.rb:19:inrun'
from /Users/jonalexander/.rvm/gems/ruby-2.2.3/gems/learn-test-2.4.0/bin/learn-test:60:in <top (required)>' from /Users/jonalexander/.rvm/gems/ruby-2.2.3/bin/learn-test:22:inload'
from /Users/jonalexander/.rvm/gems/ruby-2.2.3/bin/learn-test:22:in <main>' from /Users/jonalexander/.rvm/gems/ruby-2.2.3/bin/ruby_executable_hooks:15:ineval'
from /Users/jonalexander/.rvm/gems/ruby-2.2.3/bin/ruby_executable_hooks:15:in `

'

Open command doesn't work with in browser IDE

With the In-browser IDE, the first instructions do not work:

"Call open index.html from your terminal, open your Chrome developer tools and call mocha.run() from your console to run the tests."

The open command gives you this error message: bash: open: command not found

Instead, students should be asked to run learn and giving instructions on how to use httpserver so that they can view the index.html file in the browser.

@DanielSeehausen

Open IDE Button Not Working

Pressing the Open IDE button doesn't launch the In Broswer IDE. Checked Account Settings, and confirmed that the "Open IDE in Browser" option was selected.

Device Details:

  • Device: Apple 13" MacBook Pro (2017)
  • Browser: Brave Browser Version 1.8.96 Chromium: 81.0.4044.138 (Official Build) (64-bit)

Creating and Inserting Nodes Lab

Hi, I'm finding the submission instructions for the Creating and Inserting Nodes lab to be lacking.

In this lesson, the instructions for the lab read:

Open this lesson's index.html file in your browser or use httpserver to serve it temporarily. Once open, open up the browser's console. In the console, enter: ...

I feel that the instructions should include:

Learn IDE users should open index.js to enter the following code if you are not using a stand-alone text editor or the browser's console.

I'm not certain if it was written the original way to test our knowledge and learn how to read documents, but I worried that for those who are not more familiar with the structure of HTML documents, this might be a bit confusing.

Feedback on 4th bullet / task

Define a function deepestChild() that pulls out the most deeply nested child from div#grand-node
I found this to slightly ambiguous - I was not certain whether to return the last child (ie. <div>) or the element of that child. Perhaps reword as '...most deeply nested child element...' for clarification?

"before all" hook Uncaught SecrityError: localStorage is not available for opaque origins

Here is what is returned in my online IDE console:

// ♥ learn open javascript-hide-and-seek-bootcamp-prep-000
Looking for lesson...
Forking lesson...
Cloning lesson...
Opening lesson...
Installing npm dependencies...
yarn install v1.7.0
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
warning Your current version of Yarn is out of date. The latest version is "1.9.4", while you're on "1.7.0".
info To upgrade, run the following command:
$ sudo apt-get update && sudo apt-get install yarn
Done in 7.60s.
Done.
[10:08:17] (master) javascript-hide-and-seek-bootcamp-prep-000
// ♥ learn

> [email protected] test /home/guysbryant/javascript-hide-and-seek-bootcamp-prep-000
> mocha -R mocha-multi --reporter-options nyan=-,json=.results.json

 0   __,------,
 1   __|  /\_/\
 0   _~|_( x .x)
     _ ""  ""

  0 passing (761ms)
  1 failing

  1) "before all" hook:
     Uncaught SecurityError: localStorage is not available for opaque origins
      at Window.get localStorage [as localStorage] (node_modules/mocha-jsdom/node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
      at propagateToGlobal (node_modules/mocha-jsdom/index.js:108:27)
      at Object.done (node_modules/mocha-jsdom/index.js:59:9)
      at process.nextTick (node_modules/mocha-jsdom/node_modules/jsdom/lib/old-api.js:366:18)
      at _combinedTickCallback (internal/process/next_tick.js:131:7)
      at process._tickCallback (internal/process/next_tick.js:180:9)



npm ERR! Test failed.  See above for more details.
[10:08:23] (master) javascript-hide-and-seek-bootcamp-prep-000
// ♥

there is a typo in the 67th line of the code missing a closed parentheses

There is a missing parentheses after the end of the first sentence of this paragraph.

In the above example, the first query says, "Starting from document (the object we've called querySelector() on), find a ul with a className of ranked-list (the . is for className #). Then find an li that is a child of that ul. Then find a ul that is a child (but not necessarily a direct descendant) of that li. Finally, find an li that is a child of that (second) ul."

Specs do not match readme

The specs are slightly out of order w/ the readme - a little confusing if working through in order- switch the order of spec #3 with spec #4 to match the readme

screen shot 2017-09-01 at 3 41 54 pm

screen shot 2017-09-01 at 3 41 41 pm

Confusing Examples

Nested target requires a space between the id and class name in order to pass, but none of the lesson examples have a space in front of the class name.

Outdated tests

When working in httpserver on this lesson:

./test/index-test.js is using .to.equal() which is causing errors when using mocha.run() in DevTools. Tests need to be updated to .toEqual().

Console.log not printing to the console

Trying to figure out why console.log isn't printing to the screen for me.

console.log("TEST") is a simple example and I don't see anything on the console. Have asked learn experts twice about it, but they don't seem to have a fix for me. Is this a bug with the IDE?

Test Error

I am unable to run the tests for this lab. The results from tests return 1 failing with a "before all hooks" error.

Instructions after httpserver

The set up for this lab lack a key instruction to tell students how to exit the httpserver and return to the learn so that your work may be tested and submitted. I was told that everyone eventually asks the question, but thought an update might be useful.

Suggestion for In-Browser Learn IDE users starting httpserver

When I started httpserver on my In-Browser Learn IDE I found I could not use the command line to test my progress (e.g. learn command). So, I sent the program to the background using '&' or CTRL-Z and 'bg'. I thought this might be useful for others. However, I did log off a session without killing the background process and the next time I ran the server, it had to use a different IP/port. Not sure the change was related, but if so, perhaps when a user session ends (or when they begin a new one) the server can be shut down and IP/port freed.

Yarn Error

I get this error when opening the IDE for this lab.

♥ learn open javascript-hide-and-seek-bootcamp-prep-000 Looking for lesson... Forking lesson... Cloning lesson... Opening lesson... Installing dependencies... yarn install v1.3.2 [1/5] Validating package.json... error [email protected]: The engine "node" is incompatible with this module. Expected version "6.x". error Found incompatible module info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command. Done.

The solution for deepestChild() fails to get the deepest child if div has more then one direct child

Suggested solution for this would be :

function deepestChild() {
var answer
var children = {}
var counter = 0
var list = document.querySelectorAll('#grand-node > div')
for (var i = 0; i < list.length; i++) {
var current_child = list[i]
while (current_child.querySelector(':first-child') != null) {
counter += 1
current_child = current_child.querySelector(':first-child')
deepestChild = current_child

}
if (children[i] === undefined || children[i] < counter) {
  children[i] = counter
  answer = deepestChild
}
counter = 0

}
return answer
}

Syntax error in test causes failures for working code.

describe('index', () => {
describe('getFirstSelector(selector)', () => {
it('returns the first element that matches the selector', () => {
expect(getFirstSelector('div').id).to.equal('nested')
expect(getFirstSelector('.ranked-list')).to.equal(document.querySelector('.ranked-list'))
})
})

.to.equal throws an error. Change to the old version of the test with .toEqual. Full Snippet below.

describe('index', () => {
describe('getFirstSelector(selector)', () => {
it('returns the first element that matches the selector', () => {
expect(getFirstSelector('div').id).toEqual('nested')
expect(getFirstSelector('.ranked-list')).toEqual(document.querySelector('.ranked-list'))
})
})

describe('nestedTarget()', () => {
it('pulls a .target out of #nested', () => {
expect(nestedTarget()).toEqual(document.querySelector('#nested .target'))
})
})

describe('deepestChild()', () => {
it('returns the most deeply nested child in #grand-node', () => {
console.log(deepestChild().innerHTML)
expect(deepestChild()).toBe(document.querySelector('#grand-node div div div div'))
})
})

describe('increaseRankBy(n)', () => {
it('increases ranks in .ranked-list by n', () => {
increaseRankBy(3)

  const rankedLists = document.querySelectorAll('.ranked-list')
  const firstList = rankedLists[0]
  const secondList = rankedLists[1]

  let children = firstList.children
  let start = 1
  for (let i = 0, l = children.length; i < l; i++) {
    expect(parseInt(children[i].innerHTML)).toEqual(start + i + 3)
  }

  children = secondList.children
  start = 12

  for (let i = 0, l = children.length; i < l; i++) {
    expect(parseInt(children[i].innerHTML)).toEqual(start - i + 3)
  }
})

})
})

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.