Discover the steps to eliminate an element's attribute with the help of mutationObserver and mutationrecord

In an effort to remove attributes added by a 3rd party library from my webapp at runtime, I have been using the code provided below:

document.addEventListener('DOMNodeInserted', () => {
  const elements = document.querySelectorAll('[aria-owns]');
  elements.forEach(element => {
    element.removeAttribute('aria-owns')
  })
})

However, a recent error in the console states:

[Deprecation] Listener added for a 'DOMNodeInserted' mutation event. Support for this event type has been removed, and this event will no longer be fired. See for more information.

The reason being that DOMNodeInserted is no longer recommended for performance reasons and will soon be obsolete. The solution proposed is to use MutationObserver instead.

However, it is noted that MutationObserver does not expose Elements, only nodes.

My attempt at addressing this issue is as follows:

const observer= new MutationObserver(mutationList =>{
  mutationList.forEach(mutationRecord => {
    const elements= document.querySelectorAll('[aria-owns]');
    elements.forEach(element => 
      element.removeAttribute('aria-owns')
    )
  })
});
observer.observe(document, {
  childList: true, 
  subtree: true, 
  attributeFilter: ['aria-owns']
};

However, there is concern over the redundancy of getting all elements in the document with

document.querySelectorAll('[aria-owns]')
and then individually iterating over them to remove the attribute, when mutationRecod already provides access to the nodes that have just mutated and contain the desired attribute.

Is there a way to access the element from the nodes yielded by the MutationObserver? Or what is the correct method to edit the attributes of nodes with a MutationObserver?

Answer №1

Here's my solution that seems to be working well. I'm not entirely sure if it's the most appropriate method, but it appears to be more effective than my previous attempts (I'm currently working on a project using typescript):

const observer = new MutationObserver(mutations => {
  mutations.forEach(mutation => {
    (mutation.target as Element).removeAttribute('aria-owns');
  });
});
observer.observe(document, {
  childList: true,
  subtree: true,
  attributeFilter: ['aria-owns']
});

Answer №2

In TypeScript, there is a useful concept known as a type guard function that allows you to narrow down an existing type to a subtype using a runtime check. One common use case is to determine whether a Node is actually an Element:

Ref: Node: nodeType property

Check out this example in the TS playground.

function isElement(node: Node): node is Element {
  return node.nodeType === Node.ELEMENT_NODE;
}

declare const node: Node;

if (isElement(node)) {
  node
  // This is of type Element
} else {
  node
  // This is of type Node
}

You can leverage this type guard when working with the MutationObserver callback. Here's a practical example:

Experience this in action in the TS playground.

function observeAndRemove(): MutationObserver {
  const attributeName = "aria-owns";

  function isElement(node: Node): node is Element {
    return node.nodeType === Node.ELEMENT_NODE;
  }

  function removeAttr(node: Node): void {
    if (isElement(node) && node.hasAttribute(attributeName)) {
      node.removeAttribute(attributeName);
    }
  }

  function handleMutationRecord(mutationRecord: MutationRecord): void {
    switch (mutationRecord.type) {
      case "attributes": {
        if (mutationRecord.attributeName === attributeName) {
          removeAttr(mutationRecord.target);
        }
        break;
      }
      case "childList": {
        for (const node of mutationRecord.addedNodes) {
          removeAttr(node);
        }
        break;
      }
    }
  }

  const observer = new MutationObserver((mutationRecords) => {
    for (const mutationRecord of mutationRecords) {
      handleMutationRecord(mutationRecord);
    }
  });

  observer.observe(document, {
    childList: true,
    subtree: true,
    attributeFilter: [attributeName],
  });

  return observer;
}

const observer = observeAndRemove();
// Possibly later…
// if (condition) observer.disconnect();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A guide on incorporating a set of components to be utilized as custom HTML elements in Angular

I am in the process of revamping my application to be more modular on the UI side, with a focus on separating different elements including: App header Left navigation panel Main content on the right side of the nav panel I have successfully figured out ...

Avoid the sudden change in page content when using Router.Navigate

