JQuery kullanılarak bir CSS sınıfı eklenir veya değiştirilirse bir olayı nasıl tetikleyebilirim? CSS sınıfının değiştirilmesi jQuery change()
olayını tetikliyor mu?
JQuery kullanılarak bir CSS sınıfı eklenir veya değiştirilirse bir olayı nasıl tetikleyebilirim? CSS sınıfının değiştirilmesi jQuery change()
olayını tetikliyor mu?
Yanıtlar:
Senaryonuzdaki bir sınıfı değiştirdiğinizde trigger
, kendi etkinliğinizi yükseltmek için a kullanabilirsiniz .
$(this).addClass('someClass');
$(mySelector).trigger('cssClassChanged')
....
$(otherSelector).bind('cssClassChanged', data, function(){ do stuff });
ama aksi halde, hayır, bir sınıf değiştiğinde bir olayı ateşlemenin hiçbir yolu yoktur. change()
yalnızca odak, girdisi değiştirilen bir girdiden ayrıldıktan sonra tetiklenir.
$(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
olayı tetikleyebilirim ve bu olaya abone olan tüm nesneler buna göre tepki verebilir.
IMHO daha iyi bir çözüm @ RamboNo5 ve @Jason'un iki cevabını birleştirmektir
AddClass işlevini geçersiz kılmak ve adlı özel bir olay eklemek demek 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
});
});
$()
Gerçek eylem başladığında, onlarca DOMNodeInserted / DOMSubtreeModified olayı saniyede toplam yüzlerce olayı tetikleyen sayfalarda koştum .
cssClassChanged
olayı bir öğeye bağlarsanız , çocuğu sınıflarını değiştirdiğinde bile tetikleneceğini bilmelisiniz. Bu nedenle, örneğin bu olayı onlar için başlatmak istemiyorsanız $("#YourExampleElementID *").on('cssClassChanged', function(e) { e.stopPropagation(); });
, bağlandıktan sonra olduğu gibi bir şey ekleyin . Neyse, gerçekten güzel bir çözüm, teşekkürler!
Sınıf değişikliğini tespit etmek istiyorsanız, en iyi yol, herhangi bir özellik değişikliği üzerinde tam kontrol sağlayan Mutasyon Gözlemcilerini kullanmaktır. Ancak dinleyiciyi kendiniz tanımlamanız ve dinlediğiniz öğeye eklemeniz gerekir. İyi bir şey, dinleyici eklendikten sonra herhangi bir şeyi manuel olarak tetiklemenize gerek olmamasıdır.
$(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
}
});
});
Bu örnekte olay dinleyicisi her öğeye eklenir, ancak çoğu durumda bunu istemezsiniz (bellek tasarrufu). Gözlemlemek istediğiniz öğeye bu "yıpranma" dinleyicisini ekleyin.
DOMMutationObserver
.
AddClass işlevini geçersiz kılmanızı öneririm. Bunu şu şekilde yapabilirsiniz:
// 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
});
Sadece bir kavram kanıtı:
Bazı ek açıklamaları görmek ve güncel kalmak için özete bakın:
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));
Kullanımı oldukça basit, sadece gözlemlemek ve düğümleri genellikle istediğiniz gibi işlemek istediğiniz düğüme yeni bir listender ekleyin:
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]
tanımlanmamış ... basitçe ile çizgilerin ucunu değiştirmek var oldClass
ve var newClass
aşağıdaki atama ile:= (this[0] ? this[0].className : "");
en son jquery mutasyonunu kullanarak
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 ('arama-sınıfı') gibi $ target içinde olan sınıf zorunlu girişine sahip div'i güncelleyen herhangi bir kod ;
change()
CSS sınıfı eklendiğinde veya kaldırıldığında veya tanım değiştiğinde tetiklenmez. Seçim kutusu değerinin seçilmesi veya seçilmemesi gibi durumlarda tetiklenir.
CSS sınıfı tanımının değişip değişmediğini (programlı olarak yapılabilir, ancak sıkıcıdır ve genellikle önerilmez) veya bir öğeye sınıf eklendiğini veya kaldırıldığını kastediyorsanız emin değilim. Her iki durumda da bu olayı güvenilir bir şekilde yakalamanın bir yolu yoktur.
Elbette bunun için kendi etkinliğinizi yaratabilirsiniz, ancak bu sadece danışmanlık olarak tanımlanabilir . Size ait olmayan kodu yakalamaz.
Alternatif olarak, jQuery'de addClass()
(etc) yöntemlerini geçersiz kılabilir / değiştirebilirsiniz, ancak vanilya Javascript ile yapıldığında bu yakalanmayacaktır (her ne kadar bu yöntemleri de değiştirebileceğinizi tahmin ediyorum).
Bir yol daha vardır olmadan bir özel etkinliği tetikleyen
Html Element CSS Değişikliklerini Rick Strahl tarafından izlemek için bir jQuery Eklentisi
Yukarıdan alıntı
Saat eklentisi, FireFox'ta DOMAttrModified'e, Internet Explorer'da onPropertyChanged'e veya diğer tarayıcılarda değişikliklerin algılanması için setInterval ile bir zamanlayıcı kullanarak çalışır. Ne yazık ki WebKit şu anda DOMAttrModified'i sürekli olarak desteklemediğinden Safari ve Chrome şu anda daha yavaş setInterval mekanizmasını kullanmak zorunda.
İyi soru. Bootstrap açılır menüsünü kullanıyorum ve bir Bootstrap açılır menüsü gizlendiğinde bir olayı yürütmek için gerekli. Açılır menü açıldığında, sınıf adı "düğme-grubu" olan içeren div "açık" sınıfı ekler; ve düğmenin kendisi de true değerine ayarlanmış "aria-expanded" özelliğine sahiptir. Açılır menü kapatıldığında, bu "açık" sınıfı içeren div'den kaldırılır ve aria-genişletilmiş, true değerinden false değerine geçirilir.
Bu beni, sınıf değişikliğinin nasıl tespit edileceği sorusuna götürdü.
Bootstrap ile algılanabilen "Açılır Olaylar" vardır. Bu bağlantıda "Açılır Etkinlikler" i bulun. http://www.w3schools.com/bootstrap/bootstrap_ref_js_dropdown.asp
İşte bu olayı Bootstrap Açılır Menüsünde kullanmanın hızlı ve kirli bir örneği.
$(document).on('hidden.bs.dropdown', function(event) {
console.log('closed');
});
Şimdi bunun genel sorudan daha spesifik olduğunu anlıyorum. Ancak, Bootstrap Dropdown ile açık veya kapalı bir olayı tespit etmeye çalışan diğer geliştiricilerin bunu faydalı bulacağını düşünüyorum. Benim gibi, başlangıçta sadece bir element sınıfı değişikliğini tespit etmeye çalışabilirler (görünüşe göre bu kadar basit değil). Teşekkürler.
Belirli bir olayı tetiklemeniz gerekiyorsa, 'classadded' adlı özel bir etkinliği başlatmak için addClass () yöntemini geçersiz kılabilirsiniz.
İşte nasıl:
(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 olayını bağlayabilirsiniz. Buraya bir örnek ekliyorum:
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');
});
});
İlk olarak hangi etkinliğin sınıfı değiştirdiğini biliyorsanız, aynı etkinlikte hafif bir gecikme ve sınıfı kontrol edin. misal
//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');
});