คลิกที่องค์ประกอบ div ถึงองค์ประกอบพื้นฐาน


1591

ฉันมีdivที่มีพร้อมกับbackground:transparent borderภายใต้สิ่งนี้divฉันมีองค์ประกอบมากขึ้น

divขณะนี้ฉันสามารถคลิกองค์ประกอบพื้นฐานเมื่อฉันคลิกนอกซ้อนทับ อย่างไรก็ตามฉันไม่สามารถคลิกองค์ประกอบพื้นฐานได้เมื่อคลิกที่โอเวอร์เลย์divโดยตรง

ฉันต้องการที่จะคลิกผ่านสิ่งนี้divเพื่อให้ฉันสามารถคลิกที่องค์ประกอบพื้นฐาน

ปัญหาของฉัน

คำตอบ:


2613

ใช่คุณสามารถทำได้

การใช้pointer-events: noneพร้อมกับคำสั่ง CSS แบบมีเงื่อนไขสำหรับ IE11 (ไม่ทำงานใน IE10 หรือต่ำกว่า) คุณจะได้รับโซลูชันที่เข้ากันได้กับเบราว์เซอร์ข้ามสำหรับปัญหานี้

ใช้AlphaImageLoaderคุณยังสามารถใส่.PNG/.GIFs โปร่งใสในการซ้อนทับdivและมีการคลิกไหลผ่านไปยังองค์ประกอบที่อยู่ด้านล่าง

CSS:

pointer-events: none;
background: url('your_transparent.png');

เงื่อนไข IE11:

filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='your_transparent.png', sizingMethod='scale');
background: none !important;

นี่คือหน้าตัวอย่างพื้นฐานพร้อมโค้ดทั้งหมด


7
ถ้าฉันใช้ช่วงการเปลี่ยนภาพหรือโฮเวอร์สเตตใน div นั้น
Manticore

2
@Manticore คำตอบสั้น ๆ : คุณทำไม่ได้ ในกรณีนี้คำตอบที่ให้ไว้จะไม่ทำงาน
Niels Abildgaard

10
IE11 รองรับตัวชี้เหตุการณ์อย่างเต็มที่ นี่หมายความว่าเบราว์เซอร์ที่ทันสมัยรองรับทั้งหมด นี่เป็นวิธีแก้ปัญหาที่ใช้การได้ในช่วงปลายปี 2014 caniuse.com/#search=pointer-events
Judah Gabriel Himango

ตามที่ระบุไว้โดย @Andy การเลื่อนนี้จะหยุดลง ฉันเปิดปัญหาแยกต่างหากเพื่อดูว่ามีวิธีแก้ไขสำหรับstackoverflow.com/questions/41592349/
Oliver Joseph Ash

1
@Manticore ฉันพบว่าคุณสามารถเขียนทับ "pointer-events: none;" สำหรับองค์ประกอบซ้อนกันเพื่อให้คุณสามารถเขียนสิ่งที่ข้ามโดยคลิกด้วยสิ่งที่ได้รับการคลิกและมากกว่าสำหรับชิ้นส่วนที่เขียนทับคุณสามารถใช้ผลและคลิก
Luca C.

292

ยังเป็นเรื่องดีที่จะรู้ ...
คุณสามารถปิดการใช้งานตัวชี้เหตุการณ์ในองค์ประกอบหลัก (อาจ div โปร่งใส) แต่มันยังคงเปิดใช้งานสำหรับองค์ประกอบลูก
สิ่งนี้มีประโยชน์หากคุณทำงานกับเลเยอร์ div ที่ซ้อนทับหลายชั้นซึ่งคุณต้องการคลิกองค์ประกอบย่อยในขณะที่เลเยอร์พาเรนต์ไม่ตอบสนองต่อกิจกรรมเมาส์ใด ๆ เลย

สำหรับ divs การเลี้ยงดูทั้งหมดนี้pointer-events: noneและลูกที่คลิกได้จะได้รับตัวชี้เหตุการณ์ที่เปิดใช้อีกครั้งpointer-events: auto

.parent {
    pointer-events:none;        
}
.child {
    pointer-events:auto;
}

<div class="some-container">
   <ul class="layer-0 parent">
     <li class="click-me child"></li>
     <li class="click-me child"></li>
   </ul>

   <ul class="layer-1 parent">
     <li class="click-me-also child"></li>
     <li class="click-me-also child"></li>
   </ul>
</div>

4
สมบูรณ์แบบนี่เป็นสิ่งที่ฉันต้องการ!
RobbyReindeer

1
สุดยอดประโยชน์ขอบคุณ
SpaceBear

