Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Javascript #19

Open
petrosh opened this issue Jul 22, 2016 · 26 comments
Open

Javascript #19

petrosh opened this issue Jul 22, 2016 · 26 comments

Comments

@petrosh
Copy link
Owner Author

petrosh commented Dec 6, 2016

Design Patterns

Links

Functional instantiation

Functional instantiation is at the root of object instantiation in JavaScript. We create a function, and inside it, we can create an empty object, some scoped variables, some instance variables, and some instance methods. At the end of it all, we can return that instance, so that every time the function is called, we have access to those methods.

// Set up
var Func = function () {
  var someInstance = {}, a = 0, b = 1;
  someInstance.method1 = function () {
    // code for method1 here
  }
  someInstance.method2 = function () {
    // code for method2 here
  }
  someInstance.logA = function () {
    return a;
  }
  return someInstance;
}
// Usage
var myFunc = Func();
myFunc.logA(); // returns a

Pros: This pattern is the easiest to follow, as everything exists inside the function. It's instantly obvious that those methods and variables belong to that function.

Cons: This pattern creates a new set of functions in memory for each instance of the function Func. If you're creating a big app, it's ultimately just not suitable in terms of memory.

Rewritten:

// Set up
var Func = function () {
  var a = 0, b = 1;
  function method1 () {
    // code for method1 here
  }
  function method2 () {
    // code for method2 here
  }
  function logA () {
    return a;
  }
  return {
    logA: logA
  };
}

@petrosh petrosh changed the title Promise, Json Promise, Json, Workers Dec 11, 2016
@petrosh
Copy link
Owner Author

petrosh commented Dec 11, 2016

Fetch & JSON

function dataHandler (r) {
    // Unauthorized or bad credential
    if (response.status === 401) {
        localStorage.removeItem('fnp');
        logged = false;
        console.log('401: unlogged');
    }
    // json parse
    return response.json();
}

// Error callback
function errore (e) {
    console.log('error: ' + e);
}

function serveLoginForm (event) {
    event.preventDefault();
    var token = document.getElementById('token_field');
    return (token.value.length !== 40) ? false : fetch('https://api.github.com/user', {
        headers: { Authorization: 'token ' + token.value}
    }).then(dataHandler);
}

Stack overflow AJAX

Sending and Receiving JSON Data via POST

Fetch request promises initially return Response objects. These will provide response header information, but they don't directly include the response body, which may not have even loaded yet. Methods on the Response object such as .json() can be used to wait for the response body to load, then parse it.

const requestData = {
  method: 'getUsers'
};

const usersPromise = fetch('/api', {
  method: 'POST',
  body: JSON.stringify(requestData)
}).then(response => response.json()).then(responseData => {
  if (!response.ok) {
    throw new Error("Got non-2XX response from API server.");
  }
  return responseData.users;
});

usersPromise.then(users => {
  console.log("Known users: ", users);
}, error => {
  console.error("Failed to fetch users due to error: ", error);
});

Stack overflow JSON

Parsing with a reviver function

A reviver function can be used to filter or transform the value being parsed.

var json = '[{"name":"John","score":51},{"name":"Jack","score":17}]';

var data = JSON.parse(json, function reviver(key, value) {
  if (key === 'name' && typeof value === 'string') {
    return value.toUpperCase();
  } else {
    return value;
  }
});

@petrosh
Copy link
Owner Author

petrosh commented Dec 11, 2016

Workers

Links

Caveats

Workers cannot

  • Web workers can't access DOM elements from the web page.
  • Web workers can't access global variables and JavaScript functions from the web page.
  • Web workers can't call alert() or confirm() functions.
  • Objects such as window, document and parent can't be accessed inside the web worker.

Error handling

var worker = new Worker('worker.js');
worker.onmessage = function (event) {
    // event handling
};
worker.onerror = function (event) {
    // event.hasOwnProperty('filename') always false
    var result = ('filename' in evt) ? {evt.lineno, evt.message, evt.filename} : 'no file';
};

Post arrays

// main.js
if (window.Worker) {
  var myWorker = new Worker("worker.js");
  first.onchange = function() {
    myWorker.postMessage([first.value,second.value]);
    console.log('Message posted to worker');
  }
}
// worker.js
onmessage = function(e) {
  console.log('Message received from main script');
  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
  console.log('Posting message back to main script');
  postMessage(workerResult);
}

@petrosh
Copy link
Owner Author

petrosh commented Dec 20, 2016

Inject scripts

  var _gauges = _gauges || [];
  (function() {
    var t   = document.createElement('script');
    t.type  = 'text/javascript';
    t.async = true;
    t.id    = 'gauges-tracker';
    t.setAttribute('data-site-id', '52ebefa5de2e264d93002020');
    t.src = '//secure.gaug.es/track.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(t, s);
  })();
var     loc    		= window.location,
	repoOwner	= loc.host.split('.')[0],
	repoName	= loc.pathname.split('/')[1],
	rawGit		= 'https://rawgit.com', // cdn.rawgit for production
	scriptElement   = document.createElement('script');

scriptElement.src = (window.location.hostname === '127.0.0.1') ? '/js/loader.js' :
	[rawGit , repoOwner, repoName, 'master', 'js', 'loader.js'].join('/');

document.body.classList.add('request');
document.getElementsByTagName('head')[0].appendChild(scriptElement);

@petrosh
Copy link
Owner Author

petrosh commented Dec 22, 2016

Arrays

Check if is array arr.isArray()

class SpecialArray extends Array {};
const specialArray = new SpecialArray();
console.log(specialArray.constructor === Array); // false
console.log(specialArray.constructor === SpecialArray); // true
console.log(specialArray instanceof Array); // true
console.log(specialArray instanceof SpecialArray); // true
const noProtoArray = [];
Object.setPrototypeOf(noProtoArray, null);
console.log(noProtoArray instanceof Array); // false
console.log(Array.isArray(noProtoArray)); // true

Get a random item from an array

var randomItem = items[Math.floor(Math.random() * items.length)];

Truncate an array using length

myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].

Use logical AND/ OR for conditions

foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething(); 
foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();

Operators

  • Push array.push(element [, elements]);
    Add to end and return new length

  • Unshift array.unshift(element [, elements]);
    Add to begin and return new length

  • Pop array.pop();
    Remove and return last

  • Shift array.shift();
    Remove and return first

  • Slice array.slice([begin [, end]])
    Return from begin to end (not included)
    begin default to 0. end default to arr.length

Sorting arrays

Sort alphabetically

var sortable=['ff','eg','a','z','eh']
sortable.sort(function(a, b) {
  return a < b ? -1 : a > b ? 1 : 0;
});
// ["a", "eg", "eh", "ff", "z"]

players.json

[
  {
    "player_name": "[UJE]Niek",
    "last_seen": "12h"
  },
  {
    "player_name": "[UJE]DriVEze",
    "last_seen": "4d"
  }
]
// FINAL AT https://pastebin.com/raw/AyyW5fCR
var request = new XMLHttpRequest();
request.open("GET", "players.json", false);
request.send(null);
var r = JSON.parse(request.responseText);
r.sort(function(a,b){
	var awhat = a.last_seen.split(/\*?([a-z])$/); // any characters and capture the final letter
	var bwhat = b.last_seen.split(/\*?([a-z])$/);
	if(awhat[1] === "d" && bwhat[1] === "h") return 1;
	if(awhat[1] === "h" && bwhat[1] === "d") return -1;
	return Number(awhat[0]) - Number(bwhat[0]);
});
// Populate <main>
r.forEach(function(e,i){
	document.querySelector('main').innerHTML += (i+1)+","+e.player_name+","+e.last_seen+"<br>";
});

Combining JavaScript Arrays

a; // [1,2,3,4,5,6,7,8,9]
b; // ["foo","bar","baz","bam","bun","fun"]
// `b` onto `a`:
a.push.apply( a, b );
// `a` into `b`:
b.unshift.apply( b, a );

Example: append tile to board

var board = [1,3];
var tile = ['a','b'];
var newLength = board.push.apply(board, tile);
console.log(newLength, board); // 4, [1, 3, "a", "b"]

@petrosh petrosh removed the json label Dec 26, 2016
@petrosh petrosh changed the title Promise, Json, Workers Javascript Dec 26, 2016
@petrosh
Copy link
Owner Author

petrosh commented Dec 26, 2016

Template

<script id="hello" type="text/template">
  Hello world
</script>
<script>
  alert($('#hello').html());
</script>

Create & Fill

var t = document.createElement('article');
t.innerHTML = '<header><h1></h1><h2></h2><p></p></header><div><ul></ul></div>';

Style & Append

t.querySelector('h2').innerHTML = 'titolo';
document.body.appendChild(t);

<template> tag

<template id="article">
<article>
  <header>
    <h1 class="title"></h1>
    <p class="meta"></p>
  </header>
  <div class="content"></div>
</article>
</template>
// Explicit version
var template = document.querySelector('#article');
var content = template.content;
var entry = document.importNode(content, true));
// Short version
var entry = document.querySelector('#article').content.cloneNode(true);
// Populate
entry.querySelector('.title').innerHTML = 'title';
// Append
document.querySelector("section").appendChild(article);

@petrosh
Copy link
Owner Author

petrosh commented Dec 26, 2016

Append and Insert

Prototype: ac() Append child or childs

Append an element or an array of elements to an element.
element.ac(string | elementsArray);
Return updated element.

Element.prototype.ac = function (input) {
  if (input.constructor === Array) {
    for (var i = 0; i < input.length; i++) {
      if(input[i]) this.appendChild(input[i]);
    }
  } else {
    this.appendChild(input);
  }
  return this;
};

Prototype: Append Childs

Append an array of elements to an element: element.appendChilds(elementsArray);

Element.prototype.appendChilds = function (elementsArray) {
  for (var i = 0; i < elementsArray.length; i++) {
    if(elementsArray[i]) this.appendChild(elementsArray[i]);
  }
  return true;
};

Append

// slow explicit version
document.getElementById("container").innerHTML += "<p>more content</p>";
// Dom building faster than innerHTML
var p = document.createElement("p");
p.appendChild(document.createTextNode("more content");
document.getElementById("container").appendChild(p);

Insert

For Internet Explorer 4 MDN

element.insertAdjacentHTML(position, text);

position can be

<!-- beforebegin -->
<p>
<!-- afterbegin -->
foo
<!-- beforeend -->
</p>
<!-- afterend -->

Insert before: parent.insertBefore(newElement, reference[0]);

Insert newElement inside parent, before reference,

<tag id="parent">
  <!-- newElement inserted here -->
  <tag class="reference">
  </tag>
  <tag class="reference">
  </tag>
</tag>
var newElement = document.createElement('tag');
var parent = document.getElementById('parent');
var reference = document.querySelectorAll('#parent .reference');
parent.insertBefore(newElement,reference[0]);

Insert after an element

Where referenceNode is the node you want to put newNode after. If referenceNode is the last child within its parent element, that's fine, because referenceNode.nextSibling will be null and insertBefore handles that case by adding to the end of the list.

referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
<any>
  <other>
  <referenceNode>
  <!-- <newNode> -->
  <other>
</any>

@petrosh
Copy link
Owner Author

petrosh commented Dec 26, 2016

Elements

Click Event MDN

document.getElementById("test").addEventListener("click", function( event ) {
  event.preventDefault();
  /* event.target.innerHTML = "click count: " + event.detail; */
}, false);

Create

HTML Element create MDN

var link = document.createElement("a");
link.innerHTML = "Inner text"; // oppure
link.appendChild( document.createTextNode("Inner text") );
link.href = "http://google.com";
document.body.appendChild(link);

Create with text oneliner

document.body.appendChild(
    document.createElement('div').appendChild(
        document.createTextNode('hello')
    ).parentNode
);

The Node.parentNode read-only property returns the parent of the specified node in the DOM tree.

Attributes

document.getElementById("submit").setAttribute("disabled", "true");
document.getElementById("submit").setAttribute("disabled", ""); // no value
document.getElementById("submit").removeAttribute("disabled");

Classes

// add
element.className += ' bold';
// remove
element.className = element.className.replace(/\b(bold)\b/, '');

querySelector

querySelector returns the first element within the document. MDN

parentNode, nextSibling, previousSibling, children, lastElementChild

// select parent node
var parent = document.querySelector("div").parentNode;
// select next node
var next = document.querySelector("div").nextSibling;
// select previous node
var previous = document.querySelector("div").previousSibling;
// select first child
var child = document.querySelector("div").children[0];
// select last child
var last = document.querySelector("div").lastElementChild;

querySelectorAll

document.querySelectorAll("div.note, div.alert");

Returns a list of the elements within the document (using depth-first pre-order traversal of the document's nodes) that match the specified group of selectors.

Loop on querySelectorAll

// For Demo purposes only (show hover effect on mobile devices)
[].slice.call( document.querySelectorAll('a[href="#"') ).forEach( function(el) {
    el.addEventListener( 'click', function(ev) { ev.preventDefault(); } );
} );

Nano-library

Microscopic but very efficient library for DOM selection.

// Build the DOM selection query
function $q( selector, ctx ) {
  ctx = ctx || document;
  // Return methods for lazy evaluation of the query
  return {
    // Return array of all matches
    all: function() {
      var list, ary = [];
      list = ctx.querySelectorAll( selector );
      for ( var i = 0; i < list.length; i++ ) {
        ary[ i ] = list[ i ];
      }
      return ary;
    },
    // Return first match
    first: function() {
      return ctx.querySelector( selector );
    },
    // Return last match
    last: function() {
      var list = ctx.querySelectorAll( selector );
      return list.length > 0 ? list[ list.length - 1 ] : null;
    }
  };
}

Usage:

var query = $q(".foo .bar"); // build the query

query.first() // => first element matching the selector, or null
query.all()   // => all elements matching the selector

// Or restrict the query to the descendant of an element:
var query2 = $q(".foo", elem); // elem is a DOM element

query2.first() // => first descendant of elem matching the selector
query2.all()   // => all descendants of elem matching the selector

BASIC MANIPULATIONS sitepoint

Empty element

// Explicit
document.getElementById("container").innerHTML = null;
// Empty with a loop
var c = document.getElementById("container");
while (c.lastChild) c.removeChild(c.lastChild);

Remove element

var c = document.getElementById("container");
c.parentNode.removeChild(c);

@petrosh
Copy link
Owner Author

petrosh commented Dec 26, 2016

CSS

Link active on menù

var perm = document.getElementById('permalink').getAttribute('href');
var listItems = document.querySelectorAll("header nav a");
for (var variable in listItems) {
  if (listItems.hasOwnProperty(variable)) {
    if( listItems[variable].getAttribute('href') == perm ){
      var ele = listItems[variable];
      ele.classList.add('live');
    }
  }
}

classList Gist

// add class
element.classList.add("bar");
// remove class
element.classList.remove("foo");
// check if has class
element.classList.contains("foo");
// toggle class
element.classList.toggle("active");

Set css attribute MDN

document.getElementById("element").setAttribute("style", "color: blue");
document.getElementById("element").style.color = "blue";

CSSStyleSheet MDN Walsh

.primo{ color: red; }
var sheets = document.styleSheets, // array of stylesheets
    first = document.styleSheets[1], // stylesheet
    rules = document.styleSheets[1].cssRules; // array of rules

// document.styleSheets[1].cssRules[0].selectorText = ".primo"
// document.styleSheets[1].cssRules[0].cssText = ".primo { color: red; }"
// document.styleSheets[1].deleteRule(0);
// document.styleSheets[1].insertRule( ".primo { color: red; }", 0);

Get computed style MDN

var style = window.getComputedStyle( document.querySelector( '#id' ) );
console.log( style.getPropertyValue('color') );
// rgb(0, 0, 0)

window.getComputedStyle(z).getPropertyValue('display')

@petrosh
Copy link
Owner Author

petrosh commented Dec 26, 2016

DevTools

Redirect

<meta http-equiv="refresh" content="0; url=http://example.com/" />

Snippets

Main features

  • You can set breakpoints and debug the snippet's code just like a regular JavaScript code.
  • You are targeting the latest Chrome browser only, thus cross-browser compatibility and obsolete browsers are not a problem.
  • Any library already included on the page or global variable can be used from the snippet.
  • I prefer to wrap any code in a closure to prevent leaking code snippet's variables into global namespace.
  • Console prints any value returned from the code snippet automatically, thus it prints undefined in the example above.
  • You cannot pass any arguments to a code snippet, thus you need to modify the snippet itself.
  • The code snippets are a lot more user and developer friendly than bookmarklets - the code is clearly visible and can be modified and saved at will.

Console

Css

var style = "color: yellow; font-style: italic; background-color: blue; padding: 2px";
console.log("This is %cMy stylish message", style);

Group

console.group();
console.log("Level 3");
console.groupEnd();

Timer

console.time('name');
console.timeEnd('name');
// name: 4799.905ms

Trace caller

console.trace()
// (anonymous function) @ VM337:1

Debug

The script will stop as soon as it reaches the function you wrapped within debug(fn)

Monitor

Monitor the arguments passed into a specific function: monitor(fn)

Benchmark

window.benchmark = (count=10) => {
  console.log(`Running %c${count} %ctimes ...`, 'font-weight: bold', 'font-weight: normal');
  Array(count).fill(0).forEach(x => run())
  console.log(`Stateful                         took ${statefulTotalTime}ms`);
  console.log(`Stateless Functional Mounted     took ${statelessFunctionalMountedTotalTime}ms %c${Math.round((1-statelessFunctionalMountedTotalTime/statefulTotalTime)*100)}% %c`, 'color:green', 'color:black');
  console.log(`Stateless Functional Direct Call took ${statelessFunctionalDirectCallTotalTime}ms %c${Math.round((1-statelessFunctionalDirectCallTotalTime/statefulTotalTime)*100)}% %c`, 'color:green', 'color:black');
  console.log(`%c🎉`, 'font-size: 100px')
}

@petrosh
Copy link
Owner Author

petrosh commented Dec 26, 2016

localStorage

The sessionStorage attribute represents the set of storage areas specific to the current top-level browsing context.
Each top-level browsing context has a unique set of session storage areas, one for each origin.

Polyfill gist

if (!('localStorage' in window)) {
// if (!Modernizr.localstorage) {
  window.localStorage = {
    _data       : {},
    setItem     : function(id, val) { return this._data[id] = String(val); },
    getItem     : function(id) { return this._data.hasOwnProperty(id) ? this._data[id] : undefined; },
    removeItem  : function(id) { return delete this._data[id]; },
    clear       : function() { return this._data = {}; }
  };
}

Example: redirect only first time reddit

function openWin() {
    var session = sessionStorage.getItem('session');
    if (!session) {
        sessionStorage.setItem('session', true);
        window.open('google.com', '_blank');
    }
}

Storing Objects in HTML5 localStorage

Plain version stackoverflow

var testObject = { 'one': 1, 'two': 2, 'three': 3 };

// Put the object into storage
localStorage.setItem('testObject', JSON.stringify(testObject));

// Retrieve the object from storage
var retrievedObject = localStorage.getItem('testObject');

console.log('retrievedObject: ', JSON.parse(retrievedObject));

Prototype version

Storage.prototype.setObject = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObject = function(key) {
    var value = this.getItem(key);
    return value && JSON.parse(value);
}

// Usage
var userObject = { userId: 24, name: 'Jack Bauer' };
localStorage.setObject('user', userObject);
userObject = localStorage.getObject('user');
// "{"userId":24,"name":"Jack Bauer"}"

Hash version: codepen

@petrosh
Copy link
Owner Author

petrosh commented Feb 16, 2017

Polyfills

@petrosh
Copy link
Owner Author

petrosh commented Feb 27, 2017

Comments

/**
 * Update a gist.
 * @see https://developer.github.com/v3/gists/#edit-a-gist
 * @param {Object} gist - the new data for the gist
 * @param {Requestable.callback} [cb] - the function that receives the API result
 * @return {Promise} - the Promise for the http request
 */
update(gist, cb) {
    return this._request('PATCH', `/gists/${this.__id}`, gist, cb);
}

@petrosh
Copy link
Owner Author

petrosh commented Mar 4, 2017

Bookmarklet

Links

Google Bookmarklet

  • Search by filetype <prompt-1> filetype:<prompt-2>
javascript: document.location = 'https://www.google.com/search?hl=en&q=' + encodeURIComponent(prompt('Search term')) + ' filetype:' + encodeURIComponent(prompt('Dual')) ;
  • View cache version of this page cache:<hostname><pathname>
javascript: document.location = 'https://www.google.com/search?q=cache:' + encodeURIComponent(document.location.hostname + document.location.pathname);
  • Define a word define:<prompt>
javascript: document.location = 'https://www.google.com/search?hl=en&q=define:' + prompt('Search term') ;
  • Translate EN ➤ IT http://translate.google.com/#en/it/<prompt>
javascript:location='http://translate.google.com/#en/it/' + prompt();
  • Translate Detect ➤ EN http://translate.google.com/#auto/en/<prompt>
javascript:location='http://translate.google.com/#auto/en/' + prompt();
  • Search with "javascript" javascript+<prompt>
javascript: document.location = 'https://www.google.com/search?hl=en&q=javascript+' + prompt('Search term') ;
  • Search with Google on this site <prompt> site:<host>
javascript: var host = document.location.hostname.split('.'); if (host.length > 2) { host = host[host.length-2] + '.' + host[host.length-1]; } else { host.join('.'); } document.location = 'https://www.google.com/search?hl=en&q=' + prompt('Search term') + '+site:' + host;

Uglify

npm install uglify-js@1 -g
uglifyjs ./src/Pull_request_template.js > Pull_request_template.min.js

Replace quotes

var filter = function (content) {
  return content
    .replace(/"/g, "'")
    .replace(/\n/g, '');
};

Ramda Ramda Bookmarklet

Bl.ocks codepen

http://bl.ocks.org/<user>/<number>https://gist.github.com/<user>/<number>

Gist codepen

https://rawgit.com/<user>/<number>/raw/index.htmlhttps://gist.github.com/<user>/<number>

//javascript: (function() {})();
//    var al = location.href,
var al="https://rawgit.com/serdaradali/11346541/raw/index.htm", vec = al.split(".");
console.info(vec);
if(vec[0]=="https://gist"){
  //window.open("https://rawgit." + vec[2] + '/raw/index.html', "_self");
  console.warn("https://rawgit." + vec[2] + '/raw/index.html', "_self");
}
if(vec[0]=="https://rawgit"){
  //window.open("https://gist.github." + vec[1].slice(0,-10), "_self");
  console.warn("https://gist.github." + vec[1].slice(0,-10), "_self");
}
javascript:(function(){var al=location.href,vec=al.split(".");if(vec[0]=="https://gist"){window.open("https://rawgit."+vec[2]+'/raw/index.html',"_self");}if(vec[0]=="https://rawgit"){window.open("https://gist.github."+vec[1].slice(0,-10),"_self");}})();

GitHub

https://github.com/<user>/<repo>http://<user>.github.io/<repo>/

javascript: (function() {
    var al = location.href, vec = al.split(".");
    if (vec[1] == 'github') {
        var usr = vec[2].split('/');
        if (usr[0] == 'io') {
            window.open("https://github.com/" + vec[0].substr(7) + '/' + usr[1], "_self");
        }
    } else {
        if (vec[0] == 'https://github') {
            var par = vec[1].split('/');
            if (par[0] == 'com') {
                window.open("http://" + par[1] + ".github.io/" + par[2], "_self");
            }
        }
    }
})();

Imgur

http://i.imgur.com/4W5yZCy.pnghttp://imgur.com/4W5yZCy

javascript: (function() {
    var al = encodeURIComponent(document.title), vec = al.split(".");
    window.open("http://www.imgur.com/" + vec[0], "_self");
})();

Git-Marks

Post text selection to https://github.com/petrosh/gitmarks/issues with link and title.

javascript: (function(s) {
    try {
        s = document.selection.createRange().text
    } catch (_) {
        s = document.getSelection()
    }
    location.href = "https://github.com/petrosh/gitmarks/issues/new?title=" + encodeURIComponent (document.title) + "&body=[link](" + location + ")" + String.fromCharCode(37) + "0A---" + String.fromCharCode(37) + "0A" + encodeURIComponent(s)
})()
javascript:(function(s){try{s=document.selection.createRange().text}catch(_){s=document.getSelection()}location.href="https://github.com/petrosh/gitmarks/issues/new?title="+encodeURIComponent(document.title)+"&body=[link]("+location+")"+String.fromCharCode(37)+"0A---"+String.fromCharCode(37)+"0A"+encodeURIComponent(s)})()

Whois CODEPEN

//javascript: (function() { ... })();
var crurl;
if( window.location.href == 'data:text/html,chromewebdata' ){
  url = document.title.split(" ")[0];
  crurl = url.split("/")[2];
}else{
  crurl = location.host;
};
window.open('http://who.is/whois/' + crurl);

Parse goodreads books for Simulibros

url: https://www.goodreads.com/book/show/51664643-guardian-outcast
title

document.getElementById('bookTitle').textContent.trim()

serie:

document.getElementById('bookSeries').textContent.trim().replace(" #",", #")

author:

document.querySelector('.authorName span[itemprop="name"]').textContent.trim().replace("  "," ")

year:

document.evaluate("//div[contains(text(),'Published')]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.innerHTML.trim().match('[0-9]{4}')[0]

link:

location.href

publisher:

document.evaluate("//div[contains(text(),'Published')]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.innerHTML.trim().match('by (.*?)$')[1]

rating:

document.querySelector('[itemprop="ratingValue"]').textContent.trim()

image URL:

document.getElementById('coverImage').src

Bookmarklet for Goodreads > Simulibros

javascript:image=document.getElementById('coverImage').src;rating=document.querySelector('[itemprop="ratingValue"]').textContent.trim();publisher=document.evaluate("//div[contains(text(),'Published')]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.innerHTML.trim().match('by (.*?)$')[1];year=document.evaluate("//div[contains(text(),'Published')]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.innerHTML.trim().match('[0-9]{4}')[0];link=location.href;serie=document.getElementById('bookSeries').textContent.trim().replace(" #",",%20#");author=document.querySelector('.authorName%20span[itemprop="name"]').textContent.trim().replace("%20%20","%20");title=document.getElementById('bookTitle').textContent.trim();hash="title="+title+"%20"+serie+"&author="+author+"&year="+year+"&link="+link+"&publisher="+publisher+"&rating="+rating+"&image_url="+image;window.location="https://petrosh.github.io/simulibros/add_book?a="+btoa(hash)

@petrosh
Copy link
Owner Author

petrosh commented Mar 4, 2017

Strings

Contain

if (string.indexOf(substring) > -1) // string contain substring

Split variable with separator jsfiddle

var str = "var1/var2/var3#ciao";
var rest = str.substring(0, str.lastIndexOf("#"));
// "var1/var2/var3"
var last = str.substring(str.lastIndexOf("#") + 1, str.length);
// "ciao"

Encode HTML characters

document.createTextNode('...') return a Text node.

Do not bother with encoding. Use a text node instead.
Data in text node is guaranteed to be treated as text.

var string = 'string with HTML code <a href="#">link</a>';
// document.createTextNode(string) = "string with HTML code &lt;a href="#"&gt;link&lt;/a&gt;";

// Usage
document.querySelector('body').appendChild(document.createTextNode(string));

Unescape HTML css-tricks

function htmlDecode(input){
  var e = document.createElement('div');
  e.innerHTML = input;
  return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}

// Usage
htmlDecode("&lt;img src='myimage.jpg'&gt;"); 
// returns "<img src='myimage.jpg'>"

Case

Capitalize first letter

string.charAt(0).toUpperCase() + string.slice(1);

Titlecase

function toTitleCase(str) {
  return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}

Multifunction http://www.javascriptkit.com/script/script2/lowercase-online-tool.shtml

  • sentenceCase, toTitleCase, CapitalCase
// sentenceCase: everything lowercase except the first character and "I"
function sentenceCase(str){
	var str = str.toLowerCase().replace(/\si\s/g, ' I ');
	str = str.charAt(0).toUpperCase() + str.slice(1);
	return str; // What I do, I do for allèòàùé the people in the world!
}

// toTitleCase: first character of each word except common stop words
// reference: https://github.com/gouch/to-title-case
function toTitleCase(str){
  var smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|vs?\.?|via)$/i;
	var str = str.toLowerCase()
  return str.replace(/[A-Za-z0-9\u00C0-\u00FF]+[^\s-]*/g, function(match, index, title){
    if (index > 0 && index + match.length !== title.length &&
      match.search(smallWords) > -1 && title.charAt(index - 2) !== ":" &&
      (title.charAt(index + match.length) !== '-' || title.charAt(index - 1) === '-') &&
      title.charAt(index - 1).search(/[^\s-]/) < 0) {
      return match.toLowerCase();
    }

    if (match.substr(1).search(/[A-Z]|\../) > -1) {
      return match;
    }

    return match.charAt(0).toUpperCase() + match.substr(1);
  }); // What I Do, I Do for Allèòàùé the People in the World!
};

// CapitalCase: first character of each word
// reference: https://medium.freecodecamp.com/three-ways-to-title-case-a-sentence-in-javascript-676a9175eb27
function CapitalCase(str){
  return str.toLowerCase().split(' ').map(function(word) {
    return (word.charAt(0).toUpperCase() + word.slice(1));
  }).join(' '); // What I Do, I Do For Allèòàùé The People In The World!
}

function lowerCase(str){
  return str.toLowerCase(); // what i do, i do for allèòàùé the people in the world!
}

function upperCase(str){
  return str.toUpperCase(); // WHAT I DO, I DO FOR ALLÈÒÀÙÉ THE PEOPLE IN THE WORLD!
}

Hash from string

Slow

function hash(s){
    return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}

Fast

String.prototype.hashCode = function() {
  var hash = 0, i, chr;
  if (this.length === 0) return hash;
  for (i = 0; i < this.length; i++) {
    chr   = this.charCodeAt(i);
    hash  = ((hash << 5) - hash) + chr;
    hash |= 0; // Convert to 32bit integer
  }
  return hash;
};
// Usage
JSON.stringify(data).hashCode()

@petrosh
Copy link
Owner Author

petrosh commented Mar 4, 2017

Time & Dates

Timezone

  • getTimezoneOffset()
    Return the difference, in minutes, from UTC to current locale (host system settings).

If your time zone is GMT+2, -120 will be returned

-1 * new Date().getTimezoneOffset() / 60
// 1

Parse Time YYYYMMDDTHHMMSSZ

function parseDate(input) {
  return new Date(Date.UTC(
    parseInt(input.slice(0, 4), 10),
    parseInt(input.slice(4, 6), 10) - 1,
    parseInt(input.slice(6, 8), 10),
    parseInt(input.slice(9, 11), 10),
    parseInt(input.slice(11, 13), 10),
    parseInt(input.slice(13,15), 10)
  ));
}

console.log(parseDate('20130208T080910Z'));
// "2013-02-08T08:09:10.000Z"

Unix Timestamp

new Date(1491688800000); // = Sun Apr 09 2017 00:00:00 GMT+0200 (CEST)
new Date('Sun Apr 09 2017 00:00:00 GMT+0200 (CEST)').getTime(); // = 1491688800000

Date YYYY-MM-DD with leading zeros

var now = new Date().getFullYear() +
  '-' + ('0' + (new Date().getMonth()+1)).slice(-2) +
  '-' + ('0' + new Date().getDate()).slice(-2);

Yesterday

var date = new Date(); //# => Fri Apr 01 2011 11:14:50 GMT+0200 (CEST)
date.setDate(date.getDate() - 1); //# => Thu Mar 31 2011 11:14:50 GMT+0200 (CEST)

Add timestamp to API call if browser

return url + (typeof window !== 'undefined' ? '&' + new Date().getTime() : '');

Fraction of the day

// new Date() = Fri Jul 08 2016 13:26:07 GMT+0200 (CEST)
// new Date().getTime() = 1467977171582
// 86400000 ms in a day
var dayFraction = (new Date().getTime()-(new Date(new Date().getFullYear()+'/'+(new Date().getMonth()+1)+'/'+new Date().getDate()).getTime()))/86400000;
// dayFraction = 0.559364525462963

timeSince()

String.prototype.timeSince = function () {
    var config = function(int,str){ if (Math.round(int) <= 1) return '1 ' + str + ' ago'; else return Math.round(int) + ' ' + str + 's ago'; }
    var date = new Date(this);
    var offset = new Date().getTimezoneOffset();
    var seconds = Math.floor((new Date() - date) / 1000) + (60 * -offset);
    var interval = Math.floor(seconds / 31536000);
    if (interval > .9) return config(interval, 'year');
    interval = seconds / (86400*30);
    if (interval > .75) return config(interval, 'month');
    interval = seconds / (3600*24*7);
    if (interval > 1) return config(interval, 'week');
    interval = Math.floor(seconds / (3600*24));
    if (interval > .75) return config(interval, 'day');
    interval = Math.floor(seconds / (60*60));
    if (interval > .92) return config(interval, 'hour');
    interval = Math.floor(seconds / 60);
    if (interval > 1) return config(interval, 'minute');
    return 'just now';
};
document.body.innerHTML = '2016-07-01T11:10:00'.timeSince();
// 53 minutes ago

Dates CODEPEN MDN

var date = new Date(2016,0,1); // month-1
var nextday = new Date(date.getFullYear(),date.getMonth(),date.getDate()+7);
var text = nextday.toLocaleDateString("it-IT",{ weekday: "short", day: "2-digit" });
var time = when.toLocaleDateString("it-IT",{ weekday: "short", day: "2-digit", month: "short", year: "numeric" });
// mar 05 apr 2016
var when = new Date('Mon, 15 Feb 2016 18:06:44 +0100');
var quanno = when.toLocaleTimeString("it-IT",{
  weekday: "short",
  day: "numeric",
  month: "short",
  year: "numeric"
});
// lun 15 feb 2016, 18:06:44

toLocaleDateString

[[Weekday]]			"weekday"	"narrow", "short", "long"
[[Era]]				"era"	"narrow", "short", "long"
[[Year]]			"year"	"2-digit", "numeric"
[[Month]]			"month"	"2-digit", "numeric", "narrow", "short", "long"
[[Day]]				"day"	"2-digit", "numeric"
[[Hour]]			"hour"	"2-digit", "numeric"
[[Minute]]			"minute"	"2-digit", "numeric"
[[Second]]			"second"	"2-digit", "numeric"
[[TimeZoneName]]	"timeZoneName"	"short", "long"

@petrosh
Copy link
Owner Author

petrosh commented Mar 4, 2017

XHR

Please read this json

var request = new XMLHttpRequest();
request.open("GET", "players.json", false);
request.send(null);
var r = JSON.parse(request.responseText);

Fetch MDN GitHub
Polyfill needed for Explorer and Safari: https://github.com/github/fetch

var myRequest = new Request('filename.json');
fetch(myRequest).then(function(response) {
  return response.json().then(function(json) {
    // do something with json
  });
});

Post Form MDN

Usage sendData({test:'1'});

function sendData(data) {
  var XHR = new XMLHttpRequest();
  var urlEncodedData = "";
  var urlEncodedDataPairs = [];
  var name;

  // We turn the data object into an array of URL encoded key value pairs.
  for(name in data) {
    urlEncodedDataPairs.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
  }

  // We combine the pairs into a single string and replace all encoded spaces to 
  // the plus character to match the behaviour of the web browser form submit.
  urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g, '+');

  // We define what will happen if the data is successfully sent
  XHR.addEventListener('load', function(event) {
    alert('Yeah! Data sent and response loaded.');
  });

  // We define what will happen in case of error
  XHR.addEventListener('error', function(event) {
    alert('Oups! Something goes wrong.');
  });

  // We setup our request
  XHR.open('POST', 'http://ucommbieber.unl.edu/CORS/cors.php');

  // We add the required HTTP header to handle a form data POST request
  XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  XHR.setRequestHeader('Content-Length', urlEncodedData.length);

  // And finally, We send our data.
  XHR.send(urlEncodedData); // XHR.send( '{ "data": "1" }' )
}

@petrosh
Copy link
Owner Author

petrosh commented Mar 4, 2017

URLs

Update on special anchor link

window.onhashchange = function() {
    if (window.location.hash.substring(1,2) === '!') window.location.reload();
};
// http://petrosh.it/domtools/starsystem/#!petrosh/diarissues/14

Last fragment

var link = "https://github.com/petrosh/snippetrosh/issues/17#issuecomment-184627985"
var fragment = link.substr(link.lastIndexOf('/') + 1); // "17#issuecomment-184627985"

window.location

// https://github.com/petrosh/snippetrosh/issues/17#issuecomment-184627985
window.location = {
   "hash":"#issuecomment-184627985",
   "search":"",
   "pathname":"/petrosh/snippetrosh/issues/17",
   "port":"",
   "hostname":"github.com",
   "host":"github.com",
   "protocol":"https:",
   "origin":"https://github.com",
   "href":"https://github.com/petrosh/snippetrosh/issues/17#issuecomment-184627985"
}
window.location.pathname.split( '/' ) = ["", "petrosh", "snippetrosh", "issues", "17"];
window.location.hash.substr(1) = "issuecomment-184627985";

GitHub URLs

Return repository full name from API

function returnFullname (u) {
    return  RegExp(/https:\/\/api.github.com\/repos\/(.*?)\/issue/).exec(u)[1];
}

Repository NWO

"https://starsystem.github.io/naledi/" > "starsystem/naledi" codepen

function nwo (u) {
    // (?:\/.*|$) non capturing group, slash and characters, or end of string
    var array = RegExp(/https:\/\/(.*?).github.io\/(.*?)(?:\/.*|$)/).exec(u);
    return [array[1],array[2]].join('/');
}
// nwo("https://starsystem.github.io/naledi/") = "starsystem/naledi"

URL data

var urlSlash = window.location.pathname.split('/'),
    urlArray = window.location.host.split('.'),
    urlHash = window.location.hash.substring(1),
    repoName = urlSlash[1],
    repoOwner = urlArray[0],
    repoFullname = repoOwner + '/' + repoName,
    repoAPI = 'https://api.github.com/repos/' + repoFullname,
    repoHome = 'https://' + repoOwner + '.github.io/' + repoName,
    rawStatic = 'https://rawgit.com/' + repoFullname,
    rawCdn = 'https://cdn.rawgit.com/' + repoFullname;

paradox

http://codepen.io/Petrosh/pen/mPOVwX

Parse Hash URLSearchParams

url: https://example.com?title=Guardian%20Outcast&author=G.J.%20Ogden&year=2020&link=https://www.goodreads.com/book/show/51664643-guardian-outcast&publisher=Ogden%20Media%20Ltd&rating=4.20&image=https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1582557088l/51664643._SY475_.jpg

const parsedHash = new URLSearchParams(
  window.location.hash.substr(1) // skip the first char (#)
);
parsedHash.get('title');
// "Guardian Outcast"
parsedHash.get('author');
// "G.J. Ogden"
parsedHash.get('year');
// "2020"
parsedHash.get('serie');
// null
parsedHash.get('rating');
// "4.20"
parsedHash.get('link');
// "https://www.goodreads.com/book/show/51664643-guardian-outcast"
parsedHash.get('image');
//"https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1582557088l/51664643._SY475_.jpg"

@petrosh
Copy link
Owner Author

petrosh commented Mar 4, 2017

Boilerplates

HTML

Code Guide by @mdo

<!DOCTYPE html>
<html lang="en-us">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge">
        <title>Page title</title>
        <link rel="stylesheet" href="empty.css">
        <script src="empty.js"></script>
    </head>
    <body>
        <h1 class="hello-world">Hello, world!</h1>
        <p>Attribute order: class, id, name, data-*, src, for, type, href, value ,title, alt, role, aria-*</p>
        <h5>Boolean Attributes</h5>
        <input type="text" disabled>

        <input type="checkbox" value="1" checked>

        <select>
            <option value="0">0</option>
            <option value="1" selected>1</option>
        </select>
        <br>
        <img src="http://www.hisd.com/uploads/study-abroad-guide1.jpg" alt="Company">
    </body>
</html>

From fetch

With header

<!doctype html>
<title>title</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<header>
	<h1></h1>
	<nav></nav>
</header>
<main></main>
<footer></footer>
<script src="script.js"></script>

With section

<!doctype html>
<title>title</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<h1></h1>
<nav></nav>
<section>
	<h2></h2>
</section>
<footer></footer>
<script src="script.js"></script>

@petrosh
Copy link
Owner Author

petrosh commented Mar 4, 2017

BASE 64

Polyfill

Unicode strings MDN

function utf8_to_b64(str) {
    return window.btoa(escape(encodeURIComponent(str)));
}
function b64_to_utf8(str) {
    return decodeURIComponent(unescape(window.atob(str)));
}

For GitHub contents

function b64e(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode('0x' + p1);
    }));
}

function b64d(str) {
    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
        return '%' + c.charCodeAt(0).toString(16);
    }).join(''));
}

