JavaScript-Snippets
Eine Snippet-Sammlung für JavaScript.
Links:
- JavaScript Reference
- DOM Reference
- TODO Blog-Artikel JavaScript Errors and Stack Traces in Depth
- TODO Blog-Artikel New regex features in ES 2018
- TODO Features von ES7 und ES8. Per Transpiling verfügbar über
babel-preset-stage-0
. - TODO Blog-Artikel Build a PWA Using Only Vanilla JavaScript
Interessante Bibliotheken:
- Frappe Charts - GitHub-instpirierte Charts. Vanilla JS.
- Proton - Particle Engine
- randomColor - Generator für zufällige Farben
- consistent-shading - zusammenpassende Farbschattierungen
- react-pdf - React renderer for creating PDF files on the browser, mobile and server (verwendet pdfkit)
ES6 (aka ES2015)
Siehe:
- Übersicht der ES6-Features
- Verbreitung von ES6
- Babel - Transformator ES6 -> ES5
- Lebab - Transformator ES5 -> ES6
- babili - ES6-Minifier
- The TC39 Process - Der Prozess über welchen ECMAScript weiterentwickelt wird. Daher kommen die Begriffe "Stage 0", "Stage 1" usw. wenn es um ES-Features geht.
Common JS in ES6 (Details siehe Doku zu import und Doku zu export):
import bla from 'blubb';
import {bar} from "foo";
export const bla = 5;
export function doSomething(params) { ... }
export default MyClass;
Common JS in ES5:
'use strict';
var bla = require('blubb');
var bar = require("foo").bar;
module.exports = MyClass;
Klassen in ES6 (Details siehe MDN-Doku):
class MyClass extends MySuperClass {
constructor() {
super('foo', 'bar');
this.name = 'Otto';
}
update(camera = createCamera()) {
this.camera = camera;
}
get name() {
return this.name;
}
set name(name) {
this.name = name;
}
static myStaticMethod() {
return 42;
}
}
Klassen in ES5:
'use strict';
var MyClass = function () {
MySuperClass.prototype.call(this, 'foo', 'bar')
this.name = 'Otto';
};
MyClass.prototype = new MySuperClass();
MyClass.prototype.constructor = MyClass;
MyClass.prototype.update = function (camera) {
camera = camera || createCamera();
this.camera = camera;
};
Object.defineProperty(MyClass.prototype, 'name', {
set: function (geometry) {
this.geometry = geometry;
},
get: function () {
return this.geometry;
}
});
MyClass.myStaticMethod = function() {
return 42;
};
let
und const
:
const myConstant = 'Bob';
let myVariable = 42;
myVariable++;
Unterschied let
und var
:
let
ist vor seiner Definition nicht sichtbar.let
hat Block als Scope,var
hat Funktion als Scope.
Beispiel:function() { for (let i = 0; i < 10; i++) { ... } // i ist nicht mehr definiert }
Template-Strings:
// Muss mit Backticks definiert werden
console.log(`Hello ${name}, you have ${5 + 1} messages!`);
Objekt-Literale:
const bob = {
name, // ES5: `name: name`
myMethod() { ... }, // ES5: `myMethod: function () { ... }`
// ES5: `var bob = {}; bob['computed' + 'Property'] = someValue`
['computed' + 'Property']: someValue
};
for...of:
const myArray = [1, 2, 3]
for (const item of myArray) {
console.log(item)
}
const myObject = { a: 1, b: 2, c: 3 }
for (const key of Object.keys(myObject)) {
console.log(`${key} - ${myObject[key]}`)
}
Destructuring:
var [a, ,b] = [1,2,3];
TODO Ist var {a, b} = {a:1, b: 2, c: 3};
ES6 oder ES7?
Arrow functions (haben außerdem das gleiche this
, wie ihr umgebender Scope):
const render = () => { ... }; // ES5: `var render = function () { ... }`
const bla = param => { ... }; // ES5: `var bla = function (param) { ... }`
const add = (n1, n2) => n1 + n2; // ES5: `var add = function (n1, n2) { return n1 + n2; }`
Shortcuts für Parameter:
function f(x = 12) {} // Default-Wert
function f(x, ...y) {} // Rest-Parameter (y ist ein Array)
function f(x, y, z) {}
f(...[1, 2, 3]); // Spread
// NodeList mit Spread in Array wandeln
let divsArray = [...document.querySelectorAll('div')];
// arguments mit Spread in Array wandeln
let argsArray = [...arguments];
Kurzschreibweisen
console.assert(+'25.4' === parseFloat('25.4')) // 25.4
console.assert(~~23.8 === Math.floor(23.8)) // 23
Reguläre Ausdrücke
function splitUrlParams() {
var urlParams = {},
regex = new RegExp('[?&]([^=]+)=([^&]+)', 'g'),
match;
while ((match = regex.exec(location.search)) !== null) {
urlParams[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
}
return urlParams;
};
Arguments in echtes Array umwandeln
var args = Array.prototype.slice.call(arguments)
Text-Selektion verhindern
var dragElemJQ = jQuery(...);
var oldSelectStart;
var onDown = function(evt) {
// Prevent text selection for FF
evt.preventDefault();
// Prevent text selection for IE
if (jQuery.browser.msie) {
oldSelectStart = document.body.onselectstart;
document.body.onselectstart = function() {
event.cancelBubble = true;
return false;
};
}
};
var onDrop = function(evt) {
if (jQuery.browser.msie) {
document.body.onselectstart = oldSelectStart;
}
};
dragElemJQ.mousedown(onDown).mouseup(onDrop).mouseout(onDrop);
Command line API
Im folgenden werden einige Befehle vorgestellt, die in der JavaScript-Konsole moderner Browser verfügbar sind - die Command line API.
Siehe:
$_
enthält das Ergebnis des letzten Konsolenaufrufs:
2 + 2 // 4
$_ // 4
$0
, $1
, $2
, $3
und $4
enthalten die letzten fünf DOM-Elemente, die im Inspector selektiert wurden ($0
ist das zuletzt selektierte Element). Arbeitet man im Tab "Profiles", dann enthalten diese Variablen die letzten fünf selektierten JavaScript-Heap-Objekte.
Shortcut für document.querySelector
(Das ist nicht jQuery, außer die Seite nutzt jQuery):
$('span.green')
// Test, ob `$` die Command line API oder jQuery ist
$ // Command line API gibt aus: `function $(selector, [startNode]) { [Command Line API] }`
Shortcut für document.querySelectorAll
:
$$('p')
Objekt als Baum-Struktur anzeigen (Shortcut für console.dir
):
dir(document.body)
JSON-Daten als Tabelle anzeigen:
data = [ { name: 'Karl', age: 23 }, { name: 'Otto', age: 78 } ]
table(data)
Ein DOM-Element inspecten:
inspect($('span.green'))
Listeners ausgeben, die per addEventListener
zu einem DOM-Element hinzugefügt wurden:
getEventListeners($0)
Gibt Events eines DOM-Elements aus:
monitorEvents($0, 'click')
monitorEvents(window, ['load', 'resize'])
unmonitorEvents($0) // Nicht mehr verfolgen - alle Events
unmonitorEvents($0, 'click') // Nicht mehr verfolgen - nur Maus-Events
Es können auch mehrere Events einer Gruppe auf einmal verfolgt werden:
monitorEvents($0, 'mouse') // mousedown, mouseup, click, dblclick, mousemove, mouseover, mouseout, mousewheel
monitorEvents($0, 'key') // keydown, keyup, keypress, textInput
monitorEvents($0, 'touch') // touchstart, touchmove, touchend, touchcancel
monitorEvents($0, 'control') // resize, scroll, zoom, focus, blur, select, change, submit, reset
Funktionsaufrufe mit Parametern in Konsole verfolgen:
monitor(myFunction)
unmonitor(myFunction) // Nicht mehr verfolgen
Breakpoint an den Anfang einer Funktion oder Methode setzen:
debug(myFunction)
debug(MyClass.myMethod)
undebug(myFunction) // Breakpoint wieder entfernen
jQuery einbinden
jQuery bindet man am besten über das CDN von Google ein. Das ist zum einen sauschnell und zum anderen ist Chance gut, dass der Browser das bereits im Cache hat.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
Auf der Seite Google Libraries API kann man jeweils sehen, welche Version aktuell ist. Außerdem sind auch andere Ressourcen aufgelistet.
SVG in PNG umwandeln (mit Transparenz)
const svgUrl = 'myimage.svg'
const width = 64
const height = 64
const svgImage = new Image()
svgImage.addEventListener('load', () => {
const canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height
const ctx = canvas.getContext('2d')
ctx.drawImage(svgImage, 0, 0, width, height)
const pngImage = document.createElement('img')
pngImage.src = canvas.toDataURL('image/png')
document.body.appendChild(pngImage)
})
svgImage.src = svgUrl
"Light" JSON erzeugen (also JavaScript-Literal-Syntax)
function toLightJson(obj) {
return JSON.stringify(obj, null, 4).replace(/"([^"]*)":/g, '$1:').replace(/"([^"]*)"/g, "'$1'")
}
Oder einfach direkt in JS-Konsole:
copy(JSON.stringify(myVar, null, 4).replaceAll(/"([^"]+)":/g, '$1:').replaceAll(/"([^"]+)"/g, "'$1'"))