如何使用 jQuery 在类更改时触发事件?

IT技术 javascript jquery jquery-events
2021-01-13 04:00:06

我想要一些类似的东西:

$('#myDiv').bind('class "submission ok" added'){
    alert('class "submission ok" has been added');
});
4个回答

类更改时不会引发任何事件。另一种方法是在以编程方式更改类时手动引发事件:

$someElement.on('event', function() {
    $('#myDiv').addClass('submission-ok').trigger('classChange');
});

// in another js file, far, far away
$('#myDiv').on('classChange', function() {
     // do stuff
});

更新

这个问题似乎吸引了一些访问者,所以这里有一个更新,它可以使用一种方法,无需使用 new 修改现有代码MutationObserver

var $div = $("#foo");
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    var attributeValue = $(mutation.target).prop(mutation.attributeName);
    console.log("Class attribute changed to:", attributeValue);
  });
});

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

$div.addClass('red');
.red {
  color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo" class="bar">#foo.bar</div>

请注意,MutationObserver仅适用于较新的浏览器,特别是 Chrome 26、FF 14、IE 11、Opera 15 和 Safari 6。有关更多详细信息,请参阅MDN如果您需要支持旧版浏览器,那么您将需要使用我在第一个示例中概述的方法。

在完成这个答案后,我发现了这个:stackoverflow.com/a/1950052/1579667
2021-03-16 04:00:06
在我的情况下,当 dom 节点有一个特定的类MutationObserver对我有用时,我需要触发一个事件
2021-03-25 04:00:06
@Benj 这与我的原始答案相同(即使用trigger()),但请注意,由于使用bind(). 不过,我不确定它是如何“完成”任何事情的
2021-04-09 04:00:06
这是此解决方案的改进形式,带有过滤器stackoverflow.com/a/42121795/12074818
2021-04-11 04:00:06

您可以用您自己的函数替换原来的 jQuery addClass 和 removeClass 函数,这些函数会调用原始函数,然后触发自定义事件。(使用自调用匿名函数包含原始函数引用)

(function( func ) {
    $.fn.addClass = function() { // replace the existing function on $.fn
        func.apply( this, arguments ); // invoke the original function
        this.trigger('classChanged'); // trigger the custom event
        return this; // retain jQuery chainability
    }
})($.fn.addClass); // pass the original function as an argument

(function( func ) {
    $.fn.removeClass = function() {
        func.apply( this, arguments );
        this.trigger('classChanged');
        return this;
    }
})($.fn.removeClass);

那么您的其余代码将像您期望的一样简单。

$(selector).on('classChanged', function(){ /*...*/ });

更新:

JS小提琴演示

这种方法确实假设类只会通过 jQuery addClass 和 removeClass 方法进行更改。如果以其他方式修改类(例如通过 DOM 元素直接操作类属性),则必须使用MutationObserver此处接受的答案中解释的类似s 的内容。

同样作为对这些方法的一些改进:

  • 每个添加 ( classAdded) 或删除 ( classRemoved) 的触发事件,并将特定类作为参数传递给回调函数,并且仅在实际添加(以前不存在)或删除(以前存在)特定类时触发

  • classChanged在实际更改任何类时触发

      (function( func ) {
          $.fn.addClass = function(n) { // replace the existing function on $.fn
              this.each(function(i) { // for each element in the collection
                  var $this = $(this); // 'this' is DOM element in this context
                  var prevClasses = this.getAttribute('class'); // note its original classes
                  var classNames = $.isFunction(n) ? n(i, prevClasses) : n.toString(); // retain function-type argument support
                  $.each(classNames.split(/\s+/), function(index, className) { // allow for multiple classes being added
                      if( !$this.hasClass(className) ) { // only when the class is not already present
                          func.call( $this, className ); // invoke the original function to add the class
                          $this.trigger('classAdded', className); // trigger a classAdded event
                      }
                  });
                  if( prevClasses != this.getAttribute('class') ) $this.trigger('classChanged'); // trigger the classChanged event
              });
              return this; // retain jQuery chainability
          }
      })($.fn.addClass); // pass the original function as an argument
    
      (function( func ) {
          $.fn.removeClass = function(n) {
              this.each(function(i) {
                  var $this = $(this);
                  var prevClasses = this.getAttribute('class');
                  var classNames = $.isFunction(n) ? n(i, prevClasses) : n.toString();
                  $.each(classNames.split(/\s+/), function(index, className) {
                      if( $this.hasClass(className) ) {
                          func.call( $this, className );
                          $this.trigger('classRemoved', className);
                      }
                  });
                  if( prevClasses != this.getAttribute('class') ) $this.trigger('classChanged');
              });
              return this;
          }
      })($.fn.removeClass);
    

使用这些替换函数,您可以通过检查回调函数的参数来处理通过 classChanged 更改的任何类或添加或删除的特定类:

$(document).on('classAdded', '#myElement', function(event, className) {
    if(className == "something") { /* do something */ }
});
这工作得很好,但在“代码的其余”事件处理程序应该下放给目标选择允许绑定到新的元素:$(parent_selector).on('classChanged', target_selector, function(){ /*...*/ });我花了一段时间才明白为什么我的动态创建的元素没有触发处理程序。请参阅learn.jquery.com/events/event-delegation
2021-03-14 04:00:06

trigger火自己的事件。当您更改课程时,请添加带有名称的触发器

JS小提琴演示

$("#main").on('click', function () {
    $("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});

$('#chld').on('cssFontSet', function () {

    alert("Red bg set ");
});

你可以使用这样的东西:

$(this).addClass('someClass');

$(Selector).trigger('ClassChanged')

$(otherSelector).bind('ClassChanged', data, function(){//stuff });

但除此之外,不,没有预定义的函数可以在类更改时触发事件。

在此处阅读有关触发器的更多信息

事件的处理程序必须与触发事件的项目相同。$(this).addClass('someClass'); $(Selector).trigger('ClassChanged') //必须是同一个Selector $(Selector).bind('ClassChanged', data, function(){//stuff });
2021-03-14 04:00:06
似乎您已从此处复制,如果是,那么如果您也提供链接就好了stackoverflow.com/questions/1950038/...
2021-03-24 04:00:06