JavaScript CookbookSample solutions to common JavaScript problems.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/Raymond Camdenraymondcamden@gmail.comCreate a random nonce string using JavaScript2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Check-a-random-nonce-string-using-JavaScript/<p>Have you ever needed to come up with a random string of characters say for a password? Maybe you're looking for a random string of characters for an oauth 1.0 nonce. The function below gives an example of how to do this.</p>
<p>
We first define a string of all the allowed characters in our final randomized string. We then loop until a given length which will represent the string size. In this loop we will look at the allowed character string as a kind of array (character by character) and randomly choose an index of the array.
<pre><code class="language-javascript">var randomString = function(length) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for(var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}</code></pre>
</p>Check if a value is an array2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Check-if-a-value-is-an-array/<p>The simplest way to check if an object is an array (using ECMAScript 5 and higher) is the Array.isArray method.</p>
<pre><code class="language-javascript">var x = [1,2,3];
var y = "something else entirely";
console.log(Array.isArray(x)); // returns true
console.log(Array.isArray(y)); // returns false
</code></pre>
Check if a value is an integer2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Check-if-a-value-is-an-integer/<p>There are a few different ways you can determine if a value is an integer in JavaScript. ECMAScript6 provides a direct <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isinteger">isInteger</a> method, but for current browsers you can apply a few different methods. The simplest is to compare the result of Math.round to the original value. Using triple equality checking also handles non-numbers as well.</p>
<pre><code class="language-javascript">function isInteger(x) {
return Math.round(x) === x;
}</code></pre>
Work with Query String Data2020-08-11T13:23:22.744-00:00https://www.javascriptcookbook.com/article/Work-with-Query-String-Data/<p>The query string (everything after the question mark in the URL) can be parsed with a few simple string functions. The code below automatically parses the query string and stores it in a variable called query. Given a URL of the form kittens.html?x=1&y=2, the query object will contain an X and Y property with the proper values.</p>
<pre><code class="language-javascript">var query = (function() {
function decode(string) {
return decodeURIComponent(string.replace(/\+/g, " "));
}
var result = {};
if (location.search) {
location.search.substring(1).split('&').forEach(function(pair) {
pair = pair.split('=');
result[decode(pair[0])] = decode(pair[1]);
});
}
return result;
})();
</code></pre>
Use chained method calls2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Use-chained-method-calls/<p>Libraries like jQuery support chained method calls. This allows you to run multiple different operations at once. For example:
<p/>
$("someSelector").addClass("cool").appendTo("somethingElse");
<p/>
In order to support this your methods need to perform their particular action but then return it's own API again to the caller. In the example below, the Cyclone object supports methods spin, to, with, and start. Notice how spin, to, and with return pointers to the API such that you can chain them as you see it.</p>
<pre><code class="language-javascript">var Cyclone = function (name) {
this.name = name;
};
Cyclone.prototype.spin = function () {
var cycloneOptions = {};
var start = function () {
this.move(cycloneOptions);
}.bind(this);
var withStuff = function (debris) {
cycloneOptions.debris = debris;
return {
start: start
}
};
var to = function (location) {
cycloneOptions.location = location;
return {
start: start,
withStuff: withStuff
}
};
return {
to: to
}
};
Cyclone.prototype.move = function (options) {
// Move the cyclone with the given options
};
var marmaduke = new Cyclone('Marmaduke');
marmaduke.spin().to('Japan').start(); // A standard typhoon
var nigel = new Cyclone('Nigel');
nigel.spin().to('Japan').withStuff('Haddock').start(); // A typhoon loaded with dead fish</code></pre>
Get the current URL via JavaScript2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Get-the-current-URL-via-JavaScript/<p>There's actually two different ways to get the current URL. Both document.URL and document.location.href return the URL. However, if you wish to actually change the document's location, only document.location.href. If you only need to read the value, then document.URL is fine.</p>
<p>Note that if you wish to work with the various parts of the current location, inspect document.location. It has properties for things like the port, protocol, etc.</p>
<pre><code class="language-javascript">var ourLocation = document.URL;
console.log("Currently at " + ourLocation);</code></pre>
Restrict a number to a range.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Restrict-a-number-to-a-range/<p>Given that you need to restrict a number to a lower and upper bound, the function below will handle it by using a combination of Math.min and Math.max.</p>
<p>_number is the number you want to restrict.
_min is the minimal value.
_max is the maximum value.</p>
<p>If the _number is less than _min, the function returns the _min value. If the _number is greater than _max, the function returns _max value.</p>
<pre><code class="language-javascript">function bound(_number, _min, _max){
return Math.max(Math.min(_number, _max), _min);
}</code></pre>
Perform date manipulations based on adding or subtracting time2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Perform-date-manipulations-based-on-adding-or-subtracting-time/<p>A common programming challenge is to perform simple date "math" on a value. So for example, given that you have a certain date, what date will it be three hours from then? Or - if today is the 27th, what month will it be in two days? There are many ways of doing this (and many libraries available with their own implementation), but one simple way is just combine a get and set call. So for example, adding three hours to a JavaScript date can be done by using setHours after running getHours. In the code below, I've demonstrated multiple different versions of this in action.</p>
<pre><code class="language-javascript">//First, start with a particular time
var date = new Date();
//Add two hours
date.setHours(date.getHours() + 2);
//Go back 3 days
date.setDate(date.getDate() - 3);
//One minute ago...
date.setMinutes(date.getMinutes() - 1);</code></pre>
Create a clone of an object.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Create-a-clone-of-an-object/<p>While there are various ways to clone an object, this one is extremely consistent and also performs well on jsperf tests. However, please note that this technique with "plain objects" (ones that inherit directly from Object.prototype). See the comments for further discussion.</p>
<pre><code class="language-javascript">function clone(obj) {
return JSON.parse(JSON.stringify(obj));
}</code></pre>Generate an epoch.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Generate-an-epoch/<p>Javascript's Date Object always works in milliseconds, but most date/time code works on unix epochs. This is just a quickie one-off function designed to give you an epoch to work with.</p>
<pre><code class="language-javascript">function timestamp() {
return Math.round(Date.now() / 1000);
}</code></pre>
Map a NodeList to an array of properties.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Map-a-NodeList-to-an-array-of-properties/<p>The NodeList type does not implement the useful bits of the Array interface. This code essentially recreates the list into a regular array.</p>
<pre><code class="language-javascript">var nodes = document.querySelectorAll('a');
var urls = [].map.call(nodes, function(node) {
return node.href;
});
</code></pre>
Combining Library and Worker code in one script.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Combining-Library-and-Worker-code-in-one-script/<p>Worker location is determined relative to the html page not to the script that calls them. So if you need to call a worker from a script that might be called as <script src="script.js"> on one page and <script src="js/script.js"> on another this pattern lets you avoid using absolute URLs.</p>
<pre><code class="language-javascript">
if (typeof document === "undefined") {(function(self){
/*
worker stuff
*/
})(self)} else {(function(exports){
"use strict";
function getPath(){
var scripts = document.getElementsByTagName("script");
var len = scripts.length;
var i = 0;
while(i<len){ *="" change="" --------=""> */if(/scriptWithWorker(\.min)?\.js/.test(scripts[i].src)){
return scripts[i].src;
}
i++;
}
}
var worker = new Worker(getPath());
/*
non-worker code
*/
})(window)};
</len){></code></pre>Traversing DOM (sub)trees with a recursive "walk the DOM" function.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Traversing-DOM-subtrees-with-a-recursive-walk-the-DOM-function/<p>This function traverses a DOM (sub)tree and executes a given function on each Element and Text node it visits.</p>
<pre><code class="language-javascript">function walkTheDOM(node, func) {
func(node);
node = node.firstChild;
while (node) {
walkTheDOM(node, func);
node = node.nextSibling;
}
}
// Example usage: Process all Text nodes on the page
walkTheDOM(document.body, function (node) {
if (node.nodeType === 3) { // Is it a Text node?
var text = node.data.trim();
if (text.length > 0) { // Does it have non white-space text content?
// process text
}
}
});</code></pre>
Preserving variables inside async calls called in a loop.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Preserving-variables-inside-async-calls-called-in-a-loop/<p>f you want to run asynchronous functions inside a loop, but still want to keep the index or other variables after a callback gets executed you can wrap your code in an IIFE (immediately-invoked function expression).</p>
<pre><code class="language-javascript">var arr = ['Hello', 'World', 'Javascript', 'Async', ':)'];
for( var i = 0; i < arr.length; i++) {
(function(index){
setTimeout(function(){
console.log(arr[index]);
}, 500);
})(i);
}</code></pre>
Run code when the document has loaded.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Run-code-when-the-document-has-loaded/<p>Most popular JavaScript frameworks make it easy to run code when the document is loaded. But if you aren't using a framework, you can simply listen for the DOMContentLoaded event instead.</p>
<p>This event is fired when the document's HTML is loaded and parsed, but before any stylesheets or images may be loaded.</p>
<pre><code class="language-javascript">document.addEventListener("DOMContentLoaded", init, false);
function init() {
console.log("init");
}</code></pre>
Determine touch support and add handlers.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Determine-touch-support-and-add-handlers/<p>Determine if touch events are available and use a single line to add an event listener to handle mouse or touch in most cases.</p>
<pre><code class="language-javascript">touch = ( 'ontouchstart' in document.documentElement ) ? true : false;
// Quick ternary operation based on previous findings
element = document.querySelector( '#yourElement' );
element.addEventListener( touch ? 'touchstart' : 'mousedown', doInputStart );
// Get the coordinates based on input type
if( touch )
{
// Stop the default handling of the event
evt.preventDefault();
// Get the touch coordinates
clientX = evt.touches[0].clientX;
clientY = evt.touches[0].clientY;
} else {
// Not touch so grab mouse coordinates
clientX = evt.clientX;
clientY = evt.clientY;
}</code></pre>
Use jQuery-like Selectors without jQuery.2020-08-11T13:23:22.744-00:00https://www.javascriptcookbook.com/article/Use-jQuerylike-Selectors-without-jQuery/<p>If you wish to use jQuery-like selectors without having to actually load the jQuery framework, you can use this simple function to mimic selector behavior.</p>
<p>This function will returns false if nothing found, a DOM node if exactly one element is found and the list of matches otherwise.</p>
<pre><code class="language-javascript">function $( cssquery ) {
var t = document.querySelectorAll(cssquery);
return (t.length === 0) ? false : (t.length === 1) ? t[0] : t;
}</code></pre>
Return a random whole number in a range.2020-08-11T13:23:22.743-00:00https://www.javascriptcookbook.com/article/Return-a-random-whole-number-in-a-range/<p>This recipe will return a whole number between a lower and higher range. For a deeper discussion of this code, see this StackOverflow comment from Ionut Stan: http://stackoverflow.com/a/1527820/52160.</p>
<pre><code class="language-javascript">/**
* Returns a random integer between min and max
* Using Math.round() will give you a non-uniform distribution!
*/
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}</code></pre>