@petrosh
Copy link
Owner Author

petrosh commented Mar 8, 2017

Switch, case

Shorthand

var cases = {
    1: doX,
    2: doY,
    3: doN
};
if (cases[something]) {
    cases[something]();
}

same as

switch (something) {
    case 1:
        doX();
    break;
    case 2:
        doY();
    break;
    case 3:
        doN();
    break;
    // And so on...
}

@petrosh
Copy link
Owner Author

petrosh commented Mar 10, 2017

jQuery

DOM ready

$(document).ready(function() {
    // DOM ready
});

Version number $().jquery

console.log($().jquery);
$('header h1, title').append($().jquery);

Add class or classes

$("button").click(function(){
    $("#div1").addClass("important blue");
});

Append HTML

$('main').append('<h1>ok</h1>')

Nested append

list.append(
  $('<li/>').append(
    $('<a/>', {
        href: e.html_url,
        text: e.name
    })
  )
);

Element create and style

$('<h3/>', { text: e[0] }).appendTo('main');
var span = $("<span/>");
span.text(e);
span.insertAfter(notice);

for Each loop

$( ".alert" ).each(function() {
    var element = $( this );
    array.each(function(e){
        if (element.text().indexOf(e) >= 0){
            element.addClass(e);
        }
    });
});

Change page style onclick: https://github.com/tallys/color-theory

