pointer-events:none但是捕获click

时间:2015-12-02 08:06:57

标签: javascript css

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

顶层有一个搜索栏

底层有一个词云

我在顶层设置了pointer-events:none,因此即使字词云位于搜索栏下方,云字词中的所有字词都可以悬停。

但是我希望启用输入文本上的click事件,这样当用户想要输入某些内容时,他就可以。

enter image description here

Here is a related fiddle

文本在输入后面,但它应该是可以恢复的, 输入位于文本上方,但应使用鼠标进行聚焦,以允许用户键入。

注意:它看起来像占位符,但事实并非如此。请看原始图片,看看我想要实现的目标。

4 个答案:

答案 0 :(得分:4)

因为pointer-events阻止了interactieve事件(click,hover,mouseenter等),所以只能通过javascript访问(例如通过焦点)。

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

(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);

这个工作解决方案的小提琴:https://jsfiddle.net/cob02bpv/1/

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

如果不是解决方案,那么唯一的一个就是从输入框计算坐标并检查click事件被触发的位置。但是在输入框下你的元素仍然存在问题。

答案 1 :(得分:2)

我认为这应该有效。侦听父容器上的click事件,获取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>

答案 2 :(得分:0)

只需添加pointer-events CSS3属性,将initial设置为文本框即可。建议使用!important,因为另一个属性可以传递添加的内容。

CSS3

pointer-events:initial !important

JavaScript

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

答案 3 :(得分:0)

如果布局允许,您可以使用相邻的同级组合器,只要对元素重新排序:

在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>


其他选项

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

不要直接在输入元素上设置pointer-events,而应使用:hover伪类对其进行设置。

基于您的小提琴的示例:

.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>