hoạt hình addClass / removeClass với jQuery


225

Tôi đang sử dụng jQuery và jQuery-ui và muốn làm động các thuộc tính khác nhau trên các đối tượng khác nhau.

Để giải thích vấn đề ở đây, tôi đã đơn giản hóa nó thành một div chuyển từ màu xanh sang màu đỏ khi người dùng chuyển qua nó.

Tôi có thể có được hành vi tôi muốn khi sử dụng animate(), tuy nhiên khi thực hiện các kiểu tôi đang tạo hoạt hình phải nằm trong mã hoạt hình và do đó tách biệt với biểu định kiểu của tôi. (xem ví dụ 1 )

Một cách khác là sử dụng addClass()removeClass()tôi không thể tạo lại hành vi chính xác mà tôi có thể có animate(). (xem ví dụ 2 )


ví dụ 1

Chúng ta hãy xem mã tôi có animate():

$('#someDiv')
  .mouseover(function(){
    $(this).stop().animate( {backgroundColor:'blue'}, {duration:500});
  })
  .mouseout(function(){
    $(this).stop().animate( {backgroundColor:'red'}, {duration:500});
  });

nó hiển thị tất cả các hành vi tôi đang tìm kiếm:

  1. Hoạt hình mượt mà giữa màu đỏ và màu xanh.
  2. Không có hình ảnh động 'overqueue-ing' khi người dùng di chuyển chuột nhanh chóng vào và ra khỏi div.
  3. Nếu người dùng di chuyển chuột ra / vào trong khi hoạt hình vẫn đang phát, nó sẽ giảm chính xác giữa trạng thái 'nửa chừng' hiện tại và trạng thái 'mục tiêu' mới.

Nhưng vì các thay đổi kiểu được xác định trong animate()tôi phải thay đổi các giá trị kiểu ở đó và không thể chỉ nó vào biểu định kiểu của tôi. 'Sự phân mảnh' này trong đó các kiểu được định nghĩa là thứ thực sự làm phiền tôi.


Ví dụ 2

Đây là nỗ lực tốt nhất hiện tại của tôi bằng cách sử dụng addClass()removeClass(lưu ý rằng để hoạt hình hoạt động, bạn cần jQuery-ui):

//assume classes 'red' and 'blue' are defined

$('#someDiv')
  .addClass('blue')
  .mouseover(function(){
    $(this).stop(true,false).removeAttr('style').addClass('red', {duration:500});
  })
  .mouseout(function(){
    $(this).stop(true,false).removeAttr('style').removeClass('red', {duration:500});
  });

Điều này thể hiện cả tài sản 1. và 2. yêu cầu ban đầu của tôi, tuy nhiên 3 không hoạt động.

Tôi hiểu lý do cho việc này:

Khi hoạt hình addClass()removeClass() jQuery thêm một kiểu tạm thời cho phần tử, sau đó tăng các giá trị thích hợp cho đến khi chúng đạt đến các giá trị của lớp được cung cấp và chỉ sau đó nó mới thực sự thêm / xóa lớp.

Do đó, tôi phải xóa thuộc tính style, nếu không, nếu hoạt ảnh bị dừng giữa chừng thì thuộc tính style sẽ vẫn ghi đè vĩnh viễn bất kỳ giá trị lớp nào, vì các thuộc tính style trong thẻ có tầm quan trọng cao hơn kiểu lớp.

Tuy nhiên, khi hoạt hình được thực hiện được một nửa, nó vẫn chưa thêm lớp mới, và vì vậy với giải pháp này, màu sẽ chuyển sang màu trước đó khi người dùng di chuyển chuột trước khi hoạt ảnh hoàn tất.


Điều tôi muốn lý tưởng là có thể làm một cái gì đó như thế này:

$('#someDiv')
  .mouseover(function(){
    $(this).stop().animate( getClassContent('blue'), {duration:500});
  })
  .mouseout(function(){
    $(this).stop().animate( getClassContent('red'), {duration:500});
  });

Trường hợp getClassContentsẽ trả lại nội dung của lớp được cung cấp. Điểm mấu chốt là theo cách này tôi không phải giữ các định nghĩa phong cách của mình ở mọi nơi, nhưng có thể giữ chúng trong các lớp trong biểu định kiểu của tôi.


1
Những phiên bản IE nào bạn cần hỗ trợ? Bạn có hài lòng với IE9 không? Hay bạn cần hỗ trợ thấp hơn?
tw16

1
Thành thật mà nói tôi không quan tâm đến IE. Tất cả điều này đã được thử nghiệm chỉ với các trình duyệt webkit (safari / chrome).
Julian

thế nào getClassContentlà vẻ bề ngoài như thế nào?
sreginogemoh

Câu trả lời:


311

