jQuery를 사용하여 CSS 클래스를 추가하거나 변경하면 어떻게 이벤트를 발생시킬 수 있습니까? CSS 클래스를 변경하면 jQuery change()
이벤트가 발생합니까?
jQuery를 사용하여 CSS 클래스를 추가하거나 변경하면 어떻게 이벤트를 발생시킬 수 있습니까? 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의 두 가지 답변을 결합하는 것입니다.
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
});
});
$()
실제 작업이 시작될 때 초당 수백 개의 DOMNodeInserted / DOMSubtreeModified 이벤트를 발생시키는 페이지를 가로 질러 총 수백 개의 이벤트가 발생했습니다 .
cssClassChanged
이벤트를 요소에 바인딩하면 자식이 클래스를 변경하더라도 해고 될 것임을 알아야합니다. 따라서 예를 들어 이벤트를 시작하지 않으려면 $("#YourExampleElementID *").on('cssClassChanged', function(e) { e.stopPropagation(); });
바인드 후 같은 것을 추가 하십시오. 어쨌든 정말 좋은 해결책입니다. 감사합니다!
클래스 변경을 감지하려면 가장 좋은 방법은 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"리스너를 관찰하려는 요소에 추가하십시오.
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를 통해 완료되면 캡처되지 않습니다 (이 메소드를 대체 할 수는 있지만).
맞춤 이벤트 를 실행 하지 않고 한 가지 더 방법이 있습니다
Rick Strahl의 HTML 요소 CSS 변경 사항을 모니터링하는 jQuery 플러그인
위에서 인용
watch 플러그인은 FireFox의 DOMAttrModified, Internet Explorer의 onPropertyChanged에 연결하거나 setInterval과 함께 타이머를 사용하여 다른 브라우저의 변경 감지를 처리하여 작동합니다. 불행히도 WebKit은 현재 DOMAttrModified를 일관되게 지원하지 않으므로 Safari와 Chrome은 현재 느린 setInterval 메커니즘을 사용해야합니다.
좋은 질문. Bootstrap Dropdown Menu를 사용하고 있으며 Bootstrap Dropdown이 숨겨져있을 때 이벤트를 실행해야했습니다. 드롭 다운이 열리면 클래스 이름이 "button-group"인 포함 div에 "open"클래스가 추가됩니다. 버튼 자체에는 "aria-expanded"속성이 true로 설정되어 있습니다. 드롭 다운이 닫히면 해당 "open"클래스가 포함 된 div에서 제거되고 aria-expanded가 true에서 false로 전환됩니다.
클래스 변경을 감지하는 방법에 대한 질문으로 이어졌습니다.
부트 스트랩을 사용하면 감지 할 수있는 "드롭 다운 이벤트"가 있습니다. 이 링크에서 "드롭 다운 이벤트"를 찾으십시오. 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>
자바 스크립트
$(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');
});