ตรวจสอบหากวางเมาส์เหนือองค์ประกอบด้วย jQuery


150

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

$('#elem').mouseIsOver(); // returns true or false

มีวิธีการ jQuery ที่ทำสิ่งนี้สำเร็จหรือไม่?


ในกรณีที่มีใครบางคนกำลังมองหาโซลูชันอื่น ๆstackoverflow.com/questions/1273566/…
Jo E.

1
การทำเครื่องหมายว่าซ้ำกันดูเหมือนว่าผิด คำถามไม่ได้บอกว่าเจตนาคืออะไรสำหรับคนอื่นที่จะอ่านใจของ OP และตัดสินใจว่ามันเป็นคำถามการตรวจจับการชนกันและทำเครื่องหมายว่าซ้ำกัน
Meligy

คำตอบ:


306

คำตอบเดิม (และถูกต้อง)

คุณสามารถใช้และตรวจสอบตัวเลือกis():hover

var isHovered = $('#elem').is(":hover"); // returns true or false

ตัวอย่าง: http://jsfiddle.net/Meligy/2kyaJ/3/

(ใช้ได้เฉพาะเมื่อตัวเลือกตรงกับหนึ่งองค์ประกอบสูงสุดดูการแก้ไข 3 สำหรับเพิ่มเติม)

.

แก้ไข 1 (29 มิถุนายน 2013): (ใช้ได้กับ jQuery 1.9.x เท่านั้นซึ่งใช้ได้กับ 1.10+ ดูการแก้ไขถัดไป 2)

คำตอบนี้เป็นทางออกที่ดีที่สุดในเวลาที่ตอบคำถาม ตัวเลือก ': hover' นี้ถูกลบด้วย.hover()วิธีการลบใน jQuery 1.9.x

คำตอบล่าสุดโดย "allicarn" ที่น่าสนใจแสดงให้เห็นว่าเป็นไปได้ที่จะใช้:hoverเป็นตัวเลือก CSS (เทียบกับเสียงดังฉ่า) เมื่อคุณนำหน้าด้วยตัวเลือก$($(this).selector + ":hover").length > 0และดูเหมือนว่าจะใช้งานได้!

นอกจากนี้ปลั๊กอินhoverIntent ที่กล่าวถึงในคำตอบอื่นก็ดูดีเช่นกัน

แก้ไข 2 (21 กันยายน 2013): .is(":hover") งาน

จากความคิดเห็นอื่นฉันพบว่าวิธีดั้งเดิมที่ฉันโพสต์.is(":hover")ยังคงใช้งานได้จริงใน jQuery ดังนั้น

  1. มันทำงานใน jQuery 1.7.x

  2. มันหยุดทำงานใน 1.9.1 เมื่อมีคนรายงานมาให้ฉันและเราทุกคนคิดว่ามันเกี่ยวข้องกับการลบhoverนามแฝงjQuery สำหรับการจัดการเหตุการณ์ในรุ่นนั้น

  3. มันทำงานได้อีกครั้งใน jQuery 1.10.1 และ 2.0.2 (อาจ 2.0.x) ซึ่งแสดงให้เห็นว่าความล้มเหลวใน 1.9.x เป็นข้อบกพร่องหรือไม่ใช่พฤติกรรมโดยเจตนาตามที่เราคิดไว้ในจุดก่อนหน้า

หากคุณต้องการทดสอบสิ่งนี้ในรุ่น jQuery เฉพาะให้เปิดตัวอย่าง JSFidlle ที่จุดเริ่มต้นของคำตอบนี้เปลี่ยนเป็นรุ่น jQuery ที่ต้องการแล้วคลิก "เรียกใช้" หากสีเปลี่ยนไปเมื่อโฮเวอร์มันจะทำงาน

.

แก้ไข 3 (9 มีนาคม 2014): ใช้ได้เฉพาะเมื่อลำดับ jQuery มีองค์ประกอบเดียว

ตามที่แสดงโดย @Wilmer ในความคิดเห็นเขามีซอที่ไม่แม้แต่ทำงานกับ jQuery version I และคนอื่น ๆ ที่นี่ทดสอบกับมัน เมื่อฉันพยายามค้นหาสิ่งที่พิเศษเกี่ยวกับเคสของเขาฉันสังเกตว่าเขาพยายามตรวจสอบองค์ประกอบหลายรายการพร้อมกัน Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: hoverนี้ถูกขว้างปา

