)
}
}
)
(
}
{
)
)
(
)
(
(
{
}
)
(
)
}
)
)
{
(
(
)
)
}
)
(
}

selectAll Thoughts

  1. const lookup = new WeakMap() 
  2.  
  3. let id = 0;
  4.  
  5. export const els = selectAll(document.body)
  6. export const parentOf = el => lookup.get(el)
  7.  
  8. export function selectAll(parent) {
  9.   const els = { id, el: parent, all: {} }
  10.   const allEls = [...parent.querySelectorAll('*')]
  11.  
  12.   id++
  13.  
  14.   for (let i in allEls) {
  15.     const el = allEls[i]
  16.  
  17.     // any element can lookup `els`
  18.     lookup.set(el, els)
  19.  
  20.     const tag = el.tagName.toLowerCase()
  21.  
  22.     if (el.id) {
  23.       els[el.id] = el
  24.  
  25.       tag === 'template' &&
  26.         (els[el.id + 'Tmpl'] = () => {
  27.           const instanceEl = el.content
  28.             .cloneNode(true)
  29.             .firstElementChild
  30.           return selectAll(
  31.             instanceEl
  32.           )
  33.         })
  34.     }
  35.  
  36.     if (el.classList.length > 0) {
  37.       const name = el.classList[0]
  38.  
  39.       if (!els[name]) { 
  40.         els[name] = el
  41.         els.all[name] = [el]
  42.       } else {
  43.         els.all[name].push(el)
  44.       }
  45.     }
  46.   }
  47.   return els;
  48. }

Whenever I code a vanilla gui for some personal project/experiment I write some variation of this. I did this one a few days back to see how it would work with template tags.

// tricks // ui

Big Radio Button

  1. document.body.innerHTML = `
  2.   <p>Click/tap the radio button:</p>
  3.   <input type="radio" style="transform:translate(20px, 30px) scale(4);background:red">
  4. `;

I feel like at some point this didn’t work… nice to know it does now.

It will look different from browser to browser – as radio buttons do.

// tricks // ui

Drag Svg Circles

  1. document.addEventListener('touchmove', (e) => e.preventDefault(), {
  2.   passive: false,
  3. });
  4.  
  5. // this is just lazy - obviously goes in your stylesheet.... :P
  6. document.body.innerHTML += `
  7. <style>
  8.   body, html {
  9.     padding: 0;
  10.     height: 100%;
  11.     margin: 0;
  12.   }
  13. </style>
  14. `;
  15.  
  16. const temp = document.createElement('div');
  17. temp.innerHTML = `<svg width="100%" height="100%" viewBox="0 0 500 500"></svg>`;
  18.  
  19. const svg = document.body.appendChild(temp.querySelector('svg'));
  20.  
  21. const CIRCLE_NUM = 4;
  22.  
  23. // make some randomly positioned circles
  24. for (let i = 0; i < CIRCLE_NUM; i++) {
  25.   const x = Math.random() * 150 + 150;
  26.   const y = Math.random() * 150 + 150;
  27.   svg.innerHTML += `<circle 
  28.     cx="${x}" cy="${y}" r="60" 
  29.     stroke="#000" fill="rgba(81, 121, 200, 0.3)" 
  30.     style="cursor:pointer" />`;
  31. }
  32.  
  33. function touch(e) {
  34.   const pt = svg.createSVGPoint();
  35.   pt.x = e.clientX;
  36.   pt.y = e.clientY;
  37.   return pt.matrixTransform(svg.getScreenCTM().inverse());
  38. }
  39.  
  40. let down, ox, oy, curr;
  41. document.addEventListener('pointerdown', (e) => {
  42.   down = true;
  43.   if (e.target.tagName === 'circle') {
  44.     curr = e.target;
  45.     const { x, y } = touch(e);
  46.     ox = curr.cx.baseVal.value - x;
  47.     oy = curr.cy.baseVal.value - y;
  48.   }
  49. });
  50.  
  51. document.addEventListener('pointermove', (e) => {
  52.   if (down && curr) {
  53.     const { x, y } = touch(e);
  54.     curr.cx.baseVal.value = x + ox;
  55.     curr.cy.baseVal.value = y + oy;
  56.   }
  57. });
  58.  
  59. document.addEventListener('pointerup', (e) => {
  60.   down = false;
  61.   curr = null;
  62. });

Drag some svg circles on mobile and desktop…

// javascript // svg // ui

Confirm Background Color

  1. const btn = document.body.appendChild(
  2.   document.createElement('button')
  3. )
  4. btn.innerHTML = 'click me'
  5. btn.style.fontSize = '2em'
  6. btn.style.cursor = 'pointer'
  7. btn.addEventListener('click', e => {
  8.   if (confirm('Do you want to change the background color?')) {
  9.     const deg = Math.random() * 360
  10.     document.body.style.backgroundColor = `hsl(${deg}deg, 50%, 50%)`
  11.   }
  12. })

Change background color with a call to confirm

// javascript // ui

Select All Text contentEditable

  1. <div style="border:solid 1px #D31444"
  2.      contenteditable="true"
  3.      onclick="document.execCommand('selectAll', false, null)">some text...</div>

When clicking on an editable node, select all existing text…

Quick test version…

  1. document.body.innerHTML += `
  2.   <div id="el" style="border:solid 1px #D31444"
  3.     contenteditable="true">some text...</div>`
  4.  
  5. el.addEventListener('click', () => {
  6.   document.execCommand('selectAll', false, null)
  7. })
// html // javascript // tricks // ui
snippet.zone ~ 2021-24 /// {s/z}