有没有可能听到“style change”;事件吗?

是否有可能在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);
}
})();

这将临时覆盖内部prototype.css方法,并在结束时使用触发器重新定义它。所以它是这样工作的:

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


$('p').width(100);
$('p').css('color','red');
210955 次浏览

有趣的问题。问题是height()不接受回调,因此无法触发回调。使用animate()或css()设置高度,然后在回调中触发自定义事件。下面是一个使用animate(),测试和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在你不能启动事件的情况下,因为不是来自你的代码。但是当我使用它时,我得到一些错误。所以我写了一个新的答案给你们看我用的代码。

扩展

// Extends functionality of ".css()"
// This could be renamed if you'd like (i.e. "$.fn.cssWithListener = func ...")
(function() {
orig = $.fn.css;
$.fn.css = function() {
var result = orig.apply(this, arguments);
$(this).trigger('stylechanged');
return result;
}
})();

使用

// Add listener
$('element').on('stylechanged', function () {
console.log('css changed');
});


// Perform change
$('element').css('background', 'red');

我得到错误,因为var ev =新的$.Event('style');HtmlDiv中没有定义style之类的东西。我删除了它,现在启动$(this).trigger("stylechanged")。另一个问题是Mike没有返回$(css, ..)的结果,那么在某些情况下它会产生问题。我得到结果并返回。现在工作^^在每一个css变化包括从一些库,我不能修改和触发事件。

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

请注意,jQuery函数是可链的,并返回'this',因此可以一个接一个地调用多个调用(例如$container.css("overflow", "hidden").css("outline", 0);)。

所以改进后的代码应该是:

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

我也有同样的问题,所以我写了这个。它运行得相当好。如果你把它和一些CSS过渡混合在一起看起来很棒。

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

自从问了这个问题之后,事情发生了一些变化——现在可以使用MutationObserver来检测元素的'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'] });

传递给回调函数的参数是一个MutationRecord对象,它让你获得旧样式值和新样式值。

支持适用于现代浏览器,包括IE 11+。

你可以尝试Jquery插件,它触发事件时,css是改变,它很容易使用

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
}
});

jQuery csshook怎么样?

也许我不理解这个问题,但是你正在搜索的东西很容易用cssHooks来完成,而不需要改变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 );

https://api.jquery.com/jQuery.cssHooks/