ดังนั้นทำงานกับซอของเขาสิ่งนี้ทำ ไม่ทำงาน:

var isHovered = !!$('#up, #down').filter(":hover").length;

ในขณะนี้ งานได้ :

var isHovered = !!$('#up,#down').
                    filter(function() { return $(this).is(":hover"); }).length;

นอกจากนี้ยังทำงานร่วมกับลำดับ jQuery ที่มีองค์ประกอบเดียวเช่นถ้าตัวเลือกดั้งเดิมที่ตรงกับองค์ประกอบเดียวเท่านั้นหรือถ้าคุณเรียก.first()ผลการค้นหา ฯลฯ

นี้ยังเป็นที่อ้างอิงของฉันJavascript + เว็บ Dev เคล็ดลับและทรัพยากรจดหมายข่าว


1
ใช้งานได้ดีเรียบง่าย ขอบคุณโมฮาเหม็ด!
James Skidmore

18
โยนข้อผิดพลาดใน IE Syntax Error, unrecognized expression: hover. jquery-1.7.js line 41798:
RobG

นั่นเป็นเรื่องจริง เพิ่งทดสอบ สำหรับ IE6 ลองแฮ็คนี้อธิบายที่นี่peterned.home.xs4all.nl/csshover.htmlหรือถอยกลับไปที่โฮเวอร์ปกติเพิ่มบางสถานะและล้างโซลูชันในภายหลัง
Meligy

1
@Meligy: ผมคดเคี้ยวไวโอลินของคุณเพื่อแสดงให้เห็นว่ามันไม่ได้ทำงานกับหลายรายการในการเลือก: jsfiddle.net/p34n8
ซูเปอร์โนวา

1
นอกจากนี้หากคุณใช้ jQuery mobile มันจะไขสกรูมันเช่นกัน - ตรวจสอบซอในคำตอบของ gideons และเปิดกล่อง jQuery Mobile 1.4.4 และคุณจะเห็นว่ามันไม่ทำงาน ... ฉันสามารถยืนยันได้ด้วย 1.4.2 เช่นกัน :(
David O'Sullivan

32

ใช้:

var hovered = $("#parent").find("#element:hover").length;

jQuery 1.9+


1
มันใช้งานได้ดีเก่ง วิธีแก้ปัญหาที่ดีที่สุดในขณะที่เรียกดูการแทนที่สำหรับ. hover function และ: hover selector ขอบคุณ!
Tyler

1
ทำงานเหมือนจับใจ! :)
jroi_web


5

ตั้งค่าสถานะเป็นโฮเวอร์:

var over = false;
$('#elem').hover(function() {
  over = true;
},
function () {
  over = false;
});

จากนั้นเพียงตรวจสอบธงของคุณ


เรียบง่าย แต่ไม่สามารถนำกลับมาใช้ใหม่ได้ง่าย : /
Trevor

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

@JamesSkidmore - ในกรณีที่ MouseLeave คุณสามารถใช้และe.fromElement e.toElementมันจะใช้ได้ผลสำหรับคุณหรือไม่
mrtsherman

.data()คุณสามารถอัปเดตนี้จะใช้ตัวเลือกที่ครอบคลุมทุกองค์ประกอบที่ใช้บังคับและเก็บธงในแต่ละองค์ประกอบโดยใช้
nnnnnn

@Trevor - จริง - คุณต้องเก็บสถานะไว้ในองค์ประกอบแล้วสร้างฟังก์ชันที่ตรวจสอบสถานะ (แท็กข้อมูลแท็ก) ขององค์ประกอบ
kinakuta

4

อัปเดตคู่ที่จะเพิ่มหลังจากทำงานในหัวข้อนี้สักพัก:

  1. โซลูชันทั้งหมดที่มี. is (": hover") หยุดพักเมื่อ jQuery 1.9.1
  2. เหตุผลที่เป็นไปได้มากที่สุดในการตรวจสอบว่าเมาส์ยังคงอยู่เหนือองค์ประกอบหรือไม่คือพยายามป้องกันเหตุการณ์ที่เกิดขึ้นซึ่งกันและกัน ตัวอย่างเช่นเรากำลังมีปัญหากับ mouseleave ของเราที่ถูกเรียกใช้และเสร็จสิ้นก่อนที่เหตุการณ์ mouseenter ของเราจะเสร็จสมบูรณ์ แน่นอนว่าเป็นเพราะการเคลื่อนไหวของเมาส์อย่างรวดเร็ว

เราใช้ hoverIntent https://github.com/briancherne/jquery-hoverIntentเพื่อแก้ไขปัญหาให้เรา โดยพื้นฐานแล้วมันจะทริกเกอร์หากการเคลื่อนไหวของเมาส์มีเจตนามากขึ้น (สิ่งหนึ่งที่ควรทราบคือมันจะทริกเกอร์บนเมาส์ทั้งสองเข้าสู่องค์ประกอบและออก - ถ้าคุณต้องการใช้เพียงหนึ่งผ่านตัวสร้างเป็นฟังก์ชันว่าง)


4

คุณสามารถกรองความอิ่มเอมใจของคุณได้จากองค์ประกอบที่โฮเวอร์ทั้งหมด รหัสปัญหา:

element.filter(':hover')

บันทึกรหัส:

jQuery(':hover').filter(element)

ในการส่งคืนบูลีน:

jQuery(':hover').filter(element).length===0

4

คำตอบที่ยอมรับใช้ไม่ได้กับฉันใน JQuery 2.x .is(":hover")คืนค่า false ทุกครั้งที่โทร

ฉันลงเอยด้วยวิธีแก้ปัญหาง่ายๆที่ใช้งานได้:

function isHovered(selector) {

    return $(selector+":hover").length > 0

}

3

ขยายคำตอบของ @ Mohamed คุณสามารถใช้การห่อหุ้มเล็กน้อย

แบบนี้:

jQuery.fn.mouseIsOver = function () {
    if($(this[0]).is(":hover"))
    {
        return true;
    }
    return false;
}; 

ใช้มันเหมือน:

$("#elem").mouseIsOver();//returns true or false

ซอฟท์แวง: http://jsfiddle.net/cgWdF/1/


6
สำหรับการทำเช่นนั้นคุณอาจทำได้: jQuery.fn.mouseIsOver = function () {return $ (นี่ [0]). คือ (': hover')}; รหัสน้อย
Lathan

32
มันยากแค่ไหนที่จะทำ $ ('# elem') คือ (': โฮเวอร์')
luckykrrish

ไม่ใช่เรื่องยาก แต่มีเจตนาที่ชัดเจนกว่า แต่สำหรับตัวมันเองนั้น
gideon

1

ฉันชอบคำตอบแรก แต่สำหรับฉันมันแปลก เมื่อพยายามตรวจสอบหลังจากโหลดหน้าเว็บไปแล้วฉันต้องใช้เวลาอย่างน้อย 500 มิลลิวินาทีเพื่อให้เมาส์ทำงาน:

$(window).on('load', function() {
    setTimeout(function() {
        $('img:hover').fadeOut().fadeIn();
    }, 500);
});

http://codepen.io/molokoloco/pen/Grvkx/


0

การตั้งค่าสถานะต่อคำตอบของ kinakuta ดูเหมือนจะสมเหตุสมผลคุณสามารถใส่ผู้ฟังไว้ในร่างกายเพื่อให้คุณสามารถตรวจสอบว่ามีองค์ประกอบใดที่ถูกวางเมาส์ไว้เหนือในทันที

อย่างไรก็ตามคุณต้องการจัดการกับโหนดลูกอย่างไร? คุณควรตรวจสอบว่าองค์ประกอบนั้นเป็นบรรพบุรุษขององค์ประกอบที่โฮเวอร์อยู่หรือไม่

<script>

var isOver = (function() {
  var overElement;
  return {

    // Set the "over" element
    set: function(e) {
      overElement = e.target || e.srcElement;
    },

    // Return the current "over" element
    get: function() {
      return overElement;    
    },

    // Check if element is the current "over" element
    check: function(element) {
      return element == overElement;
    },

    // Check if element is, or an ancestor of, the 
    // current "over" element
    checkAll: function(element) {
      while (overElement.parentNode) {
         if (element == overElement) return true;
         overElement = overElement.parentNode;
      }
      return false;
    }
  };
}());


// Check every second if p0 is being hovered over
window.setInterval( function() {
  var el = document.getElementById('p0');
  document.getElementById('msg').innerHTML = isOver.checkAll(el);
}, 1000);


</script>

<body onmouseover="isOver.set(event);">
  <div>Here is a div
    <p id="p0">Here is a p in the div<span> here is a span in the p</span> foo bar </p>
  </div>
  <div id="msg"></div>
</body>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.