Mendeteksi JIKA melayang di atas elemen dengan jQuery

150

Saya tidak mencari tindakan untuk dipanggil saat melayang, melainkan cara untuk mengetahui apakah suatu elemen sedang melayang saat ini. Misalnya:

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

Apakah ada metode jQuery yang melakukan ini?

James Skidmore
sumber
Untuk berjaga-jaga jika seseorang mencari solusi lain stackoverflow.com/questions/1273566/…
Jo E.
1
Penandaan sebagai duplikat terlihat sangat salah. Pertanyaannya tidak mengatakan apa tujuannya, agar orang lain membaca pikiran OP dan memutuskan itu adalah pertanyaan deteksi tabrakan dan tandai sebagai duplikat.
Meligy

Jawaban:

306

Jawaban Asli (Dan Benar):

Anda dapat menggunakan is()dan memeriksa pemilih :hover.

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

Contoh: http://jsfiddle.net/Meligy/2kyaJ/3/

(Ini hanya berfungsi ketika pemilih cocok dengan SATU elemen maks. Lihat Edit 3 untuk lebih lanjut)

.

Sunting 1 (29 Juni 2013): (Hanya berlaku untuk jQuery 1.9.x, karena berfungsi dengan 1.10+, lihat Sunting 2 berikutnya)

Jawaban ini adalah solusi terbaik pada saat pertanyaan itu dijawab. Pemilih ': hover' ini dihapus dengan .hover()penghapusan metode di jQuery 1.9.x.

Menariknya, jawaban terbaru oleh "allicarn" menunjukkan bahwa mungkin untuk digunakan :hoversebagai pemilih CSS (vs. Sizzle) ketika Anda awalan dengan pemilih $($(this).selector + ":hover").length > 0, dan tampaknya berfungsi!

Juga, plugin hoverIntent yang disebutkan dalam jawaban lain juga terlihat sangat bagus.

Edit 2 (21 September 2013): .is(":hover") berfungsi

Berdasarkan komentar lain saya perhatikan bahwa cara asli saya memposting .is(":hover"),, sebenarnya masih berfungsi di jQuery, jadi.

  1. Ini bekerja di jQuery 1.7.x.

  2. Itu berhenti bekerja di 1.9.1, ketika seseorang melaporkannya kepada saya, dan kami semua berpikir itu terkait dengan jQuery menghapus hoveralias untuk penanganan acara di versi itu.

  3. Ini berfungsi lagi di jQuery 1.10.1 dan 2.0.2 (mungkin 2.0.x), yang menunjukkan bahwa kegagalan pada 1.9.x adalah bug atau bukan perilaku yang disengaja seperti yang kita pikirkan pada poin sebelumnya.

Jika Anda ingin menguji ini dalam versi jQuery tertentu, cukup buka contoh JSFidlle di awal jawaban ini, ubah ke versi jQuery yang diinginkan dan klik "Run". Jika warna berubah saat melayang, itu berfungsi.

.

Sunting 3 (9 Maret 2014): Ini hanya berfungsi ketika urutan jQuery berisi elemen tunggal

Seperti yang ditunjukkan oleh @Wilmer di komentar, ia memiliki biola yang bahkan tidak bekerja melawan versi jQuery I dan yang lainnya di sini mengujinya. Ketika saya mencoba menemukan apa yang spesial dari kasingnya, saya perhatikan bahwa ia mencoba memeriksa beberapa elemen sekaligus. Ini melempar Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: hover.

Jadi, bekerja dengan biolanya, ini TIDAK bekerja:

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

Sementara ini TIDAK berfungsi:

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

Ia juga bekerja dengan urutan jQuery yang berisi elemen tunggal, seperti jika pemilih asli hanya cocok dengan satu elemen, atau jika Anda memanggil .first()hasilnya, dll.

Ini juga direferensikan di JavaScript + Tip & Sumber Daya Newsletter Web saya .

Meligy
sumber
1
Bekerja dengan baik, sederhana. Mohamed terima kasih!
James Skidmore
18
Melempar kesalahan di IE 8: Syntax Error, unrecognized expression: hover. jquery-1.7.js line 4179.
RobG
Itu benar. Baru saja mengujinya. Untuk IE6, coba peretasan yang dijelaskan di sini peterned.home.xs4all.nl/csshover.html atau kembali ke hover normal, tambahkan beberapa keadaan dan hapus beberapa jenis solusi nanti.
Meligy
1
@Meligy: Saya sudah bercabang biola Anda untuk menggambarkan bahwa itu tidak bekerja dengan beberapa item dalam pemilihan: jsfiddle.net/p34n8
Supernova
1
Juga jika Anda menggunakan jQuery mobile, yang mengacaukannya juga - periksa biola di gideon menjawab dan nyalakan kotak jQuery Mobile 1.4.4 dan Anda dapat melihatnya tidak berfungsi maka ... Saya dapat mengonfirmasi hal yang sama dengan 1.4.2 juga :(
David O'Sullivan
32

Menggunakan:

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

jQuery 1.9+

pengguna2444818
sumber
1
Ini bekerja dengan sangat baik. Solusi terbaik ditemukan saat browsing untuk penggantian fungsi .hover dan: hover pemilih. Terima kasih!
Tyler
1
Bekerja seperti pesona! :)
jroi_web
9

