Proxy Quick DOM
copy const spec = { get ( o, key) { return o[ key] != null ? o[ key] : o[ key] = ( ...args ) => { const el = document.createElement ( key) ; args.forEach ( arg => { if ( typeof arg === 'string' ) { const span = document.createElement ( 'span' ) ; span.innerHTML = arg; el.appendChild ( span) ; } else if ( typeof arg === 'object' ) { if ( arg.tagName != null ) { el.appendChild ( arg) ; } else { for ( let i in arg) { el.setAttribute ( i, arg[ i] ) ; } } } } ) ; return el; } } , set ( o, key, v) { o[ key] = v; } } const dom = new Proxy( { } , spec) ; document.body .appendChild ( dom.div ( dom.button ( 'cool' ) , dom.h2 ( 'some text' , { style: 'font-style: italic' } ) , dom.br ( ) , dom.input ( { placeholder: 'zevan' } ) ) ) ; const { div, input, label } = dom; document.body .appendChild ( div( label( 'Slider:' , { for : 'slider' , style: 'padding:1em;display:block' } , input( { id: 'slider' , type: 'range' } ) ) ) ) ;
Try it out…
In this snippet a proxy is used that makes all html node tagNames
valid methods. Each method can take strings and HTMLElements
as arguments in any order to create a dom structure. This may look familiar to people who have looked a bit deeper into the inner workings of some of the popular UI libraries of the last decade.
Add Getter Setter to Object
copy const target = { } let value = null ; Object .defineProperties ( target, { magic: { get ( ) { console.log ( '- getter called::' , value) ; return value; } , set ( val) { document.body .innerHTML += val + '<br>' ; value = val; } } } ) ; target.magic = 'xyz' ; target.magic = 'snippet' ; target.magic = 'zone' ; target.magic = '- last value' ; console.log ( 'getting' , target.magic ) ;
Try it out…
This snippet shows a way to add getters and setters to a specific key of an existing object. This is powerful for decorating configuration objects with special behaviors. This kind of thing can easily be created with a little more abstraction:
copy const image = view( { tag: 'img' , src: 'myImage.jpg' , x: '20%' , y: '20%' , size: '50%' } ) ; const prev = view( { tag: 'button' , x: ( ) => image.x , y: ( ) => image.bottom } ) ; const next = view( { tag: 'button' , x: ( ) => image.right - this .width , y: ( ) => image.bottom } ) ;
Nonsense Logs
copy const SPEED = 700 ; const addKeys = obj => { obj.keys = Object .keys ( obj) return obj } const wordParts = { start: addKeys( { z: .3, zim: .1, zz: .1, zzz: .1, ziz: .05, zoo: .1, koe: .05, kob: .05, 'cow cow' : .1, 'how ' : .02, sl: .1, ko: .05 } ) , mid: addKeys( { i: .1, oo: .1, a: .1, e: .3, oe: .1, ebobe: .1, y: .1 } ) , end: addKeys( { z: .3, n: .1, t: .05, rat: .1, '!' : .05, '?' : .05, '' : .1 } ) } ; const wordPart = ( type, dupeOdds = .1, dupeMax = 8 , capOdds = .05 ) => { let result = '' ; const part = wordParts[ type] ; while ( result === '' ) { const choice = part.keys [ Math .floor ( Math .random ( ) * part.keys .length ) ] ; if ( Math .random ( ) < part[ choice] ) { result = choice; if ( Math .random ( ) < dupeOdds) { const dupes = Math .round ( Math .random ( ) * Math .random ( ) * dupeMax ) ; result = result.repeat ( dupes) ; } } } wordPart.accum += result; if ( Math .random ( ) < capOdds) { wordPart.accum = wordPart.accum .toUpperCase ( ) } return wordPart; } wordPart.accum = '' ; const word = ( ) => wordPart( 'start' ) ( 'mid' ) ( 'end' ) .accum + ' ' document.body .style .fontSize = "2em" ; setInterval( ( ) => { document.body .innerHTML += word( ) ; wordPart.accum = '' } , SPEED) ;
Try it out…
Sometimes to entertain myself I will write nonsense style print/log statements. Things like console.log('cowcow')
. This snippet generates a variety of these kinds of phrases.
Random Hex Color (semi-golfed)
copy document.body .innerHTML += 'click anywhere...' onclick = ( ) => document.body .style .background = `#${ Math .random ( ) .toString ( 16 ) .substr ( - 6 ) } `
Try it out…
I golfed this snippet slightly for no reason in particular. I recently posted a nice readable way to make random hsl
colors. This snippet generates a random hexidecimal
color.
How it works:
copy Math .random ( ) // random number between 0 and 1 .toString ( 16 ) // convert to hex string (something like "0.2d6bcee4198d4") .substr ( - 6 ) // grab the last 6 characters
Here is a non-golfed version:
copy const instructionsEl = document.createElement ( 'p' ) ; instructionsEl.innerHTML = 'click anywhere...' ; document.body .appendChild ( instructionsEl) ; const randomHexColor = ( ) => `#${ Math .random ( ) .toString ( 16 ) .substr ( - 6 ) } `; document.addEventListener ( 'click' , ( ) => { document.body .style .background = randomHexColor( ) ; } ) ;
Try it out…
Proxies and Dynamic Methods
copy const spec = { get ( o, key) { console.log ( key, ':: key' ) ; return o[ key] != null ? o[ key] : o[ key] = ( ) => { document.body .innerHTML += `< div> ${ key} !</ div> `; return anyMethod( ) ; } } , set ( o, key, v) { o[ key] = v; } } ; const anyMethod = ( ) => new Proxy( { } , spec) ; anyMethod( ) .now ( ) .this ( ) .is ( ) .pretty ( ) .cool ( ) .confusing ( ) .evil ( ) ? .or ( ) .maybe ( ) .powerful ( ) [ '... what <b>do</b> <i>you</i><br>' ] ( ) .think ( ) ;
Try it out…
Proxies can be used for all manner of strange “magic”. I can actually see some uses for this, might post in the next few days…