如何检测覆盖元素的鼠标悬停事件

时间:2018-08-15 17:33:51

标签: javascript html css

我在<mark>下有一些<textarea>。当我将mouseover侦听器添加到<mark>时,事件不会触发,因为它们在<textarea>下。

我不能为pointer-events: none<text-area>,因为我希望它能正常工作。

请不要使用jQuery。

https://jsfiddle.net/aewc13nm/

3 个答案:

答案 0 :(得分:2)

我想您正在尝试找到独立于CSS和元素/同级元素分层的解决方案。在那种情况下,我可以想到一种重建自定义鼠标悬停/悬停的方法。通过在窗口上监听全局mousemove并使用〜17ms来检查我们是否跨越了mark元素的边界,它可以工作(我与自定义事件结合使用,以防其中包含更复杂的嵌套元素,这是不必要的):

FIDDLE

我添加了随机数学运算,以便您可以识别不同的鼠标悬停/滑出状态。

!function(){
  var mark = document.getElementsByTagName("mark")[0],
        mouseout = true,
      mouseover = false,
      customMouseEvent = new CustomEvent(
        "customMouseEvent",
        {
            bubbles:false,
          detail:{
            mouseout:function(){return mouseout},
            mouseover:function(){return mouseover}
          }
        }
        );
      mark._lastGesture = "mouseout";
    window.addEventListener("mousemove",function(e){
    if(mark._busy){return}
    mark._busy = true;
    window.requestAnimationFrame(function(){
      var rect = mark._rect || (mark._rect = mark.getBoundingClientRect());
      if(
        (e.clientX - rect.left < rect.width)
        && (e.clientX - rect.left > 0)
        && (e.clientY - rect.top <= rect.height)
        && (e.clientY - rect.top > 0)
      ){
        mouseout = false;
        mouseover = true;
      } else {
        mouseout = true;
        mouseover = false;
      }
      mark.dispatchEvent(customMouseEvent);
      mark._busy = false;
      setTimeout(function(){delete mark._rect},17);
    });
  });
  mark.addEventListener("customMouseEvent",function(e){
    if(e.detail.mouseover() && this._lastGesture !== "mouseover") {
        this._lastGesture = "mouseover";
        document.getElementById("feedback").textContent = "Mousover! " + Math.random();
    } else if (e.detail.mouseout() && this._lastGesture !== "mouseout") {
        this._lastGesture = "mouseout";
      document.getElementById("feedback").textContent = "Mousout! " + Math.random();
    }
  })
}();

答案 1 :(得分:1)

尝试使用contenteditable="true"代替<textarea>

function up(x) {
    x.style.fontSize = "24px";
}

function down(x) {
    x.style.fontSize = "16px";
}
.textarea-parent {
    border: 1px solid #000;
}

div.editable {
    width: 300px;
    height: 200px;
    padding: 5px;
}
<div class="textarea-parent">
  <div contenteditable="true">
    Lorem ipsum dolor sit amet.<br>
    consecte, sed do <strong>tur adipiscing elit</strong> eiusmod tempor incididunt ut labore et dolore.
    <br>there is a  at the end?
    <br>tur adipiscing elit.
    <br>
    <br><mark onmouseover="up(this)" onmouseout="down(this)">Great</mark>
  </div>
</div>

答案 2 :(得分:0)

您可以尝试在z-index: 1标签上添加span

function up(x) {
    x.style.fontSize = "24px";
  }

  function down(x) {
      x.style.fontSize = "16px";
  }
textarea {
  border: none;
  outline: none;
  background-color: transparent;
}
textarea, span {
  position: fixed;
  font-size: 1rem;
  font-family: monospace;
  padding: 5px;
}
span {
  z-index: 1:
  color: transparent;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
  </head>
  <body>
    <textarea id='t'></textarea>
    <span>Hello <mark onmouseover="up(this)" onmouseout="down(this)">world</mark>!</span>
  </body>
</html>