แอนิเมชั่น addClass / removeClass ด้วย jQuery


225

ฉันใช้ jQuery และ jQuery-ui และต้องการเคลื่อนไหวคุณลักษณะต่าง ๆ บนวัตถุต่าง ๆ

เพื่ออธิบายปัญหาที่นี่ฉันได้ทำให้มันง่ายขึ้นสำหรับ div หนึ่งที่เปลี่ยนจากสีน้ำเงินเป็นสีแดงเมื่อผู้ใช้เลื่อนเมาส์ไปที่มัน

ฉันสามารถรับพฤติกรรมที่ฉันต้องการได้เมื่อใช้animate()อย่างไรก็ตามเมื่อทำเช่นนั้นสไตล์ที่ฉันเคลื่อนไหวต้องอยู่ในรหัสภาพเคลื่อนไหวและแยกจากสไตล์ชีตของฉัน (ดูตัวอย่างที่ 1 )

ทางเลือกที่จะใช้addClass()และแต่ฉันไม่ได้รับสามารถที่จะสร้างใหม่อีกครั้งพฤติกรรมที่แน่นอนว่าผมจะได้รับกับremoveClass() animate()(ดูตัวอย่างที่ 2 )


ตัวอย่างที่ 1

ลองดูรหัสที่ฉันมีanimate():

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

มันแสดงพฤติกรรมทั้งหมดที่ฉันกำลังมองหา:

  1. เคลื่อนไหวได้อย่างราบรื่นระหว่างสีแดงและสีน้ำเงิน
  2. ไม่มีภาพเคลื่อนไหว 'overqueue-ing' เมื่อผู้ใช้เลื่อนเม้าส์เข้าและออกจาก div อย่างรวดเร็ว
  3. หากผู้ใช้เลื่อนเมาส์ออก / เข้าในขณะที่ภาพเคลื่อนไหวยังคงเล่นอยู่จะช่วยลดความถูกต้องระหว่างสถานะ 'ครึ่งทาง' ปัจจุบันและสถานะ 'เป้าหมาย' ใหม่

แต่เนื่องจากการเปลี่ยนแปลงสไตล์ถูกกำหนดไว้ในanimate()ฉันต้องเปลี่ยนค่าสไตล์ที่นั่นและไม่สามารถชี้ไปที่สไตล์ชีทของฉันได้ 'การแตกแฟรกเมนต์' ซึ่งสไตล์ถูกกำหนดเป็นสิ่งที่รบกวนจิตใจฉันอย่างแท้จริง


ตัวอย่างที่ 2

นี่คือความพยายามที่ดีที่สุดในปัจจุบันของฉันในการใช้addClass()และremoveClass(โปรดทราบว่าเพื่อให้แอนิเมชั่นทำงานได้คุณต้อง 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});
  });

สิ่งนี้แสดงทั้งคุณสมบัติ 1 และ 2 ของข้อกำหนดเดิมของฉันอย่างไรก็ตาม 3 ไม่ทำงาน

ฉันเข้าใจเหตุผลของสิ่งนี้:

เมื่อเคลื่อนไหวaddClass()และremoveClass()jQuery เพิ่มสไตล์ชั่วคราวให้กับองค์ประกอบแล้วเพิ่มค่าที่เหมาะสมจนกว่าจะถึงค่าของคลาสที่ระบุและจากนั้นจะเพิ่มหรือลบคลาสออกจริง

ด้วยเหตุนี้ฉันต้องลบแอตทริบิวต์ style ไม่เช่นนั้นถ้าภาพเคลื่อนไหวหยุดกลางคันแอตทริบิวต์ style จะยังคงอยู่และจะเขียนทับค่าคลาสใด ๆ อย่างถาวรเนื่องจากแอตทริบิวต์สไตล์ในแท็กมีความสำคัญสูงกว่าสไตล์คลาส

อย่างไรก็ตามเมื่อแอนิเมชันดำเนินไปครึ่งทางแล้วยังไม่ได้เพิ่มคลาสใหม่ดังนั้นด้วยวิธีนี้สีจะข้ามไปเป็นสีก่อนหน้าเมื่อผู้ใช้เลื่อนเม้าส์ของพวกเขาก่อนที่อนิเมชั่นจะเสร็จสมบูรณ์


สิ่งที่ฉันต้องการในอุดมคติคือสามารถทำสิ่งนี้:

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

อยู่ที่ไหนgetClassContentก็จะส่งคืนเนื้อหาของชั้นมีให้บริการที่ จุดสำคัญคือวิธีนี้ฉันไม่จำเป็นต้องเก็บคำจำกัดความสไตล์ไว้ทุกที่ แต่สามารถเก็บไว้ในชั้นเรียนในสไตล์ชีทของฉันได้


1
คุณต้องการสนับสนุน IE เวอร์ชันใด คุณจะมีความสุขกับ IE9 หรือไม่? หรือคุณต้องการการสนับสนุนที่ต่ำกว่า?
tw16