Vì bạn không lo lắng về IE, tại sao không sử dụng các chuyển đổi css để cung cấp hoạt hình và jQuery để thay đổi các lớp. Ví dụ trực tiếp: http://jsfiddle.net/tw16/JfK6N/

#someDiv{
    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;
}

14
Kể từ 2015-06-12, điều này được hỗ trợ trong - IE 10+ - Chrome 26+ - FireFox 16+ - Safari 6.1+ - Opera 12.1+ -webkit, -moz, -o chỉ cần thiết cho các trình duyệt cũ hơn. Bạn có thể để nó ra ngoài để tiết kiệm không gian.
clst

3
@clst, tôi thích khả năng tương thích ngược với các trình duyệt cũ hơn là tiết kiệm một vài byte dung lượng.
Arman H

95

Một giải pháp khác (nhưng nó yêu cầu jQueryUI như Richard Neil Ilagan đã chỉ ra trong các bình luận): -

addClass, removeClass và toggleClass cũng chấp nhận đối số thứ hai; khoảng thời gian để đi từ trạng thái này sang trạng thái khác.

$(this).addClass('abc',1000);

Xem jsfiddle: - http://jsfiddle.net/6hvZT/1/


28
Lưu ý rằng điều này đòi hỏi UI UI. jQuery ra khỏi hộp không hỗ trợ tweening hoạt hình cho các xxxClass()chức năng.
Richard Neil Ilagan

@Richard Neil Ilagan: Cảm ơn bạn đã thông báo. Tôi thực sự đã bỏ lỡ điểm đó.
Omar Tariq

4
Bạn có thể chỉ ra tệp nào cần tải xuống và đưa vào tệp .html để tôi chỉ có thể sử dụng jQueryUI cho xxxClasshoạt hình theo cách này không?
sodiumnitrate

[jqueryui.com] (jqueryui.com) @sodiumnitrate
joe_young

1
Giải pháp này cũng không hoạt hình giống như slide () hoặc animate (). Giá trị mili giây là độ trễ, không phải là hình động.
Solona Armstrong

38

Bạn có thể sử dụng jquery ui's switchClass, đây là một ví dụ:

$( "selector" ).switchClass( "oldClass", "newClass", 1000, "easeInOutQuad" );

Hoặc xem jsfiddle này .


1
-1. Bạn đã không đáp ứng các hạn chế 1, 2 và 3 mà tôi đã liệt kê trong bài viết gốc. Cụ thể switchClass xử lý các yêu cầu 2 và 3 kém.
Julian

12

Bạn chỉ cần lõi hiệu ứng UI jQuery (13KB), để cho phép thời lượng thêm (giống như Omar Tariq mà nó đã chỉ ra)


5

Tôi đã xem xét điều này nhưng muốn có một tỷ lệ chuyển đổi khác nhau cho vào và ra.

Đây là những gì tôi đã làm:

//css
.addedClass {
    background: #5eb4fc;
}

// js
function setParentTransition(id, prop, delay, style, callback) {
    $(id).css({'-webkit-transition' : prop + ' ' + delay + ' ' + style});
    $(id).css({'-moz-transition' : prop + ' ' + delay + ' ' + style});
    $(id).css({'-o-transition' : prop + ' ' + delay + ' ' + style});
    $(id).css({'transition' : prop + ' ' + delay + ' ' + style});
    callback();
}
setParentTransition(id, 'background', '0s', 'ease', function() {
    $('#elementID').addClass('addedClass');
});

setTimeout(function() {
    setParentTransition(id, 'background', '2s', 'ease', function() {
        $('#elementID').removeClass('addedClass');
    });
});

Điều này ngay lập tức biến màu nền thành # 5eb4fc và sau đó từ từ mờ dần trở lại bình thường trong hơn 2 giây.

Đây là một câu đố


2

Mặc dù, câu hỏi khá cũ, tôi đang thêm thông tin không có trong các câu trả lời khác.

OP đang sử dụng stop () để dừng hoạt hình hiện tại ngay khi sự kiện hoàn thành. Tuy nhiên, sử dụng kết hợp đúng các tham số với chức năng sẽ giúp ích. ví dụ. dừng (đúng, đúng) hoặc dừng (đúng, sai) vì điều này ảnh hưởng tốt đến hoạt ảnh được xếp hàng.

Liên kết sau minh họa một bản demo cho thấy các tham số khác nhau có sẵn với stop () và cách chúng khác với finish ().

http://api.jquery.com/finish/

Mặc dù OP không gặp vấn đề gì khi sử dụng JqueryUI, nhưng điều này dành cho những người dùng khác có thể gặp phải các tình huống tương tự nhưng không thể sử dụng JqueryUI / cũng cần hỗ trợ IE7 và 8.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.