Learn JavaScript

lesson ā§§ / ⧝ ¡ DOM āφāϰ event: JavaScript āĻĒāĻžāϤāĻžāϟāĻž āϛ⧁āρāϝāĻŧ⧇ āĻĻ⧇āϖ⧇

Module ā§§ā§Ē ¡ DOM āφāϰ event: JavaScript āĻĒāĻžāϤāĻžāϟāĻž āϛ⧁āρāϝāĻŧ⧇ āĻĻ⧇āϖ⧇

DOM-āĻāϰ āĻ›āĻŦāĻŋ: āĻĒāĻžāϤāĻžāϟāĻž āĻāĻ•āϟāĻž tree, āϝ⧇āϟāĻž āϤ⧋āĻŽāĻžāϰ code āĻŦāĻĻāϞāĻžāϤ⧇ āĻĒāĻžāϰ⧇

FreeāĻĒāĻĄāĻŧāĻž

āĻāχ lesson-āĻ āϝāĻž āĻļāĻŋāĻ–āĻŦ⧇

  • DOM āϕ⧀, āĻŦ⧁āĻāĻŋāϝāĻŧ⧇ āĻŦāϞ⧋: HTML āĻĨ⧇āϕ⧇ browser āϝ⧇ object-āĻāϰ tree āĻŦāĻžāύāĻžāϝāĻŧ, āφāϰ āĻĒāĻ°ā§āĻĻāĻžāϝāĻŧ āϝ⧇āϟāĻž āφāρāϕ⧇āĨ¤
  • querySelector āĻĻāĻŋāϝāĻŧ⧇ āĻāĻ•āϟāĻž element āϖ⧁āρāĻœā§‡ āĻŦ⧇āϰ āĻ•āϰ⧋, āφāϰ textContent āĻĻāĻŋāϝāĻŧ⧇ āĻ“āϰ āϞ⧇āĻ–āĻž āĻŦāĻĻāϞāĻžāĻ“āĨ¤
  • addEventListener āĻĻāĻŋāϝāĻŧ⧇ āĻĒāĻžāϤāĻžāϕ⧇ āĻāĻ•āϟāĻž click-āĻāϰ āϜāĻŦāĻžāĻŦ āĻĻ⧇āĻ“āϝāĻŧāĻžāĻ“, āφāϰ āĻŦāϞ⧋ script āϕ⧇āύ markup-āĻāϰ āĻĒāϰ⧇ āĻŦāϏ⧇āĨ¤

Mitu phone-āĻ āĻāĻ•āϟāĻž āϰāĻžāĻ¨ā§āύāĻžāϰ recipe āĻĒāĻĄāĻŧāϛ⧇, āύāĻŋāĻšā§‡āϰ heart-āϟāĻžāϝāĻŧ āϚāĻžāĻĒ āĻĻāĻŋāϞāĨ¤ Heart-āĻāϰ āĻĒāĻžāĻļ⧇āϰ āϏāĻ‚āĻ–ā§āϝāĻžāϟāĻž āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ 12 āĻĨ⧇āϕ⧇ 13 āĻšāϝāĻŧ⧇ āϗ⧇āϞāĨ¤ āĻĒāĻžāϤāĻž reload āĻšāϝāĻŧāύāĻŋ, server āĻĨ⧇āϕ⧇ āύāϤ⧁āύ āϕ⧋āύ⧋ āĻĒāĻžāϤāĻžāĻ“ āφāϏ⧇āύāĻŋāĨ¤ āĻ–ā§‹āϞāĻž āĻĒāĻžāϤāĻžāϰ āϭ⧇āϤāϰ⧇āχ āĻ•āĻŋāϛ⧁ āĻāĻ•āϟāĻž āĻāĻ•āϟāĻž āϏāĻ‚āĻ–ā§āϝāĻž āĻŦāĻĻāϞ⧇ āĻĻāĻŋāϝāĻŧ⧇āϛ⧇āĨ¤

āϏ⧇āχ āĻ•āĻŋāϛ⧁ āĻāĻ•āϟāĻž āĻšāϞ⧋ JavaScriptāĨ¤ āĻĒāĻžāϤāĻž load āĻšāĻ“āϝāĻŧāĻžāϰ āϏāĻŽāϝāĻŧ browser āĻ“āϰ HTML āĻāĻ•āĻŦāĻžāϰ āĻĒāĻĄāĻŧ⧇āϛ⧇āĨ¤ āϤāĻžāϰāĻĒāϰ āĻ“āχ HTML āĻĨ⧇āϕ⧇ object-āĻāϰ āĻāĻ•āϟāĻž tree āĻŦāĻžāύāĻŋāϝāĻŧ⧇āϛ⧇, āφāϰ āĻĒāĻ°ā§āĻĻāĻž āφāρāϕ⧇ āϏ⧇āχ tree āĻĻ⧇āϖ⧇āĨ¤ Script tree-āϰ āϭ⧇āϤāϰ⧇ āĻšāĻžāϤ āĻĻāĻŋāϝāĻŧ⧇ āĻāĻ•āϟāĻž node āĻŦāĻĻāϞāĻžāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ Browser āĻŦāĻĻāϞāϟāĻž āĻŸā§‡āϰ āĻĒāĻžāϝāĻŧ, āφāϰ āĻĒāĻ°ā§āĻĻāĻž āφāĻŦāĻžāϰ āφāρāϕ⧇āĨ¤ āĻāχ tree-āϟāĻžāχ DOM, āĻŽāĻžāύ⧇ Document Object ModelāĨ¤

āĻāϤāĻĻāĻŋāύ āĻāχ track-āĻāϰ āĻĒā§āϰāϤāĻŋāϟāĻž program āϚāϞ⧇āϛ⧇ Node-āĻ, āϕ⧋āύ⧋ āĻĒāĻžāϤāĻž āĻŦāĻž āĻĒāĻ°ā§āĻĻāĻž āĻ›āĻžāĻĄāĻŧāĻžāĨ¤ āĻāχ module āĻĸ⧁āĻ•āϛ⧇ browser-āĻāĨ¤ āĻāĻ–āĻžāύāĻ•āĻžāϰ āĻĒā§āϰāϤāĻŋāϟāĻž āĻĒāĻžāϤāĻžāϰ program āϚāϞ⧇ lesson-āĻāϰ āĻĒāĻžāĻļ⧇āϰ preview-āϤ⧇: Run āϚāĻžāĻĒā§‹, āĻĒāĻžāϤāĻžāϟāĻž āϖ⧁āϞāĻŦ⧇ āĻāĻ•āϟāĻž āϛ⧋āϟ sandbox āĻ•āϰāĻž frame-āĻ, āφāϰ āĻ“āϰ console āĻĻ⧇āĻ–āĻž āϝāĻžāĻŦ⧇ āĻ āĻŋāĻ• āύāĻŋāĻšā§‡āĨ¤ Judge āĻ•āϰāĻž problem-āϗ⧁āϞ⧋ āĻāĻ–āύ⧋ āϚāϞ⧇ Node-āĻ, āϤāĻžāχ āĻ“āϰāĻž āĻāĻ•āχ āϰāĻ•āĻŽ tree āύāĻŋāϝāĻŧ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇, āϏāĻžāϧāĻžāϰāĻŖ object āĻšāĻŋāϏ⧇āĻŦ⧇ āϞ⧇āĻ–āĻžāĨ¤

āĻĒāĻžāϤāĻžāϟāĻž āĻāĻ•āϟāĻž tree

HTML āĻšāϞ⧋ textāĨ¤ āĻāχ āϝ⧇ āϤāĻžāϰ āĻāĻ•āϟāĻž āϛ⧋āϟ āϟ⧁āĻ•āϰ⧋, āĻāĻ•āϟāĻž āĻŦāĻžāϜāĻžāϰ⧇āϰ list:

<ul id="list">
  <li>rice</li>
  <li>dal</li>
</ul>

Browser āĻāχ text āĻĒāĻĄāĻŧāĻžāϰ āĻĒāϰ⧇ āĻ“āϟāĻžāϕ⧇ text āĻšāĻŋāϏ⧇āĻŦ⧇ āϰ⧇āϖ⧇ āĻĻ⧇āϝāĻŧ āύāĻžāĨ¤ āĻ“ object āĻŦāĻžāύāĻžāϝāĻŧāĨ¤ ul āĻšāϝāĻŧ āĻāĻ•āϟāĻž element objectāĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻž li-āĻ“ āĻāĻ•āϟāĻž element object, āφāϰ āĻ“āϰāĻž ul-āĻāϰ childāĨ¤ āϭ⧇āϤāϰ⧇āϰ āĻļāĻŦā§āĻĻāϗ⧁āϞ⧋, rice āφāϰ dal, āĻšāϝāĻŧ text node, āύāĻŋāĻœā§‡āϰ āύāĻŋāĻœā§‡āϰ li-āĻāϰ childāĨ¤ āϏāĻŦāĻžāϰ āĻ“āĻĒāϰ⧇āϰāϟāĻž āĻ›āĻžāĻĄāĻŧāĻž āĻĒā§āϰāϤāĻŋāϟāĻž node-āĻāϰ āĻ āĻŋāĻ• āĻāĻ•āϜāύ parent āĻĨāĻžāϕ⧇āĨ¤

