CSSクラスがjQueryを使用して追加または変更された場合、イベントを起動するにはどうすればよいですか?CSSクラスを変更すると、jQuery change()
イベントが発生しますか?
CSSクラスがjQueryを使用して追加または変更された場合、イベントを起動するにはどうすればよいですか?CSSクラスを変更すると、jQuery change()
イベントが発生しますか?
回答:
スクリプトでクラスを変更するときはいつでも、a 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>
changeColor
イベントをトリガーするだけで、そのイベントにサブスクライブしているすべてのオブジェクトがそれに応じて反応できます。
私見より良い解決策は、@ 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
});
});
$()
、実際のアクションが始まるに到達するまでに何百ものイベントが発生するページを横断しました。
cssClassChanged
イベントを要素にバインドすると、その子がクラスを変更した場合でもイベントが発生することに注意する必要があります。したがって、たとえばこのイベントを発生させたくない場合は$("#YourExampleElementID *").on('cssClassChanged', function(e) { e.stopPropagation(); });
、バインドの後に何かを追加します。とにかく、本当に素晴らしい解決策、ありがとう!
クラスの変更を検出したい場合、最善の方法は変異オブザーバーを使用することです。これにより、属性の変更を完全に制御できます。ただし、リスナーを自分で定義し、リスニングしている要素に追加する必要があります。良い点は、リスナーが追加されたら手動で何かをトリガーする必要がないことです。
$(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」リスナーを監視する要素に追加します。
DOMMutationObserver
。
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');
this[0]
定義されていません...単に持つ行の末尾置き換えるvar oldClass
とvar newClass
、以下の割り当てとを:= (this[0] ? this[0].className : "");
最新の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クラス定義が変更されているか(プログラムで行うことはできますが、面倒で一般に推奨されていません)、またはクラスが要素に追加または削除されているかどうかはわかりません。どちらの場合でも、これを確実にキャプチャする方法はありません。
もちろん、このために独自のイベントを作成することもできますが、これは助言としてのみ説明できますます。それはあなたがそれをしていないコードをキャプチャしません。
あるいはaddClass()
、jQueryの(etc)メソッドをオーバーライド/置換することもできますが、これはバニラJavascriptを介して行われたときにキャプチャされません(ただし、これらのメソッドも置換できると思います)。
カスタムイベントをトリガーしない方法がもう1つあります
Rick Strahlによる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に切り替えられます。
それで、クラスの変更をどのように検出するかというこの質問に私を導きました。
ブートストラップには、検出可能な「ドロップダウンイベント」があります。このリンクで「ドロップダウンイベント」を探します。 http://www.w3schools.com/bootstrap/bootstrap_ref_js_dropdown.asp
これは、Bootstrap Dropdownでこのイベントを使用する簡単な例です。
$(document).on('hidden.bs.dropdown', function(event) {
console.log('closed');
});
これは、質問されている一般的な質問よりも具体的であることがわかりました。しかし、Bootstrap Dropdownを使用してオープンイベントまたはクローズドイベントを検出しようとする他の開発者がこれが役立つと思います。私と同じように、彼らは最初は要素クラスの変更を検出しようとするだけの経路をたどる可能性があります(明らかにそれほど単純ではありません)。ありがとう。
特定のイベントをトリガーする必要がある場合は、メソッド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');
});