1
ฉันไม่ได้สนใจเกี่ยวกับ IE เลยแม้แต่น้อย ทั้งหมดนี้ได้รับการทดสอบด้วย webkit browser เท่านั้น (safari / chrome)
โยฮันเนส

วิธีการgetClassContentคือรูปลักษณ์ที่ชอบ?
sreginogemoh

คำตอบ:


311

เนื่องจากคุณไม่ได้กังวลเกี่ยวกับ IE ทำไมไม่ใช้การเปลี่ยน css เพื่อจัดทำแอนิเมชันและ jQuery เพื่อเปลี่ยนคลาส ตัวอย่างสด: 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
ตั้งแต่ 2015-06-12 สิ่งนี้ได้รับการสนับสนุนใน -webkit, -moz - IE 10+ - Chrome 26+ - FireFox 16+ - Safari 6.1+ - Opera 12.1+ , -o จำเป็นสำหรับเบราว์เซอร์รุ่นเก่าเท่านั้น คุณอาจปล่อยให้มันออกไปเพื่อประหยัดพื้นที่
clst

3
@clst ฉันต้องการความเข้ากันได้แบบย้อนหลังกับเบราว์เซอร์เก่ามากกว่าประหยัดพื้นที่ไม่กี่ไบต์
Arman H

95

โซลูชันอื่น (แต่ต้องใช้ jQueryUI ตามที่ Richard Neil Ilagan ระบุไว้ในความคิดเห็น): -

addClass, removeClass และ toggleClass ยังยอมรับอาร์กิวเมนต์ที่สอง ระยะเวลาที่จะไปจากรัฐหนึ่งไปอีกรัฐหนึ่ง

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

ดู jsfiddle: - http://jsfiddle.net/6hvZT/1/


28
โปรดทราบว่านี่ต้องใช้ jQuery UI jQuery ไม่ได้รองรับภาพเคลื่อนไหวสำหรับxxxClass()ฟังก์ชั่น
Richard Neil Ilagan

@ Richard Neil Ilagan: ขอบคุณสำหรับการแจ้งเตือน ฉันพลาดจุดนั้นจริงๆ
โอมาร์ทาเร็ค

4
คุณช่วยชี้ไฟล์ที่จะดาวน์โหลดและรวมไว้ในไฟล์. html เพื่อที่ฉันจะสามารถใช้ jQueryUI สำหรับxxxClassภาพเคลื่อนไหวที่ทวีคูณด้วยวิธีนี้ได้หรือไม่
sodiumnitrate

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

1
วิธีนี้ไม่ได้ทำให้เคลื่อนไหวเหมือนกันกับ slide () หรือ animate () ค่ามิลลิวินาทีคือความล่าช้าซึ่งไม่ใช่ภาพเคลื่อนไหว
Solona Armstrong

38

คุณสามารถใช้ jquery ui's switchClassได้นี่เป็นตัวอย่าง:

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

หรือดูjsfiddleนี้


1
-1 คุณไม่เป็นไปตามข้อ จำกัด 1, 2 และ 3 ที่ฉันระบุไว้ในโพสต์ต้นฉบับ switchClass เฉพาะจัดการความต้องการ 2 และ 3 ได้ไม่ดี
โยฮันเนส

12

คุณแค่ต้องการเอฟเฟกต์ jQuery UI-core (13KB) เพื่อเปิดใช้งานระยะเวลาของการเพิ่ม (เช่นเดียวกับ Omar Tariq มันชี้ให้เห็น)


5

ฉันกำลังดูอยู่นี้ แต่ต้องการมีอัตราการเปลี่ยนแปลงที่แตกต่างกันสำหรับการเข้าและออก

นี่คือสิ่งที่ฉันทำ:

//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');
    });
});

สิ่งนี้จะเปลี่ยนสีพื้นหลังเป็น # 5eb4fc จากนั้นค่อย ๆ จางหายกลับเป็นปกติใน 2 วินาที

นี่คือซอ


2

แม้ว่าคำถามนี้ค่อนข้างเก่า แต่ฉันกำลังเพิ่มข้อมูลที่ไม่ปรากฏในคำตอบอื่น ๆ

OP ใช้การหยุด () เพื่อหยุดการเคลื่อนไหวปัจจุบันทันทีที่กิจกรรมเสร็จสมบูรณ์ อย่างไรก็ตามการใช้พารามิเตอร์ที่เหมาะสมกับฟังก์ชั่นควรช่วย เช่น. stop (true, true) หรือ stop (true, false) เนื่องจากสิ่งนี้มีผลต่อภาพเคลื่อนไหวที่อยู่ในคิวอย่างดี

ลิงค์ต่อไปนี้แสดงตัวอย่างที่แสดงพารามิเตอร์ต่าง ๆ ที่มีให้กับ stop () และความแตกต่างจาก finish ()

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

แม้ว่า OP ไม่มีปัญหาในการใช้ JqueryUI แต่สำหรับผู้ใช้รายอื่นที่อาจเจอสถานการณ์ที่คล้ายกัน แต่ไม่สามารถใช้ JqueryUI / จำเป็นต้องสนับสนุน IE7 และ 8 ด้วย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.