Клацніть через div до основних елементів


1590

У мене є, divщо є background:transparent, поряд з border. Під цим у divмене більше елементів.

В даний час я можу клацнути основні елементи, коли натискаю зовні накладки div. Однак я не можу клацнути основні елементи при натисканні безпосередньо на накладку div.

Я хочу мати можливість натиснути на це, divщоб я міг натиснути на основні елементи.

Моя проблема

Відповіді:


2612

Так, ви можете це зробити.

Використовуючи 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
Що робити, якщо я використовую переходи або стану ховера на цьому діві?
Мантікоре

2
@Manticore Коротка відповідь: Ви не можете. У цьому випадку надана відповідь не працює.
Нільс Абілдгаард

10
IE11 повністю підтримує покажчики-події. Це означає, що всі сучасні браузери його підтримують. Це дієве рішення станом на кінець 2014 року. Caniuse.com/#search=pointer-events
Іуда Габріель Хіманго

Як зазначає @Andy, це порушує прокрутку. Я відкрив окрему проблему, щоб побачити, чи є рішення для цього stackoverflow.com/questions/41592349/…
Олівер Джозеф Еш,

1
@Manticore Я виявив, що ви можете перезаписати "pointer-events: none;" для вкладеного елемента, тож ви можете написати щось убік, натиснувши щось, що отримує клацання і
Luca C.

292

Також приємно знати ...
Ви можете відключити покажчик-події в батьківському елементі (можливо, прозорий div), але він все ще включений для своїх дочірніх елементів.
Це корисно, якщо ви працюєте з кількома перекриваються шарами Div, де ви хочете мати можливість натискати дочірні елементи, при цьому батьківські шари взагалі не реагують на будь-які події миші.

Для цього отримують усі батьківські діви, 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. Так в основному:

  • додайте клавішу до діва, через який потрібно натиснути
  • сховай це
  • визначте, на який елемент вказівник
  • натисніть на елемент там.
var range-selector= $("")
    .css("position", "absolute").addClass("range-selector")
    .appendTo("")
    .click(function(e) {
        _range-selector.hide();

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

У моєму випадку розділювальний розділ абсолютно розміщений - я не впевнений, чи це має значення. Це працює як мінімум на 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

Зараз я працюю з полотняними мовними кульками. Але оскільки повітряна куля з вказівником загорнута у діви, деякі посилання під нею вже не можуть натискати. Я не можу використовувати 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. Ви також можете використовувати push.

Для роботи з цим масивом:

$("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. Помістіть потрібний вміст у діві;
  2. Розмістіть накладку, що не натискає, на всю сторінку зі z-індексом вище,
  3. зробити ще одну обрізану копію оригіналу div
  4. Накладення та abs розміщують копію діва на тому самому місці, що і оригінальний вміст, на який потрібно натискати, з ще більшим z-індексом?

Будь-які думки?


2

Я думаю, що ви можете розглянути можливість зміни розмітки. Якщо я не помиляюся, ви хочете поставити невидимий шар над документом, і ваша невидима розмітка може передувати вашому зображенню документа (чи правильно це?).

Натомість я пропоную вам поставити невидимий відразу після зображення документа, але змінити позицію на абсолютну.

Зверніть увагу, що вам потрібен батьківський елемент, щоб мати позицію: relativno і тоді ви зможете використовувати цю ідею. Інакше ваш абсолютний шар буде розміщений саме у верхньому лівому куті.

Абсолютний елемент позиції розміщується відносно першого батьківського елемента, який має положення, відмінне від статичного. Якщо такого елемента не знайдено, блок містить 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>

у моєму прикладі мій клас підписів має наближаючі ефекти, що з покажчиками подій: немає;ти просто програєш

загортання вмісту збереже ваші ефекти наведення, і ви можете натиснути на все зображення, включене в розділ, з повагою!


гарна думка! 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>

просто покладіть його там, де ви не хочете, тобто натиснули. Працює у всьому.


1

Простішим способом було б вбудувати прозоре фонове зображення за допомогою URI даних таким чином:

.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 було приховано, тільки область divs впливала на неможливість клацання об'єктів під нею, а не на весь розмір зображення, яке містив DIV і відображався.

Я спробував усі методи приховати зображення, включаючи CSS display = none / block, opacity = 0, приховавши зображення приховано = true. Усі вони призвели до того, що моє зображення було приховано, але область, де воно відображалося, діяло так, ніби під ним було покриття, так що клацання тощо не впливатиме на основні об'єкти. Як тільки зображення було всередині крихітного DIV, і я заховав крихітний DIV, вся область, яку займає зображення, була чіткою, і тільки крихітна область під DIV, яку я ховав, була постраждала, але, як я зробила її досить маленькою (10x10 пікселів), проблема було зафіксовано (свого роду).

Я вважав це брудним вирішенням того, що повинно бути простою проблемою, але я не зміг знайти жодного способу приховати об'єкт у його рідному форматі без контейнера. Мій об’єкт був у формі тощо. Якщо у когось кращий спосіб, будь ласка, дайте мені знати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.