jQueryを使用してCSSクラスが追加または変更された場合、どうすればイベントを発生させることができますか?CSSクラスを変更するとjQuerychange()
イベントが発生しますか?
13 に答える
スクリプトでクラスを変更するときはいつでも、を使用しtrigger
て独自のイベントを発生させることができます。
$(this).addClass('someClass');
$(mySelector).trigger('cssClassChanged')
....
$(otherSelector).bind('cssClassChanged', data, function(){ do stuff });
それ以外の場合は、クラスが変更されたときにイベントを発生させるための組み込みの方法はありません。change()
フォーカスが入力が変更された入力を離れた後にのみ起動します。
$(function() {
var button = $('.clickme')
, box = $('.box')
;
button.on('click', function() {
box.removeClass('box');
$(document).trigger('buttonClick');
});
$(document).on('buttonClick', function() {
box.text('Clicked!');
});
});
.box { background-color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">Hi</div>
<button class="clickme">Click me</button>
私見より良い解決策は、@RamboNo5と@Jasonによる2つの答えを組み合わせることです
addClass関数をオーバーライドし、というカスタムイベントを追加することを意味しますcssClassChanged
// Create a closure
(function(){
// Your base, I'm in it!
var originalAddClassMethod = jQuery.fn.addClass;
jQuery.fn.addClass = function(){
// Execute the original method.
var result = originalAddClassMethod.apply( this, arguments );
// trigger a custom event
jQuery(this).trigger('cssClassChanged');
// return the original result
return result;
}
})();
// document ready function
$(function(){
$("#YourExampleElementID").bind('cssClassChanged', function(){
//do stuff here
});
});
クラスの変更を検出する場合は、Mutation Observersを使用するのが最善の方法です。これにより、属性の変更を完全に制御できます。ただし、リスナーを自分で定義し、それをリスニングしている要素に追加する必要があります。良い点は、リスナーが追加されたら、手動で何もトリガーする必要がないことです。
$(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」リスナーを、監視する要素に追加します。
addClass関数をオーバーライドすることをお勧めします。あなたはこのようにそれを行うことができます:
// Create a closure
(function(){
// Your base, I'm in it!
var originalAddClassMethod = jQuery.fn.addClass;
jQuery.fn.addClass = function(){
// Execute the original method.
var result = originalAddClassMethod.apply( this, arguments );
// call your function
// this gets called everytime you use the addClass method
myfunction();
// return the original result
return result;
}
})();
// document ready function
$(function(){
// do stuff
});
概念実証:
要旨を見て、いくつかの注釈を確認し、最新の状態に保ちます。
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');
最新の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
});
// $ target.addClass('search-class');のように$targetにあるクラスrequired-entryを持つdivを更新するコード
change()
CSSクラスが追加または削除されたとき、または定義が変更されたときには起動しません。選択ボックスの値が選択されている場合や選択されていない場合などに発生します。
CSSクラス定義が変更されたのか(プログラムで行うことができますが、面倒で一般的には推奨されません)、クラスが要素に追加または削除されたのかどうかはわかりません。どちらの場合でも、これを確実にキャプチャする方法はありません。
もちろん、このために独自のイベントを作成することもできますが、これは助言としてのみ説明できます。それはあなたがそれをしていないコードをキャプチャしません。
または、jQueryの(etc)メソッドをオーバーライド/置換することもできますaddClass()
が、バニラJavascriptを介して実行された場合、これはキャプチャされません(ただし、これらのメソッドも置換できると思います)。
カスタムイベントをトリガーせずにもう1つの方法があります
RickStrahlによるHTML要素CSSの変更を監視するjQueryプラグイン
上から引用
ウォッチプラグインは、FireFoxのDOMAttrModified、Internet ExplorerのonPropertyChangedに接続するか、setInterval付きのタイマーを使用して他のブラウザーの変更の検出を処理することで機能します。残念ながら、WebKitは現時点でDOMAttrModifiedを一貫してサポートしていないため、SafariとChromeは現在低速のsetIntervalメカニズムを使用する必要があります。
良い質問。ブートストラップドロップダウンメニューを使用しており、ブートストラップドロップダウンが非表示になっているときにイベントを実行する必要がありました。ドロップダウンを開くと、クラス名が「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');
});
今、私はこれが尋ねられている一般的な質問よりも具体的であることに気づきました。しかし、ブートストラップドロップダウンを使用してオープンイベントまたはクローズドイベントを検出しようとしている他の開発者は、これが役立つと思います。私のように、彼らは最初、要素クラスの変更を単に検出しようとする道をたどる可能性があります(これは明らかにそれほど単純ではありません)。ありがとう。
特定のイベントをトリガーする必要がある場合は、メソッドaddClass()をオーバーライドして、「classadded」というカスタムイベントを発生させることができます。
ここでどのように:
(function() {
var ev = new $.Event('classadded'),
orig = $.fn.addClass;
$.fn.addClass = function() {
$(this).trigger(ev, arguments);
return orig.apply(this, arguments);
}
})();
$('#myElement').on('classadded', function(ev, newClasses) {
console.log(newClasses + ' added!');
console.log(this);
// Do stuff
// ...
});
DOMSubtreeModifiedイベントをバインドできます。ここに例を追加します:
HTML
<div id="mutable" style="width:50px;height:50px;">sjdfhksfh<div>
<div>
<button id="changeClass">Change Class</button>
</div>
JavaScript
$(document).ready(function() {
$('#changeClass').click(function() {
$('#mutable').addClass("red");
});
$('#mutable').bind('DOMSubtreeModified', function(e) {
alert('class changed');
});
});
そもそもどのイベントがクラスを変更したかがわかっている場合は、同じイベントでわずかな遅延を使用して、クラスを確認することができます。例
//this is not the code you control
$('input').on('blur', function(){
$(this).addClass('error');
$(this).before("<div class='someClass'>Warning Error</div>");
});
//this is your code
$('input').on('blur', function(){
var el= $(this);
setTimeout(function(){
if ($(el).hasClass('error')){
$(el).removeClass('error');
$(el).prev('.someClass').hide();
}
},1000);
});
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');
});