Various useful js JavaScript snippets I use often - Credit = bryc.github.io
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
// #### ARRAY <-> STRING CONVERSION #### | |
// b62 - reversible base62 encoder/decoder in two lines. | |
function b62(n,c="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"){var r="",l=c.length,i=0; | |
if(n.trim)while(i<n.length)r=l*r+c.indexOf(n[i++]);else while(n>0)r=c[n%l]+r,n=Math.floor(n/l);return r} | |
// arst is a reversible string<>array utility in one line. It converts a string to an array of integers and back. | |
// ES6 (shorter) | |
arst=a=>{return a.trim?[...a].map(a=>a.charCodeAt()):String.fromCharCode.apply(0,a)} | |
// ES5 (IE11 compatibility) | |
function arst(a){return a.trim?Array.apply(0,Array(a.length)).map(function(x,i){return a[i].charCodeAt()}):String.fromCharCode.apply(0,a)} | |
// arrstr is a reversible string<>array utility in one line. It additionally supports start and end offset. | |
// also works in IE. | |
function arrstr(a,s,e){return a.trim?(a=a.slice(s||0,e||a.length))&&Array.apply(0,Array(a.length)).map(function(x,i){return a[i].charCodeAt()}):String.fromCharCode.apply(0,a[a instanceof Array?"slice":"subarray"](s||0,e||a.length))} | |
// #### INIT ARRAY #### | |
// init array with incremental bytes (supporting range) | |
Array(32 + 1).fill().map((e,i)=>(i + 0)) | |
// init array with random bytes | |
new Uint8Array(32).map(()=>Math.floor(Math.random()*256)) | |
// #### DISPLAY BYTES AS HEX #### | |
// ES6 version | |
arrhex=a=>{return[].map.call(a,x=>x.toString(16).padStart(2,0)).join(" ").toUpperCase()} | |
// IE11 compatibility version | |
function arrhex(arr){for(var i=0,s="";i<arr.length;i++)s+=("0"+(arr[i]&0xFF).toString(16)).slice(-2);return s;} | |
// #### PADDING FUNTIONS #### ...gotta clean this up | |
pad=(i,x=2)=>{return i.toString(16).padStart(x,0).toUpperCase()} | |
pad=(i,x=3,y=0)=>{return`${i}`.padStart(x,y)} | |
function pad(a,b,c){return(new Array(b||2).join(c||0)+a).slice(-(b||2))} | |
function pad(s,w=3,z=' '){return(""+s).padStart(w,z)} | |
function padhex(s,w=8,z=0){return s.toString(16).toUpperCase().padStart(w,z)} | |
var padleft = (s,c,len) => { while(s.length < len) s = c + s; return s; } | |
function pad(pad, str, padLeft) { | |
if (typeof str === 'undefined') | |
return pad; | |
if (padLeft) { | |
return (pad + str).slice(-pad.length); | |
} else { | |
return (str + pad).substring(0, pad.length); | |
} | |
} | |
var leftPad = (s, c, n) => c.repeat(n - s.length) + s; | |
function l(p,t,v){v+="";return v.length>=t?v:l(p,t,p+v)} | |
function pad(a,b){return((""+a).length<b)?pad("0"+a,b):a;} | |
// Old ES6 pad function - Instead of constantly rewriting a pad function, use this: | |
function pad(n, width=2, z=0){return(String(z).repeat(width)+String(n)).slice(String(n).length)} | |
// old version of arrstr(): array of bytes to a string, using offsets | |
function arrstr(arr, start, end) { | |
arr = arr || []; | |
start = start || 0; | |
end = end || arr.length; | |
var m = arr.constructor === Array ? 'slice' : 'subarray'; | |
arr = arr[m](start, end); | |
return String.fromCharCode.apply(null, arr); | |
} | |
// possibly a very old version? | |
var arrstr = function(arr, start, end) { | |
arr = arr || []; | |
start = start || 0; | |
end = end || arr.length; | |
for(var str = "", i = start; i < end; i++) { | |
var p = arr[i]; | |
str += String.fromCharCode(p); | |
} | |
return str; | |
}; | |
// old and obsolete: string to array of bytes | |
function strarr(str) { | |
for(var i=0,arr=[];i<str.length;i++)arr[i]=str.charCodeAt(i)&0xFF; | |
return arr; | |
} | |
// use this to test distribution of function output (such as random) | |
for(var s = {}, i = 0; i < 99999; i++) { | |
var t = 0|Math.random()*256; | |
!s[t] && (s[t] = 0), s[t]++; | |
} console.log(s); | |
// String of HEX bytes to array of bytes | |
function hexToBytes(hex) { | |
hex = hex.replace(/ /g,''); | |
for (var bytes = [], c = 0; c < hex.length; c += 2) | |
bytes.push(parseInt(hex.substr(c, 2), 16)); | |
return bytes; | |
} | |
// bi-directional 32-bit integer to byte array (big-endian) | |
intbyt=(a=>a.map?a[0]<<24|a[1]<<16|a[2]<<8|a[3]:[a>>>24&255,a>>>16&255,a>>>8&255,a&255]); | |
// bi-directional 32-bit integer to byte array (little-endian) | |
intbyt=(a=>a.map?a[3]<<24|a[2]<<16|a[1]<<8|a[0]:[a>>>24&255,a>>>16&255,a>>>8&255,a&255]); | |
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
/* binary remap (bmap) | |
This is a binary-to-text encoder/decoder. It is for displaying binary data as text in as few characters as possible. | |
It works by remapping byte values with unreliable printed characters to offset 256 and onward (currently 74 of them, or 29%). | |
The idea is simple: "Replace non-printable characters with printable ones." | |
Binary data can already be represented as text. ASCII characters are defined by binary numbers after all. | |
However, there are control characters and white space characters which do not have any symbol attached. | |
My goal was to produce a string of text which represented some binary data, similar to base64. An important requirement | |
is that the string was in as few characters as possible. | |
To accomplish this, certain problematic characters which couldn't be copied/pasted had to be remapped. | |
First 0x00, the null byte. The presence of a null-byte will destroy the string's data integrity as it cannot be copied. | |
Second, 0x0A, 0x0D - Linefeed and Carriage return. These are "new line" characters which can be troublesome and often corrupt output. | |
Third, 0xA0: non-break space. This has been a problematic one, as well. | |
Other non-printable characters had varying levels of success, but ultimately, I had to remap a few ranges of ISO-8859-1: | |
0x00-0x20 (control characters and space character) | |
0x7F-0xA0 (DEL key to NBSP) | |
0xAD ("soft hyphen", invisible? hard to see) | |
0xB8 ("spacing cedilla", very small/hard to see) | |
0x3E (the > symbol. will cause problems in HTML) | |
0x3C (the < symbol. problems in HTML) | |
0x27 (the ' symbol. quotes can terminate strings) | |
0x36 (the " symbol. quotes can terminate strings) | |
0x22 (the & symbol. problems in HTML. invokes html entitie like   etc.) | |
With all 74 of these characters remapped, we have a UTF-8 safe string representing binary data. | |
While one character maps to one byte, many UTF-8 characters are encoded as two bytes per character, putting its | |
efficiency into question for some use cases. Base91 and even Base64 may be more efficient memory-wise, so this | |
method is only advised for smaller amounts of binary data that can be copied/pasted and sent over the | |
web in UTF-8, such as passwords in games. | |
I think this is a good basis for a more advanced UTF-8 encoding scheme. It may be possible to represent more than | |
256 binary values in a single UTF-8 character, resulting in a more memory-efficient (and shorter) string. But this would require | |
probably about 350+ lines of 'real' code for the algorithm to do this. | |
If memory efficiency is a concern, consider BasE91 or Z85. | |
*/ | |
function bmap(val, mode = 0) { | |
var i, data = mode ? [...val].map(a=>a.charCodeAt()) : val.slice(), | |
bad = [ | |
0x22, 0x26, 0x27, 0x3C, 0x3E, 0xB8, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, | |
0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, | |
0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, | |
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, | |
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xAD | |
]; | |
for(i = 0; i < val.length; i++) { | |
var idx = bad.indexOf(data[i]); | |
if(mode ? data[i]>255 : idx>-1) data[i] = mode ? bad[data[i]-0x100] : 0x100+idx; | |
} | |
return mode ? data : String.fromCharCode.apply(0,data); | |
} |
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
/* | |
Once upon a time, there was this: | |
var elem = document.createElement("input"); | |
elem.type = "checkbox"; | |
elem.onclick = test; | |
Needing to generate HTML throug JS, I was looking for a betterway than | |
above, and elem() is my simple solution for that. | |
Examples: | |
1. Document Fragment (useful for appending elements) | |
elem([]) | |
2. Simple element with innerText | |
elem(["div","Test"]) | |
3. Appending child element | |
elem(["ol"],elem(["li","Hi"])) | |
4. Assign properties to HTMLElement object | |
elem(["div",{className:"test"}]) | |
TODO: prevent elem("ab") from creating weird invalid <a> element | |
what about support for style.borderColor etc? or custom html attribute names? | |
or methods? any better shortcuts for most used stuff or some syntatic sugar? | |
*/ | |
function elem(options) { | |
var el = document.createDocumentFragment(); | |
var tag = options[0]; | |
var prop = options[1]; | |
if(typeof tag === "string") { | |
el = document.createElement(tag); | |
} | |
if(typeof prop === "object") { | |
for (var item in prop) { | |
el[item] = prop[item]; | |
} | |
} else if(prop) { | |
el.innerHTML = prop; | |
} | |
for(var i = 1; i < arguments.length; i++) { | |
if(arguments[i].nodeType > 0) { | |
el.appendChild(arguments[i]); | |
} | |
} | |
return el; | |
} |
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
/* | |
Handy way to replace a target element with another | |
*/ | |
function replace(target, replacement) { | |
while(target.firstChild) { | |
target.removeChild(target.firstChild); | |
} | |
target.appendChild(replacement); | |
} |
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
/* Event handler forwarder | |
------------------------------ | |
Allows you to include a variable number of arguments in event handlers. | |
For example: elements[i].onclick = evarg(doThis, i); | |
For example: elements[i].onclick = evarg(doThis, i, {"name": usr, "location": loc}); | |
Assuming it is done in a loop, this assigns an onclick event to each element. | |
Instead of simply assigning "doThis" as the onclick function, we specify | |
another argument i, which also assigns the value of the loop counter in sequence. | |
In the second argument, we specified another argument cosisting of an object. | |
function doThis(event, id, info) { | |
// id will be set to whatever i was when it the event handler was created. | |
console.log(id); | |
console.log(info.name, info.location); | |
} | |
*/ | |
function evarg(func) { | |
var args = Array.prototype.slice.call(arguments, 1); | |
return function(event) { | |
func.apply(null, args.concat([event])); | |
}; | |
} | |
/* | |
Extend the Function prototype. | |
Example: elements[i].onclick = doThis.evarg(1); | |
*/ | |
Function.prototype.evarg = function() { | |
var func = this, args = Array.prototype.slice.call(arguments); | |
return function(event) { | |
func.apply(null, args.concat([event])); | |
}; | |
}; |
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
// Output strings to txt file in JS console. (Used in Chrome) | |
// Useful for saving console.log outputs. | |
// Notes: 1) Uses UTF-8 byte order mark. 2) Old code stopped working: new Event('click') | |
function txtout(str, file="out.txt") { | |
var A=document.createElement("a"); | |
A.download=file,A.href="data:text/plain;charset=utf-8,%EF%BB%BF"+encodeURIComponent(str), | |
A.dispatchEvent(new MouseEvent("click")); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When you need to simply check if multiple elements are equal (or any other condition), this is probably the optimal way:
Practical example. The following should
return false
if the given 8-byte array is not all 0 bytes.