├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── algorithms_and_computer_science ├── README.md └── letters_and_words │ ├── README.md │ └── questions_and_answers.js ├── events_and_callbacks ├── README.md ├── introduction_to_callbacks │ ├── 00_SUGGESTED_ORDER.md │ ├── README.md │ ├── calling_a_callback_function_more_than_once.js │ ├── introducing_predicate_functions.js │ ├── passing_functions_to_functions.js │ └── using_callback_functions_to_transform_arrays.js └── settimeout_and_setinterval │ └── README.md ├── interacting_with_the_user ├── README.md ├── command_line_arguments │ ├── 00_SUGGESTED_ORDER.md │ ├── README.md │ ├── calculator.js │ ├── parsing_arguments.js │ ├── using_an_argument_parser_library.js │ └── what_does_fox_say.js ├── manipulating_the_dom │ └── README.md ├── querying_the_dom │ └── README.md └── stdin_and_stdout │ └── README.md ├── manifest.json └── syntax_and_idioms ├── README.md └── embedding_js └── README.md /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | _Based on Version 0.4 of [Coraline 4 | Ehmke's](http://where.coraline.codes) [Contributor 5 | Covenant](https://github.com/Bantik/contributor_covenant)_ 6 | 7 | As contributors and maintainers of this project, we pledge to respect all 8 | people who contribute through reporting issues, posting feature requests, 9 | updating documentation, submitting pull requests or patches, and other 10 | activities. 11 | 12 | If any participant in this project has issues or takes exception with a 13 | contribution, they are obligated to provide constructive feedback and never 14 | resort to personal attacks, trolling, public or private harassment, insults, or 15 | other unprofessional conduct. 16 | 17 | Project maintainers have the right and responsibility to remove, edit, or 18 | reject comments, commits, code, wiki edits, issues, and other contributions 19 | that are not aligned to this Code of Conduct. Project maintainers who do not 20 | follow the Code of Conduct may be removed from the project team. 21 | 22 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 23 | reported by opening an issue or contacting one or more of the project 24 | maintainers. 25 | 26 | We promise to extend courtesy and respect to everyone involved in this project 27 | regardless of gender, gender identity, sexual orientation, ability or 28 | disability, ethnicity, religion, age, location, native language, or level of 29 | experience. 30 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | This project is a learning tool. For contributors to the baseline project, this 2 | means: 3 | 4 | 1. Clarity is prioritized over cleverness. (Even if it's really cool!) 5 | 1. Commits are held to a high standard. 6 | 1. Project maintainers and contributors are bound by our [Code of 7 | Conduct](CODE_OF_CONDUCT.md) 8 | 1. All contributions to this repository become bound by our [license](LICENSE) 9 | 10 | 11 | ### Clarity over Cleverness 12 | When providing instruction, it's easy to fall into the "this is 13 | really cool!" trap. Code should prioritize clarity over cleverness 14 | in every case; and over convention in some cases. 15 | 16 | ### Commit Standards 17 | 18 | We expect commits to: 19 | * Be small 20 | * Follow [Tim Pope's Guide to Commit 21 | Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) 22 | * Provide technical analysis of the code 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | A human friendly summary is available at 2 | http://creativecommons.org/licenses/by/4.0/ 3 | 4 | Creative Commons Attribution 4.0 International Public License 5 | 6 | By exercising the Licensed Rights (defined below), You accept and agree to be 7 | bound by the terms and conditions of this Creative Commons Attribution 4.0 8 | International Public License ("Public License"). To the extent this Public 9 | License may be interpreted as a contract, You are granted the Licensed Rights in 10 | consideration of Your acceptance of these terms and conditions, and the Licensor 11 | grants You such rights in consideration of benefits the Licensor receives from 12 | making the Licensed Material available under these terms and conditions. 13 | 14 | Section 1 – Definitions. 15 | 16 | Adapted Material means material subject to Copyright and Similar Rights that is 17 | derived from or based upon the Licensed Material and in which the Licensed 18 | Material is translated, altered, arranged, transformed, or otherwise modified in 19 | a manner requiring permission under the Copyright and Similar Rights held by the 20 | Licensor. For purposes of this Public License, where the Licensed Material is a 21 | musical work, performance, or sound recording, Adapted Material is always 22 | produced where the Licensed Material is synched in timed relation with a moving 23 | image. 24 | Adapter's License means the license You apply to Your Copyright and Similar 25 | Rights in Your contributions to Adapted Material in accordance with the terms 26 | and conditions of this Public License. 27 | Copyright and Similar Rights means copyright and/or similar rights closely 28 | related to copyright including, without limitation, performance, broadcast, 29 | sound recording, and Sui Generis Database Rights, without regard to how the 30 | rights are labeled or categorized. For purposes of this Public License, the 31 | rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. 32 | Effective Technological Measures means those measures that, in the absence of 33 | proper authority, may not be circumvented under laws fulfilling obligations 34 | under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, 35 | and/or similar international agreements. 36 | Exceptions and Limitations means fair use, fair dealing, and/or any other 37 | exception or limitation to Copyright and Similar Rights that applies to Your use 38 | of the Licensed Material. 39 | Licensed Material means the artistic or literary work, database, or other 40 | material to which the Licensor applied this Public License. 41 | Licensed Rights means the rights granted to You subject to the terms and 42 | conditions of this Public License, which are limited to all Copyright and 43 | Similar Rights that apply to Your use of the Licensed Material and that the 44 | Licensor has authority to license. 45 | Licensor means the individual(s) or entity(ies) granting rights under this 46 | Public License. 47 | Share means to provide material to the public by any means or process that 48 | requires permission under the Licensed Rights, such as reproduction, public 49 | display, public performance, distribution, dissemination, communication, or 50 | importation, and to make material available to the public including in ways that 51 | members of the public may access the material from a place and at a time 52 | individually chosen by them. 53 | Sui Generis Database Rights means rights other than copyright resulting from 54 | Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 55 | on the legal protection of databases, as amended and/or succeeded, as well as 56 | other essentially equivalent rights anywhere in the world. 57 | You means the individual or entity exercising the Licensed Rights under this 58 | Public License. Your has a corresponding meaning. 59 | Section 2 – Scope. 60 | 61 | License grant. 62 | Subject to the terms and conditions of this Public License, the Licensor hereby 63 | grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, 64 | irrevocable license to exercise the Licensed Rights in the Licensed Material to: 65 | reproduce and Share the Licensed Material, in whole or in part; and 66 | produce, reproduce, and Share Adapted Material. 67 | Exceptions and Limitations. For the avoidance of doubt, where Exceptions and 68 | Limitations apply to Your use, this Public License does not apply, and You do 69 | not need to comply with its terms and conditions. 70 | Term. The term of this Public License is specified in Section 6(a). 71 | Media and formats; technical modifications allowed. The Licensor authorizes You 72 | to exercise the Licensed Rights in all media and formats whether now known or 73 | hereafter created, and to make technical modifications necessary to do so. The 74 | Licensor waives and/or agrees not to assert any right or authority to forbid You 75 | from making technical modifications necessary to exercise the Licensed Rights, 76 | including technical modifications necessary to circumvent Effective 77 | Technological Measures. For purposes of this Public License, simply making 78 | modifications authorized by this Section 2(a)(4) never produces Adapted 79 | Material. 80 | Downstream recipients. 81 | Offer from the Licensor – Licensed Material. Every recipient of the Licensed 82 | Material automatically receives an offer from the Licensor to exercise the 83 | Licensed Rights under the terms and conditions of this Public License. 84 | No downstream restrictions. You may not offer or impose any additional or 85 | different terms or conditions on, or apply any Effective Technological Measures 86 | to, the Licensed Material if doing so restricts exercise of the Licensed Rights 87 | by any recipient of the Licensed Material. 88 | No endorsement. Nothing in this Public License constitutes or may be construed 89 | as permission to assert or imply that You are, or that Your use of the Licensed 90 | Material is, connected with, or sponsored, endorsed, or granted official status 91 | by, the Licensor or others designated to receive attribution as provided in 92 | Section 3(a)(1)(A)(i). 93 | Other rights. 94 | 95 | Moral rights, such as the right of integrity, are not licensed under this Public 96 | License, nor are publicity, privacy, and/or other similar personality rights; 97 | however, to the extent possible, the Licensor waives and/or agrees not to assert 98 | any such rights held by the Licensor to the limited extent necessary to allow 99 | You to exercise the Licensed Rights, but not otherwise. 100 | Patent and trademark rights are not licensed under this Public License. 101 | To the extent possible, the Licensor waives any right to collect royalties from 102 | You for the exercise of the Licensed Rights, whether directly or through a 103 | collecting society under any voluntary or waivable statutory or compulsory 104 | licensing scheme. In all other cases the Licensor expressly reserves any right 105 | to collect such royalties. 106 | Section 3 – License Conditions. 107 | 108 | Your exercise of the Licensed Rights is expressly made subject to the following 109 | conditions. 110 | 111 | Attribution. 112 | 113 | If You Share the Licensed Material (including in modified form), You must: 114 | 115 | retain the following if it is supplied by the Licensor with the Licensed 116 | Material: 117 | identification of the creator(s) of the Licensed Material and any others 118 | designated to receive attribution, in any reasonable manner requested by the 119 | Licensor (including by pseudonym if designated); 120 | a copyright notice; 121 | a notice that refers to this Public License; 122 | a notice that refers to the disclaimer of warranties; 123 | a URI or hyperlink to the Licensed Material to the extent reasonably 124 | practicable; 125 | indicate if You modified the Licensed Material and retain an indication of any 126 | previous modifications; and 127 | indicate the Licensed Material is licensed under this Public License, and 128 | include the text of, or the URI or hyperlink to, this Public License. 129 | You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based 130 | on the medium, means, and context in which You Share the Licensed Material. For 131 | example, it may be reasonable to satisfy the conditions by providing a URI or 132 | hyperlink to a resource that includes the required information. 133 | If requested by the Licensor, You must remove any of the information required by 134 | Section 3(a)(1)(A) to the extent reasonably practicable. 135 | If You Share Adapted Material You produce, the Adapter's License You apply must 136 | not prevent recipients of the Adapted Material from complying with this Public 137 | License. 138 | Section 4 – Sui Generis Database Rights. 139 | 140 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your 141 | use of the Licensed Material: 142 | 143 | for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, 144 | reuse, reproduce, and Share all or a substantial portion of the contents of 145 | the database; 146 | if You include all or a substantial portion of the database contents in a 147 | database in which You have Sui Generis Database Rights, then the database in 148 | which You have Sui Generis Database Rights (but not its individual contents) 149 | is Adapted Material; and 150 | You must comply with the conditions in Section 3(a) if You Share all or a 151 | substantial portion of the contents of the database. 152 | For the avoidance of doubt, this Section 4 supplements and does not replace 153 | Your obligations under this Public License where the Licensed Rights include 154 | other Copyright and Similar Rights. 155 | Section 5 – Disclaimer of Warranties and Limitation of Liability. 156 | 157 | Unless otherwise separately undertaken by the Licensor, to the extent 158 | possible, the Licensor offers the Licensed Material as-is and as-available, 159 | and makes no representations or warranties of any kind concerning the 160 | Licensed Material, whether express, implied, statutory, or other. This 161 | includes, without limitation, warranties of title, merchantability, fitness 162 | for a particular purpose, non-infringement, absence of latent or other 163 | defects, accuracy, or the presence or absence of errors, whether or not 164 | known or discoverable. Where disclaimers of warranties are not allowed in 165 | full or in part, this disclaimer may not apply to You. 166 | To the extent possible, in no event will the Licensor be liable to You on 167 | any legal theory (including, without limitation, negligence) or otherwise 168 | for any direct, special, indirect, incidental, consequential, punitive, 169 | exemplary, or other losses, costs, expenses, or damages arising out of 170 | this Public License or use of the Licensed Material, even if the 171 | Licensor has been advised of the possibility of such losses, costs, 172 | expenses, or damages. Where a limitation of liability is not allowed in 173 | full or in part, this limitation may not apply to You. 174 | The disclaimer of warranties and limitation of liability provided above 175 | shall be interpreted in a manner that, to the extent possible, most 176 | closely approximates an absolute disclaimer and waiver of all liability. 177 | Section 6 – Term and Termination. 178 | 179 | This Public License applies for the term of the Copyright and Similar 180 | Rights licensed here. However, if You fail to comply with this Public 181 | License, then Your rights under this Public License terminate 182 | automatically. 183 | Where Your right to use the Licensed Material has terminated under 184 | Section 6(a), it reinstates: 185 | 186 | automatically as of the date the violation is cured, provided it is 187 | cured within 30 days of Your discovery of the violation; or 188 | upon express reinstatement by the Licensor. 189 | For the avoidance of doubt, this Section 6(b) does not affect any right 190 | the Licensor may have to seek remedies for Your violations of this 191 | Public License. 192 | For the avoidance of doubt, the Licensor may also offer the Licensed 193 | Material under separate terms or conditions or stop distributing the 194 | Licensed Material at any time; however, doing so will not terminate this 195 | Public License. 196 | Sections 1, 5, 6, 7, and 8 survive termination of this Public License. 197 | Section 7 – Other Terms and Conditions. 198 | 199 | The Licensor shall not be bound by any additional or different terms or 200 | conditions communicated by You unless expressly agreed. 201 | Any arrangements, understandings, or agreements regarding the Licensed 202 | Material not stated herein are separate from and independent of the 203 | terms and conditions of this Public License. 204 | Section 8 – Interpretation. 205 | 206 | For the avoidance of doubt, this Public License does not, and shall not 207 | be interpreted to, reduce, limit, restrict, or impose conditions on any 208 | use of the Licensed Material that could lawfully be made without 209 | permission under this Public License. 210 | To the extent possible, if any provision of this Public License is 211 | deemed unenforceable, it shall be automatically reformed to the minimum 212 | extent necessary to make it enforceable. If the provision cannot be 213 | reformed, it shall be severed from this Public License without affecting 214 | the enforceability of the remaining terms and conditions. 215 | No term or condition of this Public License will be waived and no 216 | failure to comply consented to unless expressly agreed to by the 217 | Licensor. 218 | Nothing in this Public License constitutes or may be interpreted as a 219 | limitation upon, or waiver of, any privileges and immunities that apply 220 | to the Licensor or You, including from the legal processes of any 221 | jurisdiction or authority. 222 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Javascript Exercises 2 | A collection of bite-sized exercises to hone JavaScript skills. 3 | 4 | ## How To Use This Repo 5 | This repo is organized into [target areas](#target-areas) broken down into 6 | progressions to stretch your programming skills. 7 | 8 | For maximum effectiveness: 9 | * Have practice coding session 2+ times a week. 10 | * Timebox your practice coding sessions from 30 minutes to two hours. 11 | * Rotate through target areas. 12 | * Redo exercises that were particularly challenging. 13 | 14 | ### Preparing Your Machine for a Coding Session 15 | 1. [Download and Install Node](http://nodejs.org/download/) 16 | 1. Fork and clone this repository 17 | 18 | ### Practice Coding Session Instructions 19 | 1. Checkout a new branch for your session: `git checkout -b 20 | zee/exercises-10-15-2014` (With your own name/date) 21 | 1. Start a timer for between 30 minutes to two hours. 22 | 1. Pick a target area and level and do each exercise. 23 | 1. Repeat previous step until timer expires. 24 | 1. Push up your session: `git push origin zee/exercises-10-15-2014` 25 | 1. Submit a [pull 26 | request](https://help.github.com/articles/creating-a-pull-request/) to [your 27 | fork](https://help.github.com/articles/comparing-commits-across-time/) (by default it tries to submit pull requests to codeunion :X) 28 | 1. If you're a [CodeUnion.io](http://codeunion.io/) student, [request feedback 29 | on the pull request](https://github.com/codeunion/request-o-matic) 30 | 1. Brag about your mad skills on social media. 31 | 32 | ### Target Areas 33 | * [Syntax and Idioms](/syntax_and_idioms) 34 | * [Algorithms and Computer Science](/algorithms_and_computer_science) 35 | * [Events and Callbacks](/events_and_callbacks) 36 | * [Interacting with Users](/interacting_with_users) 37 | * [Interacting with Other Programs](/interacting_with_programs) 38 | -------------------------------------------------------------------------------- /algorithms_and_computer_science/README.md: -------------------------------------------------------------------------------- 1 | # Algorithms and Computer Science 2 | 3 | While being a good programmer doesn't **require** extensive knowledge of 4 | computer science, it's quite useful. These exercises help us think like a 5 | computer and familiarize us with the three foundations of computer science: 6 | 7 | * [Data](http://glossary.codeunion.io/data) 8 | * [Data Types](http://glossary.codeunion.io/data-types) 9 | * [Algorithms (i.e Data 10 | Transformations)](http://glossary.codeunion.io/algorithms-data-transformations) 11 | 12 | ## Exercises 13 | 14 | ### Level 1 - Numbers, Letters, and Words! (Oh My!) 15 | 16 | * [Letters and Words](letters_and_words) 17 | -------------------------------------------------------------------------------- /algorithms_and_computer_science/letters_and_words/README.md: -------------------------------------------------------------------------------- 1 | # Letters and Words 2 | While we use words without much thought, computers represent 3 | [data](https://glossary.codeunion.io/data) as numbers. In order to store words 4 | in a computer we use a [data type](http://glossary.codeunion.io/data-types) 5 | known as a [string](http://glossary.codeunion.io/string-data-type). Strings are 6 | a [list](http://glossary.codeunion.io/list-data-type) of 7 | [characters](http://glossary.codeunion.io/character-data-type); 8 | 9 | ## Instructions 10 | 11 | This set of exercises is intended to be ran within the `node` 12 | [REPL](http://glossary.codeunion.io/read-evaluate-print-loop-repl) 13 | 14 | 1. Open a terminal and run `node` 15 | 2. Work through each use case and replace `____`s with working code. 16 | 3. Confirm the output from the command matches the expected output. 17 | 18 | ## Exercises 19 | Knowing the length of a string is useful. [Docs for 20 | String.length](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length) 21 | 22 | ```javascript 23 | // The > is the REPL prompt. Don't type it! 24 | > 'hi there'.____; // Replace ____ with working code. 25 | 8 26 | > 'what's happening?'.____; // Replace ____ with working code. 27 | 17 28 | ``` 29 | Let's swap some words around. [Docs for 30 | String.prototype.replace](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) 31 | 32 | ```javascript 33 | // You know the drill. Replace `____` with appropriate code. 34 | > 'Pretty sure zee is the lamest'.____('lamest', 'coolest'); 35 | 'Pretty sure zee is the coolest' 36 | > 'Dead men tell no tales'.____('tales', 'rails'); 37 | 'Dead men tell no rails' 38 | ``` 39 | 40 | Finding a string inside of another string can be useful. [Docs for 41 | String.prototype.match](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) 42 | 43 | ```javascript 44 | > 'What kind of madness is this?'.____('madness'); 45 | [ 'madness', 46 | index: 13, 47 | input: 'What kind of madness is this?' ] 48 | > 'When there is nothing you can find'.____('something'); 49 | null 50 | > 'You can even use regular expressions!'.____(/(\w{3})/i); 51 | [ 'You' 52 | index: 0, 53 | input: 'You can even use regular expressions!' ] 54 | ``` 55 | 56 | Reflect on: Could you get the location where the found string lives? 57 | 58 | Converting strings into a list is helpful in all kinds of situations. Say, 59 | turning a comma seperated list into a set of tags for a blog post, CSV parsing 60 | or even encryption. [Docs for 61 | String.prototype.split](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) 62 | 63 | ```javascript 64 | > 'Hey there voters!'.____(' '); 65 | [ 'Hey', 'there', 'voters!' ] 66 | > 'Such a character!'.____(''); // Notice an empty string tells JavaScript to split 67 | // a string into individual characters. 68 | [ 'S', 'u', 'c', 'h', ' ', 'a', ' ', 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r', '!' ] 69 | > 'eggs, bacon, cheese, tomato, kale,'.____(____); 70 | [ 'eggs', 'bacon', 'cheese', 'tomato', 'kale,' ] 71 | ``` 72 | 73 | 74 | Reaching into a string to get it's contents based on their location in the 75 | string is useful when parsing protocols like HTTP, etc. [Docs for 76 | String.prototype.slice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) 77 | 78 | ```javascript 79 | > 'Name: Zee'.____(6); 80 | 'Zee' 81 | > 'Favorite Color: Chartreuse'.____(____); 82 | 'Chartreuse' 83 | > 'Favorite Animal: Catapult'.____(____,3); 84 | 'Cat' 85 | > 'Weirdest Trait: Can lick elbow'.____(-14); 86 | 'Can lick elbow' 87 | ``` 88 | 89 | Find the first location of a character. [Docs for 90 | String.prototype.indexOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) 91 | 92 | ```javascript 93 | > 'Pork: The Other White Meat'.____(':'); 94 | 4 95 | > 'Moods: Happy, Sad, Grumpy'.____(','); 96 | 12 97 | > 'Friend or foe?'.____('E'); 98 | -1 99 | ``` 100 | 101 | And the last location. [Docs for 102 | String.prototype.lastIndexOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) 103 | 104 | ```javascript 105 | > 'Groceries: avacados, bananas, strawberries, oregano'.____(',') 106 | Should evaluate to 42 107 | ``` 108 | 109 | Lets join some strings together. [Docs for 110 | String.prototype.concat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat) 111 | 112 | ```javascript 113 | > 'Hello'.____('World'); 114 | 'HelloWorld' 115 | > 'Hey'.____('Thats', 'A', 'Lot','Of', 'Words'); 116 | 'HeyThatsALotOfWords' 117 | ``` 118 | 119 | Sometime's we'll want some quotes in our quotes. 120 | 121 | ```javascript 122 | > 'They said: ____'Yo____''; 123 | 'They said: \'Yo\'' 124 | > ____Or you could use a different 'kind' of quotes____; 125 | 'Or you could use a different \'kind\' of quotes' 126 | ``` 127 | 128 | Search suggestion: 'Escaping quotes in JavaScript' 129 | 130 | ### Put It Together! 131 | 132 | Open the file `questions_and_answers.js` and write a function that given a 133 | string of the format 'Question: Answer' returns the "Answer" section. 134 | 135 | Verify your implementation works by running `node questions_and_answers.js`. 136 | -------------------------------------------------------------------------------- /algorithms_and_computer_science/letters_and_words/questions_and_answers.js: -------------------------------------------------------------------------------- 1 | function getAnswer(entry) { 2 | // Put your code here. 3 | } 4 | 5 | 6 | if (!module.parent) { 7 | console.log(getAnswer('Name: Zee') === 'Zee'); 8 | console.log(getAnswer('Favorite Color: Orange') === 'Orange'); 9 | console.log(getAnswer('Favorite Programming Language: Clojure') === 'Clojure'); 10 | } 11 | -------------------------------------------------------------------------------- /events_and_callbacks/README.md: -------------------------------------------------------------------------------- 1 | # Events and Callbacks 2 | 3 | Working with JavaScript requires understanding how 4 | [events](http://glossary.codeunion.io/event) work. Writing _evented_ JavaScript 5 | requires familiarity with [callback](http://glossary.codeunion.io/callback) 6 | functions. 7 | 8 | With events, you write code that says "when this happens, run this function". 9 | For example, a user clicks a button on your web page which makes a modal window 10 | appear. 11 | 12 | In both the browser and in node.js, you can write code that _listens for_ and 13 | _responds to_ various events. 14 | 15 | There are three components to writing an event listener in JavaScript: 16 | 17 | 1. The event **target** (in node.js, this is called an _emitter_) 18 | 2. The **type** (or name) of the event 19 | 3. The **callback** function to run when the event happens (or _fires_) 20 | 21 | Here is an example of an event listener in the browser: 22 | 23 | ```html 24 | 25 | 26 | 27 | 28 | 29 | 36 | 37 | ``` 38 | 39 | In the code above, the `button` is the event **target** (the button element that 40 | will fire the event), `'click'` is the event **type** (when the button is 41 | clicked, it fires this type of event), and the function 42 | 43 | ```javascript 44 | function(evt) { 45 | alert('You clicked me!'); 46 | } 47 | ``` 48 | 49 | is the **callback** (the code that runs when the event is triggered). 50 | 51 | ## Exercises 52 | 53 | ### Level 1 - Functions that Take Functions as Inputs 54 | 55 | * [Introduction to Callbacks](introduction_to_callbacks) 56 | * [setTimeout and setInterval](settimeout_and_setinterval) 57 | -------------------------------------------------------------------------------- /events_and_callbacks/introduction_to_callbacks/00_SUGGESTED_ORDER.md: -------------------------------------------------------------------------------- 1 | 1. `passing_functions_to_functions.js` 2 | 2. `introducing_predicate_functions.js` 3 | 3. `calling_a_callback_function_more_than_once.js` 4 | 4. `using_callback_functions_to_transform_arrays.js` 5 | -------------------------------------------------------------------------------- /events_and_callbacks/introduction_to_callbacks/README.md: -------------------------------------------------------------------------------- 1 | # Introduction to Callbacks 2 | 3 | In JavaScript, we frequently encounter functions which take other functions as 4 | arguments. This is a powerful technique known as a "callback function". Callback 5 | functions, also referred to as simply "callbacks", are used all over the place 6 | in JavaScript. 7 | 8 | Understanding how to use callback functions as well as how to write functions 9 | that accept callback functions as arguments is critical. 10 | 11 | These exercises are intended to get a developer comfortable with callbacks in 12 | JavaScript. 13 | 14 | ## Let's Get Started 15 | 16 | 1. Open the first JavaScript file as noted by [the suggested 17 | order](00_SUGGESTED_ORDER.md). 18 | 2. Review the use cases at the bottom of the JavaScript file. 19 | 3. Uncomment the first use case and make the code work. (Frequently this means 20 | replacing `____`s with code of your own.) 21 | 4. Verify it works. (Run the JavaScript file with `node`.) 22 | 5. Repeat steps 3 and 4 until all use cases are working. 23 | 6. Repeat steps 1 to 5 until you've worked through all the JavaScript files. 24 | 7. Submit a request for feedback on your commits! 25 | -------------------------------------------------------------------------------- /events_and_callbacks/introduction_to_callbacks/calling_a_callback_function_more_than_once.js: -------------------------------------------------------------------------------- 1 | // 1. Scroll to the bottom to get to the use cases. 2 | // 2. Uncomment the next use case and make it work. Frequently this means replacing 3 | // `____`s with code of your own. 4 | // 3. Verify it works by running the file with the `node` command line program. 5 | // 4. Repeat until all use cases are functioning. 6 | 7 | // This function checks if the contents of an array are equal to one another. 8 | // Why? Because `["hi"] === ["hi"]` is false in JavaScript. Le-sigh. 9 | var bothArraysAreEqual = function(arrayA, arrayB) { 10 | // If arrayA and arrayB are the same object then we don't have to compare 11 | // their elements. 12 | // ``` 13 | // var a = ["hi", "there"]; 14 | // var b = a; 15 | // var c = ["hi", "there"]; 16 | // a === b; // True :( 17 | // c === a; // False 18 | // ``` 19 | if (arrayA === arrayB) { return true; } 20 | 21 | // If arrayA and arrayB aren't the same length 22 | // they can't possibly be the same 23 | if (arrayA.length !== arrayB.length) { 24 | return false; 25 | } 26 | 27 | for (var i = 0; i < arrayA.length; i++) { 28 | // If any of the elements are different, BAIL OUT! 29 | if (arrayA[i] !== arrayB[i]) { 30 | return false; 31 | } 32 | } 33 | return true; 34 | } 35 | 36 | /* 37 | // This function executes a callback function many times. 38 | var doThisManyTimes = function(numberOfTimes, ____) { 39 | for (var i = 0; i < numberOfTimes; i++) { 40 | ____(); 41 | } 42 | }; 43 | */ 44 | 45 | 46 | /* 47 | // This function will go over every element in an array one by one, calling the 48 | // callback with each item. Replace the `____`s to make it work. 49 | var each = function(array, ____) { 50 | for (var ____ = ____; ____ < array.length; ____++) { 51 | var ____ = array[i]; 52 | ____(____); 53 | } 54 | }; 55 | */ 56 | 57 | 58 | // USE CASES ARE HERE. STOP SCROLLING! STOOOPPPPPPP. 59 | // OK, now read on! 60 | if (!module.parent) { 61 | // Callback functions provide a powerful way to enable code re-use. 62 | // Given the above functions, can you replace the `____`s with code to 63 | // cause the expected result? 64 | 65 | // Uncomment each use case and get it working before moving to the next. 66 | // You will know the code works because the word "true" will appear when 67 | // you run `node calling_a_callback_function_more_than_once.js` 68 | 69 | /* 70 | // Find, uncomment and implement the `doThisManyTimes` function above. Then 71 | // update this code to use it. 72 | var wows = []; 73 | ____(5, function() { 74 | wows.push("wow!"); 75 | }); 76 | 77 | var expectedWows = ["wow!", "wow!", "wow!", "wow!", "wow!"]; 78 | console.log(bothArraysAreEqual(wows, expectedWows)); 79 | */ 80 | 81 | /* 82 | // Find, uncomment and implement the `each` function above, then update this 83 | // code to use it. 84 | var doubles = []; 85 | ____([4, 2, 9], ____(num) { 86 | ____.____(num * 2); 87 | }); 88 | 89 | var expectedDoubles = [8, 4, 18]; 90 | 91 | console.log(bothArraysAreEqual(doubles, expectedDoubles)); 92 | */ 93 | 94 | 95 | /* 96 | // Let's re-use one of our functions to reverse a list of words! 97 | reversedWords = []; 98 | var ____ = ____(____) { 99 | ____.____(____.split("").reverse().join("")); 100 | }; 101 | 102 | each(["qatar", "zinfandel", "onomatopoeia"], reverseWords); 103 | 104 | expectedReversedWords = ["rataq", "lednafniz", "aieopotamono"]; 105 | console.log(bothArraysAreEqual(reversedWords, expectedReversedWords)); 106 | */ 107 | 108 | 109 | /* 110 | // Let's build a list of strings of Q's of varying lengths! 111 | listOfQs = []; 112 | var addQs = function(number) { 113 | var q = ""; 114 | while (number > 0) { 115 | q = q + "Q"; 116 | number = number - 1; 117 | } 118 | ____.____(q); 119 | }; 120 | 121 | var expectedListOfQs = ["QQQ", "Q", "QQQQQQQ"]; 122 | ____([3,1,7], addQs); 123 | console.log(bothArraysAreEqual(listOfQs, expectedListOfQs)); 124 | */ 125 | } 126 | -------------------------------------------------------------------------------- /events_and_callbacks/introduction_to_callbacks/introducing_predicate_functions.js: -------------------------------------------------------------------------------- 1 | // 1. Scroll to the bottom to get to the use cases. 2 | // 2. Uncomment the next use case and make it work. Frequently this means 3 | // replacing `____`s with code of your own. 4 | // 3. Verify it works by running the file with the `node` command line program. 5 | // 4. Repeat until all use cases are functioning. 6 | 7 | var conservativeSpender = function(balance) { 8 | return balance > 100; 9 | }; 10 | 11 | var liberalSpender = function(balance) { 12 | return balance > 10; 13 | }; 14 | 15 | var horribleSaver = function(balance) { 16 | return balance > 0; 17 | }; 18 | 19 | var yourSpendingStrategy = function(balance) { 20 | // Your code here 21 | }; 22 | 23 | /* 24 | var shouldIBuyThis = function(balance, ____) { 25 | if ( ____(balance) ) { 26 | return "Sure! I've got the money!"; 27 | } else { 28 | return "Nope! Gotta keep my savings up!"; 29 | } 30 | }; 31 | */ 32 | 33 | /* 34 | function smarterShouldIBuyThis(cost, balance, strategy) { 35 | var futureBalance = balance - cost; 36 | if ( ____(futureBalance) ) { 37 | return "Sure! I've got the money!"; 38 | } else { 39 | return "Nope! Gotta keep my savings up!"; 40 | } 41 | }; 42 | */ 43 | 44 | 45 | // USE CASES ARE HERE. STOP SCROLLING! STOOOPPPPPPP. 46 | // OK, now read on! 47 | // 48 | if (!module.parent) { 49 | // Uncomment each use case and get it working before moving to the next. 50 | // You will know the code works because the word "true" will appear when 51 | // you run `node introducing_predicate_functions.js` 52 | 53 | // We're going to use a callback to decide whether we want to buy an item or 54 | // not, based on our account balance. This kind of callback function (one 55 | // which returns true or false) is known as a "predicate" function. 56 | 57 | // Find, uncomment and implement the `shouldIBuyThis` function above, then 58 | // uncomment and implement each of the following use cases one by one. 59 | 60 | // console.log(shouldIBuyThis(20, ____) === "Nope! Gotta keep my savings up!"); 61 | // console.log(shouldIBuyThis(20, ____) === "Sure! I've got the money!"); 62 | // console.log(shouldIBuyThis(____, horribleSaver) === "Sure! I've got the money!"); 63 | 64 | // Find, uncomment, and implement the `smarterShouldIBuyThis` function above, 65 | // then uncomment the following use cases 66 | // console.log(smarterShouldIBuyThis(50, 45, horribleSaver) === "Nope! Gotta keep my savings up!"); 67 | 68 | // Can you define your own spending strategy? 69 | // Scroll up to yourSpendingStrategy above 70 | // console.log(smarterShouldIBuyThis(____, ____, yourSpendingStrategy) === ____); 71 | 72 | /* 73 | // Like all callbacks, we may define a predicate function as an anonymous 74 | // function (i.e. without storing it in a variable): 75 | console.log(shouldIBuyThis(999, ____(____) { 76 | return ____ > 1000; 77 | }) === "Nope! Gotta keep my savings up!"); 78 | */ 79 | } 80 | 81 | 82 | -------------------------------------------------------------------------------- /events_and_callbacks/introduction_to_callbacks/passing_functions_to_functions.js: -------------------------------------------------------------------------------- 1 | // 1. Scroll to the bottom to get to the use cases. 2 | // 2. Uncomment the next use case and make it work. Frequently this means 3 | // replacing `____`s with code of your own. 4 | // 3. Verify it works by running the file with the `node` command line program. 5 | // 4. Repeat until all use cases are functioning. 6 | 7 | var animalToCatTranslator = function(sentence) { 8 | return sentence.replace("animal", "cat"); 9 | }; 10 | 11 | var animalToDogTranslator = function(sentence) { 12 | return sentence.replace("animal", "dog"); 13 | }; 14 | 15 | /* 16 | // Write your own translator for your preferred animal! 17 | var ____ = ____(sentence) { 18 | return ____._____(____, ____); 19 | }; 20 | */ 21 | 22 | var favoriteAnimal = function(animalTranslator) { 23 | return animalTranslator("animals are the best!"); 24 | }; 25 | 26 | // !module.parent is true if the current file is being run directly in node 27 | // and false when being required by another file. 28 | if (!module.parent) { 29 | // Uncomment each use case and get it working before moving to the next. 30 | // You will know the code works because the word "true" will appear when 31 | // you run `node passing_functions_to_functions.js` 32 | 33 | // Because functions are data in JavaScript you can pass them as arguments to 34 | // other functions. Functions passed to another function to be called are 35 | // known as "callback functions". 36 | 37 | // Choose a callback function from the animalToXTranslators above to make the 38 | // following use cases pass. 39 | // console.log(favoriteAnimal(____) === "cats are the best!"); 40 | // console.log(favoriteAnimal(____) === "dogs are the best!"); 41 | 42 | // Define your own animal translator! Uncomment lines 15 to 20, then make the 43 | // following use case pass. 44 | // console.log(favoriteAnimal(____) === "____s are the best!"); 45 | 46 | // Have you tried to put ()'s after the callback function being passed as an 47 | // argument? What happened? Why do you think that is? 48 | 49 | 50 | // You can also define callback functions in-line: 51 | // console.log(favoriteAnimal(function(sentence) { 52 | // ____ ____.____("animal", "aardvark"); 53 | // } === "aardvarks are the best!"); 54 | // This is known as an "anonymous function". 55 | } 56 | -------------------------------------------------------------------------------- /events_and_callbacks/introduction_to_callbacks/using_callback_functions_to_transform_arrays.js: -------------------------------------------------------------------------------- 1 | // 1. Scroll to the bottom to get to the use cases. 2 | // 2. Uncomment the next use case and make it work. Frequently this means replacing 3 | // `____`s with code of your own. 4 | // 3. Verify it works by running the file with the `node` command line program. 5 | // 4. Repeat until all use cases are functioning. 6 | 7 | var bothArraysAreEqual = function(arrayA, arrayB) { 8 | if (arrayA === arrayB) { return true; } 9 | 10 | if (arrayA.length !== arrayB.length) { 11 | return false; 12 | } 13 | 14 | for (var i = 0; i < arrayA.length; i++) { 15 | if (arrayA[i] !== arrayB[i]) { 16 | return false; 17 | } 18 | } 19 | return true; 20 | }; 21 | 22 | /* 23 | // This function will go over every element in an array one by one, calling the 24 | // callback with each item, and building a new array with the callback's return 25 | // values. Replace the `____`s to make it work. 26 | var map = function(____, ____) { 27 | var newArray = []; 28 | for (var ____ = ____; ____ < ____.____; ____++) { 29 | var ____ = ____[____]; 30 | newArray[____] = ____(____); 31 | } 32 | return newArray; 33 | }; 34 | */ 35 | 36 | /* 37 | // This function will go over every element in an array one by one, calling the 38 | // callback with each item, adding the element to a new array only if 39 | // the callback returns true, and finally returning the new array. 40 | var filter = function(____, ____) { 41 | var filteredArray = []; 42 | for (var ____ = ____; ____ < ____.____; ____++) { 43 | var ____ = ____[____]; 44 | if (____(____)) { 45 | filteredArray.push(____); 46 | } 47 | } 48 | return filteredArray; 49 | }; 50 | */ 51 | 52 | 53 | // USE CASES ARE HERE. STOP SCROLLING! STOOOPPPPPPP. 54 | // OK, now read on! 55 | // 56 | if (!module.parent) { 57 | // Using callbacks to transform arrays is a very common use case. Let's 58 | // implement some functions that take an array and a callback and return a new 59 | // array with the callback applied to it. 60 | 61 | // Uncomment each use case and get it working before moving to the next. 62 | // You will know the code works because the word "true" will appear when 63 | // you run `node using_callback_functions_to_transform_arrays.js` 64 | 65 | /* 66 | // Defining an array, calling each on another array, and filling the new array 67 | // is a common pattern known as "mapping". 68 | // Find, uncomment, and implement the "map" function defined above and fill in 69 | // the `____`s to make it work. 70 | var square = function(number) { 71 | return number * number; 72 | }; 73 | var squaredNumbers = map([2, 8, 3], square); 74 | 75 | var expectedSquaredNumbers = [4, 64, 9]; 76 | console.log(bothArraysAreEqual(squaredNumbers, expectedSquaredNumbers)); 77 | */ 78 | 79 | /* 80 | // Let's shout some words: 81 | var shoutedWords = ____(["one", "two", "three"], ____(____) { 82 | ____ ____.toUpperCase(); 83 | }); 84 | 85 | var expectedShoutedWords = ["ONE", "TWO", "THREE"]; 86 | console.log(bothArraysAreEqual(shoutedWords, expectedShoutedWords)); 87 | */ 88 | 89 | /* 90 | // Sometimes you'll want to take an array and remove elements that don't 91 | // match certain criteria. Uncomment and implement the "filter" function in 92 | // the source code above. 93 | // 94 | // A callback that returns a boolean (a true or false value) is known as a 95 | // "predicate". 96 | 97 | var onlyEvenNumbers = filter([2, 9, 6, 8, 4], ____(____) { 98 | ____ ____ % 2 === 0; 99 | }); 100 | 101 | console.log(bothArraysAreEqual(onlyEvenNumbers, [2, 6, 8, 4]); 102 | */ 103 | 104 | /* 105 | // Let's filter a list down to words that start with the best letter ever. 106 | // Yes. That letter is Z. 107 | 108 | var bestWordPredicate = function(____) { 109 | return ____.toUpperCase().charAt(0) === "Z"; 110 | }; 111 | var onlyAwesomeWords = ____(["zookeeper", "zelda", "misanthrope", "anarchy", "acrostic"], ____); 112 | console.log(bothArraysAreEqual(onlyAwesomeWords, ["zookeeper", "zelda"])); 113 | */ 114 | } 115 | -------------------------------------------------------------------------------- /events_and_callbacks/settimeout_and_setinterval/README.md: -------------------------------------------------------------------------------- 1 | # setTimeout and setInterval 2 | 3 | Both node.js and the browser implement methods that let us write _timed_ code: 4 | `setInterval` and `setTimeout`. 5 | 6 | In other words, we can say things like "wait 5 minutes, then run this code" or 7 | "execute this function every 20 seconds". 8 | 9 | The various applications for this kind of code are many. Anytime you have code 10 | whose execution depends on time, you may reach for these methods. 11 | 12 | For the most part, these methods will work the same whether you run them in the 13 | browser or in node.js. It is important to recognize that these are different 14 | environments, so you should never expect timers to work _exactly_ the same. 15 | 16 | **Documentation references:** 17 | 18 | - [Documentation for Window Timers](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers) 19 | - [Documentation for Node.js Timers](http://nodejs.org/docs/v0.6.1/api/timers.html) 20 | 21 | ## Exercises 22 | 23 | ### Timeouts fire functions after x milliseconds 24 | 25 | Can you use `setTimeout` to delay execution of a callback function? 26 | 27 | ```javascript 28 | console.log("Wait for it..."); 29 | __(function() { console.log("NOW!") }, __); 30 | // should print "NOW!" after waiting one second 31 | ``` 32 | 33 | Search suggestion: `delay execution node.js` 34 | 35 | ### Delayed execution can be weird to understand 36 | 37 | Make a hypothesis about what the following code will do. Then run it. Did it do 38 | what you expected? If not, why not? 39 | 40 | ```javascript 41 | console.log("Before the timeout"); 42 | setTimeout(function() { console.log("In the timeout function"); }, 500); 43 | console.log("After the timeout"); 44 | ``` 45 | 46 | What about this code? 47 | 48 | ```javascript 49 | console.log("Before the timeout"); 50 | setTimeout(function() { console.log("In the timeout function"); }, 0); 51 | console.log("After the timeout"); 52 | ``` 53 | 54 | Search suggestion: `how does setTimeout work javascript` 55 | 56 | ### Sometimes you want to cancel the timer 57 | 58 | Can you write code to prevent the bomb from going off? 59 | 60 | ```javascript 61 | var bombTimeoutID = setTimeout(function() { console.log("KABOOM!!") }, 7000); 62 | __(__); 63 | ``` 64 | 65 | Search suggestion: `cancel setTimeout function javascript` 66 | 67 | ### Timers aren't perfect timers 68 | 69 | The following code may be confusing. Make a hypothesis about what you think it 70 | will do, then test your hypothesis by running the code. Did it do what you 71 | expected? Why or why not? 72 | 73 | ```javascript 74 | console.log("Before the timeout"); 75 | setTimeout(function() { console.log("In the timeout"); }, 500); 76 | console.log("After the timeout"); 77 | 78 | var now = Date.now(); 79 | console.log("Starting the while loop"); 80 | while (Date.now() < now + 3000) { 81 | // waiting, waiting... 82 | } 83 | console.log("While loop finished"); 84 | ``` 85 | 86 | ### But they can still be useful 87 | 88 | Can you complete the code below to create the desired behavior? 89 | 90 | ```javascript 91 | var timer = function(seconds, callback) { 92 | var milliseconds = seconds * 1000; 93 | console.log("Setting timer for " + seconds + " seconds") 94 | __(__, __); 95 | }; 96 | 97 | var breadReminder = function() { 98 | console.log("Bread is ready!"); 99 | } 100 | 101 | timer(3, breadReminder) 102 | // should print "Bread is ready!" after a delay of 3 seconds 103 | ``` 104 | 105 | Search suggestion: `syntax setTimeout function javascript` 106 | 107 | ### An example of a potential use case 108 | 109 | Can you complete the code below to configure a session timeout feature (like 110 | what you might find in an online banking account, for example)? 111 | 112 | ```javascript 113 | var warnTimeout = function() { 114 | console.log("Your online banking session will end in 5 seconds..."); 115 | }; 116 | 117 | var sessionTimeout = function() { 118 | console.log("Your online banking session has timed out"); 119 | }; 120 | 121 | var sessionLength = 20 * 1000; // 20 seconds 122 | __(__, sessionLength - 5 * 1000); // 5 seconds before 123 | __(__, sessionLength); 124 | // should print a warning in 15 seconds 125 | // and a session timeout notice in 20 seconds 126 | ``` 127 | 128 | ### Intervals do something over and over and over and... 129 | 130 | Can you make the following code print `Na-na-na-na` every half second? 131 | 132 | ```javascript 133 | console.log("Starting the counter"); 134 | __(function() { 135 | console.log("Na-na-na-na"); 136 | }, __) 137 | console.log("Counter finished. Maybe?") 138 | // should print "Na-na-na-na" every half second 139 | ``` 140 | 141 | Search suggestion: `call function repeatedly at set times javascript` 142 | 143 | ### Forever is a long time 144 | 145 | So it may be useful to be able to stop your perpetual motion machine after 146 | starting it. Can you figure out how to make a stopwatch that counts the seconds 147 | from 0 but actually **stops** after 5 seconds? 148 | 149 | ```javascript 150 | var time = 0; 151 | var stopWatch = function() { 152 | console.log(__); 153 | time++; 154 | }; 155 | 156 | console.log("Starting stopwatch"); 157 | stopWatch(); 158 | var __ = setInterval(stopWatch, 1000); 159 | 160 | setTimeout(function() { 161 | __(__); 162 | }, __); 163 | ``` 164 | 165 | Search suggestion: `stop function in setInterval javascript` 166 | 167 | ### Working with timer IDs for maximum power 168 | 169 | You can have more than one interval going at once, you know. Can you reason 170 | about the following code and see if you can understand what is going on? 171 | 172 | ```javascript 173 | var timesCounted = 0; 174 | var counter = function() { 175 | console.log(timesCounted); 176 | timesCounted++; 177 | }; 178 | var counterID = setInterval(counter, 100); 179 | 180 | var monitorID; 181 | var monitor = function() { 182 | if (timesCounted > 20) { 183 | clearInterval(counterID); 184 | clearInterval(monitorID); 185 | } 186 | }; 187 | monitorID = setInterval(monitor, 500); 188 | ``` 189 | 190 | ### A full-fledged egg timer 191 | 192 | Can you put it all together now and complete the implementation for a working 193 | timer that counts down from x seconds to zero? 194 | 195 | ```javascript 196 | var countDown = function(startTime) { 197 | console.log(startTime); 198 | 199 | return setInterval(function() { 200 | __--; 201 | console.log(__); 202 | }, __); 203 | }; 204 | 205 | var setTimer = function(seconds) { 206 | var milliseconds = __ * __; 207 | console.log("Setting timer for " + __ + " seconds"); 208 | 209 | var counterID = countDown(seconds); 210 | 211 | __(function() { 212 | console.log("Timer done!"); 213 | clearInterval(__) 214 | }, __); 215 | }; 216 | 217 | setTimer(3) 218 | // should set a timer for 3 seconds 219 | // and print each second until it stops 220 | ``` 221 | -------------------------------------------------------------------------------- /interacting_with_the_user/README.md: -------------------------------------------------------------------------------- 1 | # Interacting with the User 2 | 3 | At the end of the day, software is a tool for people. Lots of programs talk to 4 | each other, but at some point or another a real person is going to interact with 5 | the software. 6 | 7 | The ways in which a user can interact with (give inputs to and read outputs 8 | from) software is called the **user interface**, and it will differ depending on 9 | the context. 10 | 11 | For web applications, the user interface is the browser, which renders HTML with 12 | text, graphics, and media. Before the advent of the **Graphical User 13 | Interface**, or GUI, the only way to interact with a computer was by typing 14 | commands into a terminal and reading the output. 15 | 16 | We're going to explore the ways that JavaScript allows for user interaction. 17 | 18 | ## Exercises 19 | 20 | ### Level 1 - Collecting Input from the Command Line 21 | 22 | * [Command Line Arguments](command_line_arguments) 23 | * [STDIN and STDOUT](stdin_and_stdout) 24 | 25 | ### Level 2 - Finding and Changing Elements on a Web Page 26 | 27 | * [Querying the DOM](querying_the_dom) 28 | * [Manipulating the DOM](manipulating_the_dom) 29 | -------------------------------------------------------------------------------- /interacting_with_the_user/command_line_arguments/00_SUGGESTED_ORDER.md: -------------------------------------------------------------------------------- 1 | 1. `parsing_arguments.js` 2 | 2. `what_does_fox_say.js` 3 | 3. `calculator.js` 4 | 4. `using_an_argument_parser_library.js` 5 | -------------------------------------------------------------------------------- /interacting_with_the_user/command_line_arguments/README.md: -------------------------------------------------------------------------------- 1 | # Command Line Arguments 2 | 3 | When executing a program from the command line, most languages (including 4 | JavaScript) provide a mechanism by which you can access the **arguments** 5 | provided to the command. 6 | 7 | The arguments to a command are the words provided after the command itself. In 8 | the following example, `node` is the command, the first argument is `script.js` 9 | and the second argument is `foo`. 10 | 11 | ```shell 12 | $ node script.js foo # the $ is the shell prompt. Don't type it! # is a comment. 13 | ``` 14 | 15 | Solve the exercises to learn how to work with command line arguments in node.js. 16 | 17 | ## Let's Get Started 18 | 19 | 1. Review the [suggested order](00_SUGGESTED_ORDER.md). 20 | 2. Work through the exercises in the JavaScript files. 21 | 3. Submit a request for feedback! 22 | -------------------------------------------------------------------------------- /interacting_with_the_user/command_line_arguments/calculator.js: -------------------------------------------------------------------------------- 1 | // Let's do something a bit more interesting and useful with the input: we will 2 | // write a rudimentary calculator that can solve basic arithmetic expressions. 3 | // 4 | // Complete the code required to make this calculator function as expected. 5 | // 6 | // Search suggestion: "convert string to number javascript" 7 | 8 | var expression = ____.____[____].split(' '); 9 | 10 | var firstNumber = ____(expression[0]); 11 | var operator = expression[1]; 12 | var secondNumber = ____(expression[2]); 13 | 14 | switch (operator) { 15 | case ____: 16 | console.log(firstNumber ____ secondNumber); 17 | break; 18 | case ____: 19 | console.log(firstNumber ____ secondNumber); 20 | break; 21 | case ____: 22 | console.log(firstNumber ____ secondNumber); 23 | break; 24 | case ____: 25 | console.log(firstNumber ____ secondNumber); 26 | break; 27 | default: 28 | console.log("ERROR. DOES NOT COMPUTE."); 29 | break; 30 | } 31 | 32 | // Run the following commands to verify that your code produces the output shown. 33 | // 34 | // $ node calculator.js "2 + 7" 35 | // 9 36 | // 37 | // $ node calculator.js "10 - 3" 38 | // 7 39 | // 40 | // $ node calculator.js "3 * 9" 41 | // 27 42 | // 43 | // $ node calculator.js "1 / 5" 44 | // 0.2 45 | -------------------------------------------------------------------------------- /interacting_with_the_user/command_line_arguments/parsing_arguments.js: -------------------------------------------------------------------------------- 1 | /* 2 | // First use case: accessing command line arguments in node 3 | console.log(process.argv); 4 | 5 | // Run the following commands (lines starting with the command prompt `$`) in 6 | // your terminal to verify that your code produces the output shown. 7 | // 8 | // (The $ is the command prompt. Don't type it!) 9 | // 10 | // $ node parsing_arguments.js 11 | // ["node", "/path/to/parsing_arguments.js"] 12 | // 13 | // $ node parsing_arguments.js one 2 three 14 | // ["node", "/path/to/parsing_arguments.js", "one", "2", "three"] 15 | */ 16 | 17 | 18 | /* 19 | // Second use case: narrow down the results 20 | 21 | var filename = ____.____[____]; 22 | var arguments = ____.____.slice(____); 23 | console.log("The filename is " + filename); 24 | console.log("The arguments are " + arguments.join(", ")); 25 | 26 | // Search suggestion: "select part of an array javascript" 27 | 28 | // Run the following commands to verify that your code produces the output shown. 29 | // 30 | // $ node parsing_arguments.js 31 | // ["node", "/path/to/parsing_arguments.js"] 32 | // The filename is /path/to/parsing_arguments.js 33 | // The arguments are 34 | // 35 | // $ node parsing_arguments.js one 2 three 36 | // ["node", "/path/to/parsing_arguments.js", "one", "2", "three"] 37 | // The filename is /path/to/parsing_arguments.js 38 | // The arguments are one, 2, three 39 | */ 40 | -------------------------------------------------------------------------------- /interacting_with_the_user/command_line_arguments/using_an_argument_parser_library.js: -------------------------------------------------------------------------------- 1 | // Parsing command line arguments is a common task that there are libraries you 2 | // can use to do it for you. 3 | // 4 | // Use the minimist package to finish the following exercise. 5 | // 6 | // Docs: https://www.npmjs.org/package/minimist 7 | // 8 | // Note: The script will figure out how to handle messages passed with _either_ 9 | // the `-m` or the `--message` flag. 10 | 11 | var parseArgs = require("minimist"); 12 | 13 | var args = parseArgs(____.____.slice(2)); 14 | 15 | var from = ____[____]; 16 | var to = ____[____]; 17 | var message = ____[____] || ____[____]; 18 | 19 | console.log("Sending message from " + from + " to " + to); 20 | console.log("==== body ===="); 21 | console.log(message); 22 | 23 | // Run the following commands to verify that your code produces the output shown. 24 | // 25 | // $ node args.js -f Bugs -t Elmer --message "What's up doc?" 26 | // Sending message from Bugs to Elmer 27 | // ==== body ==== 28 | // What's up doc? 29 | // 30 | // $ node args.js -f "Apollo 13" -t Houston -m "We have a problem." 31 | // Sending message from Apollo 13 to Houston 32 | // ==== body ==== 33 | // We have a problem. 34 | -------------------------------------------------------------------------------- /interacting_with_the_user/command_line_arguments/what_does_fox_say.js: -------------------------------------------------------------------------------- 1 | // Often times command line arguments are used to determine which code to run. 2 | // 3 | // Complete the conditional so it responds to each command line argument 4 | // appropriately. 5 | 6 | var animal = ____.____[____]; 7 | 8 | if (animal === ____) { 9 | console.log(____); 10 | } else if (animal === ____) { 11 | console.log(____); 12 | } else if (animal === ____) { 13 | console.log(____); 14 | } else if (animal === ____) { 15 | console.log(____); 16 | } 17 | 18 | // Run the following commands to verify that your code produces the output shown. 19 | // 20 | // $ node what_does_fox_say.js cow 21 | // mooooooo 22 | // 23 | // $ node what_does_fox_say.js dog 24 | // woof 25 | // 26 | // $ node what_does_fox_say.js fish 27 | // >() >() >() 28 | // 29 | // $ node what_does_fox_say.js fox 30 | // ??? 31 | -------------------------------------------------------------------------------- /interacting_with_the_user/manipulating_the_dom/README.md: -------------------------------------------------------------------------------- 1 | # Manipulating the DOM 2 | 3 | Once you've learned how to [query the DOM](../querying_the_dom) to select 4 | elements from your web page, the next question is: what can you do with those 5 | elements? 6 | 7 | When we write JavaScript, most of the time we will be writing programs that 8 | affect the DOM, and thus, the user interface. There are many ways to do this. A 9 | small sampling: 10 | 11 | - Show a chat window on the page when a user starts a new chat session 12 | - Zoom in on the map when a user clicks on the "+" button 13 | - When a user selects a preferred airline, highlight matching flights in yellow 14 | 15 | The examples are as numerous as the stars. Just know that anytime the content of 16 | a web page changes, that is JavaScript doing its work. 17 | 18 | In these exercises, we are going to explore some of the common ways to 19 | manipulate the DOM at the level of individual elements. 20 | 21 | As a reference, we will be using the documentation for the 22 | [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) API 23 | as well as some of the objects it inherits (i.e. shares) the properties and 24 | methods of: [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) 25 | and [Node](https://developer.mozilla.org/en-US/docs/Web/API/Node). 26 | 27 | ## Exercises 28 | 29 | To complete these exercises, you will need two files: 30 | 31 | - `page.html` 32 | - `my_script.js` 33 | 34 | Create a file called `page.html` and paste the following code into it: 35 | 36 | ```html 37 | 38 | 39 | 40 |