When the link below is clicked, the current page jumps to the top before proceeding to the next page. <a href="javascript:void(0);" (click)="goToTicket(x.refNo, $event)">{{x.ticketTitle}}</a> component.ts goToTicket(refNo, e) { e.prev ...

When a selection is made in React MUI Virtualized Autocomplete, the autocomplete menu scrolls back to the top

I am currently using reactMUI autocomplete with virtualization because the listbox is expected to contain thousands of items. The virtualization feature works fine, but when I add an onchange function, the listbox automatically scrolls back to the top wh ...

Having trouble configuring the proxy port for my Vue.js application

I'm currently developing a web application using vue.js for the front end and node.js for the server. Vue is running on port 8080 and Node.js is running on port 3001. To make API calls, I have set up a proxy in my vue.config.js file, but it doesn&apos ...

Accessing the form element in the HTML outside of the form tag in Angular 2

I am attempting to achieve the following: <span *ngIf="heroForm?.dirty"> FOO </span> <form *ngIf="active" (ngSubmit)="onSubmit()" #heroForm="ngForm"> <div class="form-group"> <label for="name">Name</label& ...

Calculate the UV coordinates for a trio of CSG meshes

During a university project, I created a ThreeCSG subtraction in ThreeJS. The challenge I am facing now is applying a texture to this mesh due to the missing UV coordinates after processing. The project requirement mandates that it must be a ThreeCSG objec ...

Is there a way to fetch database content using ajax prior to triggering a filter keyup event?

I have encountered a challenge with my code below. It currently works when a filter parameter is pressed on keyup. However, I am looking to have the content of the database load via ajax as soon as the page is ready, even without any filter search being in ...

What is the best way to utilize imported classes, functions, and variables within an Angular 2 template?

I've come up with a solution for incorporating static content into a template, but I'm unsure if it's the best approach. I would like to know if there is an official or more efficient method of achieving this. Here's an example showcas ...

Using the $ sign to choose a subdocument in mongoose

Here is the structure of my document: "event": { "attendants": { "seekers": [ { "$oid": "5bcdabd27e51de001576d289" }, { "$oid": "5bc9b39c1a48dd0d7d521924" } ...

Struggling to locate a declaration file for the 'cloudinary-react' module? Consider running `npm i --save-dev @types/cloudinary-react` or exploring other options to resolve this issue

Currently, I am working with Typescript in React. Strangely, when I try to import the following: import { Image } from 'cloudinary-react'; I encounter this error: Could not find a declaration file for module 'cloudinary-react'. ' ...

Triggering a parent component function after a child component function finishes in Vue

When using Vue, I have a main component housing a child component that is loaded onto the page with a button triggering the saveTaskComment() function. Everything works perfectly until it reaches the .finally portion of the child component's function. ...

What is the best method to remove duplicate watches in AngularJS?

After creating a basic TODO app using AngularJS, I discovered some interesting features. https://i.sstatic.net/QHfdy.png The app allows me to manage my list of tasks, such as deleting, marking as completed, and adding new ones. A unique functionality is ...

A div positioned in front of a centrally-located div

Managing a website with numerous headlines can be a challenge. When a user clicks on a headline, a button located 10px to the left of the headline should appear. However, the catch is that the headlines must always remain centered, regardless of whether th ...

Prevent users from navigating back in their browser with jQuery

As I work on developing an online testing app, one of the requirements is to prevent users from refreshing the page or going back during the test until it has ended. While I have successfully disabled the refresh action in jQuery using various methods with ...

Cross-Origin Resource Sharing (CORS) for enabling the remote inclusion of JavaScript

I have a unique javascript widget that is designed to be embedded from an external server (e.g. ) The javascript, which contains a simple alert('hello'), is generated by a php script. Upon execution, I include a header like this: <?php heade ...

Enhance the form values using HTML and Javascript before submitting them via POST

Greetings to all! Apologies if my question seems elementary, as I am relatively new to using Javascript/HTML... I am encountering an issue with PayPal integration. In the past, I have successfully implemented it with a single fixed price, but now I have ...

React Native has encountered an issue with an undefined object, resulting in an error

I have a JSON file with the following structure: { "main": { "first": { "id": "123", "name": "abc" }, "second": { "id": "321", "name": "bca" } } } Before making an AP ...

Navigation that sticks and changes upon hovering over div elements

Just delving into the world of jQuery and JS, so I appreciate your patience:) Currently, I have a sticky navigation bar positioned at the top of my webpage that links to different sections of content below. I am looking to create an effect where the corr ...

What steps can I take to ensure that I establish the definition of this variable?

My situation involves a variable called Blog, which is a mongoose model. The definition of this variable is as follows: db.once("open", function(){ var userSchema = new mongoose.Schema({ username: String, password: String }); ...

Combining Multiple 3D JSON Objects in JavaScript [or jQuery]

Looking to combine multiple JSON objects into one? I have a code snippet that you can use! Here is the code: http://jsfiddle.net/5Uz27/ The issue with this code is that it only merges objects on the first level, causing deeper levels to be overwritten. T ...