āĻĒ⧁āϰ⧋ tree-āϰ āĻŽāĻžāĻĨāĻžāϝāĻŧ āĻĨāĻžāϕ⧇ documentāĨ¤ āĻ“āϰ āύāĻŋāĻšā§‡ html element, āφāϰ āϤāĻžāϰ āύāĻŋāĻšā§‡ head āφāϰ bodyāĨ¤ āĻĒāĻžāϤāĻžāϝāĻŧ āϝāĻž āĻ•āĻŋāϛ⧁ āĻĻ⧇āĻ–ā§‹, āϏāĻŦ āĻĨāĻžāϕ⧇ body-āϰ āύāĻŋāĻšā§‡ āϕ⧋āĻĨāĻžāĻ“ āύāĻž āϕ⧋āĻĨāĻžāĻ“āĨ¤

āĻāĻŽāύ āĻāĻ•āϟāĻž tree āϏāĻžāϧāĻžāϰāĻŖ JavaScript object āĻĻāĻŋāϝāĻŧ⧇ āϏāĻšāĻœā§‡āχ āϞ⧇āĻ–āĻž āϝāĻžāϝāĻŧāĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻž node āĻāĻ•āϟāĻž object, āϝāĻžāϰ āĻāĻ•āϟāĻž tag āφāϰ child-āĻĻ⧇āϰ āĻāĻ•āϟāĻž list āφāϛ⧇āĨ¤ āύāĻŋāĻšā§‡āϰ program Node-āĻ āϚāϞ⧇, browser āĻ›āĻžāĻĄāĻŧāĻžāχāĨ¤ āĻ“ tree-āϟāĻž print āĻ•āϰ⧇, āĻĒā§āϰāϤāĻŋāϟāĻž child āϤāĻžāϰ parent-āĻāϰ āύāĻŋāĻšā§‡ āĻāĻ•āϟ⧁ āϏāϰ⧇ āĻŦāϏ⧇, āĻ āĻŋāĻ• āϝ⧇āĻ­āĻžāĻŦ⧇ DevTools-āĻāϰ Elements pane āĻāĻ•āϟāĻž āĻĒāĻžāϤāĻž āĻĻ⧇āĻ–āĻžāϝāĻŧāĨ¤

const page = {
  tag: "body",
  children: [
    { tag: "h1", children: [{ text: "Bazar list" }] },
    {
      tag: "ul",
      children: [
        { tag: "li", children: [{ text: "rice" }] },
        { tag: "li", children: [{ text: "dal" }] },
      ],
    },
  ],
};

function show(node, depth) {
  const pad = "  ".repeat(depth);
  if (node.text !== undefined) {
    console.log(pad + '"' + node.text + '"');
    return;
  }
  console.log(pad + "<" + node.tag + ">");
  for (const child of node.children) show(child, depth + 1);
}

show(page, 0);
<body>
  <h1>
    "Bazar list"
  <ul>
    <li>
      "rice"
    <li>
      "dal"
Run in Compiler

āφāϏāϞ DOM-āĻāϰ āφāĻ•āĻžāϰāĻ“ āĻāϟāĻžāχ, āĻļ⧁āϧ⧁ āĻĒā§āϰāϤāĻŋāϟāĻž node-āĻ āφāϰāĻ“ āĻ…āύ⧇āĻ• āĻ•āĻŋāϛ⧁ āĻĨāĻžāϕ⧇āĨ¤ Browser-āĻāϰ āĻāĻ•āϟāĻž element-āĻ āĻĨāĻžāϕ⧇ āĻ“āϰ tag, attribute, child, parent, style, āφāϰ āĻļāϤ āĻļāϤ methodāĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻŽā§‚āϞ āĻ•āĻĨāĻž āĻāχ program-āĻāϰāϟāĻžāχ: node, āϤāĻžāĻĻ⧇āϰ child, āφāϰ āĻĒā§āϰāĻ¤ā§āϝ⧇āϕ⧇āϰ āĻāĻ•āϜāύ parentāĨ¤

Tree-āϤ⧇ āύāϤ⧁āύ āĻāĻ•āϟāĻž node āĻœā§‹āĻĄāĻŧāĻž

āĻĒāĻžāϤāĻž āĻŦāĻĻāϞāĻžāύ⧋ āĻŽāĻžāύ⧇ tree āĻŦāĻĻāϞāĻžāύ⧋āĨ¤ List-āĻ āϤ⧃āϤ⧀āϝāĻŧ āĻāĻ•āϟāĻž item āĻĻāĻŋāϤ⧇ script āĻāĻ•āϟāĻž āύāϤ⧁āύ li object āĻŦāĻžāύāĻžāϝāĻŧ, āφāϰ āĻ“āϟāĻžāϕ⧇ ul-āĻāϰ āύāĻŋāĻšā§‡ āϜ⧁āĻĄāĻŧ⧇ āĻĻ⧇āϝāĻŧāĨ¤ Insert āĻŽāĻžāύ⧇ āĻāϟ⧁āϕ⧁āχ: parent āĻāĻ•āϟāĻž child āĻŦ⧇āĻļāĻŋ āĻĒāĻžāϝāĻŧ, āφāϰ child āĻœā§‡āύ⧇ āύ⧇āϝāĻŧ āϕ⧇ āĻ“āϰ parentāĨ¤

āύāĻŋāĻšā§‡ āϧāĻžāĻĒ⧇ āϧāĻžāĻĒ⧇ āĻĻ⧇āĻ–ā§‹, list-āĻāϰ āϏāĻžāϧāĻžāϰāĻŖ object version-āĻāĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻž box āĻāĻ•āϟāĻž object, āφāϰ āĻĒā§āϰāϤāĻŋāϟāĻž āϤ⧀āϰ āĻāĻ• object āĻĨ⧇āϕ⧇ āφāϰ⧇āĻ• object-āĻāϰ āĻĻāĻŋāϕ⧇ āĻāĻ•āϟāĻž referenceāĨ¤ children array āύāĻŋāĻœā§‡āχ āĻāĻ•āϟāĻž āφāϞāĻžāĻĻāĻž boxāĨ¤

āĻāĻ•āχ āϧāĻžāĻĒāϗ⧁āϞ⧋ table-āĻ, āĻĒā§āϰāϤāĻŋ āϧāĻžāĻĒ⧇ āĻāĻ•āϟāĻž rowāĨ¤

āϧāĻžāĻĒLineChangedāϕ⧀ āĻšāϞ⧋
1const list = { tag: "ul", children: [] };list āĻšāϞ⧋ box o1, āφāϰ āĻ“āϰ children array āĻĢāĻžāρāĻ•āĻž: length 0āĨ¤
2const a = { tag: "li", text: "rice", parent: list };a āĻ“āĻĒāϰ⧇ āĻ“āϰ parent-āϕ⧇ āĻĻ⧇āĻ–āĻžāϝāĻŧ, āĻ•āĻŋāĻ¨ā§āϤ⧁ list āĻāĻ–āύ⧋ a-āϕ⧇ āĻšā§‡āύ⧇ āύāĻž: children 0āϟāĻžāĨ¤
3list.children.push(a);o2.0āĻāĻ–āύ āϤ⧀āϰ āĻĻ⧁āχ āĻĻāĻŋāϕ⧇āχ: a āĻšāϞ⧋ list-āĻāϰ 0 āύāĻŽā§āĻŦāϰ childāĨ¤
4const b = { tag: "li", text: "dal", parent: list };āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āĻāĻ•āϟāĻž item, dal, āĻŦāĻžāύāĻžāύ⧋ āĻšāϞ⧋ āĻāĻ•āχ parent āĻĻāĻŋāϝāĻŧ⧇āĨ¤
5list.children.push(b);o2.1append āĻ āĻŋāĻ• āĻāϟāĻžāχ āĻ•āϰ⧇: list-āĻāϰ āĻāĻ–āύ 2āϟāĻž child, āĻ•ā§āϰāĻŽ āϧāϰ⧇āĨ¤
6list.children.splice(0, 1); a.parent = null;o2.0āϏāϰāĻžāύ⧋ āĻŽāĻžāύ⧇ āĻĻ⧁āĻŸā§‹ āϤ⧀āϰāχ āĻ•āĻžāϟāĻž: list-āĻ āĻĨāĻžāϕ⧇ 1āϟāĻž child, dal, āφāϰ a-āĻāϰ āϕ⧋āύ⧋ parent āύ⧇āχāĨ¤

āĻŽāύ⧇ āϰāĻžāĻ–āĻžāϰ āϧāĻžāĻĒāϟāĻž āϧāĻžāĻĒ 3āĨ¤ āĻāĻ•āϟāĻž node tree-āϤ⧇ āφāϛ⧇ āϕ⧇āĻŦāϞ āϤāĻ–āύāχ, āϝāĻ–āύ āĻ“āϰ parent āĻ“āϕ⧇ child āĻšāĻŋāϏ⧇āĻŦ⧇ list-āĻ āϰāĻžāϖ⧇āĨ¤ Object āĻŦāĻžāύāĻžāϞ⧇āχ āĻšāϝāĻŧ āύāĻžāĨ¤ Browser-āĻ append āϤ⧋āĻŽāĻžāϰ āĻšāϝāĻŧ⧇ āĻĻ⧁āĻŸā§‹ āĻ…āĻ‚āĻļāχ āĻ•āϰ⧇ āĻĻ⧇āϝāĻŧ, āφāϰ remove āĻĻ⧁āĻŸā§‹āχ āωāĻ˛ā§āĻŸā§‡ āĻĻ⧇āϝāĻŧāĨ¤

Element āϖ⧁āρāĻœā§‡ āĻŦ⧇āϰ āĻ•āϰāĻž: querySelector

āĻāĻ•āϟāĻž node āĻŦāĻĻāϞāĻžāϤ⧇ āĻšāϞ⧇ script-āĻāϰ āφāϗ⧇ āĻ“āϰ āĻāĻ•āϟāĻž reference āϞāĻžāϗ⧇āĨ¤ āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āĻ•āĻžāĻœā§‡āϰ āĻ–ā§‹āρāϜāĻžāϰ āωāĻĒāĻžāϝāĻŧ āĻšāϞ⧋ document.querySelectorāĨ¤ āĻ“āϕ⧇ āĻāĻ•āϟāĻž CSS selector āĻĻāĻžāĻ“, stylesheet āϝ⧇ text āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻ āĻŋāĻ• āϏ⧇āϟāĻž, āφāϰ āĻ“ āĻĢ⧇āϰāϤ āĻĻ⧇āĻŦ⧇ āĻŽā§‡āϞ⧇ āĻāĻŽāύ āĻĒā§āϰāĻĨāĻŽ element-āϟāĻž, āĻ•āĻŋāϛ⧁ āύāĻž āĻŽāĻŋāϞāϞ⧇ nullāĨ¤

  • "h1" āĻ–ā§‹āρāĻœā§‡ āĻĒā§āϰāĻĨāĻŽ h1āĨ¤
  • "#list" āĻ–ā§‹āρāĻœā§‡ āϏ⧇āχ element, āϝāĻžāϰ id āĻšāϞ⧋ listāĨ¤
  • ".price" āĻ–ā§‹āρāĻœā§‡ price class-āĻ“āϝāĻŧāĻžāϞāĻž āĻĒā§āϰāĻĨāĻŽ elementāĨ¤
  • "#list li" āĻ–ā§‹āρāĻœā§‡ #list-āĻāϰ āϭ⧇āϤāϰ⧇āϰ āĻĒā§āϰāĻĨāĻŽ liāĨ¤

Selector āĻšāϞ⧋ tree-āϕ⧇ āĻ•āϰāĻž āĻāĻ•āϟāĻž āĻĒā§āϰāĻļā§āύ, āφāϰ querySelector āωāĻ¤ā§āϤāϰ āĻĻāĻŋāϤ⧇ tree-āϰ āϭ⧇āϤāϰ āĻĻāĻŋāϝāĻŧ⧇ āĻšāĻžāρāĻŸā§‡āĨ¤ āϝ⧇ āϏāĻŦ āĻŽāĻŋāϞ āĻĢ⧇āϰāϤ āĻĻ⧇āϝāĻŧ, āϏ⧇āχ querySelectorAll āφāϛ⧇ Lesson 02-āĻāĨ¤

āϞ⧇āĻ–āĻžāϟāĻž āĻŦāĻĻāϞāĻžāύ⧋: textContent

āĻĒā§āϰāϤāĻŋāϟāĻž element-āĻāϰ āĻāĻ•āϟāĻž textContent property āφāϛ⧇āĨ¤ āĻĒāĻĄāĻŧāϞ⧇ āĻĒāĻžāĻ“āϝāĻŧāĻž āϝāĻžāϝāĻŧ element-āĻāϰ āϭ⧇āϤāϰ⧇āϰ āϏāĻŦ āϞ⧇āĻ–āĻžāĨ¤ āϞāĻŋāĻ–āϞ⧇ āϭ⧇āϤāϰ⧇āϰ āϏāĻŦāĻ•āĻŋāϛ⧁ āϏāϰ⧇ āĻ—āĻŋāϝāĻŧ⧇ āĻŦāϏ⧇ āĻāĻ•āϟāĻž text node, āϤ⧋āĻŽāĻžāϰ string āύāĻŋāϝāĻŧ⧇āĨ¤ āύāĻŋāĻšā§‡āϰ āĻĒāĻžāϤāĻž heading āφāϰ āĻĒā§āϰāĻĨāĻŽ item āϖ⧁āρāĻœā§‡ āύ⧇āϝāĻŧ, āϤāĻžāϰāĻĒāϰ āĻĻ⧁āĻŸā§‹āχ āĻŦāĻĻāϞāĻžāϝāĻŧāĨ¤ Run āϚāĻžāĻĒā§‹āĨ¤

<h1>Bazar list</h1>
<ul id="list">
  <li>rice</li>
  <li>dal</li>
</ul>
<p id="note"></p>
<script>
  const title = document.querySelector("h1");
  const first = document.querySelector("#list li");
  console.log("before:", first.textContent);
  title.textContent = "Bazar list for Friday";
  first.textContent = "basmati rice";
  document.querySelector("#note").textContent = "2 items, edited by the script";
</script>
Run in Compiler

āĻĒāĻžāϤāĻžāϝāĻŧ āĻĻ⧇āĻ–āĻž āϝāĻžāϝāĻŧ āύāϤ⧁āύ heading, āφāϰ āĻĒā§āϰāĻĨāĻŽ item āĻšāĻŋāϏ⧇āĻŦ⧇ "basmati rice"āĨ¤ āĻĒāĻžāϤāĻžāϰ āύāĻŋāĻšā§‡āϰ console āĻĻ⧇āĻ–āĻžāϝāĻŧ āĻĒ⧁āϰ⧋āύ⧋ āϞ⧇āĻ–āĻž, rice, āĻ•āĻžāϰāĻŖ script āĻ“āϟāĻž āĻŦāĻĻāϞāĻžāύ⧋āϰ āφāϗ⧇ āĻĒāĻĄāĻŧ⧇āĻ›āĻŋāϞāĨ¤ āĻ“āĻĒāϰ⧇āϰ box-āĻāϰ HTML āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāĻ•āϟ⧁āĻ“ āĻŦāĻĻāϞāĻžāϝāĻŧāύāĻŋāĨ¤ āĻŦāĻĻāϞ⧇āϛ⧇ āĻļ⧁āϧ⧁ tree, āφāϰ āĻĒāĻ°ā§āĻĻāĻž āϚāϞ⧇ tree-āϰ āĻĒ⧇āĻ›āύ āĻĒ⧇āĻ›āύāĨ¤

āĻļā§‹āύāĻž: addEventListener

āϝ⧇ āĻĒāĻžāϤāĻž āύāĻŋāĻœā§‡āϕ⧇ āĻāĻ•āĻŦāĻžāϰ āĻŦāĻĻāϞ⧇āχ āĻĨ⧇āĻŽā§‡ āϝāĻžāϝāĻŧ, āϏ⧇āϟāĻž āϖ⧁āĻŦ āĻāĻ•āϟāĻž āĻ•āĻžāĻœā§‡āϰ āύāĻžāĨ¤ āĻŽāϜāĻžāϰ āĻ…āĻ‚āĻļ āĻšāϞ⧋ āĻĒāĻžāĻ āϕ⧇āϰ āϜāĻŦāĻžāĻŦ āĻĻ⧇āĻ“āϝāĻŧāĻžāĨ¤ āĻĒāĻžāĻ āĻ• click āĻ•āϰāϞ⧇, āϞāĻŋāĻ–āϞ⧇ āĻŦāĻž āϕ⧋āύ⧋ key āϚāĻžāĻĒāϞ⧇ browser āĻāĻ•āϟāĻž event āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤ Script addEventListener āĻĻāĻŋāϝāĻŧ⧇ āĻŦāϞ⧇ āϰāĻžāĻ–āϤ⧇ āĻĒāĻžāϰ⧇, āĻāĻ•āϟāĻž element-āĻāϰ event āĻšāϞ⧇ āĻ“āϕ⧇ āϝ⧇āύ āϜāĻžāύāĻžāύ⧋ āĻšāϝāĻŧāĨ¤

button.addEventListener("click", handler) āĻŽāĻžāύ⧇: āĻāχ button-āĻ āϝāϤāĻŦāĻžāϰ click āĻĒāĻĄāĻŧāĻŦ⧇, handler-āϕ⧇ āĻĄāĻžāϕ⧋āĨ¤ Handler āĻāĻ•āϟāĻž āϏāĻžāϧāĻžāϰāĻŖ function, āĻāĻ•āϟāĻž callback, āĻšā§āĻŦāĻšā§ Module 12-āĻāϰ callback-āϗ⧁āϞ⧋āϰ āĻŽāϤ⧋āĨ¤ Browser āĻ“āϕ⧇ āĻĄāĻžāϕ⧇ āĻĒāϰ⧇, āĻĒā§āϰāϤāĻŋāϟāĻž click-āĻ āĻāĻ•āĻŦāĻžāϰ, event loop-āĻāϰ āϕ⧋āύ⧋ āĻāĻ• āĻĒāĻžāϞāĻžāϝāĻŧāĨ¤

<p>Likes: <span id="likes">12</span></p>
<button id="heart">Like</button>
<script>
  const likes = document.querySelector("#likes");
  const heart = document.querySelector("#heart");
  let count = 12;
  heart.addEventListener("click", () => {
    count = count + 1;
    likes.textContent = String(count);
    console.log("clicked, likes are now", count);
  });
  console.log("listener added");
</script>
Run in Compiler

āϚāĻžāϞāĻžāĻ“, āφāϰ button-āϟāĻžāϝāĻŧ āĻ•āϝāĻŧ⧇āĻ•āĻŦāĻžāϰ click āĻ•āϰ⧋āĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻž click-āĻ āϏāĻ‚āĻ–ā§āϝāĻž āĻāĻ• āĻ•āϰ⧇ āĻŦāĻžāĻĄāĻŧ⧇, āφāϰ console āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻāĻ•āϟāĻž āϞāĻžāχāύ print āĻ•āϰ⧇āĨ¤ āϖ⧇āϝāĻŧāĻžāϞ āĻ•āϰ⧋ "listener added" print āĻšāϝāĻŧ⧇āϛ⧇ āϏāĻŦāĻžāϰ āφāϗ⧇, āϕ⧋āύ⧋ click-āĻāϰ āφāϗ⧇āχāĨ¤ Listener āϝ⧋āĻ— āĻ•āϰāϞ⧇ āĻ“āϟāĻž āϚāϞ⧇ āύāĻžāĨ¤ āĻļ⧁āϧ⧁ function-āϟāĻž button-āĻāϰ āĻ•āĻžāϛ⧇ āϰ⧇āϖ⧇ āĻĻ⧇āĻ“āϝāĻŧāĻž āĻšāϝāĻŧ, click āφāϏāĻž āĻĒāĻ°ā§āϝāĻ¨ā§āϤāĨ¤

āφāϰāĻ“ āϖ⧇āϝāĻŧāĻžāϞ āĻ•āϰ⧋ count āϕ⧋āĻĨāĻžāϝāĻŧ āĻĨāĻžāϕ⧇: āĻāĻ•āϟāĻž variable-āĻ, countāĨ¤ āĻĒāĻžāϤāĻž count āĻĻ⧇āĻ–āĻžāϝāĻŧ āĻ āĻŋāĻ•āχ, āĻ•āĻŋāĻ¨ā§āϤ⧁ script āĻĒāĻžāϤāĻž āĻĨ⧇āϕ⧇ āĻ“āϟāĻž āφāĻŦāĻžāϰ āĻĒāĻĄāĻŧ⧇ āύ⧇āϝāĻŧ āύāĻžāĨ¤ āĻāχ āĻ…āĻ­ā§āϝāĻžāϏ āϕ⧇āύ āϜāϰ⧁āϰāĻŋ, Lesson 04 āĻŦāϞāĻŦ⧇āĨ¤

Click-āĻāϰ āϝāĻžāĻ¤ā§āϰāĻž: bubbling

Button-āĻ āĻāĻ•āϟāĻž click āĻŽāĻžāύ⧇ āĻ“āϰ āϚāĻžāϰāĻĒāĻžāĻļ⧇āϰ āϏāĻŦāĻ•āĻŋāϛ⧁āϤ⧇āĻ“ click: āϝ⧇ p āĻŦāĻž div-āĻ āĻ“ āĻŦāϏ⧇ āφāϛ⧇, body, āĻĒ⧁āϰ⧋ documentāĨ¤ Browser āĻāϟāĻž āϏāĻžāĻŽāϞāĻžāϝāĻŧ event-āϕ⧇ bubble āĻ•āϰāϤ⧇ āĻĻāĻŋāϝāĻŧ⧇āĨ¤ āφāϗ⧇ āϚāϞ⧇ click āĻĒāĻĄāĻŧāĻž element-āĻāϰ listener, āϤāĻžāϰāĻĒāϰ āĻ“āϰ parent-āĻāϰ, āϤāĻžāϰāĻĒāϰ parent-āĻāϰ parent-āĻāϰ, āĻāĻ•āĻĻāĻŽ āĻ“āĻĒāϰ āĻĒāĻ°ā§āϝāĻ¨ā§āϤāĨ¤

āϝ⧇ element-āĻ āϏāĻ¤ā§āϝāĻŋāχ click āĻĒāĻĄāĻŧ⧇āϛ⧇, āϏ⧇āϟāĻž āĻšāϞ⧋ event-āĻāϰ targetāĨ¤ āύāĻŋāĻšā§‡ āĻāĻ•āϟāĻž click-āĻāϰ āĻĒāĻĨ āĻŦ⧇āϰ āĻ•āϰāĻž āĻšāϞ⧋ Node-āĻ, āϏāĻžāϧāĻžāϰāĻŖ object-āĻāϰ āĻāĻ•āϟāĻž tree-āϤ⧇āĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻž node āĻ“āϰ parent-āϕ⧇ āĻšā§‡āύ⧇, āϤāĻžāχ āĻĒāĻĨ āĻŽāĻžāύ⧇ parent-āĻāϰ āϏ⧂āĻ¤ā§āϰ āϧāϰ⧇ āĻ“āĻĒāϰ⧇ āĻšāĻžāρāϟāĻžāĨ¤

const body = { tag: "body", parent: null };
const main = { tag: "main", parent: body };
const card = { tag: "div", parent: main };
const heart = { tag: "button", parent: card };

const route = [];
for (let node = heart; node !== null; node = node.parent) route.push(node.tag);
console.log("target:", heart.tag);
console.log("bubbles through:", route.join(" > "));
target: button
bubbles through: button > div > main > body
Run in Compiler

Bubbling āφāϛ⧇ āĻŦāϞ⧇āχ parent-āĻāϰ āĻāĻ•āϟāĻž listener āĻ“āϰ āϏāĻŦ child-āĻāϰ click āĻļ⧁āύāϤ⧇ āĻĒāĻžāϝāĻŧāĨ¤ āĻāχ āĻ•ā§ŒāĻļāϞ⧇āϰ āύāĻžāĻŽ delegation, Lesson 02 āĻāϟāĻž āĻŦāĻžāύāĻžāĻŦ⧇āĨ¤ āφāĻĒāĻžāϤāϤ āĻ›āĻŦāĻŋāϟāĻž āĻŽāύ⧇ āϰāĻžāĻ–ā§‹: event āĻļ⧁āϰ⧁ āĻšāϝāĻŧ target āĻĨ⧇āϕ⧇, āϤāĻžāϰāĻĒāϰ āĻ“āĻĒāϰ⧇ āĻ“āϠ⧇āĨ¤

Script āϕ⧋āĻĨāĻžāϝāĻŧ āĻŦāϏāĻŦ⧇

Browser āĻĒāĻžāϤāĻž āĻĒāĻĄāĻŧāϤ⧇ āĻĒāĻĄāĻŧāϤ⧇ āϝāĻ–āύ āĻāĻ•āϟāĻž script-āĻ āĻĒ⧌āρāĻ›āĻžāϝāĻŧ, āϤāĻ–āύāχ āϏ⧇āϟāĻž āϚāϞ⧇āĨ¤ āĻ“āĻĒāϰ⧇āϰ āĻĒāĻžāϤāĻžāϗ⧁āϞ⧋ <script> āϰ⧇āϖ⧇āϛ⧇ āĻļ⧇āώ⧇, markup-āĻāϰ āĻĒāϰ⧇āĨ¤ āĻāχ āĻ•ā§āϰāĻŽāϟāĻž āϜāϰ⧁āϰāĻŋāĨ¤ Script āϝāĻ–āύ āϚāϞ⧇, āĻ“āϰ āĻ“āĻĒāϰ⧇āϰ element-āϗ⧁āϞ⧋ āϤāϤāĻ•ā§āώāϪ⧇ tree-āϤ⧇ āϤ⧈āϰāĻŋ, āϤāĻžāχ querySelector āĻ“āĻĻ⧇āϰ āϖ⧁āρāĻœā§‡ āĻĒāĻžāϝāĻŧāĨ¤

āĻāĻ•āχ script āĻ“āĻĒāϰ⧇ āĻŦāϏāĻžāĻ“, element-āϗ⧁āϞ⧋āϰ āφāϗ⧇, āϤāĻžāĻšāϞ⧇ querySelector āĻĢ⧇āϰāϤ āĻĻ⧇āĻŦ⧇ null, āĻ•āĻžāϰāĻŖ āĻ“āχ node-āϗ⧁āϞ⧋ āϤāĻ–āύ⧋ āĻŦāĻžāύāĻžāύ⧋ āĻšāϝāĻŧāύāĻŋāĨ¤ āĻšā§‡āύāĻž āĻĻ⧁āĻŸā§‹ āϏāĻŽāĻžāϧāĻžāύ āφāϛ⧇āĨ¤ āĻāĻ•āϟāĻž āĻšāϞ⧋ script āĻļ⧇āώ⧇ āϰāĻžāĻ–āĻžāĨ¤ āφāϰ⧇āĻ•āϟāĻž āĻšāϞ⧋ DOMContentLoaded event-āĻāϰ āϜāĻ¨ā§āϝ āĻ…āĻĒ⧇āĻ•ā§āώāĻž āĻ•āϰāĻž, āĻĒ⧁āϰ⧋ tree āϤ⧈āϰāĻŋ āĻšāϞ⧇ āϝ⧇āϟāĻž āĻāĻ•āĻŦāĻžāϰ āϘāĻŸā§‡āĨ¤ āύāĻŋāĻšā§‡āϰ āĻĒā§āϰāĻĨāĻŽ āϭ⧁āϞāϟāĻž āĻāχ bug āĻĻ⧇āĻ–āĻžāϝāĻŧāĨ¤

āĻāĻ• āύāϜāϰ⧇ DOM

const el = document.querySelector("#list li");   // the first match, or null
el.textContent = "new text";                     // replace what it says, as plain text
const item = document.createElement("li");       // a new element, not in the page yet
list.append(item);                               // attach it as the last child
el.addEventListener("click", (event) => {        // call this on every click
  console.log(event.target);                     // the element really clicked
});
Example 1: āĻāĻŽāύ āĻāĻ•āϟāĻž counter, āϝ⧇āϟāĻž āĻļā§‚āĻ¨ā§āϝ⧇āϰ āύāĻŋāĻšā§‡ āύāĻžāĻŽā§‡ āύāĻž

āĻĻ⧁āĻŸā§‹ button āĻāĻ•āϟāĻž āϏāĻ‚āĻ–ā§āϝāĻž āĻŦāĻĻāϞāĻžāϝāĻŧāĨ¤ āϏāĻ‚āĻ–ā§āϝāĻžāϟāĻž āĻĨāĻžāϕ⧇ āĻāĻ•āϟāĻž variable-āĻ, āφāϰ āĻāĻ•āϟāĻž āϛ⧋āϟ function āĻ“āϟāĻž āφāρāϕ⧇āĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻž handler āφāϗ⧇ variable āĻŦāĻĻāϞāĻžāϝāĻŧ, āϤāĻžāϰāĻĒāϰ āφāρāĻ•āĻžāϰ function āĻĄāĻžāϕ⧇āĨ¤ āĻāϤ⧇ āĻĒāĻžāϤāĻž āφāϰ variable āϏāĻŦāϏāĻŽāϝāĻŧ āĻŽāĻŋāϞ⧇ āĻĨāĻžāϕ⧇āĨ¤

<style>
  .count { font-size: 2rem; margin: 0.5rem 0; }
</style>
<p class="count" id="count">0</p>
<button id="minus">-1</button>
<button id="plus">+1</button>
<script>
  let count = 0;
  const shown = document.querySelector("#count");
  function draw() {
    shown.textContent = String(count);
  }
  document.querySelector("#plus").addEventListener("click", () => {
    count++;
    draw();
  });
  document.querySelector("#minus").addEventListener("click", () => {
    if (count > 0) count--;
    draw();
  });
  draw();
</script>

āφāϗ⧇ -1 āϚāĻžāĻĒā§‹: āĻ•āĻŋāϛ⧁āχ āĻŦāĻĻāϞāĻžāϝāĻŧ āύāĻž, āĻ•āĻžāϰāĻŖ handler āĻļā§‚āĻ¨ā§āϝ⧇āϰ āύāĻŋāĻšā§‡ āύāĻžāĻŽāϤ⧇ āϰāĻžāϜāĻŋ āύāĻžāĨ¤ āϤāĻžāϰāĻĒāϰ +1 āϤāĻŋāύāĻŦāĻžāϰ āφāϰ -1 āĻāĻ•āĻŦāĻžāϰ āϚāĻžāĻĒā§‹, āĻĒāĻžāϤāĻž āĻĻ⧇āĻ–āĻžāĻŦ⧇ 2āĨ¤ āύāĻŋāϝāĻŧāĻŽāϟāĻž āĻĨāĻžāϕ⧇ script-āĻ, āĻĒāĻžāϤāĻžāϝāĻŧ āύāĻžāĨ¤

Run in Compiler
Example 2: āĻāĻ•āϟāĻž click-āĻāϰ āĻĒāĻĨ, tree āĻĨ⧇āϕ⧇ āĻĒāĻĄāĻŧāĻž

āĻāχ program āϚāϞ⧇ Node-āĻāĨ¤ āĻ“ āĻāĻ•āϟāĻž āϛ⧋āϟ āĻĒāĻžāϤāĻž āĻŦāĻžāύāĻžāϝāĻŧ āϏāĻžāϧāĻžāϰāĻŖ object āĻĻāĻŋāϝāĻŧ⧇, āĻĒā§āϰāĻ¤ā§āϝ⧇āϕ⧇āϰ āĻāĻ•āϟāĻž parent āϏāĻš, āφāϰ āĻāĻ•āϟāĻž link-āĻ click āĻĒāĻĄāĻŧāϞ⧇ bubbling-āĻāϰ āĻĒāĻĨ āĻŦ⧇āϰ āĻ•āϰ⧇āĨ¤ āĻ•āĻŋāϛ⧁ node-āĻāϰ listener āĻĨāĻžāĻ•āϞ⧇ click āĻ•āϝāĻŧāϟāĻž listener āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻĒ⧌āρāĻ›āĻžāϤ, āϏ⧇āϟāĻžāĻ“ āĻ—ā§‹āύ⧇āĨ¤

function node(tag, parent, listens) {
  return { tag, parent, listens };
}
const body = node("body", null, true);
const nav = node("nav", body, false);
const menu = node("ul", nav, true);
const item = node("li", menu, false);
const link = node("a", item, true);

const route = [];
let heard = 0;
for (let n = link; n !== null; n = n.parent) {
  route.push(n.tag);
  if (n.listens) heard++;
}
console.log(route.join(" > "));
console.log("listeners reached:", heard);
a > li > ul > nav > body
listeners reached: 3

āφāϗ⧇ āϚāϞ⧇ link-āĻāϰ āύāĻŋāĻœā§‡āϰ listener, āϤāĻžāϰāĻĒāϰ menu-āϰ, āϤāĻžāϰāĻĒāϰ body-āϰāĨ¤ nav āφāϰ li āĻĒāĻžāϰ āĻšāϝāĻŧ⧇ āϝāĻžāϝāĻŧ, āĻ“āĻĻ⧇āϰ āϕ⧋āύ⧋ listener āύ⧇āχāĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻž click-āĻ browser āĻ āĻŋāĻ• āĻāĻ­āĻžāĻŦ⧇āχ āĻšāĻžāρāĻŸā§‡āĨ¤

Run in Compiler

āĻāϟāĻž āϕ⧋āĻĨāĻžāϝāĻŧ āĻ•āĻžāĻœā§‡ āϞāĻžāϗ⧇

  • Chrome DevTools: Elements pane āφāρāϕ⧇ āϚāϞāĻŽāĻžāύ DOM, HTML file āύāĻž, āϤāĻžāχ script āϝāĻž āĻŦāĻĻāϞāĻžāϝāĻŧ āϏ⧇āϟāĻž āĻ“āĻ–āĻžāύ⧇ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ āĻĻ⧇āĻ–āĻž āϝāĻžāϝāĻŧāĨ¤
  • GitHub: āĻāĻ•āϟāĻž repository-āϰ star button āĻāĻ•āϟāĻž listener āφāϰ āĻāĻ•āϟāĻž request āĻĻāĻŋāϝāĻŧ⧇ āĻĒāĻžāϤāĻžāϰ āϭ⧇āϤāϰ⧇āχ count āĻŦāĻĻāϞāĻžāϝāĻŧ, reload āĻ›āĻžāĻĄāĻŧāĻžāĨ¤
  • Gmail: j āφāϰ k-āĻāϰ āĻŽāϤ⧋ keyboard shortcut āĻšāϞ⧋ document-āĻāϰ āĻ“āĻĒāϰ keydown listener, āϝ⧇āϟāĻž DOM-āĻāϰ āϭ⧇āϤāϰ āĻĻāĻŋāϝāĻŧ⧇ āĻāĻ•āϟāĻž highlight āϏāϰāĻžāϝāĻŧāĨ¤
  • Wikipedia: āϏ⧂āϚāĻŋāĻĒāĻ¤ā§āϰ⧇āϰ āĻ…āĻ‚āĻļāϗ⧁āϞ⧋ āĻ–ā§‹āϞ⧇ āφāϰ āĻŦāĻ¨ā§āϧ āĻšāϝāĻŧ click listener āĻĻāĻŋāϝāĻŧ⧇, āϝ⧇āϟāĻž tree āĻŦāĻĻāϞāĻžāϝāĻŧāĨ¤

āϝ⧇ āϭ⧁āϞāϗ⧁āϞ⧋ āϏāĻŦāĻžāχ āĻ•āϰ⧇

ā§§. Element āϤ⧈āϰāĻŋ āĻšāĻ“āϝāĻŧāĻžāϰ āφāϗ⧇āχ āϚāϞāĻž script

<script>
  const heart = document.querySelector("#heart");
  console.log("found:", heart);
  heart.addEventListener("click", () => console.log("liked"));
</script>
<button id="heart">Like</button>

āϚāĻžāϞāĻžāĻ“āĨ¤ Console āĻĻ⧇āĻ–āĻžāϝāĻŧ heart āĻšāϞ⧋ null, āϤāĻžāϰāĻĒāϰ null-āĻāϰ addEventListener āĻĒāĻĄāĻŧāϤ⧇ āĻ—āĻŋāϝāĻŧ⧇ āĻāĻ•āϟāĻž TypeErrorāĨ¤ Browser script-āĻ āĻĒ⧌āρāĻ›āĻžāύ⧋āϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇āχ āϏ⧇āϟāĻž āϚāϞ⧇āϛ⧇, āφāϰ āύāĻŋāĻšā§‡āϰ button āϤāĻ–āύ⧋ tree-āϤ⧇ āĻ›āĻŋāϞ āύāĻžāĨ¤ Button-āĻ click āĻ•āϰāϞ⧇ āĻ•āĻŋāϛ⧁āχ āĻšāϝāĻŧ āύāĻžāĨ¤ Script-āϟāĻž button-āĻāϰ āĻĒāϰ⧇ āϏāϰāĻžāĻ“, āĻ…āĻĨāĻŦāĻž code-āϟāĻž āĻāĻ•āϟāĻž DOMContentLoaded listener-āĻāϰ āϭ⧇āϤāϰ⧇ āĻŽā§āĻĄāĻŧ⧇ āĻĻāĻžāĻ“āĨ¤

⧍. āĻ­āĻžāĻŦāĻž āϝ⧇ querySelector āϏāĻŦāϗ⧁āϞ⧋ āϖ⧁āρāĻœā§‡ āĻĻ⧇āĻŦ⧇

<ul>
  <li>rice</li>
  <li>dal</li>
  <li>oil</li>
</ul>
<script>
  const item = document.querySelector("li");
  item.textContent = item.textContent.toUpperCase();
</script>

āĻŦāĻĻāϞāĻžāϝāĻŧ āĻļ⧁āϧ⧁ "RICE"āĨ¤ querySelector āĻĒā§āϰāĻĨāĻŽ āĻŽāĻŋāϞāϟāĻž āĻĢ⧇āϰāϤ āĻĻāĻŋāϝāĻŧ⧇āχ āĻĨ⧇āĻŽā§‡ āϝāĻžāϝāĻŧāĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻž item āĻŦāĻĻāϞāĻžāϤ⧇ āϚāĻžāχāϞ⧇ querySelectorAll("li") āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧋ āφāϰ āĻĢāϞāĻžāĻĢāϞ⧇āϰ āĻ“āĻĒāϰ loop āϚāĻžāϞāĻžāĻ“, Lesson 02 āϏ⧇āϟāĻž āĻĻ⧇āĻ–āĻžāϝāĻŧāĨ¤

ā§Š. Handler āĻĒāĻžāĻ āĻžāύ⧋āϰ āĻŦāĻĻāϞ⧇ āĻĄā§‡āϕ⧇ āĻĢ⧇āϞāĻž

<button id="go">Go</button>
<script>
  function sayHi() {
    console.log("hi");
  }
  document.querySelector("#go").addEventListener("click", sayHi());
</script>

Console āĻāĻ•āĻŦāĻžāϰ "hi" print āĻ•āϰ⧇, load-āĻāϰ āϏāĻŽāϝāĻŧ⧇āχ, āφāϰ click-āĻ āĻ•āĻŋāϛ⧁āχ print āĻšāϝāĻŧ āύāĻžāĨ¤ āĻŦāĻ¨ā§āϧāύ⧀ āϏāĻš sayHi() function-āϟāĻžāϕ⧇ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ āĻĄāĻžāϕ⧇, āφāϰ āĻ“āϰ āĻĢāϞ, undefined, āĻĒāĻžāĻ āĻžāϝāĻŧ addEventListener-āϕ⧇āĨ¤ Function-āϟāĻžāχ āĻĒāĻžāĻ āĻžāĻ“, sayHi, āĻŦāĻ¨ā§āϧāύ⧀ āĻ›āĻžāĻĄāĻŧāĻžāĨ¤

āĻŽāĻžāĻĨāĻž āĻ–āĻžāϟāĻžāĻ“

āĻĻ⧁āĻŸā§‹ listener, āĻāĻ•āϟāĻž button

Rafi āĻāĻ•āχ button-āĻ āĻĻ⧁āĻŸā§‹ click listener āϝ⧋āĻ— āĻ•āϰ⧇āĨ¤ āĻāĻ•āϟāĻž print āĻ•āϰ⧇ "first", āφāϰ⧇āĻ•āϟāĻž "second"āĨ¤ āĻ“āϰ āϧāĻžāϰāĻŖāĻž, āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧāϟāĻž āĻĒā§āϰāĻĨāĻŽāϟāĻžāϕ⧇ āϏāϰāĻŋāϝāĻŧ⧇ āĻĻ⧇āϝāĻŧ, āϝ⧇āĻŽāύ āĻāĻ•āϟāĻž variable-āĻ āĻĻ⧁āĻŦāĻžāϰ āĻŽāĻžāύ āĻŦāϏāĻžāϞ⧇ āĻšāϝāĻŧāĨ¤

<button id="b">Click me</button>
<script>
  const b = document.querySelector("#b");
  b.addEventListener("click", () => console.log("first"));
  b.addEventListener("click", () => console.log("second"));
</script>

āĻ“ āĻ•āĻŋ āĻ āĻŋāĻ•? āĻāĻ•āϟāĻž click āϕ⧀ print āĻ•āϰāĻŦ⧇?

Exercise 1āϏāĻšāϜ

Sumi Chrome DevTools-āĻāϰ Elements pane āĻĒāĻĄāĻŧāĻž āĻļāĻŋāĻ–āϛ⧇āĨ¤ āĻ“āĻ–āĻžāύ⧇ āĻĒāĻžāϤāĻžāϟāĻž āĻĻ⧇āĻ–āĻžāϝāĻŧ āĻāĻ•āϟāĻžāϰ āϭ⧇āϤāϰ⧇ āφāϰ⧇āĻ•āϟāĻž tag āĻšāĻŋāϏ⧇āĻŦ⧇, āĻĒā§āϰāϤāĻŋāϟāĻž child āϤāĻžāϰ parent-āĻāϰ āύāĻŋāĻšā§‡ āĻāĻ•āϟ⧁ āϏāϰ⧇ āĻŦāϏ⧇āĨ¤ Sumi-āϰ āĻšāĻžāϤ⧇ āĻāĻ•āϟāĻž āĻĒāĻžāϤāĻžāϰ tree āφāϛ⧇, node-āĻāϰ āĻāĻ•āϟāĻž list āĻšāĻŋāϏ⧇āĻŦ⧇āĨ¤ āĻ“ āĻ āĻŋāĻ• āĻ“āχ āĻ›āĻŦāĻŋāϟāĻžāχ āϏāĻžāϧāĻžāϰāĻŖ text-āĻ āϚāĻžāϝāĻŧāĨ¤

Input. āĻĒā§āϰāĻĨāĻŽ āϞāĻžāχāύ⧇ nāĨ¤ āϤāĻžāϰāĻĒāϰ n āϟāĻž āϞāĻžāχāύ, āĻĒā§āϰāϤāĻŋāϟāĻž node-āĻāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻž, document-āĻāϰ āĻ•ā§āϰāĻŽā§‡āĨ¤ i āύāĻŽā§āĻŦāϰ āϞāĻžāχāύ⧇ āĻĨāĻžāϕ⧇ node i-āĻāϰ parent āφāϰ node-āϟāĻžāϰ tagāĨ¤ Node 1 āĻšāϞ⧋ root, āĻ“āϰ parent 0āĨ¤ āĻŦāĻžāĻ•āĻŋ āĻĒā§āϰāϤāĻŋāϟāĻž node-āĻāϰ parent-āĻāϰ āύāĻŽā§āĻŦāϰ āĻ“āϰ āύāĻŋāĻœā§‡āϰ āĻšā§‡āϝāĻŧ⧇ āϛ⧋āϟāĨ¤

Output. Markup-āϟāĻž, āĻĒā§āϰāϤāĻŋ āϞāĻžāχāύ⧇ āĻāĻ•āϟāĻž tagāĨ¤ āϕ⧋āύ⧋ node-āĻ āĻĸā§‹āĻ•āĻžāϰ āϏāĻŽāϝāĻŧ print āĻ•āϰ⧋ <tag>, āφāϰ āĻ“āϰ āϏāĻŦ child āĻļ⧇āώ āĻ•āϰ⧇ āĻŦ⧇āϰ āĻšāĻ“āϝāĻŧāĻžāϰ āϏāĻŽāϝāĻŧ </tag>āĨ¤ Child-āϰāĻž āφāϏ⧇ input-āĻāϰ āĻ•ā§āϰāĻŽā§‡āĨ¤ Depth d-āĻāϰ node-āĻāϰ āφāϗ⧇ āĻĨāĻžāϕ⧇ 2d āϟāĻž space, āφāϰ root-āĻāϰ depth 0āĨ¤

Constraints. 1 <= n <= 1000; the tree is at most 50 levels deep; every tag is 1 to 10 lowercase letters.

Sample.

6
0 ul
1 li
2 a
1 li
1 li
5 span
<ul>
  <li>
    <a>
    </a>
  </li>
  <li>
  </li>
  <li>
    <span>
    </span>
  </li>
</ul>
const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out

console.log(out.join("\n"));
Run in Compiler

tree-markup āύāĻžāĻŽā§‡ grade āĻšāϝāĻŧāĨ¤

Exercise 2āϏāĻšāϜ

Farhan āĻāĻ•āϟāĻž āĻĒāĻžāϤāĻžāϝāĻŧ āĻāϟāĻž āĻ“āϟāĻž click āĻ•āϰ⧇ test āĻ•āϰāϛ⧇āĨ¤ āĻāĻ•āϟāĻž click āĻļ⧁āϰ⧁ āĻšāϝāĻŧ pointer-āĻāϰ āύāĻŋāĻšā§‡āϰ element āĻĨ⧇āϕ⧇, āϤāĻžāϰāĻĒāϰ bubble āĻ•āϰ⧇ āĻ“āϰ āĻĒā§āϰāϤāĻŋāϟāĻž ancestor āĻĒāĻžāϰ āĻšāϝāĻŧ⧇ root āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻ“āϠ⧇āĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻž click-āĻāϰ āϜāĻ¨ā§āϝ Farhan bubbling-āĻāϰ āĻĒāĻĨāϟāĻž āϚāĻžāϝāĻŧ: event āĻ“āĻĒāϰ⧇ āĻ“āĻ āĻžāϰ āĻĒāĻĨ⧇ āϝ⧇ āϝ⧇ tag āĻĒāĻžāϰ āĻšāϝāĻŧ, āϤāĻžāϰ listāĨ¤

Input. āĻĒā§āϰāĻĨāĻŽ āϞāĻžāχāύ⧇ nāĨ¤ āϤāĻžāϰāĻĒāϰ n āϟāĻž āϞāĻžāχāύ, āĻĒā§āϰāϤāĻŋāϟāĻž node-āĻāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻž, document-āĻāϰ āĻ•ā§āϰāĻŽā§‡: node i-āĻāϰ parent āφāϰ āĻ“āϰ tagāĨ¤ Node 1 āĻšāϞ⧋ root, āĻ“āϰ parent 0āĨ¤ āĻŦāĻžāĻ•āĻŋ āĻĒā§āϰāϤāĻŋāϟāĻž node-āĻāϰ parent-āĻāϰ āύāĻŽā§āĻŦāϰ āĻ“āϰ āύāĻŋāĻœā§‡āϰ āĻšā§‡āϝāĻŧ⧇ āϛ⧋āϟāĨ¤ āϤāĻžāϰāĻĒāϰ āĻāĻ• āϞāĻžāχāύ⧇ q, āϤāĻžāϰāĻĒāϰ q āϟāĻž āϞāĻžāχāύ, āĻĒā§āϰāϤāĻŋāϟāĻžāϝāĻŧ āϏ⧇āχ node, āϝāĻžāϰ āĻ“āĻĒāϰ click āĻĒāĻĄāĻŧ⧇āĨ¤

Output. āĻĒā§āϰāϤāĻŋāϟāĻž click-āĻāϰ āϜāĻ¨ā§āϝ āĻāĻ• āϞāĻžāχāύ: click āĻĒāĻĄāĻŧāĻž node āĻĨ⧇āϕ⧇ root āĻĒāĻ°ā§āϝāĻ¨ā§āϤ tag-āϗ⧁āϞ⧋, āĻŽāĻžāĻā§‡ āĻāĻ•āϟāĻž āĻ•āϰ⧇ spaceāĨ¤

Constraints. 1 <= n <= 200; 1 <= q <= 200; every tag is 1 to 10 lowercase letters.

Sample.

7
0 body
1 header
1 main
3 ul
4 li
5 button
4 li
3
6
2
7
button li ul main body
header body
li ul main body
const input = require("fs").readFileSync(0, "utf8");
const tokens = input.split(/\s+/).filter(Boolean);
let at = 0;
const next = () => tokens[at++];
const nextInt = () => Number(next());
const out = [];

// your code: read with next() and nextInt(), push every line of output to out

console.log(out.join("\n"));
Run in Compiler

bubble-route āύāĻžāĻŽā§‡ grade āĻšāϝāĻŧāĨ¤

Exercise 3āĻŽāĻžāĻāĻžāϰāĻŋ

Lima āĻāĻ•āϟāĻž āĻļ⧁āϭ⧇āĻšā§āĻ›āĻž āĻ•āĻžāĻ°ā§āĻĄ āĻŦāĻžāύāĻžāϤ⧇ āϚāĻžāϝāĻŧāĨ¤ āĻĒāĻžāϤāĻžāϝāĻŧ āĻāĻ•āϟāĻž heading āφāϛ⧇, āϝ⧇āϟāĻž āĻŦāϞ⧇ "Hello", āφāϰ āĻāĻ•āϟāĻž button, āϝ⧇āϟāĻžāϝāĻŧ āϞ⧇āĻ–āĻž "Bangla"āĨ¤ Button-āĻ click āĻ•āϰāϞ⧇ heading āĻŦāĻĻāϞ⧇ āĻšāĻ“āϝāĻŧāĻž āωāϚāĻŋāϤ "Shubho shokal"āĨ¤ āύāĻŋāĻšā§‡āϰ script-āϟāĻž āĻļ⧇āώ āĻ•āϰ⧋, āϤāĻžāϰāĻĒāϰ Run āĻšā§‡āĻĒ⧇ button-āĻ click āĻ•āϰ⧋āĨ¤

<h1 id="greeting">Hello</h1>
<button id="bangla">Bangla</button>
<script>
  // find the heading and the button with querySelector
  // add a click listener that changes the heading's textContent
</script>
Run in Compiler
Exercise 4āĻ•āĻ āĻŋāύ

Example 1-āϕ⧇ āĻāĻ•āϟāĻž āĻĻā§‹āĻ•āĻžāύ⧇āϰ stock counter āĻŦāĻžāύāĻžāĻ“āĨ¤ āϤ⧃āϤ⧀āϝāĻŧ āĻāĻ•āϟāĻž button āϝ⧋āĻ— āĻ•āϰ⧋, "Reset", āϝ⧇āϟāĻž count āφāĻŦāĻžāϰ 0 āĻ•āϰ⧇ āĻĻ⧇āϝāĻŧāĨ¤ āĻāĻ•āϟāĻž āϏ⧀āĻŽāĻžāĻ“ āĻĻāĻžāĻ“: count āĻ•āĻ–āύ⧋ 10-āĻāϰ āĻ“āĻĒāϰ⧇ āϝāĻžāĻŦ⧇ āύāĻž, āφāϰ 10-āĻ āĻĒ⧌āρāĻ›āĻžāϞ⧇ āύāĻŋāĻšā§‡āϰ āĻāĻ•āϟāĻž paragraph āĻŦāϞāĻŦ⧇ "Shelf is full"āĨ¤ āĻ…āĻ¨ā§āϝ āϝ⧇āϕ⧋āύ⧋ count-āĻ paragraph-āϟāĻž āĻĢāĻžāρāĻ•āĻž āĻĨāĻžāϕ⧇āĨ¤ Count āĻāĻ•āϟāĻž variable-āĻ āϰāĻžāĻ–ā§‹, āφāϰ āφāρāϕ⧋ āĻāĻ•āϟāĻž function āĻĻāĻŋāϝāĻŧ⧇āĨ¤

<p id="count">0</p>
<p id="status"></p>
<button id="minus">-1</button>
<button id="plus">+1</button>
<script>
  let count = 0;
  // add a Reset button above in the markup, then wire all three buttons here
</script>
Run in Compiler

āϏāϚāϰāĻžāϚāϰ āϝ⧇ āĻĒā§āϰāĻļā§āύāϗ⧁āϞ⧋ āφāϏ⧇

  • DOM āφāϰ HTML file āĻ•āĻŋ āĻāĻ•āχ āϜāĻŋāύāĻŋāϏ?

    āύāĻžāĨ¤ HTML file āĻšāϞ⧋ text, browser āϝ⧇āϟāĻž āĻāĻ•āĻŦāĻžāϰ āĻĒāĻĄāĻŧ⧇āĨ¤ DOM āĻšāϞ⧋ āĻ“āχ text āĻĨ⧇āϕ⧇ āĻŦāĻžāύāĻžāύ⧋ object-āĻāϰ tree, āφāϰ āϤ⧋āĻŽāĻžāϰ script āĻŦāĻĻāϞāĻžāϝāĻŧ āϏ⧇āχ tree-āϟāĻžāχāĨ¤ Script āϚāϞāĻžāϰ āĻĒāϰ⧇ āĻĻ⧁āĻŸā§‹ āφāϰ āĻŽā§‡āϞ⧇ āύāĻžāĨ¤ View Source āĻĻ⧇āĻ–āĻžāϝāĻŧ file, DevTools-āĻāϰ Elements pane āĻĻ⧇āĻ–āĻžāϝāĻŧ DOMāĨ¤

  • āĻŦāĻžāĻ•āĻŋ track Node-āĻ āϚāϞ⧇, āĻāχ module āϤāĻžāĻšāϞ⧇ preview-āϤ⧇ āĻĒāĻžāϤāĻž āϚāĻžāϞāĻžāϝāĻŧ āϕ⧇āύ?

    Node-āĻāϰ āϕ⧋āύ⧋ āĻĒāĻžāϤāĻž āύ⧇āχ, āĻĒāĻ°ā§āĻĻāĻž āύ⧇āχ, document-āĻ“ āύ⧇āχāĨ¤ āĻĒāĻžāϤāĻžāϰ program-āĻāϰ āϞāĻžāϗ⧇ āĻāĻ•āϟāĻž browser, āϤāĻžāχ preview lesson-āĻāϰ āϭ⧇āϤāϰ⧇āχ āĻāĻ•āϟāĻž sandbox āĻ•āϰāĻž frame-āĻ āϏ⧇āϟāĻž āĻ–ā§‹āϞ⧇āĨ¤ āĻ“āĻ–āĻžāύ⧇ network āύ⧇āχ, storage āύ⧇āχ, āφāϰ āĻĒā§āϰāϤāĻŋāϟāĻž Run āĻĒāĻžāϤāĻžāϕ⧇ āύāϤ⧁āύ āĻ•āϰ⧇ āĻļ⧁āϰ⧁ āĻ•āϰ⧇āĨ¤ Judge āĻ•āϰāĻž problem-āϗ⧁āϞ⧋ āĻāĻ–āύ⧋ Node-āĻ āϚāϞ⧇, āϤāĻžāχ āĻ“āϰāĻž āĻ•āĻžāϜ āĻ•āϰ⧇ āϏāĻžāϧāĻžāϰāĻŖ object āĻšāĻŋāϏ⧇āĻŦ⧇ āϞ⧇āĻ–āĻž tree āύāĻŋāϝāĻŧ⧇āĨ¤

  • āĻāĻ•āϟāĻž value āĻĻ⧇āĻ–āϤ⧇ āĻ•āĻŋ alert āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝāĻžāϝāĻŧ?

    Preview-āϤ⧇ alert, confirm āφāϰ prompt āĻļ⧁āϧ⧁ console-āĻ āĻāĻ•āϟāĻž āϞāĻžāχāύ print āĻ•āϰ⧇ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ āĻĢāĻŋāϰ⧇ āφāϏ⧇āĨ¤ console.log āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧋, āĻ…āĻĨāĻŦāĻž textContent āĻĻāĻŋāϝāĻŧ⧇ value-āϟāĻž āĻĒāĻžāϤāĻžāϤ⧇āχ āϞāĻŋāϖ⧇ āĻĻāĻžāĻ“āĨ¤ āĻāĻŽāύāĻŋāϤ⧇āĻ“ āĻĻ⧁āĻŸā§‹āχ āĻ­āĻžāϞ⧋ āĻ…āĻ­ā§āϝāĻžāϏ, āĻ•āĻžāϰāĻŖ āϏāĻ¤ā§āϝāĻŋāĻ•āĻžāϰ⧇āϰ dialog āĻĒ⧁āϰ⧋ āĻĒāĻžāϤāĻž āφāϟāϕ⧇ āĻĻ⧇āϝāĻŧāĨ¤

  • Event handler āĻ•āĻŋ Module 12-āĻāϰ callback-āĻāϰ āĻŽāϤ⧋āχ?

    āĻšā§āϝāĻžāρāĨ¤ Browser āϤ⧋āĻŽāĻžāϰ function āϰ⧇āϖ⧇ āĻĻ⧇āϝāĻŧ, āφāϰ āĻĒāϰ⧇ āĻĄāĻžāϕ⧇, event loop-āĻāϰ āϕ⧋āύ⧋ āĻĒāĻžāϞāĻžāϝāĻŧ, āĻĒā§āϰāϤāĻŋāϟāĻž event-āĻ āĻāĻ•āĻŦāĻžāϰāĨ¤ āϤ⧋āĻŽāĻžāϰ handler āϚāϞāĻžāϰ āϏāĻŽāϝāĻŧ āĻĒāĻžāϤāĻžāϝāĻŧ āφāϰ āĻ•āĻŋāϛ⧁āχ āϚāϞ⧇ āύāĻž, āϤāĻžāχ āϧ⧀āϰ āĻāĻ•āϟāĻž handler āĻĒ⧁āϰ⧋ āĻĒāĻžāϤāĻž āϜāĻŽāĻŋāϝāĻŧ⧇ āĻĻ⧇āϝāĻŧāĨ¤

āĻŽā§‚āϞ āĻ•āĻĨāĻž

  • DOM āĻšāϞ⧋ HTML āĻĨ⧇āϕ⧇ browser-āĻāϰ āĻŦāĻžāύāĻžāύ⧋ object-āĻāϰ tree, āφāϰ āĻĒāĻ°ā§āĻĻāĻž āφāρāĻ•āĻž āĻšāϝāĻŧ āϏ⧇āϟāĻž āĻĻ⧇āϖ⧇āĨ¤
  • āĻĒā§āϰāϤāĻŋāϟāĻž node-āĻāϰ āĻāĻ•āϜāύ parent āφāϰ child-āĻĻ⧇āϰ āĻāĻ•āϟāĻž list; āĻĒāĻžāϤāĻžāϰ āϕ⧋āύ⧋ parent āϧāϰāϞ⧇ āϤāĻŦ⧇āχ node āĻĻ⧇āĻ–āĻž āϝāĻžāϝāĻŧāĨ¤
  • querySelector āĻāĻ•āϟāĻž CSS selector-āĻāϰ āĻĒā§āϰāĻĨāĻŽ āĻŽāĻŋāϞ āĻĢ⧇āϰāϤ āĻĻ⧇āϝāĻŧ, āĻ…āĻĨāĻŦāĻž nullāĨ¤
  • textContent āĻāĻ•āϟāĻž element-āĻāϰ āϞ⧇āĻ–āĻž āĻĒāĻĄāĻŧ⧇ āĻŦāĻž āĻŦāĻĻāϞāĻžāϝāĻŧ, āφāϰ addEventListener āĻĒā§āϰāϤāĻŋāϟāĻž event-āĻ āĻāĻ•āϟāĻž function āĻĄāĻžāϕ⧇āĨ¤
  • Click āĻļ⧁āϰ⧁ āĻšāϝāĻŧ target āĻĨ⧇āϕ⧇, bubble āĻ•āϰ⧇ āĻĒā§āϰāϤāĻŋāϟāĻž ancestor āĻĒāĻžāϰ āĻšāϝāĻŧ⧇ āĻ“āϠ⧇; script-āϕ⧇ āϚāϞāϤ⧇ āĻšāĻŦ⧇ āĻĻāϰāĻ•āĻžāϰāĻŋ element-āϗ⧁āϞ⧋āϰ āĻĒāϰ⧇āĨ¤
  • āφāϰāĻ“ āĻ—āĻ­ā§€āϰ⧇ āϝ⧇āϤ⧇ āϚāĻžāχāϞ⧇: āϭ⧇āϤāϰ⧇āϰ āĻ•āϞāĻ•āĻŦāϜāĻž, reflow, repaint, live list āφāϰ batching (Pro)āĨ¤

āĻāϰāĻĒāϰ: DOM-āĻāϰ āĻĒā§āϰāϤāĻŋāϟāĻž āĻšāĻžāϤāĻŋāϝāĻŧāĻžāϰ, āĻāĻ•āϟāĻž āĻāĻ•āϟāĻž āĻ•āϰ⧇, querySelectorAll āĻĨ⧇āϕ⧇ listener āϏāϰāĻžāύ⧋ āĻĒāĻ°ā§āϝāĻ¨ā§āϤāĨ¤

lesson ā§§ āĻļ⧇āώ

āĻļ⧇āώ āĻšāϞ⧇ āϚāĻŋāĻšā§āύ āĻĻāĻŋāύ, āĻ…āĻ—ā§āϰāĻ—āϤāĻŋ āφāĻĒāύāĻžāϰ āϏāĻžāĻĨ⧇ āĻĨāĻžāĻ•āĻŦ⧇āĨ¤

āĻĒāϰ⧇āϰāϟāĻž: DOM-āĻāϰ āĻĒā§āϰāϤāĻŋāϟāĻž āĻšāĻžāϤāĻŋāϝāĻŧāĻžāϰ, āĻāĻ•āϟāĻž āĻāĻ•āϟāĻž āĻ•āϰ⧇, āϕ⧀ āĻĢ⧇āϰāϤ āĻĻ⧇āϝāĻŧ āϤāĻž āϏāĻš