Created
May 29, 2016 19:39
-
-
Save shuding/c4630c40043080088315461250f4ed33 to your computer and use it in GitHub Desktop.
javascript js tips, tricks, snippets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// random numbergenerator between 0 and 1 | |
var randomNum = ((Math.random () * 2 | 0) + 1) - 1; | |
// jquery inline style w/ !important | |
$(el).css("cssText", "overflow: visible !important;"); | |
// random numbergenerator between 1 and 100 | |
Math.round((Math.random() * 99) + 1) | |
(+new Date() + Math.floor(Math.random()*999999)).toString(36) | |
// Convert arguments to Array | |
function myFn(/* any number of arguments */) { | |
var args = Array.prototype.slice.call(arguments); | |
// or [].slice.call(arguments) | |
args.forEach(function(arg) { | |
// do something with args here | |
}); | |
} | |
// Convert NodeList to Array | |
var nodesArray = Array.prototype.slice.call(document.querySelectorAll("div")); | |
// Verify that a given argument is an array | |
function isArray(obj){ return Object.prototype.toString.call(obj) === '[object Array]'; } | |
// indexof ie8 polyfill, sigh. | |
if(!Array.indexOf){Array.prototype.indexOf = function(obj){for(var i=0; i<this.length; i++){if(this[i]==obj){return i; } } return -1; } } | |
// object.create ES3 polyfill | |
if (typeof Object.create !== 'function') {Object.create = function (o) {function F() {} F.prototype = o; return new F(); }; } | |
// trim IE8 (es3 polyfill) | |
if(!String.prototype.trim) {String.prototype.trim = function () {return this.replace(/^\s+|\s+$/g,''); }; } | |
// module pattern | |
var MyThingy = (function() { | |
function doSomethingCool() { | |
... | |
} | |
function internalSomething() { | |
.... | |
} | |
function anotherNiftyThing() { | |
// Note that within the scoping function, functions can | |
// call each other direct. | |
doSomethingCool(); | |
internalSomething(); | |
} | |
return { | |
doSomethingCool: doSomethingCool, | |
anotherNiftyThing: anotherNiftyThing | |
}; | |
})(); | |
// module pattern example 2 | |
var MODULE = (function () { | |
var my = {}, | |
privateVariable = 1; | |
function privateMethod() { | |
// ... | |
} | |
my.moduleProperty = 1; | |
my.moduleMethod = function () { | |
// ... | |
}; | |
return my; | |
}()); | |
// another method to MODULE | |
var MODULE = (function (my) { | |
my.anotherMethod = function () { | |
// added method... | |
}; | |
return my; | |
}(MODULE)); | |
// decorator pattern | |
var Lamb = function(name){ | |
this.name = name; | |
} | |
var DecoratedLamb = function(name, light){ | |
Lamb.call(this, name) | |
this.light = light; | |
} | |
DecoratedLamb.prototype = Object.create(Lamb.prototype); | |
// dom manipulation | |
var frag = document.createDocumentFragment(); | |
var myDiv = document.createElement("div"); | |
var im = document.createElement("img"); | |
im.src = "im.gif"; | |
myDiv.id = "myDiv"; | |
myDiv.appendChild(im); | |
frag.appendChild(myDiv); | |
/* append */ document.body.appendChild(frag); | |
/* prepend */ document.body.insertBefore(frag, document.body.firstChild); | |
var textToBeReplaced = document.createTextNode("xxx"); | |
imageToBeChanged.parentNode.replaceChild(textToBeReplaced, imageToBeChanged); | |
// dom manipulation 2 (better?) | |
var p, t, frag; | |
frag = document.createDocumentFragment(); | |
p = document.createElement('p'); | |
t = document.createTextNode('first paragraph'); | |
p.appendChild(t); | |
frag.appendChild(p); | |
document.body.appendChild(frag); | |
// Math | |
// Get a random item from an array | |
var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119]; | |
var randomItem = items[Math.floor(Math.random() * items.length)]; | |
// Get a random number in a specific range | |
var x = Math.floor(Math.random() * (max - min + 1)) + min; | |
// Shuffle an array of numbers | |
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411]; | |
numbers = numbers.sort(function(){ return Math.random() - 0.5}); | |
// Verify that a given argument is a number | |
function isNumber(n){ return !isNaN(parseFloat(n)) && isFinite(n); } | |
// Get the max or the min in an array of numbers | |
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411]; | |
var maxInNumbers = Math.max.apply(Math, numbers); | |
var minInNumbers = Math.min.apply(Math, numbers); | |
var text="link to camasuvi"; | |
var url="http://www.camasuvi.net"; | |
text.link(url) // outputs: <a href="http://www.camasuvi.net">link to camasuvi</a> | |
// return color hex code | |
'#'+(~~(Math.random()*(1<<24))).toString(16); | |
// veya | |
'#'+Math.floor(Math.random()*16777215).toString(16); | |
// preferred v2, timeout instead of interval - no unnecessary ticks | |
// window-scroll-event | |
var scrollTimeout; // global for any pending scrollTimeout | |
var outerPane = $details.find(".details-pane-outer"); | |
$(window).scroll(function () { | |
if (scrollTimeout) { | |
// clear the timeout, if one is pending | |
clearTimeout(scrollTimeout); | |
scrollTimeout = null; | |
} | |
scrollTimeout = setTimeout(scrollHandler, 250); | |
}); | |
scrollHandler = function () { | |
// Check your page position and then | |
// Load in more results | |
// outerPane.html(); | |
}; | |
/* Title: Mix-ins | |
Description: copy from any number of objects and mix them all into a new object */ | |
function mix() { | |
var arg, prop, l, child = {}; | |
for (arg = 0, l = arguments.length; arg < l; arg += 1) { | |
for (prop in arguments[arg]) { | |
if (arguments[arg].hasOwnProperty(prop)) { | |
child[prop] = arguments[arg][prop]; | |
} | |
} | |
} | |
return child; | |
} | |
var cake = mix( | |
{eggs:2, large:true}, | |
{butter:1, salted:true} | |
} | |
// prototypal inheritance | |
function LifelikeWorld(map, legend) { | |
World.call(this, map, legend); | |
} | |
LifelikeWorld.prototype = Object.create(World.prototype); | |
LifelikeWorld.prototype.methodXXX = function(){} | |
// sort numbers in arr | |
function compareCanonically(a, b) { | |
return a < b ? -1 (a > b ? 1 : 0); | |
} | |
[-1, -20, 7, 50].sort(compareCanonically) --> [ -20, -1, 7, 50 ] | |
// common gotchas | |
typeof null --> "object" | |
NaN === NaN --> false | |
'abc' && 'def' --> 'def' | |
'abc' || 'def' --> 'abc' | |
parseInt(0.0000008, 10) --> 8 (String(0.0000008) --> '8e-7') | |
{}.hasOwnProperty.call(obj, 'foo') | |
Array.isArray(arr) | |
Retrieve global object for ES3 or ES5 (window) --> (function(){ return this || (1,eval)('this') })() | |
// credits to davidwalsh blog | |
// debounce for scroll resize listen | |
function debounce(func, wait, immediate) { | |
var timeout; | |
return function() { | |
var context = this, args = arguments; | |
var later = function() { | |
timeout = null; | |
if (!immediate) func.apply(context, args); | |
}; | |
var callNow = immediate && !timeout; | |
clearTimeout(timeout); | |
timeout = setTimeout(later, wait); | |
if (callNow) func.apply(context, args); | |
}; | |
}; | |
// debounce usage | |
var myEfficientFn = debounce(function() { | |
// All the taxing stuff you do | |
}, 250); | |
window.addEventListener('resize', myEfficientFn); | |
// credits to davidwalsh blog | |
// polling for long waited operations | |
function poll(fn, callback, errback, timeout, interval) { | |
var endTime = Number(new Date()) + (timeout || 2000); | |
interval = interval || 100; | |
(function p() { | |
// If the condition is met, we're done! | |
if(fn()) { | |
callback(); | |
} | |
// If the condition isn't met but the timeout hasn't elapsed, go again | |
else if (Number(new Date()) < endTime) { | |
setTimeout(p, interval); | |
} | |
// Didn't match and too much time, reject! | |
else { | |
errback(new Error('timed out for ' + fn + ': ' + arguments)); | |
} | |
})(); | |
} | |
// poll Usage: ensure element is visible | |
poll( | |
function() { | |
return document.getElementById('lightbox').offsetWidth > 0; | |
}, | |
function() { | |
// Done, success callback | |
}, | |
function() { | |
// Error, failure callback | |
} | |
); | |
// credits to davidwalsh blog | |
// once helper func to ensure a given function can only be called once | |
function once(fn, context) { | |
var result; | |
return function() { | |
if(fn) { | |
result = fn.apply(context || this, arguments); | |
fn = null; | |
} | |
return result; | |
}; | |
} | |
// once Usage | |
var canOnlyFireOnce = once(function() { | |
console.log('Fired!'); | |
}); | |
canOnlyFireOnce(); // "Fired!" | |
canOnlyFireOnce(); // nada | |
// extend | |
// changes made to child, does affect parent | |
function extend(parent, child) { | |
var i; | |
child = child || {}; | |
for (i in parent) { | |
if (parent.hasOwnProperty(i)) { | |
child[i] = parent[i]; | |
} | |
} | |
return child; | |
} | |
// extending opts | |
function Alert(parent, message, opts) { | |
opts = extend({ | |
width: 320, | |
height: 240 | |
}); | |
opts = extend({ | |
x: (parent.width / 2) - (opts.width / 2), | |
y: (parent.height / 2) - (opts.height / 2), | |
title: "Alert", | |
titleColor: "gray", | |
bgColor: "white", | |
textColor: "black", | |
icon: "info", | |
modal: false | |
}, opts); | |
extend(this, opts); | |
} | |
// deep extend | |
// changes made to child, does NOT affect parent | |
function extendDeep(parent, child) { | |
var i, | |
toStr = Object.prototype.toString, | |
astr = "[object Array]"; | |
child = child || {}; | |
for (i in parent) { | |
if (parent.hasOwnProperty(i)) { | |
if (typeof parent[i] === "object") { | |
child[i] = (toStr.call(parent[i]) === astr) ? [] : {}; | |
extendDeep(parent[i], child[i]); | |
} else { | |
child[i] = parent[i]; | |
} | |
} | |
} | |
return child; | |
} | |
// dom clone work | |
var oldnode = document.getElementById('result'), | |
clone = oldnode.cloneNode(true); | |
// work with the clone... | |
// when you're done: | |
oldnode.parentNode.replaceChild(clone, oldnode); | |
/* Functions can be invoked in various ways, and the invocation mechanism determines | |
the function context value: | |
– When invoked as a simple function, the context is the global object (window). | |
– When invoked as a method, the context is the object owning the method. | |
– When invoked as a constructor, the context is a newly allocated object. | |
– When invoked via the apply() or call() methods of the function, the context | |
can be whatever the heck we want. */ | |
// Storing a collection of unique functions | |
var store = { | |
nextId: 1, | |
cache: {}, | |
add: function(fn) { | |
if (!fn.id) { | |
fn.id = store.nextId++; | |
return !!(store.cache[fn.id] = fn); | |
} | |
} | |
}; | |
function ninja(){}; | |
store.add(ninja); | |
// memoizing dom | |
function getElements(name) { | |
if (!getElements.cache) getElements.cache = {}; | |
return getElements.cache[name] = getElements.cache[name] || document.getElementsByTagName(name); | |
} | |
// credits: Secrets of the JavaScript Ninja by John Resig | |
// method overloading function | |
function addMethod(object, name, fn) { | |
var old = object[name]; | |
object[name] = function(){ | |
if (fn.length == arguments.length) { | |
return fn.apply(this, arguments) | |
} else if (typeof old == 'function') { | |
return old.apply(this, arguments); | |
} | |
}; | |
} | |
var ninja = {}; | |
addMethod(ninja,'whatever',function(){ /* do something */ }); | |
addMethod(ninja,'whatever',function(a){ /* do something else */ }); | |
addMethod(ninja,'whatever',function(a,b){ /* yet something else */ }); | |
// angular $index like | |
$first, $middle, $last, $even, and $odd | |
// angular debug helpers | |
$($0) || angular.element($0) | |
$($0).scope() | |
$($0).scope().$parent | |
$($0).isolateScope() //for directive scopes | |
// run $($0).scope().isFoo = true to set isFoo | |
// run $($0).scope().$digest() | |
// credits to http://eng.localytics.com/tips-and-tricks-for-debugging-unfamiliar-angularjs-code/ | |
/** | |
* copied from lodash | |
* | |
* @private | |
* @param {Object} source The object to copy properties from. | |
* @param {Array} props The property names to copy. | |
* @param {Object} [object={}] The object to copy properties to. | |
* @param {Function} [customizer] The function to customize copied values. | |
* @returns {Object} Returns `object`. | |
*/ | |
function copyObjectWith(source, props, object, customizer) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment