javascript 指针事件:无但捕获点击

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34037649/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 17:10:06  来源:igfitidea点击:

pointer-events:none but capture click

javascriptcss

提问by gaurav5430

is it possible to allow only click and disable all other pointer-events

是否可以只允许单击并禁用所有其他指针事件

top-layer has a search bar

顶层有一个搜索栏

bottom-layer has a word cloud

底层有词云

I have set pointer-events:noneon top-layer, so all words in the word cloud can be hovered over even if they are below the search bar.

我设置pointer-events:none在顶层,所以词云中的所有词即使在搜索栏下方也可以悬停。

but I want the click event on the input text to be enabled, so that when the user wants to type in something, he can.

但我希望启用输入文本上的点击事件,以便当用户想要输入内容时,他可以。

enter image description here

在此处输入图片说明

Here is a related fiddle

这是一个相关的小提琴

The text is behind the input, but it should be hoverable, the input is above the text, but it should be focusable using mouse, to allow the user to type in.

文本在输入的后面,但它应该是可悬停的,输入在文本的上方,但它应该是可使用鼠标聚焦的,以允许用户输入。

Note: it looks like a placeholder thing, but it is not. please see the original image to see what i am trying to achieve.

注意:它看起来像一个占位符,但它不是。请查看原始图像以了解我想要实现的目标。

回答by Yoram de Langen

Because pointer-eventsis blocking interactieve events(click, hover, mouseenter etc.) it would be only accessible with javascript (through focus for example).

因为pointer-events阻止了交互事件(单击、悬停、鼠标输入等),所以只能使用 javascript 访问(例如通过焦点)。

It's maybe not the best solution but it will do I guess in your case?

这可能不是最好的解决方案,但我猜你的情况会这样吗?

(function($) {
  var focus = false;
  $(document).on('click', function(e) {
    console.log(focus);
    e.preventDefault();
    if (focus) {
      focus = false;
      $('.cl1').trigger('blur');
    } else {
      focus = true;
      $('.cl1').focus();
    }
  });
})(jQuery);

a fiddle with this working solution: https://jsfiddle.net/cob02bpv/1/

摆弄这个工作解决方案:https: //jsfiddle.net/cob02bpv/1/

Edit: you could check on which element was clicked, only elements under the input will be tricky.

编辑:您可以检查点击了哪个元素,只有输入下的元素会很棘手。

If its not the solution the only one would be to calculate the coordinates from the input box and check where the clickevent was triggered. But still you would have problems for your elements under the input box.

如果它不是解决方案,唯一的方法是从输入框中计算坐标并检查click触发事件的位置。但是您仍然会遇到输入框下元素的问题。

回答by DavidDomain

I think this should work. Listening to the click event on the parent container, getting the event.clientXand event.clientYvalues to check if they are within the bounds of the inputelement. If so, you can then set the focus to the inputelement. You can still determine if one of the random words underneath the inputelement has been clicked.

我认为这应该有效。侦听父容器上的单击事件,获取event.clientXevent.clientY值以检查它们是否在input元素的范围内。如果是这样,您可以将焦点设置到input元素上。您仍然可以确定是否input单击了元素下方的随机单词之一。

var d = document,
    c = d.getElementsByClassName('container').item(0),
    inp = d.createElement('input'),
    a = 50,
    i = 0;


/*
 | get the clientBoundingRect of the input element
 | and if the mouse x and mouse y positions are within
 | the bounds set the focus on to the input element.
------------------------------------------------------------- */
function inpClickHndl (evt) {
  var inpRect = inp.getBoundingClientRect(),
      x = evt.clientX,
      y = evt.clientY,
      l = inpRect.left,
      w = l + inpRect.width,
      t = inpRect.top,
      h = t + inpRect.height;

  if (x >= l && x <= w && y >= t && y <= h) {
    inp.focus();
  }
}

/* 
 | ignore this, it's just to create the random words.
------------------------------------------------------------- */
function wordClickHndl (evt) {
  this.style.color = "yellow";
}

for (i; i < a; i++) {
  var p = d.createElement('p'),
      t = d.createTextNode('Random Word');
  p.appendChild(t);
  p.addEventListener('click', wordClickHndl, false);
  p.style.position = 'absolute';
  p.style.top = Math.floor(Math.random() * (window.innerHeight - 80)) + -40 + 'px';
  p.style.left = Math.floor(Math.random() * (window.innerWidth - 80)) + -40 + 'px';
  p.style.fontSize = Math.floor(Math.random() * (38 - 8)) + 8 + 'px';
  p.style.fontWeight = 'bold';
  c.appendChild(p);
}

inp.setAttribute('type', 'text');
c.appendChild(inp);

/*------------------------------------------------------------- */

// add a click handler to your parent element.
c.addEventListener('click', inpClickHndl, false);
body {
  margin: 0;
  font-family: sans-serif;
}

.container {
  position: relative;
  height: 100vh; width: 100vw;
  background-color: #1a1a1a;
}

.container p {
  color: green;
}

.container p:hover {
  color: red;
  cursor: pointer;
}

.container input {
  position: absolute;
  top: 50%; left: calc(50% - 85px);
  pointer-events:none;
  opacity: .75;
}
<div class="container"></div>

回答by user3342816

If layout permits it you could use the adjacent sibling combinator, given that you re-order the elements:

如果布局允许,您可以使用相邻的兄弟组合器,因为您对元素进行了重新排序:

Tested on FireFox and Chrome.

在 FireFox 和 Chrome 上测试。

.backText:hover {
  color           : red;
}
.cl1 {
  opacity         : 0.7;
  position        : absolute;
}
/* adjacent sibling combinator */
.wrap-input:hover + div {
  color           : red;
}
.cl1:focus {
  opacity         : 1;
}
<div>
  <div class="wrap-input">
    <input type="text" class="cl1" value="aa" />
  </div>
  <div class="backText">
     Some text to be hovered even if input is above
  </div>
</div>



Other options

其他选项

The following only works on FireFox. Tested on Chrome and it flickers when pointer is moved, - but could perhaps give some ideas.

以下仅适用于 FireFox。在 Chrome 上进行了测试,当指针移动时它会闪烁,但也许可以提供一些想法。

Instead of setting pointer-eventson the input-element directly, set it using the :hoverpseudo-class.

不是pointer-events直接在输入元素上设置,而是使用:hover伪类设置它。

Example, based on your fiddle:

示例,基于您的小提琴:

.cl1 {
  position        : absolute;
  top             : 0px;
  opacity         : 0.7;
  height          : 30px;
}
/* Move pointer-events here */
.cl1:hover {
  pointer-events  : none;
}
.cl1:focus {
  opacity         : 1;
}

.backText:hover {
  color           : red;
}
<div>
  <div class="backText">
     Some text to be hovered even if input is above
  </div>
  <div>
    <input type="text" class="cl1" />
  </div>
</div>

回答by Hydroper

Just add the pointer-eventsCSS3 property, setting as initialto the text box. Using !importantis recommended also, so because another property can pass that added.

只需添加pointer-eventsCSS3 属性,设置为initial文本框。!important也推荐使用,因为另一个属性可以通过添加。

In CSS3:

CSS3 中

pointer-events:initial !important

In JavaScript:

JavaScript 中

document.querySelector('input[type=text]').style.pointerEvents="initial"

document.querySelector('input[type=text]').style.pointerEvents="initial"