Tidak berfungsi di jQuery 1.9. Membuat plugin ini berdasarkan jawaban user2444818.

jQuery.fn.mouseIsOver = function () {
    return $(this).parent().find($(this).selector + ":hover").length > 0;
}; 

http://jsfiddle.net/Wp2v4/1/

allicarn
sumber
5

Tetapkan bendera pada kursor:

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

Kemudian, periksa benderamu.

kinakuta
sumber
Sederhana, tetapi tidak mudah digunakan kembali. : /
Trevor
Tampaknya tidak berfungsi dalam situasi khusus saya, tetapi saya setuju itu cara yang baik untuk pergi sebaliknya. Dalam kasus saya, ketika saya mouseleavesatu elemen, saya ingin memeriksa untuk melihat apakah mouse masuk elemen tertentu.
James Skidmore
@JamesSkidmore - dalam acara mouseleave yang dapat Anda gunakan e.fromElementdan e.toElement. Apakah itu akan berhasil untuk Anda?
mrtsherman
Anda bisa memperbarui ini untuk menggunakan pemilih yang mencakup semua elemen yang berlaku, dan menyimpan bendera pada elemen individu menggunakan .data().
nnnnnn
@ Trvor - true - Anda harus menyimpan status pada elemen lalu membuat fungsi yang memeriksa status (mungkin data-tag) elemen.
kinakuta
4

Perbarui pasangan untuk ditambahkan setelah mengerjakan masalah ini untuk sementara waktu:

  1. semua solusi dengan .is (": hover") di jQuery 1.9.1
  2. Alasan yang paling mungkin untuk memeriksa apakah mouse masih melebihi elemen adalah untuk mencoba mencegah peristiwa saling menembak. Misalnya, kami mengalami masalah dengan mouseleave kami dipicu dan diselesaikan sebelum acara mouseenter kami bahkan selesai. Tentu saja ini karena gerakan mouse yang cepat.

Kami menggunakan hoverIntent https://github.com/briancherne/jquery-hoverIntent untuk menyelesaikan masalah bagi kami. Pada dasarnya itu memicu jika gerakan mouse lebih disengaja. (Satu hal yang perlu diperhatikan adalah ia akan memicu kedua mouse memasukkan elemen dan pergi - jika Anda hanya ingin menggunakan satu pass, konstruktor merupakan fungsi kosong)

Donald A Nummer Jr
sumber
4

Anda dapat memfilter elemen Anda dari semua elemen melayang. Kode bermasalah:

element.filter(':hover')

Simpan kode:

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

Untuk mengembalikan boolean:

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

Jawaban yang diterima tidak berfungsi untuk saya di JQuery 2.x .is(":hover")mengembalikan false pada setiap panggilan.

Saya berakhir dengan solusi yang cukup sederhana yang berfungsi:

function isHovered(selector) {

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

}
gidim
sumber
3

Memperluas jawaban @ Mohamed. Anda bisa menggunakan enkapsulasi kecil

Seperti ini:

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

Gunakan seperti:

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

Forked the fiddle: http://jsfiddle.net/cgWdF/1/

Gideon
sumber
6
untuk melakukan itu, Anda sebaiknya melakukannya: jQuery.fn.mouseIsOver = function () {return $ (this [0]). is (': hover')}; kode kurang
Lathan
32
betapa sulitnya hanya melakukan $ ('# elem'). is (': hover')
luckykrrish
bukan masalah yang sulit tetapi lebih jelas maksudnya diungkapkan. Tetapi untuk masing-masing itu sendiri.
gideon
1

Saya suka tanggapan pertama, tetapi bagi saya itu aneh. Ketika mencoba untuk memeriksa setelah memuat halaman untuk mouse, saya harus memasukkan setidaknya 500 milidetik penundaan untuk itu berfungsi:

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

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

molokoloco
sumber
0

Mengatur bendera per jawaban kinakuta tampaknya masuk akal, Anda dapat menempatkan pendengar pada tubuh sehingga Anda dapat memeriksa apakah ada elemen yang melayang pada saat tertentu.

Namun, bagaimana Anda ingin berurusan dengan node anak? Anda mungkin harus memeriksa apakah elemen tersebut merupakan leluhur dari elemen yang saat ini melayang.

<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>
RobG
sumber