2009-11-04 33 views
11

Tôi muốn một số mã Javascript chạy khi con chuột rời khỏi cửa sổ trình duyệt. Tôi chỉ cần hỗ trợ Safari (WebKit.)Sự kiện Javascript khi chuột rời khỏi cửa sổ trình duyệt

Tôi đã thử đặt trình xử lý mouseout trên cửa sổ. Trình xử lý đó được gọi một cách đáng tin cậy khi con chuột rời khỏi cửa sổ trình duyệt. Nhưng vì sủi bọt nó cũng được gọi khi chuột di chuyển giữa các phần tử trong tài liệu. Tôi không thể tìm ra cách xác định khi nào con chuột đã thực sự rời khỏi cửa sổ và khi nó chỉ di chuyển giữa các phần tử.

Khi chuột rời khỏi cửa sổ, chính xác một sự kiện được tạo và phần tử đích xuất hiện là phần tử con chuột thực sự kết thúc. Vì vậy, kiểm tra xem phần tử đích là cửa sổ hoặc tài liệu không hoạt động. Và gói toàn bộ trang trong một div có chứa vô hình không hoạt động: hoặc nếu div là vô hình, thì con chuột sẽ không bao giờ vượt qua nó, vì vậy không có gì thay đổi.

(Điều tương tự cũng xảy ra nếu tôi đặt trình xử lý trên tài liệu hoặc tài liệu.chúng tôi, ngoại trừ tài liệu đáng ngạc nhiên đó không nhận được sự kiện di chuyển chuột/chuột khi chuột vào hoặc để trống phần cửa sổ, chẳng hạn như không gian dọc trống được tạo bởi hoàn toàn định vị phần tử có phần dưới: 0. Đối với không gian đó, tài liệu và cửa sổ sẽ nhận được các sự kiện di chuột qua/di chuột với mục tiêu là <html>, nhưng document.body sẽ không.)

Một số ý tưởng tôi đã có:

  • Trên mỗi sự kiện trên chuột, nhận vị trí thực tế của chuột và xem liệu nó có trong thực tế trên cửa sổ không. Nhưng tôi không biết nếu điều này là thực sự có thể và nó có vẻ như nó sẽ là khó khăn để loại bỏ tất cả các điều kiện chủng tộc.
  • Đồng thời đăng ký trình xử lý di chuột và phát hiện các trường hợp không di chuột qua (hoặc theo sau bởi a) di chuột qua. Nhưng điều đó sẽ đòi hỏi một bộ đếm thời gian.

Chúng tôi sử dụng prototype.js vì vậy lý tưởng tôi muốn thể hiện giải pháp về Event.observe của mẫu thử nghiệm, nhưng tôi có thể tìm ra phần đó.

Cảm ơn mọi đề xuất!

+0