43

การอนุญาตให้ผู้ใช้คลิก a divถึงองค์ประกอบพื้นฐานนั้นขึ้นอยู่กับเบราว์เซอร์ เบราว์เซอร์ที่ทันสมัยทั้งหมดรวมทั้ง Firefox, Chrome, Safari และ Opera pointer-events:noneเข้าใจ

สำหรับ IE มันขึ้นอยู่กับพื้นหลัง หากพื้นหลังโปร่งใสการคลิกผ่านจะทำงานโดยที่คุณไม่ต้องทำอะไรเลย ในอีกทางหนึ่งเช่นbackground:white; opacity:0; filter:Alpha(opacity=0);IE ต้องการส่งต่อเหตุการณ์ด้วยตนเอง

ดูการทดสอบ JSFiddleและ CanIUse เหตุการณ์ชี้


20

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

  • แนบคลิกเพื่อ div ที่คุณต้องการที่จะคลิกผ่าน
  • ซ่อนมันไว้
  • กำหนดองค์ประกอบที่ตัวชี้เปิดอยู่
  • ยิงคลิกที่องค์ประกอบที่นั่น
var range-selector= $("")
    .css("position", "absolute").addClass("range-selector")
    .appendTo("")
    .click(function(e) {
        _range-selector.hide();

        $(document.elementFromPoint(e.clientX,e.clientY)).trigger("click");
    });

ในกรณีของฉัน Div overlaying อยู่ในตำแหน่งที่แน่นอน - ฉันไม่แน่ใจว่าสิ่งนี้จะสร้างความแตกต่างหรือไม่ ใช้ได้กับ IE8 / 9, Safari Chrome และ Firefox อย่างน้อย


12
  1. ซ่อนการซ้อนทับองค์ประกอบ
  2. กำหนดพิกัดเคอร์เซอร์
  3. รับองค์ประกอบในพิกัดเหล่านั้น
  4. ทริกเกอร์คลิกที่องค์ประกอบ
  5. แสดงองค์ประกอบที่ซ้อนทับอีกครั้ง
$('#elementontop').click(e => {
    $('#elementontop').hide();
    $(document.elementFromPoint(e.clientX, e.clientY)).trigger("click");
    $('#elementontop').show();
});

