DOM


SGML-like trees, но больше заточен под HTML, SVG/XML.

DOM API довольно крутой у нас.

Времена, когда нужен был jQuery, чтобы фиксить несовместимости уже прошли. Еще со времен ie10.

spec link whatwg
idl spec для расшифровки

Понятие BOM - не корректно, все, что есть в браузере разбросано по большому количеству стандартов.

Наследование

class EventTarget {
  addEventListener() {}
  removeEventListener() {}
  dispatchEvent() {} // возвращает boolean - удачно или нет
}

document.createelement('select')
select.__proto__
HTMLSelectElement.__proto__
HTMLElement.__proto__
Element.__proto__
Node.__proto__
EventTarget.__proto__
Object

addEventListener

addEventListener(type, object, options)
"click", "animationend", "input"
{
  handleEvent() {}
}
options {
  capture: true/false,
  passive: true/false (новая штука) - сказать, что preventDefault не будет и можно выполнять код параллельно например с wheel
  once: true/false (новая штука)
}

handleEvent

new Event("click", {bubbles: true})

eventPhase 0
eventPhase 1 - capture
eventPhase 2 - event.target
eventPhase 3 - bubbles

current.target == this

На window не слушать ничего, кроме ресайза и скрола, остальное на document

preventDefault
stopPropagation
stopImmediatePropagation

Node

Node.prototype.nodeType - возвращает константу типа
1 - element
3 - text node
8 - comment
11 - document fragment

someNode.contains(child) // true если содержит ребенка или сам попадает

appendChild // this
removeChild // removed
insertBefore(before, what) если null - то appendChild
replaceChild(new, old) // return old
after // принимает строку, либо ноды, строку обернет в текстовый узел
before
replaceWith
remove
append
prepend

все возвращают undefined

children, siblings, descendant - названия
childNodes, children
firstElementChild, lastElementChild, nextElementSibling
closest(selector), matches(selector)

attrs (начальное) vs IDL props (текущее значение)

innerHTML/outerHTML Возможна утечка памяти
НЕ ПИСАТЬ ТАК!!!

innerHTML +=

замена элементов на такие же, вызывать коллбеки (на кастомных элементах например), если остались ссылки, то они будут ссылаться на эл, которые уже вне дома и т.д.

insertAdjacentHTML лучше юзать

Вместо className юзать classList

Iterator есть:

Разница между NodeList и HTMLCollection.
При document.querySelectorAll - NodeList, не является массивом и инстансом массива. Static.
Делаем Array.from, [ ...document ]

fragments Раньше были проблеммы с производительностью, когда вставляли элементы по одному, поэтому нужен был createDocumentFragment. Можно юзать.

template.content.closeNode(true)

dataset

dataset
var smth = el.getAttribute('data-smth')
var {smth, camelCase, id} = el.dataset // camelCase будет camel-case

delete el.dataset.id

query/queryAll, Elements < Array

Возвращает obj instanceof Elements extends Array

document.queryAll(selectorA).map(...).queryAll()

custom events

new CustomEvent(type, {
  bubbles, cancelable, detail: {

  }
})

не надо писать

document.createEvent()
.initMouseEvent(...)

юзать конструкторы

new Document
new Text
new Event

mutation events vs observers

events не юзать (выпиливаются из движков) - проблема в синхронности

new MutationObserver(records => {

}).observe(node, {
  attributes: true,
  attributeFilter: [ "data-smth" ]
})

addy osmani

custom elements

Чтобы сделать в том числе разметку более читаемой

<hangout-message>

могут экстендить другие элементы (лучше писать так, чтобы было семантическое значение и было проще реюзать методы)

<article is=hangout-message>
</article>

<button is=send-message>
</button>

Регистрация

document.registerElement("name", {
  extends: "dialog",
  prototype: Object.create(HTMLDialogElement.prototype)
})

customElements.define('name', class extends HTMLDialogElement {
  constructor() {
    super(...arguments)
    // не писать много логики, выполняется, когда парсер встретил в html
    // не полагаться, что у элемента есть родитель, дети
  }

  connectedCallback() {
    // лоигка и слушатели тут в disconnectedCallback убирать слушатели
  }

  attributeChangedCallback() {}
})

Есть библиотеки, вроде Polymer

WEB components

web components in React

<dialog is=react-ready
  open={state.dialog}
  modal={true}
  anchor={state.pokemon}
>
</dialog>

spec

ShadowDOM

продвинутый способ инкапсулировать внутри компонента логику и стили
все, что внутри стилей будет применено только к компоненту

<link rel=import href=component.html>

<template>
  <link rel=stylesheet href=...>

</template>

<script>
  ...
</script>

link spec example