Javascript 是否可以收听“风格改变”活动?

Javascript 是否可以收听“风格改变”活动?,javascript,jquery,Javascript,Jquery,是否可以在jQuery中创建可以绑定到任何样式更改的事件侦听器?例如,如果我想在元素更改尺寸或样式属性中的任何其他更改时执行某些操作,我可以执行以下操作: $('div').bind('style', function() { console.log($(this).css('height')); }); $('div').height(100); // yields '100' 这真的很有用 有什么想法吗 更新 很抱歉我自己回答了这个问题,但我写了一个可能适合其他人的简洁解决方案:

是否可以在jQuery中创建可以绑定到任何样式更改的事件侦听器?例如,如果我想在元素更改尺寸或样式属性中的任何其他更改时执行某些操作,我可以执行以下操作:

$('div').bind('style', function() {
    console.log($(this).css('height'));
});

$('div').height(100); // yields '100'
这真的很有用

有什么想法吗

更新

很抱歉我自己回答了这个问题,但我写了一个可能适合其他人的简洁解决方案:

(function() {
    var ev = new $.Event('style'),
        orig = $.fn.css;
    $.fn.css = function() {
        $(this).trigger(ev);
        return orig.apply(this, arguments);
    }
})();
这将临时重写internal prototype.css方法,并在最后使用触发器重新定义它。所以它是这样工作的:

$('p').bind('style', function(e) {
    console.log( $(this).attr('style') );
});

$('p').width(100);
$('p').css('color','red');

有趣的问题。问题是height不接受回调,因此无法启动回调。使用动画或css设置高度,然后在回调中触发自定义事件。以下是一个使用animate、tested和works作为概念证明的示例:

$('#test').bind('style', function() {
    alert($(this).css('height'));
});

$('#test').animate({height: 100},function(){
$(this).trigger('style');
}); 

jQuery或java脚本中没有对样式更改事件的内置支持。但是jQuery支持创建自定义事件并侦听它,但是每次有更改时,您都应该有自己触发它的方法。因此,这不是一个完整的解决方案。

正如其他人所建议的,如果您可以控制更改元素样式的任何代码,则可以在更改元素高度时触发自定义事件:

$('#blah').bind('height-changed',function(){...});
...
$('#blah').css({height:'100px'});
$('#blah').trigger('height-changed');

否则,尽管资源非常密集,但您可以设置一个计时器来定期检查元素高度的更改…

因为jQuery是开源的,我想您可以调整css函数,以便在每次通过jQuery对象调用它时调用您选择的函数。当然,您需要仔细检查jQuery代码,以确保其内部没有其他用于设置CSS属性的内容。理想情况下,您希望为jQuery编写一个单独的插件,这样它就不会干扰jQuery库本身,但您必须决定这对您的项目是否可行。

事件对象的声明必须在新的css函数中。否则,事件只能触发一次

(function() {
    orig = $.fn.css;
    $.fn.css = function() {
        var ev = new $.Event('style');
        orig.apply(this, arguments);
        $(this).trigger(ev);
    }
})();

我认为最好的答案是Mike,如果你不能启动你的活动,因为这不是你的代码。但是当我使用它时,我会犯一些错误。所以我写了一个新的答案,告诉你我使用的代码

延伸

用法


我得到了错误,因为var ev=new$.Event'style';HtmlDiv中没有定义类似样式的内容。。我删除了它,现在启动$this.triggerstylechanged。另一个问题是Mike没有返回$css的结果。。在某些情况下,它可能会产生问题。所以我得到结果并返回它。现在^^^在每个css更改中都有效,包括一些我无法修改和触发事件的lib。

只需从上面添加并形式化@David的解决方案:

请注意,jQuery函数是可链接的,并返回“this”,因此可以逐个调用多个调用,例如$container.cssoverflow、hidden.cssoutline、0

因此,改进后的代码应该是:

作用{ var ev=新的$.Event'style', orig=$.fn.css; $.fn.css=函数{ var ret=orig.applythis,参数; $this.triggerev; return ret;//必须包含以下内容 } };
我也有同样的问题,所以我写了这个。它相当有效。如果您将它与一些CSS转换混合在一起,看起来很棒

function toggle_visibility(id) {
   var e = document.getElementById("mjwelcome");
   if(e.style.height == '')
      e.style.height = '0px';
   else
      e.style.height = '';
}

自从提出这个问题以来,事情有了一些进展——现在可以使用检测元素的“style”属性中的更改,不需要jQuery:

var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutationRecord) {
        console.log('style changed!');
    });    
});

var target = document.getElementById('myId');
observer.observe(target, { attributes : true, attributeFilter : ['style'] });
传递给回调函数的参数是一个对象,用于获取旧样式值和新样式值


