programing

jQuery를 사용하여 클래스 변경 시 이벤트를 발화하는 방법은?

elecom 2023. 9. 15. 20:45
반응형

jQuery를 사용하여 클래스 변경 시 이벤트를 발화하는 방법은?

저는 다음과 같은 것을 원합니다.

$('#myDiv').bind('class "submission ok" added'){
    alert('class "submission ok" has been added');
});

클래스가 변경되면 이벤트가 발생하지 않습니다.클래스를 프로그램적으로 변경할 때 이벤트를 수동으로 올리는 방법도 있습니다.

$someElement.on('event', function() {
    $('#myDiv').addClass('submission-ok').trigger('classChange');
});

// in another js file, far, far away
$('#myDiv').on('classChange', function() {
     // do stuff
});

업데이트 - 2015

이 질문은 방문자들을 모으고 있는 것 같습니다. 그래서 여기 새로운 코드를 사용하여 기존 코드를 수정할 필요 없이 사용할 수 있는 접근 방식의 업데이트가 있습니다.MutationObserver:

var $div = $("#foo");
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    var attributeValue = $(mutation.target).prop(mutation.attributeName);
    console.log("Class attribute changed to:", attributeValue);
  });
});

observer.observe($div[0], {
  attributes: true,
  attributeFilter: ['class']
});

$div.addClass('red');
.red {
  color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="foo" class="bar">#foo.bar</div>

주의하세요.MutationObserver최신 브라우저, 특히 Chrome 26, FF 14, IE 11, Opera 15 및 Safari 6에서만 사용할 수 있습니다.자세한 내용은 MDN을 참조하십시오.레거시 브라우저를 지원해야 하는 경우 첫 번째 예제에서 설명한 방법을 사용해야 합니다.


업데이트 - 2022년

다음은 jQuery 확장 방법으로 요약된 위의 구현입니다.

// extension method:
$.fn.onClassChange = function(cb) {
  return $(this).each((_, el) => {
    new MutationObserver(mutations => {
      mutations.forEach(mutation => cb && cb(mutation.target, $(mutation.target).prop(mutation.attributeName)));
    }).observe(el, {
      attributes: true,
      attributeFilter: ['class'] // only listen for class attribute changes 
    });
  });
}

// usage:
const $foo = $("#foo").onClassChange((el, newClass) => console.log(`#${el.id} had its class updated to: ${newClass}`));
const $fizz = $("#fizz").onClassChange((el, newClass) => console.log(`#${el.id} had its class updated to: ${newClass}`));

// trigger
$('#trigger').on('click', () => {
  $foo.removeClass('red');
  $fizz.addClass('green dark-bg');
});
.red {
  color: #C00;
}

.green {
  color: #0C0;
}

.dark-bg {
  background-color: #666;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<button id="trigger">Change classes</button>
<div id="foo" class="bar red">#foo.bar</div>
<div id="fizz" class="buzz">#fizz.buzz</div>

원래 jQuery addClass를 대체하고 원래 함수를 호출한 후 사용자 지정 이벤트를 트리거하는 자신의 함수로 Class 함수를 제거할 수 있습니다.(원래 함수 참조를 포함하기 위해 자체 호출 익명 함수 사용)

(function( func ) {
    $.fn.addClass = function() { // replace the existing function on $.fn
        func.apply( this, arguments ); // invoke the original function
        this.trigger('classChanged'); // trigger the custom event
        return this; // retain jQuery chainability
    }
})($.fn.addClass); // pass the original function as an argument

(function( func ) {
    $.fn.removeClass = function() {
        func.apply( this, arguments );
        this.trigger('classChanged');
        return this;
    }
})($.fn.removeClass);

그러면 나머지 코드는 예상한 것처럼 간단해집니다.

$(selector).on('classChanged', function(){ /*...*/ });

업데이트:

JS 피들 데모

이 접근 방식은 jQuery addClass 메서드와 removeClass 메서드를 통해서만 클래스가 변경된다는 가정을 합니다.클래스가 다른 방식으로 수정되는 경우(DOM 요소를 통한 클래스 속성 직접 조작 등) 다음과 같은 것을 사용합니다.MutationObserver여기서 수락된 답변에서 설명된 바와 같이 필요합니다.

또한 이러한 방법에 대한 몇 가지 개선 사항이 있습니다.

  • 추가되는 각 클래스에 대해 이벤트를 트리거합니다(classAdded또는 제거됨(classRemoved특정 클래스가 콜백 함수에 대한 인수로 전달되고 특정 클래스가 실제로 추가되었거나(이전에 존재하지 않음) 제거된 경우에만 트리거됩니다.

  • 트리거만classChanged실제로 변경된 수업이 있다면

      (function( func ) {
          $.fn.addClass = function(n) { // replace the existing function on $.fn
              this.each(function(i) { // for each element in the collection
                  var $this = $(this); // 'this' is DOM element in this context
                  var prevClasses = this.getAttribute('class'); // note its original classes
                  var classNames = $.isFunction(n) ? n(i, prevClasses) : n.toString(); // retain function-type argument support
                  $.each(classNames.split(/\s+/), function(index, className) { // allow for multiple classes being added
                      if( !$this.hasClass(className) ) { // only when the class is not already present
                          func.call( $this, className ); // invoke the original function to add the class
                          $this.trigger('classAdded', className); // trigger a classAdded event
                      }
                  });
                  if( prevClasses != this.getAttribute('class') ) $this.trigger('classChanged'); // trigger the classChanged event
              });
              return this; // retain jQuery chainability
          }
      })($.fn.addClass); // pass the original function as an argument
    
      (function( func ) {
          $.fn.removeClass = function(n) {
              this.each(function(i) {
                  var $this = $(this);
                  var prevClasses = this.getAttribute('class');
                  var classNames = $.isFunction(n) ? n(i, prevClasses) : n.toString();
                  $.each(classNames.split(/\s+/), function(index, className) {
                      if( $this.hasClass(className) ) {
                          func.call( $this, className );
                          $this.trigger('classRemoved', className);
                      }
                  });
                  if( prevClasses != this.getAttribute('class') ) $this.trigger('classChanged');
              });
              return this;
          }
      })($.fn.removeClass);
    

다음 대체 기능을 사용하면 callback 기능에 대한 인수를 확인하여 classChanged 또는 특정 클래스가 추가 또는 제거되는 과정을 통해 변경된 클래스를 처리할 수 있습니다.

$(document).on('classAdded', '#myElement', function(event, className) {
    if(className == "something") { /* do something */ }
});

사용하다trigger당신의 이벤트를 해고할 수 있습니다.클래스를 변경할 때마다 이름으로 트리거 추가

JS Fiddle DEMO

$("#main").on('click', function () {
    $("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});

$('#chld').on('cssFontSet', function () {

    alert("Red bg set ");
});

다음과 같은 것을 사용할 수 있습니다.

$(this).addClass('someClass');

$(Selector).trigger('ClassChanged')

$(otherSelector).bind('ClassChanged', data, function(){//stuff });

그렇지 않으면 클래스가 변경될 때 이벤트를 실행할 수 있는 미리 정의된 기능이 없습니다.

트리거에 대한 자세한 내용은 여기에서 확인

언급URL : https://stackoverflow.com/questions/19401633/how-to-fire-an-event-on-class-change-using-jquery

반응형