admin管理员组

文章数量:1418064

I am currently trying to use the MutationObserver API to fire a message (which later will be functions) based on class change of an element.

I'm currently firing a log on mutation change, but I'm assuming there are mutations such as DOM position etc that are firing. Is there a way to make the MutationObserver only look for specific attributes in this case the class?

As primarily a Drupal developer I'm used to using jQuery and that's why I have the classList function as I like chaining.

Here is my code:

var foo = document.getElementById("foo");
var wrapper = document.getElementById("wrapper");

var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (mutation.attributeName === "class") {
        	var attributeValue = mutation.target.getAttribute(mutation.attributeName);
            console.log("Class attribute changed to:", attributeValue);
        }
    });
});

function classList(el) {
  var list = el.classList;
  return {
      add: function(c) { 
         if (!list.contains(c)){
            console.log('Contains: '+list.contains(c));
      	    list.add(c); 
         }
         return this;
      },
      remove: function(c) { 
         if (!list.contains(c)){ 
            list.remove(c); 
         }
         return this; 
      }
  };
}

observer.observe(foo,  {
    attributes: true
});

wrapper.addEventListener("scroll",function(){
    classList(foo).add('red').remove('yellow');
    if(wrapper.scrollTop > 500){
         classList(foo).add('yellow').remove('red');
    }
});
#wrapper {
  height: 200px;
  overflow: scroll;
}
#foo {
  height: 1000px;
}
<div id="wrapper">
   <div id="foo">Element</div>
</div>

I am currently trying to use the MutationObserver API to fire a message (which later will be functions) based on class change of an element.

I'm currently firing a log on mutation change, but I'm assuming there are mutations such as DOM position etc that are firing. Is there a way to make the MutationObserver only look for specific attributes in this case the class?

As primarily a Drupal developer I'm used to using jQuery and that's why I have the classList function as I like chaining.

Here is my code:

var foo = document.getElementById("foo");
var wrapper = document.getElementById("wrapper");

var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (mutation.attributeName === "class") {
        	var attributeValue = mutation.target.getAttribute(mutation.attributeName);
            console.log("Class attribute changed to:", attributeValue);
        }
    });
});

function classList(el) {
  var list = el.classList;
  return {
      add: function(c) { 
         if (!list.contains(c)){
            console.log('Contains: '+list.contains(c));
      	    list.add(c); 
         }
         return this;
      },
      remove: function(c) { 
         if (!list.contains(c)){ 
            list.remove(c); 
         }
         return this; 
      }
  };
}

observer.observe(foo,  {
    attributes: true
});

wrapper.addEventListener("scroll",function(){
    classList(foo).add('red').remove('yellow');
    if(wrapper.scrollTop > 500){
         classList(foo).add('yellow').remove('red');
    }
});
#wrapper {
  height: 200px;
  overflow: scroll;
}
#foo {
  height: 1000px;
}
<div id="wrapper">
   <div id="foo">Element</div>
</div>

Share Improve this question asked Aug 17, 2016 at 12:17 Ian TaylorIan Taylor 3572 silver badges15 bronze badges 3
  • 3 Use attributeFilter: ['class'] as per documentation? – woxxom Commented Aug 17, 2016 at 12:26
  • Classic case of having a grown ups look there. Thank you @wOxxOm – Ian Taylor Commented Aug 17, 2016 at 12:40
  • @wOxxOm Should I delete the question? Or will you move your ment to an answer and I'll accept that? – Ian Taylor Commented Aug 17, 2016 at 12:51
Add a ment  | 

1 Answer 1

Reset to default 5

Although @wOxxOm answered my question(negligence) in his ment, I applied the functionaily and realised that I no longer needed a forEach as I was only expecting a singular attribute, so the finished(test) code looks like:

var foo = document.getElementById("foo");
var wrapper = document.getElementById("wrapper");

var observer = new MutationObserver(function(mutation) {
    console.log('Current class:' + mutation[0].target.className);
});

observer.observe(foo, {
    attributes: true,
    attributeFilter: ['class']
});

wrapper.addEventListener("scroll",function(){
    if(wrapper.scrollTop > 500){
        if(!foo.classList.contains('yellow')){
           foo.classList.add('yellow');
           foo.classList.remove('red');
        }
    } else {
        if(!foo.classList.contains('red')){
           foo.classList.add('red');
           foo.classList.remove('yellow');
        }
    }
});
#wrapper {
  height: 200px;
  overflow: scroll;
}
#foo {
  height: 1000px;
}
<div id="wrapper">
   <div id="foo">Element</div>
</div>

I have tidied up the mutation observer to find the class name. I removed my function to allow me to chain the class elements, as I came across an issue where it was triggering the mutation even when the class was not changed, just because the element was being returned.

本文标签: javascriptMutationObserver with specific mutationsStack Overflow