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

Remove a DOM HTML Element

  1. const button = document.createElement('button');
  2. button.innerText = 'Hello There';
  3. document.body.appendChild(button);
  4.  
  5. // click anywhere
  6. document.body.addEventListener('click', () => {
  7.   if (button.parentNode != null) {
  8.     button.parentNode.removeChild(button);
  9.   }
  10. });

In vanilla js you’ll find yourself checking if an HTML DOM element can be removed, by seeing if it has a parent (as seen above). Forgetting to do so is the source of many errors.

With the death of IE11 you can use remove()

  1. const button = document.createElement('button');
  2. button.innerText = 'Hello There 2';
  3. document.body.appendChild(button);
  4.  
  5. // click anywhere
  6. document.body.addEventListener('click', () => {
  7.    button.remove();
  8. });

No error occurs when calling remove() on something that is already removed… just like the old jQuery days 😉

// dom // javascript // ui

Normalize Value Between 0 and 1

  1. const d = document.body.appendChild(
  2.   document.createElement`div`)
  3. d.innerHTML = `
  4. <input 
  5.   id="input"
  6.   type="range" 
  7.   min="-2" max="5" 
  8.   value="0">
  9. `
  10.  
  11. let val = 0;
  12.  
  13. console.log('drag slider...')
  14.  
  15. const range = (input.max - input.min);
  16.  
  17. input.oninput = () => {
  18.   val = (input.value - input.min) / range
  19.   console.log(input.value + ' - normalized = ' + val)
  20. }
// html // javascript // math // ui

Little Grid

  1. const NUM = 9
  2. const col = 3
  3. const size = 30
  4. const pad = 10
  5. const box = (x, y) => Object.assign(
  6.   document.body.appendChild(
  7.     document.createElement('div')
  8.   ).style, {
  9.     position: 'absolute',
  10.     width: size + 'px', 
  11.     height: size + 'px',
  12.     top: y + 'px', 
  13.     left: x + 'px',
  14.     background: 'red'
  15. })
  16.  
  17. const off = (size + pad)
  18. for (let i = 0; i < NUM; i++) {
  19.   const x = (i % col) * off
  20.   const y = parseInt(i / col, 10) * off
  21.   box(x, y)
  22. }

Mutation Observer

  1. // Select the node that will be observed for mutations
  2. const targetNode = document.getElementById('some-id');
  3.  
  4. // Options for the observer (which mutations to observe)
  5. const config = { attributes: true, childList: true, subtree: true };
  6.  
  7. // Callback function to execute when mutations are observed
  8. const callback = function(mutationsList, observer) {
  9.     // Use traditional 'for loops' for IE 11 (goodbye IE11!!!!)
  10.     for(const mutation of mutationsList) {
  11.         if (mutation.type === 'childList') {
  12.             console.log('A child node has been added or removed.');
  13.         }
  14.         else if (mutation.type === 'attributes') {
  15.             console.log('The ' + mutation.attributeName + ' attribute was modified.');
  16.         }
  17.     }
  18. };
  19.  
  20. // Create an observer instance linked to the callback function
  21. const observer = new MutationObserver(callback);
  22.  
  23. // Start observing the target node for configured mutations
  24. observer.observe(targetNode, config);
  25.  
  26. // Later, you can stop observing
  27. observer.disconnect();

This is pure gold if you haven’t used it… (from MDN)

// dom // events // graphics // html // javascript // ui

React Vanilla

  1. <style>*{ font-family: sans-serif; margin-bottoM: .5em;}</style>
  2.  
  3. <h3>TODO</h3>
  4. <ul id=todos></ul>
  5. <label>What needs to be done?<br>
  6.   <input id=todo onchange="newTodo()"/><br>
  7. </label>
  8. <button id=add onclick="newTodo()">Add #1</button>
  9.  
  10. <script>
  11.   let count = 1
  12.   function newTodo() {
  13.     if (todo.value.length > 0) {
  14.       todos.innerHTML += `<li>${todo.value}</li>`
  15.       todo.value = ''
  16.       add.innerText = `Add #${++count}`
  17.     }
  18.   }
  19. </script>

I don’t really like React… Don’t get me wrong, I don’t mind it and I even kind of like using it – there’s something fun about it… But it’s surprising to me that UI work is still so bulky… I think React and most other UI libraries are overly complex… Every now and then I do evil style vanilla js versions of the React homepage examples as a sort of rebellion 😀 This is the React version of the above snippet:

  1. class TodoApp extends React.Component {
  2.   constructor(props) {
  3.     super(props);
  4.     this.state = { items: [], text: '' };
  5.     this.handleChange = this.handleChange.bind(this);
  6.     this.handleSubmit = this.handleSubmit.bind(this);
  7.   }
  8.  
  9.   render() {
  10.     return (
  11.       <div>
  12.         <h3>TODO</h3>
  13.         <TodoList items={this.state.items} />
  14.         <form onSubmit={this.handleSubmit}>
  15.           <label htmlFor="new-todo">
  16.             What needs to be done?
  17.           </label>
  18.           <input
  19.             id="new-todo"
  20.             onChange={this.handleChange}
  21.             value={this.state.text}
  22.           />
  23.           <button>
  24.             Add #{this.state.items.length + 1}
  25.           </button>
  26.         </form>
  27.       </div>
  28.     );
  29.   }
  30.  
  31.   handleChange(e) {
  32.     this.setState({ text: e.target.value });
  33.   }
  34.  
  35.   handleSubmit(e) {
  36.     e.preventDefault();
  37.     if (this.state.text.length === 0) {
  38.       return;
  39.     }
  40.     const newItem = {
  41.       text: this.state.text,
  42.       id: Date.now()
  43.     };
  44.     this.setState(state => ({
  45.       items: state.items.concat(newItem),
  46.       text: ''
  47.     }));
  48.   }
  49. }
  50.  
  51. class TodoList extends React.Component {
  52.   render() {
  53.     return (
  54.       <ul>
  55.         {this.props.items.map(item => (
  56.           <li key={item.id}>{item.text}</li>
  57.         ))}
  58.       </ul>
  59.     );
  60.   }
  61. }
  62.  
  63. root.render(<TodoApp />);
// dom // globals // hacks // humor // ui
snippet.zone ~ 2021-22 /// {s/z}