首页 > 解决方案 > 浏览器对 dispatchEvent 没有反应

问题描述

我正在开发一个 web 应用程序,我在 iframe 中运行 pdfjs,这样我的用户就可以打开多个 PDF。在父窗口中,用户可以用注释覆盖 pdf。所以父窗口捕获鼠标,我想使用 postMessage 将鼠标事件发送到 iframe。我的问题是,例如,当我使用 postMessage 向 pdf 发送鼠标滚轮事件,然后使用 dispatchEvent 在 iframe 中重新创建事件时,文件不会滚动。

我不认为我的问题与 pdfjs 有任何关系,所以我创建了一个小例子:

textE = document.getElementById('text');
textE.addEventListener('mousedown', textF);
textE.addEventListener('mousemove', textF);
textE.addEventListener('mouseup', textF);
textE.addEventListener('mouseover', textF);
textE.addEventListener('scroll', textF);
overlayE = document.getElementById('overlay');
overlayE.addEventListener('mousedown', overlayF);
overlayE.addEventListener('mousemove', overlayF);
overlayE.addEventListener('mouseup',   overlayF);
overlayE.addEventListener('mouseover', overlayF);
overlayE.addEventListener('scroll',    overlayF);

function textF(event) {
  if (event.type !== 'mousemove')
    console.log('text event', event.type, event);
}
function overlayF(event) {
  if (event.type !== 'mousemove')
    console.log('external event', event.type);
  overlayE = document.getElementById('overlay');
  textE.dispatchEvent(new MouseEvent(event.type, event));
}
<div style="position:absolute; width:80%; height:100px;">
    <div id="text" style="position:absolute; width:100%; height:100%; overflow-y:scroll;">

        Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
      
    </div>
</div>

<div id="overlay" style="position:absolute; top:0; left:50%; width:30%; height:100%; background:rgba(255,128,128,0.5);">
</div>

在这里,我有一个带有一些文本的 div,我用另一个 div 覆盖了其中的一些。然后我使用 dispatchEvent 将鼠标事件发送到文本层。因此,例如尝试选择一些以白色背景文本开头的文本,然后可以选择文本(请耐心等待,代码片段由于某种原因运行缓慢)。如果您首先在 read 覆盖的文本中尝试相同的单击,则不会选择文本,尽管事件侦听器实际上接收到事件。

没看懂,有大神帮忙吗?

标签: javascripteventsmouseeventdispatchevent

解决方案


正如评论中提到的,这不是事件的事情,而是分层的事情。叠加层就是这样,位于带有文本的 div 上方,因此如果您尝试选择叠加层中的任何内容,您将被限制在叠加层中的内容。

只需通过添加z-index:-1;其 CSS 来制作叠加层和底层,然后您就可以在 main 中选择文本div

textE = document.getElementById('text');
textE.addEventListener('mousedown', textF);
textE.addEventListener('mousemove', textF);
textE.addEventListener('mouseup', textF);
textE.addEventListener('mouseover', textF);
textE.addEventListener('scroll', textF);
overlayE = document.getElementById('underlay');
overlayE.addEventListener('mousedown', overlayF);
overlayE.addEventListener('mousemove', overlayF);
overlayE.addEventListener('mouseup',   overlayF);
overlayE.addEventListener('mouseover', overlayF);
overlayE.addEventListener('scroll',    overlayF);

function textF(event) {
  if (event.type !== 'mousemove')
    console.log('text event', event.type);
}
function overlayF(event) {
  if (event.type !== 'mousemove')
    console.log('external event', event.type);
  overlayE = document.getElementById('underlay');
  textE.dispatchEvent(new MouseEvent(event.type, event));
}
<div style="position:absolute; width:80%; height:100px;">
    <div id="text" style="position:absolute; width:100%; height:100%; overflow-y:scroll;">

        Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
      
    </div>
</div>

<div id="underlay" style="position:absolute; z-index:-1; top:0; left:50%; width:30%; height:100%; background:rgba(255,128,128,0.5);">
</div>


推荐阅读