Mutation Observer
<quiet-mutation-observer>
            Watches child elements and dispatches an event when they mutate.
            The component uses a
            MutationObserver
            to monitor when its direct children are added, removed, or modified. A quiet-mutation event is
            dispatched for each observed change, providing detailed information about what was mutated.
          
            The component is styled with
            display: contents, allowing you to easily apply flex and grid layouts to the containing element without the component
            interfering.
          
<div id="mutation__overview"> <quiet-mutation-observer child-list> <div class="box">1 <button aria-label="Remove">✕</button></div> <div class="box">2 <button aria-label="Remove">✕</button></div> <div class="box">3 <button aria-label="Remove">✕</button></div> </quiet-mutation-observer> </div> <quiet-button>Add box</quiet-button> <small>Add and remove some items, then open the console to inspect the output.</small> <script> const container = document.getElementById('mutation__overview'); const mutationObserver = container.querySelector('quiet-mutation-observer'); const appendButton = container.nextElementSibling; let count = mutationObserver.querySelectorAll('.box').length; // Listen for mutations mutationObserver.addEventListener('quiet-mutation', event => { console.log(event.detail.record); }); // Remove a card mutationObserver.addEventListener('click', event => { const button = event.target.closest('button'); const box = button?.closest('.box'); box?.remove(); }); // Append a box appendButton.addEventListener('click', () => { const html = `<div class="box">${++count} <button aria-label="Remove">✕</button></div>`; mutationObserver.insertAdjacentHTML('beforeEnd', html); }); </script> <style> #mutation__overview { display: flex; flex-wrap: wrap; gap: 1.5rem; min-height: 5rem; margin-block-end: 1rem; .box { display: flex; align-items: center; justify-content: center; position: relative; min-width: 5rem; height: 5rem; border-radius: var(--quiet-border-radius-md); background-color: var(--quiet-neutral-fill-softer); box-shadow: var(--quiet-shadow-softer); text-align: center; padding: 1rem; button { display: flex; align-items: center; justify-content: center; background-color: var(--quiet-neutral-fill-loud); color: var(--quiet-neutral-text-on-loud); font-size: .75em; padding: 0; width: 1.25rem; height: 1.25rem; min-height: 0; position: absolute; top: -0.625rem; right: -0.625rem; border-radius: var(--quiet-border-radius-circle); } } ~ small { display: block; margin-block-start: 1rem; } } </style>
              Remember that only direct children of the host element are observed. Nested elements will not trigger
              mutation events unless the subtree attribute is enabled.
            
Examples Jump to heading
Providing content Jump to heading
            Slot one or more elements into the mutation observer and listen for the quiet-mutation event.
            The event includes event.detail.record, which is a
            MutationRecord
            object that corresponds to the mutated element.
          
In its simplest form, a mutation observer can be used like this.
<quiet-mutation-observer child-list> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </quiet-mutation-observer> <script> const mutationObserver = document.querySelector('quiet-mutation-observer'); // Listen for mutations mutationObserver.addEventListener('quiet-mutation', event => { console.log(event.detail.record); // MutationRecord }); </script>
Observing attribute changes Jump to heading
            Use the attr attribute to monitor changes to element attributes. You can optionally specify
            attr-old-value to record the previous attribute value.
          
<quiet-mutation-observer attr attr-old-value> <div id="target" class="example">Watch my attributes</div> </quiet-mutation-observer> <script> const observer = document.querySelector('quiet-mutation-observer'); const target = observer.querySelector('#target'); observer.addEventListener('quiet-mutation', event => { const record = event.detail.record; console.log(`Attribute "${record.attributeName}" changed`); console.log(`Old value: ${record.oldValue}`); console.log(`New value: ${record.target.getAttribute(record.attributeName)}`); }); // Change an attribute to trigger the observer target.className = 'modified'; </script>
Filtering specific attributes Jump to heading
            Limit observations to specific attributes using the attr-filter attribute. Separate multiple
            attribute names with spaces.
          
<quiet-mutation-observer attr attr-filter="class data-state"> <div class="example" data-state="active" id="example"> Only class and data-state changes are observed </div> </quiet-mutation-observer> <script> const observer = document.querySelector('quiet-mutation-observer'); const target = observer.querySelector('#example'); observer.addEventListener('quiet-mutation', event => { console.log(`Observed attribute: ${event.detail.record.attributeName}`); }); // These will trigger events target.className = 'modified'; target.setAttribute('data-state', 'inactive'); // This will NOT trigger an event target.id = 'new-id'; </script>
Observing text content changes Jump to heading
            Use the character-data attribute to monitor changes to text nodes. The
            character-data-old-value attribute records the previous text content.
          
<quiet-mutation-observer character-data character-data-old-value subtree> <p id="text-content">Original text content</p> </quiet-mutation-observer> <script> const observer = document.querySelector('quiet-mutation-observer'); const paragraph = observer.querySelector('#text-content'); observer.addEventListener('quiet-mutation', event => { const record = event.detail.record; console.log(`Text changed from "${record.oldValue}" to "${record.target.textContent}"`); }); // Change text content to trigger the observer paragraph.textContent = 'Updated text content'; </script>
Observing nested elements Jump to heading
            By default, only direct children are observed. Add the subtree attribute to observe changes in
            nested elements as well.
          
<quiet-mutation-observer child-list subtree> <div class="container"> <div class="nested"> <span>Nested content</span> </div> </div> </quiet-mutation-observer> <script> const observer = document.querySelector('quiet-mutation-observer'); const nested = observer.querySelector('.nested'); observer.addEventListener('quiet-mutation', event => { console.log('Mutation detected in subtree:', event.detail.record); }); // This will trigger the observer even though span is deeply nested nested.innerHTML = '<span>New nested content</span>'; </script>
Combining multiple observation types Jump to heading
You can observe multiple types of mutations simultaneously by combining attributes.
<quiet-mutation-observer child-list attr character-data subtree attr-old-value character-data-old-value > <div class="comprehensive-example"> <p>This observer watches everything</p> </div> </quiet-mutation-observer> <script> const observer = document.querySelector('quiet-mutation-observer'); observer.addEventListener('quiet-mutation', event => { const record = event.detail.record; switch (record.type) { case 'childList': console.log('Child nodes changed'); break; case 'attributes': console.log(`Attribute "${record.attributeName}" changed`); break; case 'characterData': console.log('Text content changed'); break; } }); </script>
Disabling the observer Jump to heading
            Use the disabled attribute to temporarily stop observing mutations without removing the
            component.
          
<quiet-mutation-observer child-list disabled> <div>Changes to this content won't be observed</div> </quiet-mutation-observer> <script> const observer = document.querySelector('quiet-mutation-observer'); // Re-enable observation observer.disabled = false; // Disable observation again observer.disabled = true; </script>
API Jump to heading
Importing Jump to heading
The autoloader is the recommended way to import components but, if you prefer to do it manually, the following code snippets will be helpful.
                To manually import <quiet-mutation-observer> from the CDN, use the following code.
              
import 'https://cdn.jsdelivr.net/npm/@quietui/quiet-browser@1.6.1/dist/components/mutation-observer/mutation-observer.js';
To manually import <quiet-mutation-observer> from npm, use the following code.
import '@quietui/quiet/components/mutation-observer/mutation-observer.js';
Slots Jump to heading
Mutation Observer supports the following slots. Learn more about using slots
| Name | Description | 
|---|---|
| (default) | The elements to observe. All direct children of the host element are observed, but not nested elements. | 
Properties Jump to heading
Mutation Observer has the following properties that can be set with corresponding attributes. In many cases, the attribute's name is the same as the property's name. If an attribute is different, it will be displayed after the property. Learn more about attributes and properties
| Property / Attribute | Description | Reflects | Type | Default | 
|---|---|---|---|---|
| disabled | Disables the mutation observer. |  | boolean | false | 
| attr | Indicates whether attributes should be observed. |  | boolean | false | 
| attrOldValueattr-old-value | Indicates whether attribute old value should be recorded. |  | boolean | false | 
| attrFilterattr-filter | One or more attributes to limit observations to, separate by a space. When not specified, all attributes are observed. |  | string | '' | 
| childListchild-list | Indicates whether mutations to target's children are to be observed. |  | boolean | false | 
| subtree | Indicates whether mutations to target's descendants are to be observed. |  | boolean | false | 
| characterDatacharacter-data | Indicates whether character data should be observed. |  | boolean | false | 
| characterDataOldValuecharacter-data-old-value | Indicates whether character data old value should be recorded. |  | boolean | false | 
Events Jump to heading
Mutation Observer dispatches the following custom events. You can listen to them the same way was native events. Learn more about custom events
| Name | Description | 
|---|---|
| quiet-mutation | Emitted when a slotted element is mutated. The event.detail.recordproperty contains aMutationRecordwith information about the mutation. |