Created
October 20, 2024 03:09
-
-
Save galanggg/ed11823dd9540c6a3a1d00a8bce3d92b to your computer and use it in GitHub Desktop.
Mutation Observer Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Frontend System Design Fundamentals</title> | |
| <link rel="stylesheet" href="../../styles/index.css"> | |
| <template id="card_template"> | |
| <article class="card"> | |
| <h3 class="card__title"></h3> | |
| <div class="card__body"> | |
| <div class='card__body__image'></div> | |
| <section contenteditable="true" class='card__body__content'> | |
| </section> | |
| </div> | |
| </article> | |
| </template> | |
| </head> | |
| <body> | |
| <main id="container"> | |
| <div id="list"></div> | |
| <div id="bottom-observer"> | |
| Bottom Observer | |
| </div> | |
| </main> | |
| <script type="module"> | |
| import {createCardElement, getHeading} from "./utils.js"; | |
| import {initMockDB} from "../../utils/db.js"; | |
| const SUPPORTED_ELEMENTS = new Set([ | |
| '/h1', | |
| '/h2', | |
| '/h3', | |
| '/p', | |
| '/li' | |
| ]); | |
| const db = initMockDB({ | |
| title: "Fundamentals of Frontend System Design", | |
| body: "Learning to use Intersection Observer" | |
| }); | |
| const list = document.getElementById('list'); | |
| const observerElement = document.getElementById('bottom-observer'); | |
| const mutationObserver = new MutationObserver((mutationList) => { | |
| /* | |
| * @todo | |
| * | |
| * 1. Loop through mutations (first arg of callback) | |
| * 2. use mutation.type === 'characterData' | |
| * 3. When the content matches with any supported tag in SUPPORTED_ELEMENTS | |
| * use getHeading function to convert text to HTMLHeading element | |
| * 4. Replace the node with a newly created node | |
| * 5. Keep focus on the element | |
| */ | |
| for(const mutation of mutationList) { | |
| const target = mutation.target; | |
| if(mutation.type === 'characterData' && SUPPORTED_ELEMENTS.has(target.textContent)) { | |
| const heading = getHeading(target); | |
| target.replaceWith(heading) | |
| heading.focus(); | |
| } | |
| } | |
| }); | |
| let page = 0; | |
| const observer = new IntersectionObserver(async ([bottom]) => { | |
| if (bottom.isIntersecting) { | |
| observerElement.textContent = "Loading"; | |
| const data = await db.getPage(page++); | |
| const fragment = new DocumentFragment(); | |
| data.forEach(({title, body}) => { | |
| const card = createCardElement(title, body); | |
| fragment.appendChild(card); | |
| // @todo register observer | |
| mutationObserver.observe(card, {characterData: true, subtree: true}); | |
| }); | |
| list.appendChild(fragment); | |
| } | |
| }, {threshold: 0.1}) | |
| observer.observe(observerElement); | |
| mutationObserver.disconnect() | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment