Javascript

contentEditable bookmarklet

Edit

<a href='javascript:document.querySelectorAll("*").forEach(e=>e.contentEditable = true);'>Edit</a>

reducer

keys = ['a','b','c']
values = [1,2,3]
const data = keys.reduce((obj, key, index) => {
  obj[key] = values[index];
  return obj;
}, {});
// result: { a:1, b:2, c:3 }

download text/json data as file

const text = JSON.stringify(geoJson);
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', "output.json");
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);

delete from array using filter

this.friends = this.friends.filter((friend) => friend.id !== id);

findIndex

onImageClick(id) {
    this.index = this.events.findIndex(event => event.id === id)
}

Optional chaining (?.)

webdev cheatsheet van Hay

getJson(url)

tip van Hay

async function getJson(url) {
    const req = await window.fetch(url); //
    const json = await req.json();
    return json;
}

everything after last slash

let name = /[^/]*$/.exec(fileName)[0];

microtemplate

// micro templating, sort-of
function microTemplate( src, data ) {
  // replace {{tags}} in source
  return src.replace( /\{\{([\w\-_\.]+)\}\}/gi, function( match, key ) {
    // walk through objects to get value
    var value = data;
    key.split('.').forEach( function( part ) {
      value = value[ part ];
    });
    return value;
  });
}

Date/time as string

new Date().toJSON()
"2018-07-17T21:15:44.914Z"

(just) Date as string

new Date().toISOString().split('T')[0]

disable ipad zoom gesture

https://stackoverflow.com/questions/37808180/disable-viewport-zooming-ios-10-safari

document.addEventListener('touchmove', function (event) {
  if (event.scale !== 1) { event.preventDefault(); }
}, false);

disable ipad doubletap for zoom gesture

var lastTouchEnd = 0;
document.addEventListener('touchend', function (event) {
  var now = (new Date()).getTime();
  if (now - lastTouchEnd <= 300) {
    event.preventDefault();
  }
  lastTouchEnd = now;
}, false);

Download

//download
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', "payments.csv");
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);

Chart.js

Simple yet flexible JavaScript charting for designers & developers

GPU Accelerated JavaScript

Parallel processing

Interessante technieken voor als we met de app meer parallel willen gaan doen, zoals die floodfill: http://www.htmlgoodies.com/html5/client/using-web-workers-to-improve-performance-of-image-manipulation.html https://developer.mozilla.org/en-US/docs/Web/API/Worker/terminate De toekomst ziet er nog beter uit:
https://hacks.mozilla.org/2016/01/webgl-off-the-main-thread/ https://hacks.mozilla.org/2016/05/a-taste-of-javascripts-new-parallel-primitives/

Local Storage

Klein browser storage onderzoekje afgerond, conclusies en links:

Local storage​: Limited from 2 MB (android browser) to 10 MB (besides opera there is no option to expand this). There is no nice way to check the available space (left). Bad performance & synchronous. ​WebSQL​: Deprecated, but supported on iOS and Android browser. Usually up to 50MB. ​IndexedDB​: The future, but less supported (iOS8 has gotten buggy support). Generally at least 50 MB. More space can be requested. There is a polyfill that uses WebSQL.

Advies; Gebruik IndexedDB met Polyfill. Minder enge limieten, beschikbare ruimte is te controlleren, betere performance. Liefst via een library die het makkelijker maakt zoals Dexie.

http://www.html5rocks.com/en/tutorials/offline/quota-research/ http://www.smashingmagazine.com/2014/09/building-simple-cross-browser-offline-todo-list-indexeddb-websql/ http://stackoverflow.com/questions/3027142/calculating-usage-of-localstorage-space IndexedDB Polyfill: https://github.com/axemclion/IndexedDBShim IndexedDB wrapper: http://www.dexie.org/ (can work with polyfill) http://diveintohtml5.info/storage.html http://caniuse.com/#search=indexeddb https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria https://developers.google.com/web/updates/2011/11/Quota-Management-API-Fast-Facts

reducers

immutable

  • immutable.js

Printable bulletlist

Section 1

  • Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  • Nam eu ligula eu felis placerat consectetur quis eu arcu.
  • Duis tempus ex nec bibendum consequat. Suspendisse at mi ut mi mattis mollis in a leo.

Section 2

  • In mollis est nec tempor scelerisque.
  • Nulla augue velit, commodo in feugiat et, suscipit vitae nisi. Quisque augue justo.
  • tincidunt quis mattis sit amet, tincidunt et felis.
<style>
  div#data {
    display: none;
  }
  table {
    border: 1px solid black;
    width: 100%;
    width: 800px;
    page-break-inside:avoid;
  }
  td,th {
    text-align: left;
    font-family: Abel;
    border: 1px solid black;
  }
  h2 {
    font-family: 'Arial Black';
    font-size: 30px;
  }
  th {
    font-size: 30px;
    padding: 10px 10px 10px 10px;
  }
  table {
    margin-bottom: 30px;
    border-spacing: 0;
    border-collapse: collapse;
  }
  td.section {
    font-size: 24px;
    font-family: 'Arial Black';
  }
  td {
    width: 25%;
    padding: 10px 10px 10px 10px;
  }
  @media print {
    div.section {page-break-after: always;}
  }
  .color0 { background-color: #fdf; }
  .color1 { background-color: #dff; }
  .color2 { background-color: #fdd; }
  .color3 { background-color: #dfd; }
  .color4 { background-color: #ddf; }
  .color5 { background-color: #ffd; }
  .color6 { background-color: #fcc; }
  .color7 { background-color: #cff; }
  }
</style>

<script type="text/javascript">
  var sections = [];
  var lines = data.innerHTML.split('
');
  for (var i in lines) {
    if (lines[i].charAt(0)=='#') sections.push({title:lines[i].substr(2),items:[]});
    if (lines[i].charAt(0)=='-') sections[sections.length-1].items.push(lines[i].substr(2));
  }

  for (var i in sections) {
    var section = sections[i];
    document.write('<div class="section color'+i+'">');
    document.write('<h2>'+section.title+'</h2>');
    for (var j in section.items) {
      var item = section.items[j].trim();
      document.write('<table><tr><th colspan=4>'+item+'</th></tr><td class="section">'+section.title+'</td><td>Prioriteit:</td><td>Tijd:</td><td>Sprint #</td><//tr></table>');
    }
    document.write('</div>');
  }

</script>

React.js

see [[reactjs]]

Peter's presentation=

Babel playground

https://babeljs.io/repl/

blogpost React on ES6 plus

http://babeljs.io/blog/2015/06/07/react-on-es6-plus/

ES6 / ES7 presentation video

https://www.youtube.com/watch?v=6AytbSdWBKg

Javascript in 2015

https://www.youtube.com/watch?v=iukBMY4apvI

rendering

Array filter

function removeShortPaths(minLength,minPoints) {
  if (!minLength) minLength = 10;
  if (!minPoints) minPoints = 1;

  path.setPolylines(path.getPolylines().filter(function(polyline) {
    return polyline.getPoints().length>minPoints && polyline.getPerimeter()>minLength;
  }));

}

compile c code to javascript

objectInfo

console.log(JSON.stringify(result, null, 4));

future of javascript (ES6)

talk at FOSDEM 15: Hannes Verschore (http://H4writer.com)

compilers

  • traceur
  • 6to5

generators

generate a sequence, one item at a time. a function that can be paused in the middle

function *foo() {
   console.log("running");
   var x = yield 1;
   var y = yield 2;
   return 3;
}
var generator = foo();
//generator = { next: function() { }, throw: function() { } }
var result1 = geneator.next();
//console: "running"
//result =  {value:1, done:false}
var result 2 = generator.next();
//result = {value: 2, done: false}
var result3 = generator.next();
//result3 = {value:3, done:true }

var result 2= generator.next(10);
//result = {value:2, done:false}
var result = generator.next(20);

function *range(start,end) {
  while(start!=end) {
    yield start;
    start++;
  }
}

for (let i of range(0,10)) {
  console.log(i);
}
//result
>0
>1
>2
>......

function *fibonacci() {
....
}

classes

(with inheritance)

class Animal() {
  constructor() {
    this.cuteness = 0
  }
  approach() {
    //...
  } 
  get fullness() {
    return 100-this.cuteness; //...
  }
  set
.......

arrow function

(alternative for 'self' and/or 'bind')

function Archer() {
this.arrows = 100;
setInterval( () => {
this.arrows--;
}, 5 * 10000);
.....

destructuring

lists:

var [a,b] = [1,2];

var [a,b, ...c] = [1,2,3,4,5]
//result a=1, b=2, c=[3,4,5]

var { data:var1 } = {data : 50 }
//var1 = 50

var {m:month, y:year } =  { d:1, m:2,y:2015}
//month=2, year=2015

var { data }= { data:50 } 
//result: data=50

function g({name:x}) {
  console.log(x);
}
g({name:5, foo:0})
//console: 5

var [a] = []
a===undefined

modules

///lib.js
var privateProperty =1 ;
export var publicProperty = 2

function privateFunction() { ... }
export function publicFunction() { ...}
export default function() { ... }

/////main.js
import { publicProperty, publicFunction } from 'lib';
//..........

import (publicFunction  as libfunc } from 'lib'
//libfunc = function() {....}

module loader: 
System.import('some_module')
//returns a promise? that loads the module async

promises

function executor(resolve, reject) {
  ////

  if (....) reject();

  resolve(); //if success
}

img.then(function() {
  return imgs[1].getReadyPromise(); 
}).then(function() {
  ...
});

//Promise.all...... ?

inheritance with prototypes

var Animal = function(name) {
  this.name= name;
}
Animal.prototype.breath = function() {
  //do breath
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.bark = function() {
  //do bark
}

call the Animal super constructor from the Dog constructor

var Dog = function(name,color) {
  Animal.call(this,name);
  this.color = color; //where to declare color?
}

ECMAScript 6

FileReader

libraries & frameworks