如果使用jQuery添加或更改CSS类,如何触发事件? CSS类的变化是否会触发jQuery change()事件?


当前回答

change()在添加或删除CSS类或定义更改时不会触发。它会在选择框值被选中或未选中等情况下触发。

我不确定你的意思是如果CSS类定义被改变(这可以通过编程来完成,但很乏味,通常不推荐),或者如果一个类被添加或删除到一个元素。在这两种情况下,都没有办法可靠地捕捉到这种情况。

当然,您可以为此创建自己的事件,但这只能被描述为建议。它不会捕获不是你的代码。

或者,你可以覆盖/替换addClass()(等)方法在jQuery,但这不会捕获当它是通过香草Javascript(虽然我猜你可以替换这些方法太)。

其他回答

如果您想检测类更改,最好的方法是使用Mutation observer,它可以让您完全控制任何属性更改。但是,您需要自己定义监听器,并将其附加到您正在监听的元素。好消息是,一旦追加了listener,您就不需要手动触发任何事情。

$(function() {
(function($) {
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;

    $.fn.attrchange = function(callback) {
        if (MutationObserver) {
            var options = {
                subtree: false,
                attributes: true
            };

            var observer = new MutationObserver(function(mutations) {
                mutations.forEach(function(e) {
                    callback.call(e.target, e.attributeName);
                });
            });

            return this.each(function() {
                observer.observe(this, options);
            });

        }
    }
})(jQuery);

//Now you need to append event listener
$('body *').attrchange(function(attrName) {

    if(attrName=='class'){
            alert('class changed');
    }else if(attrName=='id'){
            alert('id changed');
    }else{
        //OTHER ATTR CHANGED
    }

});
});

在本例中,事件监听器被附加到每个元素,但在大多数情况下您不希望这样(节省内存)。将这个“attrchange”监听器附加到你想观察的元素上。

使用最新的jquery突变

var $target = jQuery(".required-entry");
            var observer = new MutationObserver(function(mutations) {
                mutations.forEach(function(mutation) {
                    if (mutation.attributeName === "class") {
                        var attributeValue = jQuery(mutation.target).prop(mutation.attributeName);
                        if (attributeValue.indexOf("search-class") >= 0){
                            // do what you want
                        }
                    }
                });
            });
            observer.observe($target[0],  {
                attributes: true
            });

//任何代码更新div类required-entry是在$target 美元target.addClass(搜索类);

好问题。我正在使用引导下拉菜单,需要在引导下拉菜单被隐藏时执行一个事件。当打开下拉菜单时,包含类名为“button-group”的div会添加一个类名为“open”;按钮本身有一个“aria-expanded”属性设置为true。当下拉菜单关闭时,“open”类将从包含的div中删除,aria-expanded将从true切换为false。

这让我想到了一个问题,如何检测类的变化。

使用Bootstrap,可以检测到“下拉事件”。在这个链接中寻找“下拉事件”。 http://www.w3schools.com/bootstrap/bootstrap_ref_js_dropdown.asp

下面是在引导下拉列表中使用此事件的快速示例。

$(document).on('hidden.bs.dropdown', function(event) {
    console.log('closed');
});

现在我意识到这比被问到的一般问题更具体。但我想其他试图用Bootstrap下拉菜单检测打开或关闭事件的开发人员会发现这很有帮助。像我一样,他们最初可能只是尝试检测元素类的变化(这显然不是那么简单)。谢谢。

var timeout_check_change_class;

function check_change_class( selector )
{
    $(selector).each(function(index, el) {
        var data_old_class = $(el).attr('data-old-class');
        if (typeof data_old_class !== typeof undefined && data_old_class !== false) 
        {

            if( data_old_class != $(el).attr('class') )
            {
                $(el).trigger('change_class');
            }
        }

        $(el).attr('data-old-class', $(el).attr('class') );

    });

    clearTimeout( timeout_check_change_class );
    timeout_check_change_class = setTimeout(check_change_class, 10, selector);
}
check_change_class( '.breakpoint' );


$('.breakpoint').on('change_class', function(event) {
    console.log('haschange');
});

只是一个概念的证明:

查看要点,查看一些注释,并保持更新:

https://gist.github.com/yckart/c893d7db0f49b1ea4dfb

(function ($) {
  var methods = ['addClass', 'toggleClass', 'removeClass'];

  $.each(methods, function (index, method) {
    var originalMethod = $.fn[method];

    $.fn[method] = function () {
      var oldClass = this[0].className;
      var result = originalMethod.apply(this, arguments);
      var newClass = this[0].className;

      this.trigger(method, [oldClass, newClass]);

      return result;
    };
  });
}(window.jQuery || window.Zepto));

用法很简单,只要在你想观察和操作类的节点上添加一个新的监听器:

var $node = $('div')

// listen to class-manipulation
.on('addClass toggleClass removeClass', function (e, oldClass, newClass) {
  console.log('Changed from %s to %s due %s', oldClass, newClass, e.type);
})

// make some changes
.addClass('foo')
.removeClass('foo')
.toggleClass('foo');