支持包括IE11+。

您可以尝试Jquery插件,它在css发生更改时触发事件,并且易于使用


jQuery-cssHooks怎么样

也许我不明白这个问题,但是你正在搜索的东西很容易用csshook完成,而不需要改变css函数

文件副本:

(function( $ ) {

// First, check to see if cssHooks are supported
if ( !$.cssHooks ) {
  // If not, output an error message
  throw( new Error( "jQuery 1.4.3 or above is required for this plugin to work" ) );
}

// Wrap in a document ready call, because jQuery writes
// cssHooks at this time and will blow away your functions
// if they exist.
$(function () {
  $.cssHooks[ "someCSSProp" ] = {
    get: function( elem, computed, extra ) {
      // Handle getting the CSS property
    },
    set: function( elem, value ) {
      // Handle setting the CSS value
    }
  };
});

})( jQuery ); 

对不起,这证明了什么?您可以手动触发事件。当修改样式属性时,我会认为OP是在某个自动触发事件之后发生的。@JPot他显示高度属性在更改时不会引发事件。是的,这是一个不错的解决方案,但在实际应用程序中,我怀疑这可能会占用大量资源,甚至会使浏览器看起来很慢,无法跟上用户的交互。我很想知道情况是否如此。@pixeline:我看不出它应该慢那么多。jQuery仍然会调用css原型,我只是给它添加了一个触发器。因此,基本上这只是一个额外的方法调用。我理解:在用户与应用程序交互的流程中,css似乎被调用了很多时间。如果只是一个控制台日志,我想你是安全的,当然,这可能会产生问题。我只是想知道。这也取决于应用程序。我个人倾向于在工作中做很多视觉反馈
还有几件事要做才能使它与现有的jquery css调用一起工作:1您可能希望从新的css函数中返回元素,否则它将中断流畅样式的css调用。例如$'p'.css'display','block'.css'color','black';如果是对属性值的调用,例如'obj.css'height';'您可能希望返回原始函数的返回值-我通过检查函数的参数列表是否只包含一个参数来实现这一点。我为这种方法制作了一个更健壮的版本,在删除style属性本身时也可以使用。它将为以这种方式删除的每个样式抛出一个“样式”事件。但是在这种情况下,如果我直接用DOM函数设置style属性会发生什么呢?这里有一个完整的解决方案示例:很好,谢谢。有些人告诉你改变原始的来源,但是你的扩展是最好的。我遇到了一些问题,但最终还是成功了。它在执行此代码后不断触发,甚至没有达到要求的结果。如果可以访问正在更改样式的代码,这确实是一个非常好的解决方案。请记住,这只适用于内联样式,不是因为阶级改变或@media改变而导致风格改变。@bfred。你知道如何做到这一点吗?我想在将类的css规则应用于元素后运行一些js。你可以将getComputedStyle与setInterval一起使用,但这会大大降低你的网站速度。注意:MutationObserver实际上并不适用于所有版本的Android 4.4,不管caniuse怎么说,看看这个旋转的例子,当文本区域的宽度超过300px时,将文本区域的背景颜色改为蓝色。不幸的是,FF中似乎有一个bug挂起了HTMLElement.style.prop=value处的脚本非常有用,就像这个答案中提到的那样,如果事件不是从代码生成的,那么一种方法将非常有用。请注意,这只针对通过jQuery中的css函数进行的更改。如果外部代码没有对css函数进行更改,则永远不会调用事件处理程序。
var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutationRecord) {
        console.log('style changed!');
    });    
});

var target = document.getElementById('myId');
observer.observe(target, { attributes : true, attributeFilter : ['style'] });
http://meetselva.github.io/#gist-section-attrchangeExtension
 $([selector]).attrchange({
  trackValues: true, 
  callback: function (e) {
    //console.log( '<p>Attribute <b>' + e.attributeName +'</b> changed from <b>' + e.oldValue +'</b> to <b>' + e.newValue +'</b></p>');
    //event.attributeName - Attribute Name
    //event.oldValue - Prev Value
    //event.newValue - New Value
  }
});
(function( $ ) {

// First, check to see if cssHooks are supported
if ( !$.cssHooks ) {
  // If not, output an error message
  throw( new Error( "jQuery 1.4.3 or above is required for this plugin to work" ) );
}

// Wrap in a document ready call, because jQuery writes
// cssHooks at this time and will blow away your functions
// if they exist.
$(function () {
  $.cssHooks[ "someCSSProp" ] = {
    get: function( elem, computed, extra ) {
      // Handle getting the CSS property
    },
    set: function( elem, value ) {
      // Handle setting the CSS value
    }
  };
});

})( jQuery );