Перейдите через div к базовым элементам


1593

У меня есть, divчто есть background:transparent, наряду с border. Под этим у divменя есть больше элементов.

В настоящее время я могу щелкнуть нижележащие элементы, когда щелкаю за пределами наложения div. Тем не менее, я не могу щелкнуть базовые элементы при нажатии непосредственно на оверлей div.

Я хочу быть в состоянии щелкнуть через это, divчтобы я мог щелкнуть на базовых элементах.

Моя проблема

Ответы:


2616

Да, вы МОЖЕТЕ сделать это.

Используя 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?
Мантикора

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, где вы хотите иметь возможность щелкать дочерние элементы, в то время как родительские слои вообще не реагируют ни на какие события мыши.

Для этого все родительские 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

Разрешение пользователю нажимать через элемент 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");
    });

В моем случае наложенный div абсолютно позиционирован - я не уверен, что это имеет значение. Это работает как минимум на 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 - дополнительно атрибут name для того, что делать, если кто-то нажимает на эти координаты, и я любил устанавливать 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 --
            }
          });

Эта функция проверяет координаты события щелчка тела или уже щелкнуло и возвращает атрибут имени. Я думаю, что нет необходимости углубляться, но вы видите, что это не так уж сложно. Надеюсь, что был enlish ...


4

это не работает таким образом. Обходной путь заключается в том, чтобы вручную проверять координаты щелчка мыши по области, занимаемой каждым элементом.

Площадь, занимаемая элементом, может быть найдена путем: 1. получения местоположения элемента относительно верхнего левого края страницы и 2. ширины и высоты. библиотека типа jQuery делает это довольно простым, хотя это можно сделать простым js. добавление обработчика событий дляmousemove на documentобъекте обеспечит непрерывное обновление положения курсора мыши из верхней и левой части страницы. Решение, находится ли мышь над каким-либо заданным объектом, состоит в проверке, находится ли положение мыши между левым, правым, верхним и нижним краями элемента.


2
Как упоминалось выше, вы можете достичь этого, используя CSSs {pointer-events: none;} в вашем прозрачном контейнере.
Empereol

4

Нет, вы не можете нажать «через» элемент. Вы можете получить координаты клика и попытаться выяснить, какой элемент находился под щелкающим элементом, но это действительно утомительно для браузеров, у которых этого нет document.elementFromPoint. Тогда вам все равно придется эмулировать действие по умолчанию, нажав, что не обязательно тривиально, в зависимости от того, какие элементы у вас там.

Поскольку у вас есть полностью прозрачная область окна, вам, вероятно, будет лучше реализовать ее как отдельные граничные элементы снаружи, оставляя центральную область свободной от препятствий, чтобы вы могли просто щелкнуть прямо через нее.


4

Другая идея (ситуативно) заключается в следующем:

  1. Поместите контент, который вы хотите в div;
  2. Поместите оверлей без щелчка на всю страницу с z-индексом выше,
  3. сделать еще одну обрезанную копию оригинального div
  4. overlay и abs располагают копию div в том же месте, что и исходный контент, на который вы хотите кликать с еще большим 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, с уважением!


хорошая точка зрения! спасибо
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();следует упомянуть и здесь. Добавьте это к функции Click вашей кнопки.

Предотвращает всплытие события в DOM-дереве, предотвращая уведомление любых родительских обработчиков о событии.


0

Это не точный ответ на вопрос, но может помочь найти обходной путь для него.

У меня было изображение, которое я прятал при загрузке страницы и которое отображалось при ожидании вызова AJAX, а затем снова скрывалось ...

Я нашел единственный способ отобразить свое изображение при загрузке страницы, а затем заставить ее исчезнуть и щелкнуть объекты, на которых находилось изображение, перед тем как скрыть его, это поместить изображение в DIV, сделать размер DIV 10x10 пикселей или маленьким. достаточно, чтобы предотвратить возникновение проблемы, а затем скрыть содержащий div. Это позволило изображению переполнить div, пока он виден, и когда div был скрыт, только область div была затронута невозможностью щелкать объекты ниже, а не весь размер изображения, которое DIV содержал и отображал.

Я перепробовал все методы, чтобы скрыть изображение, включая CSS display = none / block, opacity = 0, скрывая изображение с hidden = true. Все они привели к тому, что мое изображение было скрыто, но область, в которой оно отображалось, действовала так, будто на нем находилось покрытие, поэтому щелчки и т. Д. Не воздействовали на лежащие в основе объекты. Как только изображение оказалось внутри крошечного DIV, и я спрятал крошечный DIV, вся область, занятая изображением, была чистой, и была затронута только крошечная область под DIV, которую я спрятал, но, поскольку я сделал его достаточно маленьким (10x10 пикселей), проблема было исправлено (вроде).

Я нашел, что это грязный обходной путь для простой проблемы, но я не смог найти способ скрыть объект в его исходном формате без контейнера. Мой объект был в форме и т. Д. Если у кого-то есть способ получше, пожалуйста, дайте мне знать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.