Web Development and Design | Tutorial for Java, PHP, HTML, Javascript: JavaScript

Web Development and Design | Tutorial for Java, PHP, HTML, Javascript: JavaScript
Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

JAVA SCRIPT - Adding Filter Effects to Video via Canvas

 Adding Filter Effects to Video via Canvas


Problem

You’re interested in not only playing video in your web page but also playing modified versions of the video, such as one that has been grayscaled, or manipulated in some way. 

Solution

Use HTML5 video with the Canvas element, playing the video to a scratch Canvas element:

function drawVideo() {
 var videoObj = document.getElementById("videoobj");
 // if not playing, quit
 if (videoObj.paused || videoObj.ended) return false;
 // draw video on canvas
 var canvasObj = document.getElementById("canvasobj");
 var ctx = canvasObj.getContext("2d");
 ctx.drawImage(videoObj,0,0,480,270);
 ...
 setTimeout(drawVideo,20);
}


You can then add the ability to capture the image data using the Canvas element’s getImageData(), modify the image data with whatever filter you want, and then play the image data to a second, visible Canvas element:


var pData = ctx.getImageData(0,0,480,270);
// grayscale it and set to display canvas
pData = grayScale(pData);
ctx2.putImageData(pData,0,0);


EXPLAIN

The best thing about all the new HTML5 media elements is how you can use them together. Using video and Canvas, you can not only provide custom controls, you can also provide custom video filters, too.

To play a video in a Canvas element, we’ll need to add both elements to the web page:


<video id="videoobj" controls width="480" height="270">
 <source src="videofile.mp4" type="video/mp4" />
 <source src="videofile.webm" type="video/webm" />
 </video>
 <canvas id="canvasobj" width="480" height="270"></canvas>

Both the canvas and video elements are the same width and height. To draw the video onto the canvas, we’re going to use the Canvas drawImage(). There are several variations of parameters we could use with this method, but the signature we’re interested in is the following:


void drawImage(
 in nsIDOMElement image,
 in float dx,
 in float dy,
 in float dw,
 in float dh
);

These parameters are:

• image: A reference to a Canvas element, an img element, or a Video element

• dx: x coordinate of the top-left corner of the source image

• dy: y coordinate of the top-left corner of the source image

• dw: Width of the source image (can be scaled)

• dh: Height of the source image (can be scaled)

Demonstrates a first pass at an application to modify the video playing the Canvas element. It just takes what’s showing in the video and plays it, as is, in the Canvas.

The application uses setTimeout() to test whether the video is still playing and grabs the video every 20 milliseconds, which is fast enough to provide smooth playback for human perceptions.

There is a timeupdate event handler for the Video element, but it’s only invoked every 200 milliseconds (per the W3C specification on the media elements), which is way too slow for our purposes.

A first cut at drawing video data to a canvas element


<!DOCTYPE html>
<head>
<title>Play video in canvas</title>
 <meta charset="utf-8" />
 <script>
 window.onload=function() {
 document.getElementById("videoobj").
 addEventListener("timeupdate", drawVideo, false);
 }
 function drawVideo() {
 var videoObj = document.getElementById("videoobj");
 var canvasObj = document.getElementById("canvasobj");
 var ctx = canvasObj.getContext("2d");
 ctx.drawImage(videoObj,0,0);
 }
 </script>
</head>
<body>
 <video id="videoobj" controls width="480" height="270">
 <source src="videofile.mp4" type="video/mp4" />
 <source src="videofile.webm" type="video/webm" />
 </video>
 <canvas id="canvasobj" width="480" height="270"></canvas>
</body>

In the code, during each time out event, the video is tested to see if it’s still playing before it’s grabbed and displayed in the Canvas element. The application works in all modern browsers.

The next step is to modify the video data before it’s streamed to the Canvas element. For the example, I’m going to do a crude modification of the original video to simulate how a person could perceive the video if they suffered from a form of color blindness known as protanopia.

This type of color blindness is one of the most common, and those who have it can’t perceive red light. I say “crude” because a much more accurate representation is so computationally expensive that the playback visibly stutters.

To modify the video playback, we need two things: the function to modify the data, and a scratch canvas object used to capture the video data, as it is, and then serve as our intermediate in the transformation.

We need a scratch Canvas element because we’re using the Canvas element’s getImageData() to access the actual video data, and putI mageData() to play the video data after it has been manipulated.

The getImageData() function returns an object consisting of three values: the width, the height, and the image data as a Uint8ClampedArray typed array.

Video with applied color blind filter, playing side by side with original 


<!DOCTYPE html>
<head>
<title>Protanopia</title>
 <meta charset="utf-8" />
 <script>
 // Protanopia filter
 function protanopia(pixels) {
 var d = pixels.data;
 for (var i=0; i<d.length; i+=4) {
 var r = d[i];
 var g = d[i+1];
 var b = d[i+2];
 //convert to an approximate protanopia value
 d[i] = 0.567*r + 0.433*g;
 d[i+1] = 0.558*r + 0.442*g;
 d[i+2] = 0.242*g + .758*b;
 }
 return pixels;
 }
 // event listeners
 window.onload=function() {
 document.getElementById("videoobj").
 addEventListener("play", drawVideo, false);
 }
 // draw the video
 function drawVideo() {
 var videoObj = document.getElementById("videoobj");
// if not playing, quit
 if (videoObj.paused || videoObj.ended) return false;
 // create scratch canvas
 var canvasObj = document.getElementById("canvasobj");
 var bc = document.createElement("canvas");
 bc.width=480;
 bc.height=270;
 // get contexts for scratch and display canvases
 var ctx = canvasObj.getContext("2d");
 var ctx2 = bc.getContext("2d");
 // draw video on scratch and get its data
 ctx2.drawImage(videoObj, 0, 0, 480, 270);
 var pData = ctx2.getImageData(0,0,480,270);
 // grayscale it and set to display canvas
 pData = protanopia(pData);
 ctx.putImageData(pData,0,0);
 setTimeout(drawVideo,20);
 }
 </script>
</head>
<body>
 <video id="videoobj" controls width="480" height="270">
 <source src="videofile.mp4" type="video/mp4" />
 <source src="videofile.webm" type="video/webm" />
 </video>
 <canvas id="canvasobj" width="480" height="270"></canvas>
</body>

JAVA SCRIPT - Controlling Video from JavaScript with the video Element

Controlling Video from JavaScript with the video Element


Problem

You want to embed video in your web page, without using Flash. You also want a con‐ sistent look for the video control, regardless of browser and operating system.


Solution

Use the HTML5 video element: 

<video id="meadow" poster="purples.jpg" >
 <source src="meadow.m4v" type="video/mp4"/>
 <source src="meadow.ogv" type="video/ogg" />
</video>


You can provide controls for it via JavaScript, as shown in Example 9-5. Buttons are used to provide the video control, and text in a div element is used to provide feedback on time during the playback.

Providing a custom control for the HTML5 video element :


<!DOCTYPE html>
<head>
<title>Meadow Video</title>
<script>
<style>
 video {
 border: 1px solid black;
 }
</style>
window.onload=function() {
 // events for buttons
 document.getElementById("start").addEventListener("click",startPlayback);
 document.getElementById("stop").addEventListener("click",stopPlayback);
 document.getElementById("pause").addEventListener("click",pausePlayback);
 // setup for video playback
 var meadow = document.getElementById("meadow");
 meadow.addEventListener("timeupdate",reportProgress);
 // video fallback
 var detect = document.createElement("video");
 if (!detect.canPlayType) {
 document.getElementById("controls").style.display="none";
 }
}
// start video, enable stop and pause
// disable play
function startPlayback() {
 var meadow = document.getElementById("meadow");
 meadow.play();
 document.getElementById("pause").disabled=false;
 document.getElementById("stop").disabled=false;
 this.disabled=true;
}
// pause video, enable start, disable stop
// disable pause
function pausePlayback() {
 document.getElementById("meadow").pause();
 this.disabled=true;
 document.getElementById("start").disabled=false;
 document.getElementById("stop").disabled=true;
}
// stop video, return to zero time
// enable play, disable pause and stop
function stopPlayback() {
 var meadow = document.getElementById("meadow");
meadow.pause();
 meadow.currentTime=0;
 document.getElementById("start").disabled=false;
 document.getElementById("pause").disabled=true;
 this.disabled=true;
}
// for every time divisible by 5, output feedback
function reportProgress() {
 var time = Math.round(this.currentTime);
 var div = document.getElementById("feedback");
 div.innerHTML = time + " seconds";
}
</script>
</head>
<body>
<video id="meadow" poster="purples.jpg" >
 <source src="meadow.m4v" type="video/mp4"/>
 <source src="meadow.ogv" type="video/ogg" />
</video>
<div id="feedback"></div>
<div id="controls">
<button id="start">Play</button>
<button id="stop">Stop</button>
<button id="pause">Pause</button>
</controls>
</body>


EXPLAIN

The new HTML5 video element, as with the HTML5 audio element, can be controlled with its own built-in controls, or you can provide your own. The media elements support the following methods: 

• play: Starts playing the video 

• pause: Pauses the video 

• load: Preloads the video without starting play 

• canPlayType: Tests if the user agent supports the video type The media elements don’t support a stop method, so the code emulates one by pausing video play and then setting the video’s currentTime attribute to 0, 

which basically resets the play start time. I also used currentTime to print out the video time, using Math.round to round the time to the nearest second.

The video control is providing two different video codecs: H.264 (.mp4), and Ogg Theora (.ogv). Firefox, Opera, and Chrome support Ogg Theora, but Safari and IE only support the H.264-formatted video. 

However, by providing both types, the video works in all of the browsers that support the video element. The video and audio controls are inherently keyboard-accessible. 

If you do replace the controls, you’ll want to provide accessibility information with your replacements. The video control doesn’t have built-in captioning, but work is underway to provide the API for captioning.


JAVA SCRIPT- Adding JavaScript to SVG

Adding JavaScript to SVG


Problem

You want to add JavaScript to an SVG file or element. 

Solution

JavaScript in SVG is included in script elements, just as with HTML, except with the addition of CDATA markup surrounding the script in case XHTML-sensitive charac‐ ters, such as < and >.

The DOM methods are also available for working with the SVG elements.

Demonstration of JavaScript within an SVG file


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600">
 <script type="text/ecmascript">
 <![CDATA[
// set element onclick event handler
 window.onload=function () {
 var square = document.getElementById("square");
 // onclick event handler, change circle radius
 square.onclick = function() {
 var color = this.getAttribute("fill");
 if (color == "#ff0000") {
 this.setAttribute("fill", "#0000ff");
 } else {
 this.setAttribute("fill","#ff0000");
 }
 }
 }
 ]]>
 </script>
 <rect id="square" width="400" height="400" fill="#ff0000"
 x="10" y="10" />
</svg>


EXPLAIN

As the solution demonstrates, SVG is XML, and the rules for embedding script into XML must be adhered to. This means providing the script type within the script tag, as well as wrapping the script contents in a CDATA block. If you don’t have the CDATA section, and your script uses characters such as < or &, your page will have errors, because the XML parser treats them as XML characters, not script.

The DOM methods, such as document.getElementById(), aren’t HTML specific; they’re usable with any XML document, including SVG. What’s new is the SVG-specific fill attribute, an attribute unique to SVG elements, such as rect. 

The code in the solution is a standalone SVG file, with a .svg extension. If we were to embed the SVG within an HTML file, , the color-changing animation would work the same. The CDATA section is removed because all modern browsers understand the SVG is now in an HTML context. If the file is XHTML, though, add them back.

SVG element , embedded into an HTML page





<!DOCTYPE html>
<html>
<head>
<title>Accessing Inline SVG</title>
<meta charset="utf-8">
</head>
<body>
<svg width="600" height="600">
 <script>
 // set element onclick event handler
 window.onload=function () {
 var square = document.getElementById("square");
 // onclick event handler, change circle radius
 square.onclick = function() {
 var color = this.getAttribute("fill");
 if (color == "#ff0000") {
 this.setAttribute("fill","#0000ff");
 } else {
 this.setAttribute("fill","#ff0000");
 }
 }
 }
 </script>
 <rect id="square" width="400" height="400" fill="#ff0000"
x="10" y="10" />
</svg>
</body>
</html>

Using SVG Libraries

There aren’t quite as many libraries for working with SVG as there are for working with Canvas, but the ones that exist are very handy. One of the most popular is the D3 library, . 

Three other popular libraries include the granddaddy of the SVG libraries, Raphaël, and the newer Snap.svg and SVG.js. All three can simplify SVG cre‐ ation and animation. You can even use Raphaël in both jsBin and jsFiddle, . The following code snippet shows an example of using Raphaël:


// Creates canvas 320 × 200 at 10, 50
var paper = Raphael(10, 50, 320, 400);
// Creates circle at x = 150, y = 140, with radius 100
var circle = paper.circle(150, 140, 100);
// Sets the fill attribute of the circle to red (#f00)
circle.attr("fill", "#f0f");
// Sets the stroke attribute of the circle to white
circle.attr("stroke", "#ff0");

JAVA SCRIPT - Creating a Dynamic Line Chart in Canvas

Creating a Dynamic Line Chart in Canvas


Problem

You want to display a line chart in your web page, but the data changes over time, and you want to dynamically update it. 

Solution

Use the canvas element and the path method to create the chart. When the data changes, update the chart:

var array1 = [[100,100], [150, 50], [200,185],
 [250, 185], [300,250], [350,100], [400,250],
 [450, 100], [500,20], [550,80], [600, 120]];
var imgcanvas = document.getElementById("imgcanvas");
if (imgcanvas.getContext) {
 var ctx = imgcanvas.getContext('2d');
 // rect one
 ctx.strokeRect(0,0,600,300);
 // line path
 ctx.beginPath();
 ctx.moveTo(0,100);
 for (var i = 0; i < array1.length; i++) {
 ctx.lineTo(array1[i][0], array1[i][1]);
 }
 ctx.stroke();
}

EXPLAIN


Canvas paths are the way to create arbitrary shapes in Canvas. After getting the canvas context, ctx, the path is begun with a call to ctx.beginPath(), which begins a new Canvas path. The next line of code is ctx.moveTo, which moves the drawing “pen” to a beginning location, but without drawing. From that point, several lineTo() calls are made using an array of paired values representing the x,y location for each line endpoint. 

After the path has been defined, it’s drawn. We’re not creating a closed path, so I’m not using ctx.closePath(), which would draw all the defined lines and then attempt to draw a line from the ending point to the beginning point. Instead, I’m drawing the line given the points that have been defined, using ctx.stroke(). 

The appearance of the drawing is influenced by two Canvas settings: strokeStyle and fillStyle. The strokeStyle setting sets the color for the outline of a drawing, while the fillStyle does the same for the drawing filling: 


ctx.strokeStyle="black";
ctx.fillStyle="#ff0000;

Any CSS setting will do, or you can use a CanvasGradient or CanvasPattern. You can use the rgba setting to add transparency:

ctx.fillStyle="rgba(255,0,0,0.5)";

You can also use the globalAlpha setting to set the transparency for any drawing that follows:


ctx.globalAlpha = 0.2;

You can further control the appearance of the drawing outline by changing the stroke’s line width:

ctx.line

To dynamically update the chart, you can incorporate timers, and either replace the path (by creating an entirely new context, which would erase the old), or add the new line chart to the same chart.

 shows a web page that creates the line in the solution and then creates two others, each drawn after a short period of time using timers. The colors for the stroke path are changed between lines.

Using timers to dynamically update a line chart


<!DOCTYPE html>
<head>
<title>Canvas Chart</title>
<meta charset="utf-8" />
</head>
<body>
<canvas id="imgcanvas" width="650" height="350">
<p>Include an image that has a static representation of the chart</p>
</canvas>
<script>
 var points = [[[100,100], [150, 50], [200,185],
 [250, 185], [300,250], [350,100], [400,250],
 [450, 100], [500,20], [550,80], [600, 120]],
 [[100,100], [150, 150], [200,135],
 [250, 285], [300,150], [350,150], [400,280],
 [450, 100], [500,120], [550,80], [600, 190]],
 [[100,200], [150, 100], [200,35],
 [250, 185], [300,10], [350,15], [400,80],
 [450, 100], [500,120], [550,80], [600, 120]]];
 var colors = ['black','red','green'];
 var imgcanvas = document.getElementById("imgcanvas");
 if (imgcanvas.getContext) {
 var ctx = imgcanvas.getContext('2d');
// rectangle wrapping line chart
 ctx.strokeRect(0,0,600,300);
 points.forEach(function(element, indx, arry) {
 setTimeout(function() {
 // set up beginning
 ctx.beginPath();
 ctx.moveTo(0,100);
 ctx.strokeStyle = colors[indx];
 for (var i = 0; i < element.length; i++) {
 ctx.lineTo(element[i][0], element[i][1]);
 }
 ctx.stroke();
 }, indx * 5000);
 });
 }