Smoothie Time

41 | 42 |

43 | Everyone likes smoothies. My favorite is blueberry. 44 |

45 | 46 |

A list of fruits

47 | 48 | 54 | 55 |

56 | Sign up for our email newsletter. 57 |

58 | 59 |
60 | 61 | 62 | 63 |
64 | 65 | 66 | 67 | 68 | ``` 69 | 70 | **You do not need to change this page.** Your exercise code will go in 71 | `my_script.js`. Make sure to create this file in the same directory as 72 | `page.html`. 73 | 74 | Notice that ` where you are. 122 |

123 | 124 | 125 | ``` 126 | 127 | Search suggestion: `javascript write text to document` 128 | 129 | > What's that `new Date().toString()` code? That is a how, in JavaScript, we can 130 | > say "get me the current date and time, and then convert it to a String". 131 | 132 | ### Think global, act local 133 | 134 | So that last example left us with a lot of JavaScript in one ` 147 | 148 | 149 |

What time is it?

150 | 151 |

152 | The time is where you are. 153 |

154 | 155 | 156 | ``` 157 | 158 | Search suggestion: `javascript store value in variable` 159 | 160 | > Even though the JavaScript in this example is split between two ` 193 | 194 | 195 |

What time is it?

196 | 197 |

198 | The time is where you are. 199 |