$(document).ready(function () {
  $('.color-swatches .swatch').click(function () {
  	var color = $(this).data('color');
  	$('#themed').remove();
        $('head').append('<link rel="stylesheet" href="stylesheets/'+color+'.css" type="text/css" id="themed" />');
	});

    $('.partymode').click(function () {
        $('body').toggleClass('party');
    });
});

Style

<link rel="stylesheet" href="stylesheets/green.css" type="text/css" id="themed">

Swatch

<div class="color-swatches">
    <button class= "swatch" data-color="red"></button>
</div>

Parse HTML element from remote page

$.ajax({
  url: 'https://cors-anywhere.herokuapp.com/https://www.3bmeteo.com/meteo/giove/sintesi',
  type: 'GET',
  success: function(res) {
    var chart = $(res).find('#chartdiv');
    $('body').append(chart);
  }
});

Parse XML RSS Feed

$.get('https://cors-anywhere.herokuapp.com/http://source.xml', function(data) {
  var $xml = $(data), ul = $('<ul>');
  $xml.find("item").each(function() {
    var $this = $(this), item = {
      title: $this.find("title").text(),
      link: $this.find("link").text(),
      description: $this.find("description").text(),
      pubDate: $this.find("pubDate").text(),
      author: $this.find("author").text()
    };
    console.log(item);
  });
});