</script>
</body>

Simplify Your Canvas Charts Using a Library

It doesn’t have to be difficult to create a chart using Canvas from scratch, but why walk the steps taken by others? There are several excellent libraries that can simplify not only chart making but other Canvas effects. Over 50 libraries for chart making are listed in a TechSlides Page, including the in‐ creasingly popular D3, . 

Most of the libraries are freely available, though some do charge a fee for commercial use. One of the libraries, Highcharts, even provides demonstrations that you can edit in jsFiddle, making it easy to try out the library’s capability. 

It’s dependent on jQuery, reducing the code to an absurdly simple level. As an example, one of the demonstrations is for a very professional line chart, with plot lines and labels,. Yet the code to create this example is equivalent to that in the following code block, which I modified to feature my own locations and temperature metric, which you can try yourself at jsFiddle: 


$(function () {
 $('#container').highcharts({
 title: {
 text: 'Monthly Average Temperature',
 x: -20 //center
 },
 subtitle: {
 text: 'Source: Weather.com',
 x: -20
 },
 xAxis: {
 categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
 },
 yAxis: {
 title: {
 text: 'Temperature (°F)'
 },
 plotLines: [{
 value: 0,
 width: 1,
 color: '#808080'
 }]
 },
 tooltip: {
 valueSuffix: '°F'
 },
 legend: {
 layout: 'vertical',
 align: 'right',
 verticalAlign: 'middle',
 borderWidth: 0
 },
 series: [{
 name: 'Seattle, WA',
 data: [47,51,55,59,65,70,75,75,70,60,52,47]
 }, {
 name: 'Grand Isle, VT',
 data: [27,31,40,54,67,76,81,79,71,57,45,33]
 }, {
 name: 'St. Louis, MO',
 data: [40,45,55,67,77,85,89,88,81,69,56,43]
 }]
 });
 });


Not only is the plotted chart professional looking, it’s zoomable, which means you can move your mouse cursor over the chart to examine the plot points in detail. That level of interactivity isn’t necessarily trivial in Canvas, because one of the downsides to Canvas is the fact that you can’t attach event handlers to the individual elements of Canvas— only to the Canvas area itself.

Not being able to attach an event to individual elements means that you’ll have to keep track of where the mouse is, and what’s underneath it at any point in time

JAVA SCRIPT - Using a Timer to Automatically Update the Page with Fresh Data

Using a Timer to Automatically Update the Page with Fresh Data


Problem

You want to display entries from a file, but the file is updated frequently. 

Solution

Use Ajax and a timer to periodically check the file for new values and update the display accordingly. The Ajax we use is no different than any other Ajax request. We’ll use a GET, because we’re retrieving data.

 We put together the request, attach a function to the onreadysta techange event handler, and send the request: 


var xmlhttp;
// prepare and send XHR request
function populateList() {
 var url = 'text.txt'; // change to full url to prevent caching problems
 xmlhttp.open('GET', url, true);
 xmlhttp.onreadystatechange = processResponse;
 xmlhttp.send(null);
}

In the code that processes the response, we just place the new text into a new unordered list item and append it to an existing ul element:

// process return
function processResponse() {
 if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
 var li = document.createElement("li");
 var txt = document.createTextNode(xmlhttp.responseText);
 li.appendChild(txt);
 document.getElementById("update").appendChild(li);
 setTimeout(populateList,15000);
 } else if (xmlhttp.readyState == 4 && xmlhttp.status != 200) {
 console.log(xmlhttp.responseText);
 }
}

The new part is the addition of the setTimeout() in the code. It triggers the entire process again in 15 seconds.The process is started by creating the xmlHttpRequest object in the Window load event handler, and then calling populateList() the first time:

window.onload=function() {
 xmlhttp = new XMLHttpRequest();
 populateList();
}


EXPLAIN

The fact that we’re doing a direct request on a static text file might be new, but remember that a GET request is more or less the same as the requests we put into the location bar of our browsers. If something works in the browser, it should successfully return in an Ajax GET request…within reason. 

The key to using timers with Ajax calls is to make sure that the last call is completed before making the next. By adding the call to setTimeout() at the end of the Ajax call, we trigger the timer when we know an outstanding request isn’t being processed. We can also put in a check for the request status, and cancel the timer event altogether if we’re concerned about hitting a failing service, over and over again. When I ran the application that included the solution code, 

I changed the text file by using the Unix echo command: 


$ echo "This is working" > text.txt

JAVA SCRIPT - Creating a Dynamic Line Chart in Canvas

Creating a Dynamic Line Chart in Canvas


Problem

You want to display a line chart in your web page, but the data changes over time, and you want to dynamically update it. 

Solution

Use the canvas element and the path method to create the chart. When the data changes, update the chart: 

var array1 = [[100,100], [150, 50], [200,185],
 [250, 185], [300,250], [350,100], [400,250],
 [450, 100], [500,20], [550,80], [600, 120]];
var imgcanvas = document.getElementById("imgcanvas");
if (imgcanvas.getContext) {
 var ctx = imgcanvas.getContext('2d');
 // rect one
 ctx.strokeRect(0,0,600,300);
 // line path
 ctx.beginPath();
 ctx.moveTo(0,100);
 for (var i = 0; i < array1.length; i++) {
 ctx.lineTo(array1[i][0], array1[i][1]);
 }
 ctx.stroke();
}


EXPLAIN

Canvas paths are the way to create arbitrary shapes in Canvas. After getting the canvas context, ctx, the path is begun with a call to ctx.beginPath(), which begins a new Canvas path. The next line of code is ctx.moveTo, which moves the drawing “pen” to a beginning location, but without drawing. From that point, several lineTo() calls are made using an array of paired values representing the x,y location for each line endpoint. 


After the path has been defined, it’s drawn. We’re not creating a closed path, so I’m not using ctx.closePath(), which would draw all the defined lines and then attempt to draw a line from the ending point to the beginning point. Instead, I’m drawing the line given the points that have been defined, using ctx.stroke(). 

The appearance of the drawing is influenced by two Canvas settings: strokeStyle and fillStyle. The strokeStyle setting sets the color for the outline of a drawing, while the fillStyle does the same for the drawing filling:


ctx.strokeStyle="black";
ctx.fillStyle="#ff0000;

Any CSS setting will do, or you can use a CanvasGradient or CanvasPattern. You can use the rgba setting to add transparency:

ctx.fillStyle="rgba(255,0,0,0.5)";

You can also use the globalAlpha setting to set the transparency for any drawing that follows:

ctx.globalAlpha = 0.2;

You can further control the appearance of the drawing outline by changing the stroke’s line width:

ctx.line

To dynamically update the chart, you can incorporate timers, and either replace the path (by creating an entirely new context, which would erase the old), or add the new line chart to the same chart.

Shows a web page that creates the line in the solution and then creates two others, each drawn after a short period of time using timers. The colors for the stroke path are changed between lines.

Using timers to dynamically update a line chart


<!DOCTYPE html>
<head>
<title>Canvas Chart</title>
<meta charset="utf-8" />
</head>
<body>
<canvas id="imgcanvas" width="650" height="350">
<p>Include an image that has a static representation of the chart</p>
</canvas>
<script>
 var points = [[[100,100], [150, 50], [200,185],
 [250, 185], [300,250], [350,100], [400,250],
 [450, 100], [500,20], [550,80], [600, 120]],
 [[100,100], [150, 150], [200,135],
 [250, 285], [300,150], [350,150], [400,280],
 [450, 100], [500,120], [550,80], [600, 190]],
 [[100,200], [150, 100], [200,35],
 [250, 185], [300,10], [350,15], [400,80],
 [450, 100], [500,120], [550,80], [600, 120]]];
 var colors = ['black','red','green'];
 var imgcanvas = document.getElementById("imgcanvas");
 if (imgcanvas.getContext) {
 var ctx = imgcanvas.getContext('2d');
// rectangle wrapping line chart
 ctx.strokeRect(0,0,600,300);
 points.forEach(function(element, indx, arry) {
 setTimeout(function() {
 // set up beginning
 ctx.beginPath();
 ctx.moveTo(0,100);
 ctx.strokeStyle = colors[indx];
 for (var i = 0; i < element.length; i++) {
 ctx.lineTo(element[i][0], element[i][1]);
 }
 ctx.stroke();
 }, indx * 5000);
 });
 }
</script>
</body>

Simplify Your Canvas Charts Using a Library

It doesn’t have to be difficult to create a chart using Canvas from scratch, but why walk the steps taken by others? There are several excellent libraries that can simplify not only chart making but other Canvas effects. Over 50 libraries for chart making are listed in a TechSlides Page, including the in‐ creasingly popular D3, which I’ll cover in . 

Most of the libraries are freely available, though some do charge a fee for commercial use. One of the libraries, Highcharts, even provides demonstrations that you can edit in jsFiddle, making it easy to try out the library’s capability. It’s dependent on jQuery, reducing the code to an absurdly simple level. As an example, one of the demonstrations is for a very professional line chart, with plot lines and labels, 


Yet the code to create this example is equivalent to that in the following code block, which I modified to feature my own locations and temperature metric, which you can try yourself at jsFiddle:

$(function () {
 $('#container').highcharts({
 title: {
 text: 'Monthly Average Temperature',
 x: -20 //center
},
 subtitle: {
 text: 'Source: Weather.com',
 x: -20
 },
 xAxis: {
 categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
 },
 yAxis: {
 title: {
 text: 'Temperature (°F)'
 },
 plotLines: [{
 value: 0,
 width: 1,
 color: '#808080'
 }]
 },
 tooltip: {
 valueSuffix: '°F'
 },
 legend: {
 layout: 'vertical',
 align: 'right',
 verticalAlign: 'middle',
 borderWidth: 0
 },
 series: [{
 name: 'Seattle, WA',
 data: [47,51,55,59,65,70,75,75,70,60,52,47]
 }, {
 name: 'Grand Isle, VT',
 data: [27,31,40,54,67,76,81,79,71,57,45,33]
 }, {
 name: 'St. Louis, MO',
 data: [40,45,55,67,77,85,89,88,81,69,56,43]
 }]
 });
 });


Not only is the plotted chart professional looking, it’s zoomable, which means you can move your mouse cursor over the chart to examine the plot points in detail. That level of interactivity isn’t necessarily trivial in Canvas, because one of the downsides to Canvas is the fact that you can’t attach event handlers to the individual elements of Canvas— only to the Canvas area itself.

Not being able to attach an event to individual elements means that you’ll have to keep track of where the mouse is, and what’s underneath it at any point in time.

Thankfully, you can attach event handlers to SVG elements, as demonstrated.

JAVA SCRIPT - Making an Ajax Request to Another Domain (Using JSONP)

Making an Ajax Request to Another Domain (Using JSONP)


Problem

You want to query for data using a web service API, such as the Rotten Tomatoes API, or the Flicker API. However, the Ajax same-origin security policy prevents cross-domain communication

Solution

One approach is to use JSONP (JSON with padding) to work around the security issues.

First, you create a new script element, making the URL the endpoint for the API method call. The following creates a script element with a call to Flickr’s photo search API method: 


function addScript( url) {
 var script = document.createElement('script');
 script.type="text/javascript";
 script.src = url;
 document.getElementsByTagName('head')[0].appendChild(script);
}

The URL looks like the following, including a request to return the data formatted as JSON, and providing a callback function name. The api_key is generated by Flickr, and the user_id is the unique user identifier, the NSID, for your account. Note this isn’t the same as the username. I’m asking for the first page of results for a given user:

http://api.flickr.com/services/rest/?method=flickr.photos.search&user_id=xxx
&api_key=xxx&page=1&format=json&jsoncallback=processPhotos

When the script tag is created, the request to Flickr is made, and because I passed in the request for a JSON-formatted result and provided a callback function name, that’s how the return is provided. The following is a basic callback function that just displays the results to the console:

function processPhotos(obj) {
 photos = obj.photos.photo;
 var str = '';
 photos.forEach(function(photo) {
 str+=photo.title + '
 ';
 });
 document.getElementById('result').innerHTML = str;
}

EXPLAIN

Ajax works within a protected environment that ensures we don’t end up embedding dangerous text or code into a web page because of a call to an external application (which may or may not be secure).The downside to this security is that we can’t directly access services to external APIs. Instead, we have to create a server-side proxy application because server applications don’t face the cross-domain restriction.

One workaround is to use JSONP, demonstrated in the solution. Instead of using XMLHttpRequest, we convert the request URL into one that we can attach to a script’s src attribute, because the script element does not follow the same-origin policy. If the service is amenable, it returns the data formatted as JSON, even wrapping it in a callback function. 

When the script is created, it’s no different than if the function call is made directly in our code, and we’ve passed an object as a parameter. We don’t even have to worry about converting the string to a JavaScript object.The callback’s argument is a JSON object. 


The photos are returned in pages, and you can repeat the calls as many times as you want to get as many photos as you need, changing the page number with each call. contains a simple, working example of using JSONP to access information from Flickr. Just remember to use your own API key and NSID. 

 Using JSONP to circumvent cross-domain restrictions and processing the result


<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>JSONP</title>
</head>
<body>
 <div id="result">
 </div>