MooTools cung cấp sự kiện chuột/chuộtNhận tùy chỉnh chuột (http://demos.mootools.net/Mouseenter). Tôi không biết Prototype, nhưng nó không cung cấp một cái gì đó tương tự? – Duroth

+0

@Duroth Cảm ơn con trỏ. Prototype 1.6.1 không xuất hiện, nhưng có vẻ như 1.6.2 có thể. – Geoff

Trả lời

12

TÓM TẮT: Điều này có thể được thực hiện bằng cách kiểm tra sạch tài sản relatedTarget trong sự kiện mouseout. Nếu relatedTarget không phải là một con của tài liệu, thì con chuột vừa rời khỏi cửa sổ. Thật dễ dàng để làm cho chính mình, nhưng nếu bạn không muốn, một số thư viện (Mootools, Prototype tương lai ..) có chức năng nướng sẵn, và những người khác (Prototype hiện tại) có phần mở rộng có sẵn. Trên IE, bạn có thể sử dụng mouseleave, một phiên bản không có bọt.

Chi tiết:

IE có các sự kiện được gọi là mouseenter và mouseleave không có phiên bản di chuột qua và di chuột. Các trình duyệt khác thì không, nhưng nếu chúng đã làm, việc thiết lập một trình lắng nghe mouseleave trên cửa sổ hoặc tài liệu sẽ thực hiện thủ thuật.

Một người đàn ông tên là Ken Snyder đến để giải thoát:

Trên một di chuột, phần relatedTarget tài liệu tham khảo hữu nút từ mà con trỏ đến. Trên một mouseout, tài liệu tham khảo hữu relatedTarget nút mà con trỏ went.On bất kỳ sự kiện, phạm vi là nút để mà sự kiện này attached.When các relatedTarget là một không phải là con của currentTarget, một sự kiện di chuột qua là tương đương với sự kiện mouseenter và sự kiện di chuột tương đương với sự kiện mouseleave .

- http://kendsnyder.com/archives/6-MouseEnter-and-MouseLeave.html

này làm cho nó có thể thực hiện MouseEnter và MouseLeave trong các trình duyệt khác. Trên thực tế, Ken cung cấp cùng một mã Prototype để làm như vậy: http://kendsnyder.com/sandbox/enterleave/MouseEnterLeave.js

Duroth chỉ ra trong các nhận xét rằng MooTools đã bao gồm một cái gì đó tương tự. (Cảm ơn Duroth.) Có vẻ như bản phát hành Prototype sắp tới (1.6.2) có thể bao gồm chức năng này, nhưng tôi không thể tìm thấy bất cứ thứ gì xác định.

+1

Cập nhật: có vẻ như điều này hiện có trong FF 10+, Chrome 30+ và Opera, cùng với IE - https://developer.mozilla.org/en-US/docs/Web/Events/mouseleave – snappieT

-1

Bạn có thể sử dụng onmouseout sự kiện trên một cửa sổ thay vì

+0

Đây thực sự là những gì tôi đã thử (xin lỗi là không rõ ràng. Tôi đã chỉnh sửa câu hỏi để làm rõ.) Làm cách nào để phân biệt trường hợp con chuột đã rời khỏi cửa sổ từ trường hợp chuột chỉ di chuyển giữa các phần tử và xử lý đang được gọi là vì sủi bọt? – Geoff

9

Chỉ sử dụng javascript, không có nguyên mẫu hoặc jquery, vv

<html> 
<head> 
<script type="text/javascript"> 
    var mouseX = 0; 
    var mouseY = 0; 
    var counter = 0; 
var mouseIsIn = true; 
function wireEvent() { 
window.addEventListener("mouseout", 
    function(e){ 
     mouseX = e.pageX; 
     mouseY = e.pageY; 
     if ((mouseY >= 0 && mouseY <= window.innerHeight) 
     && (mouseX >= 0 && mouseX <= window.innerWidth)) 
      return; 
     //do something for mouse out 
     counter++; 
     mouseIsIn = false; 
     document.getElementById('in_out').innerHTML='out' + counter; 
    }, 
    false); 
window.addEventListener("mouseover", 
    function(e){ 
     if(mouseIsIn) 
      return; 
     //do something for mouse over 
     counter++; 
     mouseIsIn = true; 
     document.getElementById('in_out').innerHTML='in' + counter; 
    }, 
    false); 
} 
</script> 
</head> 
<body onload="wireEvent();"> 
<div id="in_out">&nbsp;</div> 
<div style="width:300px; height: 200px; background: red;">Dummy element</div> 
</body> 
</html> 

UPDATE:
gia tăng kiểm tra cho vị trí chuột trên mouseout kích hoạt khi di chuyển trong/ngoài các yếu tố bên trong cơ thể. Nếu nó nằm trong cửa sổ, sự kiện mouseout không được kích hoạt.
Cũng đã giới thiệu một cờ cho trạng thái hiện tại của chuột 'in' hoặc 'out' bằng cách sử dụng mouseIsIn. Nếu đó là true, mouseover cũng sẽ không kích hoạt.

+0

Điều này dường như hoạt động, nhưng thực sự thì không. Cả hai trình xử lý đều được gọi mỗi khi chuột di chuyển qua hộp màu đỏ ("Phần tử giả"). Chỉ là việc di chuyển chuột (xảy ra?) Được gọi là cuối cùng, vì vậy bạn không nhận thấy. Bạn có thể thấy điều này bằng cách giữ một bộ đếm tổng số lần trình xử lý đã được gọi và in ra ngoài phần 'in' hoặc 'out'. Hoặc bằng cách sử dụng console.log(). – Geoff

+0

@Geoff: Tôi hiểu, cảm ơn vì đã chỉ ra. Hãy để tôi kiểm tra xem tôi có thể làm gì khác ... –

+0

@Geoff: Tôi đã triển khai thêm logic cho vị trí của con chuột trên 'mouseout'. Nếu nó nằm trong cửa sổ, bỏ qua. Điều này sẽ ngăn chặn kích hoạt không mong muốn. Tôi đã thử nghiệm nó trên Safari, dường như làm việc. –

1

Có lẽ bạn có thể đặt người nghe để di chuột và di chuột document, body hoặc một số yếu tố khác bao bọc toàn bộ tài liệu và sử dụng phần tử đó (bằng cách lưu nó xảy ra) làm trình kích hoạt để xác định xem đó có phải là một mouseout hợp lệ trên cửa sổ hay không ?

Nếu không, ý tưởng đầu tiên của bạn (liên quan đến kiểm tra vị trí) sẽ hoạt động khá tốt. Bất kỳ sự kiện nào đi qua X/Y sự kiện đã xảy ra. Nếu nó là bất cứ điều gì xa hơn chiều cao/chiều rộng của cửa sổ, bạn rời khỏi cửa sổ thực tế.Nếu nó là bất cứ điều gì tiêu cực, bạn rời khỏi cửa sổ. Và, có thể, nếu nó là chính xác chiều cao/chiều rộng hoặc chính xác hàng đầu: 0 hoặc trái: 0, sau đó bạn rời khỏi cửa sổ.

0

Sự cố của bạn xuất phát từ các sự kiện di chuột được tạo cho các phần tử bên trong cửa sổ, sau đó bong bóng lên như được mô tả trong W3C events spec. Bạn có thể kiểm tra các yếu tố sự kiện này đã thực sự bắn vào:

function mouseoutFunction(event) { 
    event = event || window.event; 
    var sender = event.srcElement || event.target; 
} 
+0

Mã đó sẽ tìm người gửi sự kiện, nhưng làm cách nào tôi có thể sử dụng thông tin đó để xác định xem con chuột đã rời khỏi cửa sổ chưa? Ngay cả khi chuột rời khỏi cửa sổ, người gửi không phải là cửa sổ hoặc tài liệu - đó là phần tử có chứa thấp nhất, một số ngẫu nhiên <p> hoặc <div> tùy thuộc vào vị trí của chuột trước khi nó rời khỏi cửa sổ. – Geoff

0

Đây là giải pháp của tôi dựa trên bộ hẹn giờ. Bộ đếm thời gian ở đây về cơ bản được sử dụng để cung cấp cho một cơ hội cho xử lý sự kiện khác (cụ thể, onmouseover) để thực hiện trước khi quyết định rằng các mosue là ra khỏi cửa sổ. Thời gian chờ 1ms (thực sự khoảng 33ms, có độ phân giải hẹn giờ tối thiểu) cho phép một chút thời gian để di chuyển chuột xảy ra nếu nó chưa có.

var inWin=0; 
window.onmouseout = function(e) 
{ 
    inWin--; 
    setTimeout(checkIfOut, 1); 
} 
window.onmouseover = function(e) 
{ 
    inWin++; 
} 

function checkIfOut() 
{ 
    if(!inWin) 
    { 
    //Yay! Mouse is out of the window (probably) 
    } 
} 
1

Khi chuột lá bất kỳ yếu tố, bao gồm cửa sổ, các đối tượng cửa sổ sẽ cháy một sự kiện mouseout và vượt qua các đối tượng event cùng với nó.

Một trong các mục trong đối tượng sự kiện được gọi là toElement, là con trỏ đến phần tử mà chuột vừa nhập khi nó rời khỏi hình ảnh cũ.Nhưng khi con chuột rời khỏi cửa sổ, không có toElement để mục này trở thành null.

Bằng cách kiểm tra xem mục này có là null trên sự kiện mouseout hay không, bạn có thể biết liệu con chuột có rời khỏi cửa sổ hay không. Đây là mã số:

window.onmouseout=function(event){ 
    if(event.toElement===null) console.log('the mouse left the window'); 
} 
Các vấn đề liên quan