200 | 201 | 202 | ``` 203 | 204 | Search suggestion: `how to load external javascript file in html` 205 | 206 | ### Importing scripts from anywhere 207 | 208 | If we can load our own scripts from other files, why not load scripts that other 209 | people have written? For example, what about a third-party library like 210 | `jQuery`? 211 | 212 | Can you figure out how to import the [jQuery library](http://jquery.com/) into 213 | the page? Once you get it to work, you will see an alert appear. 214 | 215 | `page.html`: 216 | 217 | ```html 218 | 219 | 220 | 221 | 222 | 223 |

Waiting for jQuery...

224 | 231 | 232 | 233 | ``` 234 | 235 | Search suggestion: `import jquery` 236 | 237 | > As you dig around, you may notice that there is more than one way to import 238 | > jQuery (or any other library, for that matter). Because the `src` attribute of 239 | > a ` 264 | 265 | 266 | 267 | 268 | ``` 269 | 270 | `my_script.js`: 271 | 272 | ```javascript 273 | // The jQuery variable is defined by the jQuery library. If the library is 274 | // loaded, this variable will evaluate to a truthy value. 275 | if (jQuery) { 276 | alert("We have jQuery!"); 277 | } 278 | ``` 279 | 280 | Search suggestion: `should script tags be in head or body` 281 | 282 | > Remember: the browser reads HTML from top to bottom. When it encounters a 283 | > `