คุณลืมปิดอะพอสโทรฟีหรือไม่? อาจ$('#elementontop)จะเป็น$('#elementontop')อย่างไร
johannchopin

10

ฉันต้องการทำสิ่งนี้และตัดสินใจที่จะใช้เส้นทางนี้:

$('.overlay').click(function(e){
    var left = $(window).scrollLeft();
    var top = $(window).scrollTop();

    //hide the overlay for now so the document can find the underlying elements
    $(this).css('display','none');
    //use the current scroll position to deduct from the click position
    $(document.elementFromPoint(e.pageX-left, e.pageY-top)).click();
    //show the overlay again
    $(this).css('display','block');
});

6

ฉันกำลังทำงานกับบอลลูนคำพูดบนผืนผ้าใบ แต่เนื่องจากบอลลูนที่มีตัวชี้อยู่ใน div ดังนั้นบางลิงก์ที่อยู่ภายใต้จึงไม่สามารถคลิกได้อีกต่อไป ฉันไม่สามารถใช้ extjs ได้ในกรณีนี้ ดูตัวอย่างพื้นฐานสำหรับการสอนบอลลูนคำพูดของฉัน ต้องใช้ HTML5

ดังนั้นฉันจึงตัดสินใจที่จะรวบรวมพิกัดลิงก์ทั้งหมดจากภายในลูกโป่งในอาร์เรย์

var clickarray=[];
function getcoo(thatdiv){
         thatdiv.find(".link").each(function(){
                 var offset=$(this).offset();           
                 clickarray.unshift([(offset.left),
                                     (offset.top),
                                     (offset.left+$(this).width()),
                                     (offset.top+$(this).height()),
                                     ($(this).attr('name')),
                                     1]);
                                     });
         }

ฉันเรียกฟังก์ชันนี้กับบอลลูน (ใหม่) แต่ละอัน มันจับพิกัดของมุมซ้าย / ด้านบนและด้านขวา / ล่างของ link.class - นอกจากนี้ยังมีชื่อคุณลักษณะสำหรับสิ่งที่ต้องทำถ้ามีคนคลิกที่พิกัดนั้นและฉันชอบตั้งค่า 1 ซึ่งหมายความว่ามันไม่ได้คลิกไอพ่น . และยกเลิกการเลือกอาร์เรย์นี้เป็น clickarray คุณสามารถใช้การกดได้เช่นกัน

ในการทำงานกับอาเรย์นั้น:

$("body").click(function(event){
          event.preventDefault();//if it is a a-tag
          var x=event.pageX;
          var y=event.pageY;
          var job="";
          for(var i in clickarray){
              if(x>=clickarray[i][0] && x<=clickarray[i][2] && y>=clickarray[i][1] && y<=clickarray[i][3] && clickarray[i][5]==1){
                 job=clickarray[i][4];
                 clickarray[i][5]=0;//set to allready clicked
                 break;
                }
             }
          if(job.length>0){   
             // --do some thing with the job --
            }
          });

ฟังก์ชั่นนี้พิสูจน์พิกัดของเหตุการณ์การคลิกของร่างกายหรือไม่ว่ามันจะถูกคลิกแล้วและส่งกลับแอตทริบิวต์ชื่อ ฉันคิดว่ามันไม่จำเป็นที่จะต้องเจาะลึก แต่คุณเห็นว่ามันไม่ซับซ้อน หวังว่าจะเป็นภาษาอังกฤษ ...


4

มันไม่ทำงานอย่างนั้น การแก้ไขคือการตรวจสอบพิกัดของการคลิกเมาส์กับพื้นที่ที่แต่ละองค์ประกอบครอบครองด้วยตนเอง

พื้นที่ที่ถูกครอบครองโดยองค์ประกอบสามารถพบได้โดย 1. การหาที่ตั้งขององค์ประกอบที่เกี่ยวกับด้านบนซ้ายของหน้าและ 2. ความกว้างและความสูง ไลบรารี่อย่าง jQuery ทำให้มันค่อนข้างง่าย แต่ก็สามารถทำได้ใน js ธรรมดา การเพิ่มตัวจัดการเหตุการณ์สำหรับmousemoveบนdocumentวัตถุจะให้การอัปเดตตำแหน่งเมาส์อย่างต่อเนื่องจากด้านบนและด้านซ้ายของหน้า การตัดสินใจว่าเมาส์อยู่เหนือวัตถุใดก็ตามที่ประกอบไปด้วยการตรวจสอบว่าตำแหน่งของเมาส์อยู่ระหว่างขอบด้านซ้ายขวาด้านบนและด้านล่างขององค์ประกอบหรือไม่


2
ดังที่ได้กล่าวไว้ข้างต้นคุณสามารถบรรลุสิ่งนี้ได้โดยใช้ CSS {pointer-events: none;} บนคอนเทนเนอร์โปร่งใสของคุณ
Empereol

4

ไม่คุณไม่สามารถคลิก 'ถึง' องค์ประกอบ คุณจะได้รับพิกัดของการคลิกและพยายามที่จะทำงานสิ่งที่เป็นองค์ประกอบอยู่ภายใต้องค์ประกอบคลิก document.elementFromPointแต่นี้เป็นที่น่าเบื่อจริงๆสำหรับเบราว์เซอร์ที่ไม่ได้มี จากนั้นคุณยังคงต้องเลียนแบบการกระทำเริ่มต้นของการคลิกซึ่งไม่จำเป็นต้องเป็นเรื่องเล็กน้อยขึ้นอยู่กับองค์ประกอบที่คุณมีอยู่

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


4

ความคิดอื่นที่จะลอง (ตามสถานการณ์) คือ:

  1. ใส่เนื้อหาที่คุณต้องการใน div;
  2. วางไม่ใช่การคลิกซ้อนทับทั่วทั้งหน้าด้วย z-index ที่สูงขึ้น
  3. ทำสำเนา div ที่ถูกครอบตัดอีกชุดหนึ่ง
  4. วางซ้อนและ abs วางตำแหน่ง div copy ไว้ในที่เดียวกับเนื้อหาต้นฉบับที่คุณต้องการให้คลิกได้ด้วยดัชนี z ที่สูงขึ้น?

ความคิดใด ๆ


2

ฉันคิดว่าคุณสามารถเปลี่ยนมาร์กอัปของคุณได้ หากฉันไม่ผิดคุณต้องการวางเลเยอร์ที่มองไม่เห็นอยู่เหนือเอกสารและมาร์กอัปที่มองไม่เห็นของคุณอาจนำหน้าภาพเอกสารของคุณ (ถูกต้องหรือไม่)

ฉันขอเสนอให้คุณใส่สิ่งที่มองไม่เห็นหลังภาพเอกสาร แต่เปลี่ยนตำแหน่งเป็นแบบสัมบูรณ์

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

องค์ประกอบตำแหน่งที่แน่นอนอยู่ในตำแหน่งที่สัมพันธ์กับองค์ประกอบหลักแรกที่มีตำแหน่งอื่นที่ไม่ใช่แบบคงที่ หากไม่พบองค์ประกอบดังกล่าวบล็อกที่มีคือ html

หวังว่านี่จะช่วยได้ ดูที่นี่สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการวางตำแหน่ง CSS


2

เพียงแค่ห่อaแท็กทั่วทุกสารสกัดจาก HTML ตัวอย่างเช่น

<a href="/categories/1">
  <img alt="test1" class="img-responsive" src="/assets/photo.jpg" />
  <div class="caption bg-orange">
    <h2>
      test1
    </h2>
  </div>
</a>

ในตัวอย่างของฉันคลาสคำบรรยายภาพของฉันมีผลการโฮเวอร์, ที่มีตัวชี้เหตุการณ์: ไม่มี;คุณจะสูญเสีย

การตัดเนื้อหาจะทำให้เอฟเฟกต์โฮเวอร์ของคุณอยู่และคุณสามารถคลิกที่รูปภาพทั้งหมดรวมถึง div ด้วยความนับถือ!


จุดดี! thnks
Mr.Vertigo

1

คุณสามารถวางซ้อนทับ AP เช่น ...

#overlay {
  position: absolute;
  top: -79px;
  left: -60px;
  height: 80px;
  width: 380px;
  z-index: 2;
  background: url(fake.gif);
}
<div id="overlay"></div>

เพียงแค่วางไว้เหนือที่คุณไม่ต้องการเช่นถูก cliked ทำงานได้ในทุก


1

วิธีที่ง่ายกว่าคือการแทรกรูปภาพพื้นหลังแบบโปร่งใสโดยใช้ Data URIs ดังต่อไปนี้:

.click-through {
    pointer-events: none;
    background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}

0

ฉันคิดว่าevent.stopPropagation();ควรพูดถึงที่นี่เช่นกัน เพิ่มไปยังฟังก์ชันคลิกปุ่มของคุณ

ป้องกันเหตุการณ์จากการทำให้ทรี DOM สูงขึ้นทำให้ป้องกันตัวจัดการพาเรนต์ไม่ได้รับการแจ้งเตือนของเหตุการณ์


0

นี่ไม่ใช่คำตอบที่ถูกต้องสำหรับคำถาม แต่อาจช่วยในการหาวิธีแก้ปัญหาสำหรับมัน

ฉันมีภาพที่ฉันซ่อนไว้ในการโหลดหน้าเว็บและแสดงเมื่อรอสาย AJAX แล้วซ่อนอีกครั้งอย่างไรก็ตาม ...

ฉันพบวิธีเดียวที่จะแสดงภาพของฉันเมื่อโหลดหน้าเว็บจากนั้นทำให้มันหายไปและสามารถคลิกสิ่งที่ภาพนั้นอยู่ก่อนที่จะซ่อนมันเพื่อวางภาพลงใน DIV ทำให้ขนาดของ DIV 10x10 พิกเซลหรือเล็ก เพียงพอที่จะป้องกันไม่ให้เกิดปัญหาจากนั้นซ่อน Div ที่มีอยู่ สิ่งนี้อนุญาตให้รูปภาพล้น div ขณะที่มองเห็นและเมื่อ div ถูกซ่อนเฉพาะพื้นที่ div เท่านั้นที่ได้รับผลกระทบจากการไม่สามารถคลิกวัตถุที่อยู่ด้านล่างและไม่ใช่ขนาดทั้งหมดของภาพ DIV ที่บรรจุอยู่และกำลังแสดงอยู่

ฉันพยายามทุกวิธีในการซ่อนภาพรวมถึง CSS display = none / block, opacity = 0, ซ่อนรูปภาพด้วย hidden = true พวกเขาทั้งหมดทำให้ภาพของฉันถูกซ่อนอยู่ แต่บริเวณที่มันแสดงให้เห็นว่ามีสิ่งปกคลุมอยู่ข้างใต้ดังนั้นการคลิกและอื่น ๆ จะไม่กระทำกับวัตถุต้นแบบ เมื่อภาพอยู่ใน DIV ขนาดเล็กและฉันซ่อน DIV เล็ก ๆ พื้นที่ทั้งหมดที่ถูกครอบครองโดยภาพมีความชัดเจนและมีเพียงพื้นที่เล็ก ๆ ภายใต้ DIV ที่ฉันซ่อนได้รับผลกระทบ แต่เมื่อฉันทำให้มันเล็กพอ (10x10 พิกเซล) ปัญหา ได้รับการแก้ไข (เรียงลำดับ)

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

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