<script >
function addScript( url) {
 var script = document.createElement('script');
 script.src = url;
 document.getElementsByTagName('head')[0].appendChild(script);
}
addScript('https://api.flickr.com/services/rest/?method=flickr.photos.search
&user_id=NSID&api_key=yourapikey&page=1&format=json&jsoncallback=processPhotos');
// assign photos globally, call first to load
function processPhotos(obj) {
 photos = obj.photos.photo;
 var str = '';
 photos.forEach(function(photo) {
 str+=photo.title + '<br /> ';
 });
 document.getElementById('result').innerHTML = str;
}
</script>
</body>
</html>

It’s a clever trick, but should only be used with caution. Even with secure services such as Flickr, there is the remote possibility that someone could find a way to inject JavaScript into the data via the client-side application for the service, which can cause havoc in the application.

JAVA SCRIPT - Converting an Object to a Filtered/Transformed String with JSON

Converting an Object to a Filtered/Transformed String with JSON


Problem

You need to convert a JavaScript object to a JSON-formatted string for posting to a web application. However, the web application has data requirements that differ from your client application.

Solution

Use the JSON.stringify() method, passing in the object as first parameter and pro‐ viding a transforming function (a replacer) as the second parameter:
function convertBoolToNums(key, value) {
 if (typeof value == 'boolean') {
 if (value)
 value = 1;
 else
 value = 0;
 }
 return value;
};
var obj = {test : "value1",
 test2 : 3.44,
 test3 : false};
var jsonstr = JSON.stringify(obj, convertBoolToNums, 3);
console.log(jsonstr); // '{ "test" : "value1", "test2" : 3.44, "test3" : 0}'

EXPLAIN

The JSON.stringify() method takes three parameters: the object to be transformed into JSON, an optional function or array used either to transform or filter one or more object values, and an optional third parameter that defines how much and what kind of whitespace is used in the generated result. In the solution, a function is used to check property values, and if the value is a Boolean, converts false to 0, and true to 1. 

The function results are transformed into a string if the return value is a number or Boolean. The function can also act as a filter: if the returned value from the function is null, the property/value pair is removed from the JSON.

You can also use an array rather than a function. The array can contain strings or num‐ bers, and is a whitelist of properties that are allowed in the result. The following code:



var whitelist = ["test","test2"];
var obj = {"test" : "value1", "test2" : 3.44, "test3" : false};
var jsonobj = JSON.stringify(obj, whitelist, '\t');
Would result in a JSON string including the object’s test and test2 properties, but not the third property (test3), The resulting string is also pretty-printed using a tab (\t) this time, instead of the three spaces used in the solution:
{
 "test": "value1",
 "test2": 3.44
}

The last parameter controls how much whitespace is used in the result. It can be a number representing the number of spaces or a string. If it is a string, the first 10 char‐ acters are used as whitespace. If I use the following:

var jsonobj = JSON.stringify(obj, whitelist, "***");

the result is:

{
***"test": "value1",
***"test2": 3.44
}

JAVA SCRIPT - Parsing and Automatically Modifying JSON

 Parsing and Automatically Modifying JSON


Problem

You want to safely create a JavaScript object from JSON. You also want to replace the numeric representation of true and false (1 and 0, respectively) with their Boolean counterparts (true and false).

Solution

Parse the object with the JSON built-in capability added to browsers via ECMAScript 5. To transform the numeric values to their Boolean counterparts, create a reviver function:

var jsonobj = '{"test" : "value1", "test2" : 3.44, "test3" : 0}';
var obj = JSON.parse(jsonobj, function (key, value) {
 if (typeof value == 'number') {
 if (value == 0) {
 value = false;
 } else if (value == 1) {
 value = true;
 }
 }
 return value;
 });
console.log(obj.test3); // false


EXPLAIN

To figure out how to create JSON, think about how you create an object literal and just translate it into a string (with some caveats). If the object is an array:

var arr = new Array("one","two","three");

the JSON notation would be equivalent to the literal notation for the array:

["one","two","three"];


Note the use of double quotes ("") rather than single, which are not allowed in JSON. If you’re working with an object:

var obj3 = {
 prop1 : "test",
 result : true,
 num : 5.44,
 name : "Joe",
 cts : [45,62,13]};


the JSON notation would be:


{"prop1":"test","result":true,"num":5.44,"name":"Joe","cts":[45,62,13]}

Notice in JSON how the property names are in quotes, but the values are only quoted when they’re strings. In addition, if the object contains other objects, such as an array, it’s also transformed into its JSON equivalent. However, the object cannot contain methods. If it does, an error is thrown. JSON works with data only.

The JSON static object isn’t complex, as it only provides two methods: stringify() and parse(). The parse() method takes two arguments: a JSON-formatted string and an optional reviver function. This function takes a key/value pair as parameters, and returns either the original value or a modified result. In the solution, the JSON-formatted string is an object with three properties: a string, a numeric, and a third property, which has a numeric value but is really a Boolean with a numeric representation—0 is false, 1 is true.

To transform all 0, 1 values into false, true, a function is provided as the second ar‐ gument to JSON.parse(). It checks each property of the object to see if it is a numeric. If it is, the function checks to see if the value is 0 or 1. If the value is 0, the return value is set to false; if 1, the return value is set to true; otherwise, the original value is returned.

The ability to transform incoming JSON-formatted data is essential, especially if you’re processing the result of an Ajax request or JSONP response. You can’t always control the structure of the data you get from a service.


JAVA SCRIPT - Extracting Pertinent Information from an XML Tree

Extracting Pertinent Information from an XML Tree


Problem

You want to access individual pieces of data from an XML document. 

Solution

Use the same DOM methods you use to query your web page elements to query the XML document. For example, the following will get all elements that have a resource tag name:

var resources = xmlHttpObj.responseXML.getElementsByTagName("resource");

EXPLAIN

When you have a reference to an XML document, you can use the DOM methods to query any of the data in the document. It’s not as simple as accessing data from a JSON object, but it’s vastly superior to extracting data from a large piece of just plain text. 

To demonstrate working with an XML document, Contains a Node.js (commonly referred to simply as Node) application that returns XML containing three resources. Each resource contains a title and a url. It’s not a complicated application or a complex XML result, but it’s sufficient to generate an XML document. Notice that a MIME type of text/xml is given in the header, and the Access-Control-

Allow-Origin header value is set to accept queries from all do‐ mains (*). Because the Node application is running at a different port than the web page querying it, we have to set this value in order to allow cross-domain requests.

Node.js server application that returns an XML result


var http = require('http'),
 url = require('url');
var XMLWriter = require('xml-writer');
// start server, listen for requests
var server = http.createServer().listen(8080);
server.on('request', function(req, res) {
 var xw = new XMLWriter;
 // start doc and root element
 xw.startDocument().startElement("resources");
 // resource
 xw.startElement("resource");
 xw.writeElement("title","Ecma-262 Edition 6");
 xw.writeElement("url",
 "http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts");
 xw.endElement();
 // resource
 xw.startElement("resource");
 xw.writeElement("title","ECMA-262 Edition 5.1");
 xw.writeElement("url",
 "http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf");
 xw.endElement();
 // resource
 xw.startElement("resource");
 xw.writeElement("title", "ECMA-402");
 xw.writeElement("url",
 "http://ecma-international.org/ecma-402/1.0/ECMA-402.pdf");
 xw.endElement();
 // end resources
 xw.endElement();
 res.writeHeader(200, {"Content-Type": "application/xml",
 "Access-Control-Allow-Origin": "*"});
 res.end(xw.toString(),"utf8");
});


Most Ajax calls process plain text or JSON, but there’s still a need for processing XML. SVG is still XML, as is MathML, XHTML, and other markup languages.

In the solution, a new XMLHttpRequest object is created to handle the client-server communication. If you’ve not used Ajax previously, the XMLHttpRequest object’s methods are:

• open: Initializes a request. Parameters include the method (GET, POST, DELETE, or PUT), the request URL, whether the request is asynchronous, and a possible username and password. By default, all requests are sent asynchronously.
• setRequestHeader: Sets the MIME type of the request.
• send: Sends the request.
• sendAsBinary: Sends binary data.
• abort: Aborts an already sent request.
• getResponseHeader: Retrieves the header text, or null if the response hasn’t been returned yet or there is no header.
• getAllResponseHeaders: Retrieves the header text for a multipart request

The communication is opened using object’s open() method, passing in the HTTP method (GET), the request URL (the Node application), as well as a value of true, signaling that the communication is asynchronous (the application doesn’t block wait‐ ing on the return request). If the application is password protected, the fourth and fifth optional parameters are the username and password, respectively.

I know that the application I’m calling is returning an XML-formatted response, so it’s not necessary to override the MIME type In the application, the XMLHttpRequest’s onReadyStateChange event handler is assigned a callback function, getData(), and then the request is sent with send(). If the HTTP method had been POST, the prepared data would have been sent as a parameter of send().

In the callback function getData(), the XMLHttpRequest object’s readyState and status properties are checked . Only when the readyState is 4 and status is 200 is the result processed.

The readyState indicates what state the Ajax call is in, and the value of 200 is the HTTP OK response code. Because we know the result is XML, the application accesses the XML document via the XMLHttpRequest object’s responseXML property.

For other data types, the data is accessed via the response prop‐ erty, and responseType provides the data type (arrayBuffer, blob, document, json, text). Not all browsers support all data types, but all modern browsers do support XML and at least arrayBuffer, JSON, and text.

Application to process resources from returned XML 


<!DOCTYPE html>
<html>
<head>
 <title>Stories</title>
 <meta charset="utf-8" />
</head>
<body>
 <div id="result">
 </div>
<script type="text/javascript">
 var xmlHttpObj;
 // ajax object
 if (window.XMLHttpRequest) {
 xmlRequest = new XMLHttpRequest();
 }
 // build request
 var url = "http://shelleystoybox.com:8080";
 xmlRequest.open('GET', url, true);
 xmlRequest.onreadystatechange = getData;
 xmlRequest.send();
 function getData() {
 if (xmlRequest.readyState == 4 && xmlRequest.status == 200) {
 try {
 var result = document.getElementById("result");
 var str = "<p>";
 // can use DOM methods on XML document
 var resources =
 xmlRequest.responseXML.getElementsByTagName("resource");
 // process resources
 for (var i = 0; i < resources.length; i++) {
 var resource = resources[i];
 // get title and url, generate HTML
 var title = resource.childNodes[0].firstChild.nodeValue;
 var url = resource.childNodes[1].firstChild.nodeValue;
 str += "<a href='" + url + "'>" + title + "</a><br />";
 }
 // finish HTML and insert
 str+="</p>";
 result.innerHTML=str;
 } catch (e) {
 console.log(e.message);
 }
 }
 }
</script>
</body>
</html>

When processing the XML code, the application first queries for all resource elements, returned in a nodeList. The application cycles through the collection, accessing each resource element in order to access the title and url, both of which are child nodes. Each is accessed via the childNodes collection, and their data, contained in the node Value attribute, is extracted.

The resource data is used to build a string of linked resources, which is output to the page using innerHTML. Instead of using a succession of childNodes element collections to walk the trees, I could have used the Selectors API to access all URLs and titles, and then traversed both collections at one time, pulling the paired values from each, in sequence:

var urls = xmlRequest.responseXML.querySelectorAll("resource url");
var titles = xmlRequest.responseXML.querySelectorAll("resource title");
for (var i = 0; i < urls.length; i++) {
 var url = urls[i].firstChild.nodeValue;
 var title = titles[i].firstChild.nodeValue;
 str += "" + title + "
";
}

I could have also used getElementsByTagName against each returned resource element —any XML DOM method that works with the web page works with the returned XML. The try…catch error handling should catch any query that fails because the XML is incomplete.

JAVA SCRIPT - Safely Combining Several Libraries in Your Applications

 Safely Combining Several Libraries in Your Applications


Problem

You want to incorporate more than one external library, as well as your own, into one application without each stepping all over the others.

Solution

The safest approach for using multiple libraries is to pick ones that are all based on the same framework, such as using only libraries based on jQuery, the framework used in earlier recipes. 

If that strategy doesn’t work, make sure the libraries all use good programming practices, and none are overriding functionality or event handling provided by the others.

EXPLAIN

Regardless of library purpose, there are fundamental rules governing the behavior of libraries that must be followed. Well-designed libraries do not do things like this:


window.onload=function() {...}


I use the DOM Level 0 window.onload event handler with some of the examples in the book because it’s quick, simple, and doesn’t add a lot of code to the sample.

However, if you have one library that uses the old DOM Level 0 event handling, it overwrites the event capturing utilized by the other libraries and your own application.

Well-designed libraries don’t use DOM Level 0 event handling. Well-designed libraries also namespace all of their functionality. You won’t find the following in a well-defined library:


function foo() { ... }
function bar() { ... }
Each function like this ends up in the global space, which increases the likelihood of clashes with other libraries, and your own applications. Well-designed libraries typically use an anonymous function, ensuring no clash with whatever is exposed to the global space:
 var root = this;
 ...
 if (typeof define === 'function' && define.amd) {
 define('underscore', [], function() {
 return _;
 });
 }
}).call(this);