@petrosh
Copy link
Owner Author

petrosh commented May 3, 2017

d3.js

Element sizes

For SVG elements Using something like selection.node().getBBox() you get values like

{
    height: 5, 
    width: 5, 
    y: 50, 
    x: 20
}

For HTML elements Use selection.node().getBoundingClientRect()

Mouse position

 var point = d3.mouse(this), p = {x: point[0], y: point[1] };

keyboard

function keydown() {
  if (!selected) return;
  switch (d3.event.keyCode) {
    case 8: // backspace
    case 46: { // delete
      var i = points.indexOf(selected);
      points.splice(i, 1);
      selected = points.length ? points[i > 0 ? i - 1 : 0] : null;
      redraw();
      break;
    }
  }
}

Get input field

var normal = Number(d3.select('#normal').property('value'));

Mouse pixel position

var point = d3.mouse(this),
    p = {x: point[0], y: point[1] };
d3.select('#coordinates').text([p.x,p.y].join(','));

Formatting numbers

d3.format(".1f")(d3.event.scale); // x.x

Starting number: 1500
d3.format(",") : 1,500
d3.format(".1f") : 1500.0
d3.format(",.2f") : 1,500.00
d3.format("s") : 1.5k
d3.format(".1s") : 2k
d3.format(".2s") : 1.5k
function(d) { return "$" + d3.format(",.2f")(d); } : $1,500.00
d3.format(",.2%") : 150,000.00%

Parse Dates

Parse dd/mm/yyyy

var parseDate = d3.timeParse("%d/%m/%Y");
parseDate(d.Seed);

Append svg

var dim = {w: 960, h: 960, margin: 5},
    width = dim.w - (dim.margin * 2),
    height = dim.h - (dim.margin * 2);

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + dim.margin + "," + dim.margin + ")");

@petrosh
Copy link
Owner Author

petrosh commented Jun 1, 2017

Images

Get image size

//Load image and get size.
var img = new Image();
img.src = logoUrl;
img.onload = function() {
 var width = this.width;
 var height = this.height;

@petrosh
Copy link
Owner Author

petrosh commented Sep 24, 2017

Objects

Delete a property

delete myObject.property;

Check empty object

Object.keys(obj).length === 0
// or
Object.getOwnPropertyNames(obj).length == 0

Store objects in element attributes

<div data-foobar='{"foo":"bar"}'></div>

Access with

$('div').data('foobar').foo

@petrosh
Copy link
Owner Author

petrosh commented Feb 22, 2018

Numbers

String to number

Number("13.4")

Round with any digit only if decimal

resolution = 10 ^ digits
Math.round(e.target.value*resolution)/resolution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant