Tôi muốn có một cái gì đó như:
$('#myDiv').bind('class "submission ok" added'){
alert('class "submission ok" has been added');
});
Câu trả lời:
Không có sự kiện nào được nêu ra khi một lớp thay đổi. Giải pháp thay thế là tăng sự kiện theo cách thủ công khi bạn thay đổi lớp theo chương trình:
$someElement.on('event', function() {
$('#myDiv').addClass('submission-ok').trigger('classChange');
});
// in another js file, far, far away
$('#myDiv').on('classChange', function() {
// do stuff
});
CẬP NHẬT
Câu hỏi này dường như đang thu thập một số khách truy cập, vì vậy đây là bản cập nhật với một cách tiếp cận có thể được sử dụng mà không cần phải sửa đổi mã hiện có bằng cách sử dụng mới MutationObserver
:
var $div = $("#foo");
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === "class") {
var attributeValue = $(mutation.target).prop(mutation.attributeName);
console.log("Class attribute changed to:", attributeValue);
}
});
});
observer.observe($div[0], {
attributes: true
});
$div.addClass('red');
.red { color: #C00; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo" class="bar">#foo.bar</div>
Lưu ý rằng tính năng MutationObserver
này chỉ khả dụng cho các trình duyệt mới hơn, cụ thể là Chrome 26, FF 14, IE 11, Opera 15 và Safari 6. Xem MDN để biết thêm chi tiết. Nếu bạn cần hỗ trợ các trình duyệt cũ thì bạn sẽ cần sử dụng phương pháp mà tôi đã nêu trong ví dụ đầu tiên của mình.
trigger()
) mặc dù lưu ý rằng nó rất lỗi thời do việc sử dụng bind()
. Tuy nhiên, tôi không chắc nó 'hoàn thành' bất cứ điều gì
MutationObserver
công trình đối với tôi
Bạn có thể thay thế các hàm addClass và removeClass của jQuery ban đầu bằng hàm của riêng bạn sẽ gọi các hàm gốc và sau đó kích hoạt một sự kiện tùy chỉnh. (Sử dụng một hàm ẩn danh tự gọi để chứa tham chiếu hàm gốc)
(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);
Sau đó, phần còn lại của mã của bạn sẽ đơn giản như bạn mong đợi.
$(selector).on('classChanged', function(){ /*...*/ });
Cập nhật:
Cách tiếp cận này đưa ra giả định rằng các lớp sẽ chỉ được thay đổi thông qua các phương thức addClass và removeClass của jQuery. Nếu các lớp được sửa đổi theo những cách khác (chẳng hạn như thao tác trực tiếp với thuộc tính lớp thông qua phần tử DOM) thì việc sử dụng một cái gì đó như MutationObserver
s như được giải thích trong câu trả lời được chấp nhận ở đây sẽ là cần thiết.
Cũng như một số cải tiến cho các phương pháp này:
classAdded
) hoặc loại bỏ ( classRemoved
) với lớp cụ thể được truyền làm đối số cho hàm gọi lại và chỉ được kích hoạt nếu lớp cụ thể thực sự được thêm vào (không có trước đây) hoặc bị xóa (đã có trước đó)Chỉ kích hoạt classChanged
nếu bất kỳ lớp nào thực sự được thay đổi
(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
}
});
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);
}
});
prevClasses != this.getAttribute('class') && $this.trigger('classChanged');
});
return this;
}
})($.fn.removeClass);
Với các hàm thay thế này, bạn có thể xử lý bất kỳ lớp nào đã thay đổi thông qua classChanged hoặc các lớp cụ thể được thêm vào hoặc xóa bằng cách kiểm tra đối số của hàm gọi lại:
$(document).on('classAdded', '#myElement', function(event, className) {
if(className == "something") { /* do something */ }
});
$(parent_selector).on('classChanged', target_selector, function(){ /*...*/ });
. Tôi đã mất một thời gian để xem tại sao các phần tử được tạo động của tôi không kích hoạt trình xử lý. Xem learning.jquery.com/events/event-delegation
Sử dụng trigger
để kích hoạt sự kiện của riêng bạn. Khi nào bạn thay đổi lớp, hãy thêm trình kích hoạt với tên
$("#main").on('click', function () {
$("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});
$('#chld').on('cssFontSet', function () {
alert("Red bg set ");
});
Tìm hiểu jQuery: Blog hướng dẫn về jQuery đơn giản và dễ dàng
bạn có thể sử dụng một cái gì đó như thế này:
$(this).addClass('someClass');
$(Selector).trigger('ClassChanged')
$(otherSelector).bind('ClassChanged', data, function(){//stuff });
nhưng nếu không, không, không có hàm được xác định trước để kích hoạt một sự kiện khi một lớp thay đổi.
Đọc thêm về trình kích hoạt tại đây