A library that plays well with other libraries and applications will not extend existing objects via the prototype object. Yes, I know it’s a wonderful way of extending objects, and fundamental to JavaScript, but you can’t control one library from overriding another if both are extending the prototype property for the same object.

Besides, if the frame‐ work and external libraries you use don’t extend existing objects via the prototype, this leaves you free to play in your application. Come to that, library builders should never assume that their library is the only one used in a project.

Well-designed libraries provide event hooks so that you can hook into the library at the points where it performs a major action. the jQuery plug-in described in the solution provided event handler hooks you can use to provide your own func‐ tionality before or after the plug-in’s validation routine.

Well-designed libraries provide good documentation of all of the publicly exposed bits, including methods, properties, and events. You shouldn’t have to guess how to use the library, or examine minute portions of the code, in order to figure out what you need to do.

Well-designed libraries are thoroughly tested, and provide a way to report bugs and view existing bugs. Test code should be accessible wherever it’s hosted. If there’s a major security problem with an existing library, you need to know about it. If there are minor bugs, you need to know about these, too.


Well-designed libraries provide nonminified, original source code. This isn’t essential —just helpful, and something I look for in a library. It goes without saying that a good library is one actively maintained, but it can’t hurt to repeat this assertion.

An even better library is one that’s open sourced, and maintained by a community of users, who hopefully play well together—or is one you can maintain on your own, if the original maintainer can no longer do so. To summarize:

• A good library does not use DOM Level 0 event handling.
• A well-defined library uses an anonymous function to wrap its functionality and doesn’t pollute the global namespace.
• A well-defined library introduces few global objects.
• Libraries that play well with others provide event hooks. Well-behaved libraries also don’t extend existing objects via the prototype property.
• Solid libraries are well-tested, and provide these tests as deliverables.
• Stable libraries are actively maintained, and preferably, open sourced.
• Secure libraries provide documentation of known bugs and problems, and a way to report on any bugs and problems you find.
• Usable libraries are well-documented. Bandwidth-friendly libraries are optimized and compressed, though you can always compress the library yourself.
• Confident libraries aren’t built on the assumption that no other library will be used.

For the most part, you should be able to find what you need and have it work with your preferred framework. Be cautious if a library requires you to add a new framework, that needs to coexist with another framework. However, most well-built framework libraries could work with others.

As an example of framework coexistence, if you use jQuery, you can use another frame‐ work library, such as Underscore or Mootools. The use of global namespaces should prevent name clashes. The only exception to the namespace rule is the dollar sign ($) function, which can be used in other libraries.

You can override the $ by adding the following, after all the libraries have been loaded:

var $j = jQuery.noConflict();

Once you add this code, instead of:

$("#elem").fadeOut('slow');

use :

$j("#elem").fadeOut('slow');

You can use most well-made framework libraries together, but there is tremendous overlap in functionality between the libraries, and this overlap in functionality comes with a cost: bandwidth to download the libraries.

Try to avoid using more than one framework library at a time. Find the one you like, and be prepared to commit to it for some time to come.

JAVA SCRIPT - Convert Your Library to a jQuery Plug-in

Convert Your Library to a jQuery Plug-in


Problem

You want to convert your library methods and functions into a jQuery plug-in for use by others. 

Solution

If your plug-in has one or more separate functions that do not need to participate in the jQuery chain, create a function on the fn property:

$.fn.setColor = function(color) {
 this.css("color", color);
 };


If you want your method to participate in the jQuery chain, assign your method to the fn property and then return the original jQuery object:


$.fn.increaseWidth = function() {
 return this.each(function() {
 var width = $(this).width() + 10;
 $(this).width(width);
 });
};


If your function uses the jQuery dollar sign function ($) and you’re concerned that the library could be used with other libraries that make use of $, wrap your function in an anonymous function:


;(function($) {
 $.fn.flashBlueRed = function() {
return this.each(function() {
 var hex = rgb2hex($(this).css("background-color"));
 if (hex == "#0000ff") {
 $(this).css("background-color", "#ff0000");
 } else {
 $(this).css("background-color", "#0000ff");
 }
 });
 };
})(jQuery);

EXPLAIN

It’s relatively simple to create a jQuery plug-in once you understand the nuances of the jQuery plugin infrastructure. If you’re interested in creating a jQuery method that can be used with a jQuery selector and participate in the jQuery chain, you’ll use syntax such as the following, which sets the function to the fn property, and returns the original jQuery object:


$.fn.increaseWidth = function() {
 return this.each(function() {
 var width = $(this).width() + 10;
 $(this).width(width);
 });
};


However, if you want to make use of the dollar sign function ($) within the code, but still have the plug-in work within a multiple library setting, wrap the method in an anonymous function:


;(function($) {
 $.fn.flashBlueRed = function() {
 return this.each(function() {
 var hex = rgb2hex($(this).css("background-color"));
 if (hex == "#0000ff") {
 $(this).css("background-color", "#ff0000");
 } else {
 $(this).css("background-color", "#0000ff");
 }
 });
 };
})(jQuery);


Notice the following line in both examples:

return this.each(function () {

This code is necessary to allow the method to work on whatever is returned by the selector, regardless of whether it’s a single item or a group of items.

The line begins the code block that includes your actual method code.If you’re only interested in adding a jQuery function that isn’t part of the jQuery chain, use the jQuery function syntax:

$.fn.setColor = function(color) {
 this.css("color", color);
 };

Once you have created your plug-in code, package it in a separate file; to use the code, all someone has to do is create a script reference to include the plugin source following the jQuery script.

JAVA SCRIPT - Serving Code from a CDN

Serving Code from a CDN


Problem

You’ve created a module or library and want to make it available for others to use. You’re providing it for download, but you also want to provide a link to the code allowing people to directly link it—a concept known as hotlinking. However, you don’t want to host the source on your own server because you’re concerned about up-time, availability, and performance. 

Solution

Use a content delivery network (CDN)—sometimes referred to as a content distribution network—to host your module/library. In addition, encourage developers to link to the module/library using a protocol-less URL or protocol-relative URL, in order to prevent unnecessary browser or user agent warnings:

//somedomain.com/somescript.js


EXPLAIN

The first time you access a web page or application that incorporates a JavaScript file, the browser or other user agent typically caches the results. The browser pulls up the cached library the next time you access the file, making the access that much faster. 

The ability to take advantage of browser caching is just one of the reasons why hosting popular JavaScript libraries on a CDN makes sense. Others are ensuring access even if your server goes down (or goes away), as well as preventing an unnecessary burden on your own server. 

After all, when you provide a link to a JavaScript file to download, people will link the script directly (as the jQuery folks discovered). There are various CDNs, and which one you use is dependent on cost, availability, and company preference. 

Google provides CDN service for popular script libraries, but hosting libraries is by invitation only. jQuery uses MaxCDN, but it is a commercial service. In fact, most CDNs are commercial, with only a few, such as cdnjs, providing a free service.

Once you do decide on a CDN, when you provide links for developers, you’ll also want to encourage the use of protocol-less or a protocol-relative URL:

//somedomain.com/library.js

This is because the browser or user agent will use the same protocol used to access the web page with all the protocol-less links, which means the resource is accessed with a compatible protocol. If you’ve ever accessed a script or file with “http://” in a web page that you’ve accessed with, “https://”, then you’re familiar with the annoying warning you can get in a browser such as Internet Explorer.

JAVA SCRIPT - Hosting Your Library

Hosting Your Library


Problem

You want to open source your code, but you don’t want to have to maintain the libraries on your own server.

Solution

Use one of the source code sites to host your code, and provide the tools to manage collaboration with other developers.

EXPLAIN 

One of the beautiful things about JavaScript is that many of the libraries and applications are open source, which means that not only are they typically free to use, but you can also adapt the library with your innovations, or even collaborate on the original. I strongly encourage open sourcing your libraries as much as possible. 

However, unless you have the resources to mount a public-facing source code control system, you’ll want to use one of the sites that provide support for open source applications. One source code host is Google Code, which contains a simple user interface to start a new project and upload code. You can choose between two version control software systems (Subversion and Mercurial), as well as one of a host of open source licenses. 

There is a wiki component to each project where you can provide documentation, as well as a way to provide updates for those interested in the project. The site also provides issue-tracking software for people to file bugs in addition to a download link and a separate link for source code. 

The SVG-enabling software SVGWeb is hosted in Google Code.shows the front page for the project and the links to all of the secondary support pages, including the Wiki, Downloads, Issues, Source, and so on.

There is no charge for hosting an application on Google Code. Another very popular host for open source projects is GitHub. Unlike Google Code, there are limits to what is supported for a free account on the service, but JavaScript libraries should not tax these limits. You shouldn’t incur any costs, as long as your projects are open source and publicly available. 

However, there is a fee if you want to use the service for a private collaboration with several others. As with Google Code, GitHub supports source code control and collaboration from several people, including records of issues, downloads, a wiki support page, and a nice graphs page that provides graphics of language support, usage, and other interesting indicators. 

The very popular jQuery library is hosted on GitHub, though you can download jQuery from its own domain. Node and most Node modules are also hosted by GitHub. 

GitHub is based on Git, an open source, source code control system. You typically install Git locally and manage your project in GitHub via Git. There are Git client applications for Linux, Windows, and Mac OS X.

Git is usually accessed via the command line. When setting it up, the first thing you’ll do is introduce yourself to it—providing a name that is used to label all commits:

git config --global user.name "name"

Next, you’ll need to sign up for a GitHub account, providing an email you’ll use with Git to connect your local environment with the hub:

git config --global user.email "email address"

At this point, you can do a variety of tasks, including setting up a repository, as well as participating in other GitHub-hosted projects

JAVA SCRIPT - Minify Your Library

Minify Your Library


Problem

You want to compactly package your code for wider distribution. 

Solution

After you’ve optimized your library code and tested it thoroughly through unit testing, compress it with a JavaScript optimizer.

EXPLAIN

Once you’ve created your library, optimized it for efficiency, and run it through your unit testing, you’re ready to prep your code for production use. One preparation is to compress the JavaScript as much as possible, so the file is small and loads quickly. 

JavaScript compression is handled through minify applications you can find online, such as the well-known and interestingly named UglifyJS. Why Uglify? Because when you compress your JavaScript, it becomes an incomprehensible jumble of densely packed characters. 

To use Uglify, you can either cut and paste your JavaScript into the UglifyJS website page, provide the URL for your JavaScript library, or use the command-line tool. 

The result of running the tool is a mess, like the following:
function timerEvent(){4==xmlhttp.readyState&&populateList(),timer=
setTimeout(timerEvent,3e3)}function populateList(){var a=
"http://burningbird.net/text.txt";xmlhttp.open("GET",a,!0),
xmlhttp.onreadystatechange=processResponse,xmlhttp.send(null)}
function processResponse(){if(4==xmlhttp.readyState&&200==xmlhttp.status)
{var a=document.createElement("li"),
b=document.createTextNode(xmlhttp.responseText);
a.appendChild(b);var c=document.getElementById("update");c.appendChild(a),
c.childNodes.length>10&&c.removeChild(c.firstChild)}else 4==
xmlhttp.readyState&&200!=xmlhttp.status&&console.log(xmlhttp.responseText)}
var xmlhttp=new XMLHttpRequest,timer;window.onload=function()
{populateList(),timerEvent()};


The purpose of a minification tool is to compress the text so it requires less bandwidth and loads faster. Some would say the lack of readability is a perk.

JAVA SCRIPT - Utilizing the Utility Library Underscore

Utilizing the Utility Library Underscore


Problem

You want a simple-to-use, basic utility library that can be used with your applications or in combination with other more complex frameworks like jQuery

Solution

Use the increasingly ubiquitous Underscore.js library. It can be downloaded, installed using npm or Bower, or accessed via CDN:
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore.js">
</script>

I demonstrated memoization with a Fibonacci. With Underscore.js, my job is greatly simplified


var fibonacci = _.memoize(function(n) {
 return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2);
});
console.log(fibonacci(10)); // 55

EXPLAIN

Underscore.js provides various functions categorized as: 

• Collections 
• Arrays 
• Functions 
• Objects 
• Utility 
• Chaining 

Underscore.js enhances existing JavaScript capability, but does so without extending the prototype object, which could make the library incompatible with other libraries or your own application. The utility’s functionality is accessible via the underscore (_) character, hence the name. However, if you use it with another library that also uses the underscore, you can remove the conflict: 


var underscore = _.noConflict();

The solution demonstrated the _.memoize() functionality. The following code dem‐ onstrates just a sampling of some of the other functionality:

// flatten a multidimensional array
var ary = _.flatten([1, ['apple'], [3, [['peach']]]]);
console.log(ary); // [1, "apple", 3, "peach"]
// filter an object based on an array of blacklisted keys
var fltobj = _.omit({name: 'moe', age: 50, userid: 'moe1'}, 'userid');
console.log(fltobj); // [object Object] { age: 50, name: "moe'}
// escape a string for insertion into HTML
var str = _.escape("
This & that and 'the other'
"); console.log(str); // "<div>This & that and 'the other'</div>"

JAVA SCRIPT - Handling Keyboard Shortcuts with Mousetrap

Handling Keyboard Shortcuts with Mousetrap


Problem

You need to provide support for keyboard shortcuts, but coding for these is exceedingly tedious.

Solution

Use a standalone library, such as Keypress, or a jQuery plugin, like jQuery.hotkeys. Keypress is very simple to use. Just drop in the library, and set up the shortcuts or key combinations you want to capture. You can capture simple combos, or more complex sequences:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Keypress</title>
<script src="keypress.js"></script>
</head>
<body>
 <div id="message">Press shift-r or press a b c </div>
<script>
 var message = document.getElementByIdundefined"message");
 var listener = new window.keypress.Listenerundefined);
 listener.simple_comboundefined"shift r", functionundefined) {
 message.innerHTML = "Pressed shift r";
 });
 listener.sequence_comboundefined"a b c", functionundefined) {
 message.innerHTML = "you know your ABCs";
 });
</script>
</body>
</html>
If you’re using jQuery, then you can use the jQuery.hotkeys plugin as follows:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery hotkeys</title>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="jquery.hotkeys.js"></script>
<script type="text/javascript">
$undefineddocument).readyundefinedfunctionundefined) {
 $undefineddocument).onundefined'keydown',null,'shift+r', functionundefined) {
 $undefined'#message').htmlundefined'you pressed shift r');
 });
 $undefineddocument).bindundefined'keydown', 'ctrl+a', functionundefined) {
 $undefined'#message').htmlundefined'Pressed ctrl+a');
 });
});
</script>
</head>
<body>
<div id="message"></div>
</body>
</html>

EXPLAIN

Capturing keystrokes and shortcut combinations isn’t a complex task, but it is tedious, which makes it ideal for a library. Two popular libraries for keyboard shortcut and key tracking are Mousetrap and the one demonstrated in the solution, Keypress. 

I went with Keypress because it looks to be more actively maintained than Mousetrap—an important consideration when picking a library. In addition, Keypress supports more sophisticated keyboard actions I found to be useful. Keypress is very easy to use, as the solution demonstrated. 

There are three simple meth‐ ods to use: 
• simple_combo: For the typical two-key shortcut, such as Ctrl+a 
• counting_combo: Takes two arguments, the key sequence, and a counter 
• sequence_combo: Takes a sequence of keys The counting_combo() function is a handy bit of code. 


It takes a two-key combination, such as Tab+space, or Ctrl+a. As long as you continue holding down the first key, the counter increases for key press on the second key. It makes a great way to cycle through tabs, or highlight paragraphs in a row, or whatever action cycling through a collection.

Any key combination can be a modifier in Keypress. Typically, modifiers would be combinations like Alt+q, Ctrl+a, or Shift+r. The combinations begin with one of the three: 

• Ctrl 
• Shift 
• Tab 

Keypress basically allows you to define your shortcut to be whatever you want it to be, which is extensible, but use such freedom with caution: we’re creatures of habit, and we like our shortcuts to be familiar. 

If you need something even more complicated, there’s register_combo() that takes an object specifying any number of properties associated with the key action. In the fol‐ lowing code, register_combo() specifies both key up and key down functions, as well as setting the is_unordered to true. This property allows me to type Alt+m and m+Alt, equally: 


listener.register_combo( {
 "keys": "alt m",
 "on_keydown": function() {
 message.innerHTML = "alt m down";
 },
 "on_keyup": function() {
 message.innerHTML = "alt m up";
 },
 "is_unordered": true
 });
}

There are several other properties you can set, detailed in the library’s documentation. Lastly, if you want to register several shortcuts at one time, use register_many():

var scope = this;
var many = listener.register_many([
 {
 "keys": "alt b",
 "on_keydown": function() {
 message.innerHTML = "alt b";
 },
 "this": scope
 },
 {
 "keys": "alt c",
 "on_keydown": function() {
 message.innerHTML = "alt c";
 },
 "this": scope
 }]);

The scope of the object is specifically set to the window via the this property. You can also unregister any key combination with:

• unregister_combo(shift r)
• unregister_many(name of variable)
• reset: Resets all combinations

There are also opportunities to pause the keyboard capturing when the cursor is in an input field or in other circumstances. Keypress works equally on its own or in combi‐ nation with JQuery. If you prefer to use a jQuery plugin, though, then jQuery.hotkeys is probably for you, as demonstrated in the solution.

Note, though, that its functionality is limited compared to Keypress. However, if you’re only interested in creating traditional shortcuts, then the plugin fits your needs. To use, simply map the key combination using jQuery’s on()/off() syntax, or you can use the plugins own bind()/unbind() methods.

JAVA SCRIPT - Using a jQuery Plugin

Using a jQuery Plugin


Problem

You’ve made use of jQuery in all of your applications, but it doesn’t support some func‐ tionality you need, such as sliding an element in from the side of the web page, or providing a color animation.

Solution

Use a jQuery UI plugin to provide the additional functionality. I’m using the jQuery UI Toggle plugin to show and hide a block of text based on a button clicked event. The effect I’m using is fold, which creates a nice paper fold effect as the content is shown. I’m also starting with the block hidden with the style setting on the element, with a value of display: none

Showing and hiding a block of text using a jQuery UI effect


<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery fold demo</title>
<link rel="stylesheet"
 href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<style>
#extra {
 width: 600px;
 height: 200px;
 background-color: floralwhite;
 padding: 10px;
 margin-bottom: 20px;
}
</style>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
</head>
<body>
<div id="extra" style="display: none">Lorem ipsum dolor sit amet, consectetur ad
ipiscing elit. Integer in erat semper, condimentum erat nec, porttitor ipsum. Ma
uris id erat luctus, finibus quam a, luctus est. Morbi id metus magna. Sed inter
dum vel arcu sed accumsan. Etiam quis ultrices elit. Maecenas efficitur in orci a efficitur. Duis id elit commodo, malesuada lorem nec, aliquet lacus. Praesent
sit amet laoreet eros, eu pulvinar libero. Sed vel dolor ac orci congue vulputat
e. Donec pulvinar risus magna, non feugiat sem aliquet eget. Nullam viverra vive
rra nunc et rutrum. Sed sed tellus a lorem porta vestibulum vel ac lacus. Suspen
disse potenti. Curabitur ac tristique lorem, sed ullamcorper odio. Mauris at acc
umsan lacus. Pellentesque at faucibus neque, nec aliquet mauris.</div>
<button id="choice">Show additional info</button>
<script>
$("#choice").click(function() {
 $( "#extra" ).toggle( "fold" , {horizFirst: true});
});
</script>
</body>
</html>

EXPLAIN

jQuery is a slim library providing core functionality that allows us to manipulate the DOM simply and easily. To keep it slim, any additional functionality is added via plugins, each of which are created to work within the jQuery infrastructure. 

The jQuery UI is a set of plugins and is probably one of the better known jQuery ex‐ tensions. As the name implies, we can use it to create a nice variety of visual effects to add some liveliness to the page—and without having to spend days coding the effect. 

In the solution, the code links to a stylesheet, as well as two JavaScript libraries: the primary jQuery library, and the jQuery UI. The stylesheet ensures that the effects meet our expectations, as the jQuery UI plugins are all involved with appearance.

Why Not Just Use HTML5 and CSS3 for Managing Visual Effects?

Some of the functionality in jQuery and the plugins is now implemented declaratively in HTML5 and CSS3. Declarative functionality is the ability to specify what we want, and it just happens. Instead of having to code a transition, we declare it in CSS and trust that the browser handles the transition properly. The following CSS modifies the extra div element. 

Now, when the mouse cursor is over the element, it shrinks until disappearing completely. Move the mouse cursor out, and it transitions back to its full size:


#message {
 width: 600px;
 height: 200px;
 background-color: floralwhite;
 padding: 10px;
 margin-bottom: 20px;
 -webkit-transition:width 2s, height 2s, background-color 2s,
 -webkit-transform 2s;
 transition:width 2s, height 2s, transform 2s;
}
#message:hover {
 -webkit-transform:scaleundefined0);
 transform:scaleundefined0);
}

The advantage to this approach is it works even if JavaScript is turned off. And the browser developers can optimize the transition effect—increasing both the efficiency and the overall appearance of the effect. It seems like a win-win. The limitation to using CSS3/HTML5 is trying to trigger the effect based on the button’s click event. In addition, you don’t have complete control over appearance or effect.

This is particularly true with HTML5 elements. If you’re using the new HTML5 input elements, such as date, the browser creates the appropriate container, but you’ll find that the container’s appearance can differ dra‐ matically from browser to browser. Firefox just provides a field, while Opera pops up a calendar picker when you click in the field.

The color input pops up the system color picker in Firefox and Chrome, but an odd drop-down color picker in Opera. If it’s important for appearance and behavior to be consistent across all agents and in all environments, depending on the declarative power of HTML5 and CSS3 is probably not going to be the best option.

They can be a useful addition, but not a complete replacement.

Plugin? Or Plug-in?

I use both “plug-in” and “plugin” in the book. The proper word usage is plug-in, hy‐ phenated, but as you’ll notice, many communities (e.g., the jQuery community) use plugin without hyphenation. Eventually, I expect plugin without the hyphenation to become the standard. 

Ultimately, though, we all know what we’re talking about, so use whatever is comfortable for you, or whatever maps to what the community uses.