2009-07-18 37 views
17

Tôi có các phần tử nằm trong phần tử có độ mờ: 0,5 mà tôi muốn có thể nhấp vào. Làm cách nào tôi có thể nhấp vào "thông qua" phần tử trên cùng?đăng ký lần nhấp vào một phần tử nằm trong một phần tử khác

Đây là ví dụ minh họa sự cố của tôi. Nhấp vào các hộp để bật và tắt chúng. Bạn có thể chỉnh sửa nó on jsbin để thử giải pháp của bạn.

Điểm thưởng nếu bạn có thể bật hoặc tắt hộp khi di chuột.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<title>Sandbox</title> 
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
<style type="text/css" media="screen"> 
body { background-color: #000; } 
.box {width: 50px; height: 50px; border: 1px solid white} 
.highlight {background-color: yellow;} 
</style> 
<script type="text/javascript"> 
var dthen = new Date(); 
$('<div id="past">').css({'height': (dthen.getMinutes()*60)+dthen.getSeconds() +'px' 
      ,'position': 'absolute' 
      ,'width': '200px' 
      ,'top': '0px' 
      ,'background-color': 'grey' 
      ,'opacity': '0.5' 
      }) 
     .appendTo("#container"); 

setInterval(function(){ 
    dNow = new Date(); 
    $('#past').css('height', ((dNow.getSeconds()+(dNow.getMilliseconds()/1000))*50)%300 +'px'); 
},10) 

$(".box").click(function(){ 
     $(this).toggleClass("highlight"); 
    }); 
</script> 
</head> 
<body> 
    <div id="container"> 
    <div class="box" style="position:absolute; top: 25px; left: 25px;"></div> 
    <div class="box" style="position:absolute; top: 50px; left: 125px;"></div> 
    <div class="box" style="position:absolute; top: 100px; left: 25px;"></div> 
    <div class="box" style="position:absolute; top: 125px; left: 125px;"></div> 
    <div class="box" style="position:absolute; top: 225px; left: 25px;"></div> 
    <div class="box" style="position:absolute; top: 185px; left: 125px;"></div> 
    </div> 
</body> 
</html> 
+1

Tôi không nghĩ rằng chúng tôi đang ở đây để viết ra một giải pháp hoàn chỉnh cho bạn. Sử dụng các gợi ý được đưa ra dưới đây, bạn nên tự mình thực hiện giải pháp. SO không phải là một cửa hàng tư vấn miễn phí. –

+3

Tôi không thể tin mình là người duy nhất muốn làm điều này. Vì vậy, tôi nghĩ rằng bất kỳ mã nào chứng tỏ làm thế nào để làm điều đó sẽ được tìm thấy sử dụng vượt ra ngoài những gì tôi đã lên kế hoạch cho nó. Tôi không thấy bất kỳ vấn đề với yêu cầu mã để làm điều này. –

+1

sam, cũng sử dụng addClass thay vì tất cả các cài đặt đó bằng cách sử dụng .css – redsquare

Trả lời

16

OK, vì vậy có 2 điều tôi nghĩ mình sẽ làm: (1) câu trả lời CSS3, không phải chưa được áp dụng rộng rãi, và (2) một kế hoạch sao lưu Javascript cho phần còn lại. (không biết phải làm gì với người dùng không có JS trên các trình duyệt cũ hơn không hỗ trợ phần CSS). Đọc ...

đầu tiên: Sử dụng mã CSS3 này để làm cho các yếu tố trên 'vô hình' cho chuột tương tác:

pointer-events: none; 

này chưa qua trình duyệt tương thích. Nó chỉ hoạt động trên SVG & Các phần tử HTML trong Gecko & Trình duyệt webkit, nhưng chỉ trên các phần tử SVG trong Opera và hoàn toàn không có trong IE.

mỗi MDN:

CSS sở hữu con trỏ-sự kiện cho phép tác giả để kiểm soát hay khi một phần tử có thể là mục tiêu của một sự kiện chuột. Thuộc tính này được sử dụng để chỉ định trong trường hợp nào (nếu bất kỳ) sự kiện chuột phải "qua" một phần tử và nhắm mục tiêu bất kỳ phần nào là "bên dưới" phần tử đó thay thế.

Dưới đây là tài liệu hướng dẫn: https://developer.mozilla.org/en/css/pointer-events

Thứ hai: Sử dụng một số javascript Detection Tính năng cho những trình duyệt chưa hỗ trợ CSS này. Bạn sẽ phải cuộn của riêng bạn, tương tự như Modernizr, vì nó không kiểm tra cho điều này được nêu ra (theo kiến ​​thức của tôi). Ý tưởng là bạn tạo một phần tử, áp dụng CSS con trỏ sự kiện cho nó, kiểm tra nó và nếu trình duyệt hỗ trợ tính năng này, bạn sẽ nhận được kết quả mong đợi, trái ngược với một cái gì đó null hoặc undefined; sau đó phá hủy phần tử. Dù sao, một khi bạn đã phát hiện tính năng, bạn có thể sử dụng jQuery hoặc tương tự để đính kèm một người nghe vào phần tử trên cùng và gán một cú nhấp chuột từ nó để bấm qua một cái gì đó khác. Kiểm tra jQuery và sử dụng hàm click() để biết thêm thông tin (không đủ danh tiếng để đăng liên kết, sry).

Nếu tôi có thời gian sau, tôi có thể làm việc nhanh lên jsFiddle trên đó. Tôi hi vọng cái này giúp được.

+0

Tác phẩm này hoạt động! So sánh giải pháp [điểm-sự kiện] (http://jsbin.com/limesat/edit?html,css,js,output) với [giải pháp gốc] (http://jsbin.com/pefop/edit?html, css, js, đầu ra). Tất nhiên con trỏ-sự kiện không tồn tại khi tôi lần đầu tiên hỏi điều này trong năm 2009. [IE11 ​​là phiên bản đầu tiên hỗ trợ các sự kiện con trỏ] (http://caniuse.com/#search=pointer-events) và nó xuất hiện trong 2013. –

+0

Nếu bạn cần hỗ trợ IE10 hoặc thấp hơn, Modernizr giờ đây dường như có kiểm tra cho Sự kiện Con trỏ CSS –

+0

Điều này cũng giải quyết được sự cố di chuột. Bạn chỉ có thể đính kèm kiểu vào '.box: hover' và nó sẽ vẫn kích hoạt nếu dưới phần tử #past. –

20

Nếu phần tử trên cùng của bạn được chứa trong phần tử bên dưới, bạn có thể để sự kiện "bong bóng". Nếu không, bạn phải kích hoạt nhấp chuột theo cách thủ công. Không có cách nào để kích hoạt trình xử lý sự kiện chỉ bằng cách nhấp vào.

Để cháy, sự kiện một cách thủ công, bạn có thể làm điều này:

$("#topelement").click(function() { 
    $("#elementbelow").click(); 
    return false; 
}); 

EDIT (phản ứng với ý kiến):

Để liệt kê tất cả các hộp, bạn có thể làm điều này (ra khỏi đỉnh của tôi đầu. không kiểm tra, thậm chí không thể là cú pháp-lỗi miễn phí)

$("#topelement").click(function(e) { 
    $(".box").each(function() { 
     // check if clicked point (taken from event) is inside element 
     var mouseX = e.pageX; 
     var mouseY = e.pageY; 
     var offset = $(this).offset; 
     var width = $(this).width(); 
     var height = $(this).height(); 

     if (mouseX > offset.left && mouseX < offset.left+width 
      && mouseY > offset.top && mouseY < offset.top+height) 
     $(this).click(); // force click event 
    }); 
}); 
+0

Bạn sẽ phải liệt kê tất cả các phần tử DOM để xem liệu điểm được nhấp có nằm trong một hoặc nhiều phần tử hay không. Không có cách nào trình duyệt có thể thực hiện việc này cho bạn –

+0

Cảm ơn bạn đã xử lý: http://jsbin.com/pefop/edit –

2

tôi đã sửa đổi mã từ trên vào chức năng jquery, ai đó có thể tìm thấy nó hữu ích:

Tìm thay thế nhấp-trên các yếu tố:

$('.child').click(function(e) { 
    $(this).siblingsUnderMouse(e).each(fn); 
}); 

Nếu bạn muốn bỏ qua điểm ảnh trong suốt trong hình ảnh:

$('.child').click(function(e) { 
    $(this).siblingsUnderMouse(e).each(function() { 
     var clickOnVisiblePixel = $(this).isOnVisiblePixel(e); 
    }); 
}); 

Code:

$.fn.reverse = [].reverse; 
$.fn.siblingsUnderMouse = function(e, filter) 
{ 
    filter = filter || '*'; 

    var arr = $(); 
    this.parent().children().filter(filter).reverse().each(function() 
    { 
     var t = $(this); 
     // check if clicked point (taken from event) is inside element 
     var x = (e.pageX - t.offset().left).toFixed(); 
     var y = (e.pageY - t.offset().top).toFixed(); 
     var w = t.width(); 
     var h = t.height(); 

     if (x < 0 || x >= w || y < 0 || y >= h) 
      return; 

     arr.push(t); 
    }); 
    return arr; 
} 

$.fn.isOnVisiblePixel = function(e) 
{ 
    if (e.type == 'mouseleave') return false; 

    var t = this[0]; 
    if (!t || t.tagName != 'IMG') 
     t = this.find('img')[0]; 
    if (!t) return; 

    var w = $(t).width(); 
    var h = $(t).height(); 
    var o = $(t).offset(); 
    var x = (e.pageX - o.left).toFixed(); 
    var y = (e.pageY - o.top).toFixed(); 
    if (x < 0 || y < 0 || x >= w || y >= h) 
     return false; 

    var c = $('<canvas>')[0]; 
    c.width = w; 
    c.height = h; 

    var ctx = c.getContext('2d'); 
    ctx.drawImage(t, 0, 0, w, h); 

    var a = ctx.getImageData(x, y, 1, 1).data[3]; 
    return (a > 128); 
} 
1

Tôi nghĩ rằng Lelando có được cú đánh đúng. Trong trường hợp của tôi, tôi đã giải quyết chỉ bằng css và bạn có thể chèn con trỏ-sự kiện: không vào thành phần #past của bạn.

Các vấn đề liên quan