On Github abramhindle / CMPUT404-Javascript-Slides
Created by Abram Hindle abram dot hindle at ualberta dot ca Department of Computing Science University of Alberta Edmonton, Alberta, Canada Earth
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Good resources:
Where did it come from?
What kind of language is it?
Why?
It runs in browsers (with minimal compatibility issues).
It runs on webservers.
It runs in PDFs.
It is embedded everywhere.
<script type="text/javascript"> //<![CDATA[ // ^^^ do this for XHTML Compatibility if you are going to embed javascript var someJS = "Put your javascript here"; //]]> </script>
<script>
var someJS = "This works but isn't XHTML compatible";
</script>
<!-- you can embed oneliners within HTML! -->
<input value="test me!" type=button
onclick="javascript:alert('hey look ma!');"/>
// here's a comment
/* here's a variable assignment */
var variable = "A string value";
function init() {
f = "Globally available don't do this!";
}
function testF() {
return f;
}
function testVariable() {
var variable = "A local value!";
return variable;
}
init();
// Good style dictates all variables should be defined with var
// this avoid confusion
var variable = "A string value";
// var causes variables to be defined in their initially scope
// and are made available to all functions defined within their scope.
function lexical() {
var shared = "share!"; // defined in this scope
return function() { // shared is also defined (and shared) in this function
return shared; // note how this function references shared
}; // did you also see we just returned an
} // anonymous function!
alert( // so now we call lexical() get a function and then
( lexical() )() // call that function using ()
);
// Closures are functions who reference another scope
// First we make a named function called makeCounter
function makeCounter() {
var counter = 0;
// note that functions are values!
var count = function() {
return counter++; //post increment counter
}
return count;
}
var myCounter = makeCounter();
myCounter();
myCounter();
myCounter();
// myCounter returned 2
function cpsAdd(val1, val2, continuation) {
continuation(val1 + val2);
}
function add1234(continuation) {
cpsAdd(1,2, function(x) {
cpsAdd(x,3, function(x) {
// x is shadowed
cpsAdd(x,4, continuation);
});
});
}
add1234(alert);
function cpsAddR(val1, val2) {
return function(continuation) {
continuation(val1 + val2);
};
}
function addR(continuation) {
// if you don't have a return the last value
// is implicitly returned!
cpsAddR(4,5)( function(x) {
cpsAddR(x,6)( function(y) {
// both x and y are available here
cpsAddR(x,y)( continuation );
})
});
}
addR(alert);
var aString = "Strings"; var break = "not allowed!"; var BREAK = "This is allowed!"; var BrEAK = "Try not to abuse case sensitivity";
var aNumber = 10; var aNumber = 11.11; var aNumber = 1e-100; var aNumber = 1E+100; var nan = NaN; var inf = Infinity; var negativeInfinity = -Infinity;
var aString = ""; var anotherString ="Hi how are you"; var escapesString = "\r\n\t\f\b\/\\\\'\""; var snowMan = "\u2603"; snowMan.length === 1; aString.length === 0;
false null undefined '' 0 NaN
var empty = []; var arrayInitialized = [1,2,3,4,'5'];//mixed! var arr = new Array(10); arr[0] === undefined; arr[0] = 'Assigned'; 'Assigned' === arr[0]; arrayInitialized[4] === '5'; arrayInitialized.length === 5; arrayInitialized.splice(3,1); // delete 4 from the array (slow)
var empty = {};
var abram = {
"name":"Abram Hindle",
"job":"Throwing Down JS",
"favorite tea":"puerh"
};
var dog = {
paws: 4 // note I didn't quote paws
};
dog.paws === 4;
abram["favorite tea"] === "puerh";
abram.name === "Abram Hindle";
abram["favorite tea"] = "oolong";
undefined.property; // Throws a type error
undefined && undefined.property // returns undefined
var empty = {};
empty.property === undefined;
var abram = {
"name":"Abram Hindle",
"job":"Throwing Down JS",
"favorite tea":"puerh"
};
keys(abram); // produces ["name","job","favorite tea"]
//prototype!
var abramChild = Object.create(abram)
keys(abramChild); // produces []
abramChild.name === "Abram Hindle"; // inherits keys from abram
var abram = {
"name":"Abram Hindle",
"job":"Throwing Down JS",
"favorite tea":"puerh",
"sayName": function() {
alert(this.name);
}
};
abramChild = Object.create(abram);
abramChild.name = "Child";
function doit() {
abram.sayName();
abramChild.sayName();
}
var abram = {
"name":"Abram Hindle",
"job":"Throwing Down JS",
"favorite tea":"puerh",
"sayName": function() {
alert(this.name);
}
};
abramChild = Object.create(abram);
abramChild.name = "Child";
function doit() {
abram.sayName();
abramChild.sayName();
}
// we can use new on person now!
var Person = function() { // function is an object
this.name = "Abram Hindle"; // this is the current function
this.job = "Throwing Down JS";
this["favorite tea"] = "puerh";
var self = this; // you could do this if you like perl
var that = this; // this is more idiomatic
this.sayName = function() {
var thatNameAccessor = function () {
return that.name;
};
var thisNameAccessor = function () {
return this.name;
};
alert("this:" + thisNameAccessor() +
" that:" + thatNameAccessor());
}
};
function doit2() {
var p = new Person();
p.sayName();
}
// look a constructor!
var Animal = function(name) { // function is an object
this.name = name; // this is the current function
this.odd = (Math.random() > 0.5);
var that = this;
this.likesNumber = function(x) {
return (x%2 == 1)?this.odd:!this.odd;
}
};
function doit3() {
var animal = new Animal(prompt("Name your Animal"));
var num = prompt("A number your animal might like!");
alert( animal.likesNumber( num ) ? "Yes!"+animal.name+" loves it" :
"No "+animal.name+" hates it!" );
}
// look a constructor!
var Counter = function(name) { // function is an object
this.name = name; // this is the current function
this.count = 0;
this.inc = function() { ++this.count; }
};
function counterTest() {
var counter1 = new Counter("sheep");
var counter2 = new Counter("people");
for (var i = 0 ; i < 10; i++) {
counter1.inc();
counter2.inc();
}
// Dynamically Add a method to all counters in the system
Counter.prototype.dec = function() { --this.count };
counter2.dec();
alert("Counter1:"+counter1.count+" Counter2:"+counter2.count);
}
<h1>A header title</h1> <div> Hi! <a href="http://google.ca">Click me!</a> </div>
Document
document
Get children
document.children // a list (only Elements)
document.childNodes // a list of Nodes (includes text)
// oh look you can dynamically make elements!
var elm = document.createElement("div");
// textContent returns text of childNodes!
elm.textContent = "Here's some text in that div";
elm.childNodes.length === 1; // TextNode is a node child
elm.children.length === 0; // no Element children
// Append it to the body
document.children[0].children[1].appendChild(elm);
// Get all DIVs
var divs = document.getElementsByTagName("div");
// gets all elements with class divider
var dividers = document.getElementsByClassName("divider");
// get the element with the ID main
var main = document.getElementById('main');
// get the element by name
var ups = document.getElementsByName('up');
function addToExample() {
// gets all elements with class divider
var example = document.getElementsByClassName("example")[0];
var elm = document.createElement("div");
elm.textContent = "Add me!";
example.appendChild(elm);
}
<div class="example"> Hi! I'm Example! </div>
function modifyStyle() {
// gets all elements with class divider
var examples = document.getElementsByClassName("example2");
examples.map( function(example) {
example.style.borderWidth = int(10*Math.random())+"px";
});
}
<div class="example2">Hi! I'm Example2!</div> <div class="example2">So am I!</div>
$( document ).ready(function() {
// Do everything you have to now that the page has loaded
}
// How many slides in this document? alert( $( "section" ).length );
function note( event )
{
alert("Clicked");
}
/* For all list items add a click listener */
function selectExample()
{
$("li").click( note );
}
// for all list items remove that listener we added
function removeSelectExample()
{
$("li").off("click","",note);
}
function hideIt()
{
$("li").hide();
}
function showIt()
{
$("li").show();
}
function hideIt2()
{
$("li").fadeOut();
}
function showIt2()
{
$("li").fadeIn();
}
function censor()
{
$( "button.censor" ).html("CENSORED");
}
<button class="censor" onclick="javascript:censor()"> I think _____ about ____ </button>
function getSomeJSON() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'some.json');
// This is a call back
xhr.onreadystatechange = function(){
// readystate tells you how the transfer is going
// 4 is done
if( xhr.readyState === 4 ){
// This is the HTTP Code
if(xhr.status === 200){
alert(xhr.responseText);
} else {
alert("There was an error " + xhr.status);
}
}
};
// finally send it
xhr.send(null);
}
Let's make a generic GET
function getJSON( url, successCallback ) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
// This is a call back
xhr.onreadystatechange = function(){
// readystate tells you how the transfer is going
// 4 is done
if( xhr.readyState === 4 ){
// This is the HTTP Code
if(xhr.status === 200){
successCallback( xhr.responseText );
} else {
alert("There was an error " + xhr.status);
}
}
};
// finally send it
xhr.send(null);
}
Now let's try to do something dynamic! With callbacks
window.setInterval Lets run a function at a set interval.
window.setTimeout Lets you run a function after a period of time.
var myInterval;
function startGetting() {
myInterval = window.setInterval( function() { //callback
var now = new Date();
var s = 1 + (now.getSeconds() % 3);
var url = s + ".json";
getJSON( url, function( ourJSON ) { //another
$("#ajaxy").text( ourJSON ); //callback
});
},1000); // 1 second or 1000 ms
}
<div id="ajaxy">AJAXY</div>
Now let's try to do something dynamic! With callbacks
window.setInterval Lets run a function at a set interval.
window.setTimeout Lets you run a function after a period of time.
function startGettingJQuery() {
var myInterval = window.setInterval( function() { //callback
var now = new Date();
var s = 1 + (now.getSeconds() % 3);
var url = s + ".json";
$.getJSON( url, function( data ) {
// JSON Parsing
$("#ajaxy2").text( data.message );
});
},1000); // 1 second or 1000 ms
}
<div id="ajaxy2">AJAXY2</div>
Strict subset of Javascript see http://json.org for details
function hotDogs() {
var obj = { "food":"hotdog",
"condiments":["ketchup","mustard","cheese"],
"sausage":"weiner"
};
$("#hotdog").text( JSON.stringify( obj, null, " " ) ); //pretty print
var newObj = JSON.parse($("#hotdog").text());
$("#sausage").text( newObj.sausage );
}
<div id="sausage">sausage</div> <pre><span id="hotdog">hotdog</span></pre>
hotdog
Copyright 2014 (C) Abram Hindle
The textual components of this slide deck are placed under the Creative Commons Attribute-ShareAlike 4.0 International License (CC BY-SA 4.0)
The source code to this slide deck is:
Copyright (C) 2013 Hakim El Hattab, http://hakim.se Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN