javascript - 为任意 html 文档创建不显眼的覆盖层

标签 javascript html css google-chrome-extension overlay

我正在尝试创建一个覆盖层,将其自身附加到现有 DOM 节点并覆盖其整个内容区域。无论此节点是页面主体还是某些深层嵌套的 div,这都应该有效。关键是我所覆盖的页面布局不应改变。最终,我的代码将作为浏览器扩展在现有 html 页面之上运行。

我在一个非常简单的情况下遇到了一个问题,我试图用直接嵌套在文档正文中的文本(或任何占用空间的内容)覆盖页面。我别无选择,只能将覆盖 div 添加为 body 的另一个子节点,并将其位置设置为绝对,并将其宽度/高度设置为 100%。当然,在主体静态定位(默认)的情况下,我的 div 将根据视口(viewport)调整大小,而不是主体的内容。如果内容溢出,我的叠加层将无法覆盖所有内容:\.

所有其他答案都建议设置父 div(在我的例子中为 body)的位置,以将其定义为定位上下文。然而我做不到这一点。例如,将文档正文的位置更改为“相对”可能会更改正文内容的布局,并且违背了不引人注目的覆盖的目的。该怎么办?

欢迎针对特定扩展提出建议。作为引用,该扩展程序将适用于 Chrome。

这是一个jsfiddle带有我必须覆盖的假设页面。请注意,虽然原始页面的格式很奇怪,但我的叠加层无法更改它。

<body>
  <style>
    .overlay {
        position: absolute;
        top: 0px;
        left: 0px;
        width: 100%;
        height: 100%
        /*some magic I am unaware of*/
    }
  </style>
  <!-- begin original document (stupid hypothetical scenario) -->
  <div style="position:absolute;top:0px;width:100%;height:100%;background-color:red;">
    <!-- this div is part of the original html document I want to overlay.
    It should behave as it did originally, i.e size to the viewport of the document-->
  </div>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id tellus vehicula, tincidunt est fermentum, hendrerit dui. Nullam lacinia, justo sed porta hendrerit, nisl quam blandit nunc, ut imperdiet nibh metus in ante. Pellentesque viverra egestas
  nulla eu dictum. Aliquam ac accumsan leo. Integer ut tellus odio. Duis blandit venenatis venenatis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum vel lorem egestas, tincidunt sem vel, venenatis
  ipsum. Donec vitae blandit nibh. Curabitur cursus nunc arcu, id tempor massa gravida ut. Integer vulputate libero in placerat vestibulum. Duis quis turpis vel lectus venenatis rhoncus. Sed congue est consequat, dapibus odio sit amet, sollicitudin arcu.
  Praesent hendrerit massa velit, vel pretium erat viverra quis. Proin non enim facilisis, venenatis dolor ut, dapibus nulla. Morbi vestibulum mollis felis ut venenatis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus
  mus. Ut mollis velit nulla, et tristique sapien auctor eu. Phasellus tincidunt mauris elit, vel fringilla leo consectetur a. Vivamus a porta magna. Mauris hendrerit leo eget sapien aliquet dignissim. Nunc id sem est. Integer sed lacus est. Nulla sit
  amet sapien et ex aliquam malesuada quis vel eros. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus turpis ligula, elementum sit amet sapien nec, malesuada fringilla nibh. Duis euismod, purus semper viverra aliquam, ligula sem
  vehicula mi, sit amet cursus mauris augue vel enim. Donec lacinia diam quis sapien laoreet vulputate in eu est. Proin consequat, ex vitae molestie pellentesque, libero purus pellentesque arcu, id porttitor orci sem a lectus. Morbi mattis in metus quis
  euismod. Nam arcu augue, imperdiet eu felis eu, rhoncus facilisis lectus. Nullam placerat, tortor non tincidunt tristique, purus magna cursus leo, vitae sagittis odio turpis sodales nisi. Nullam vehicula erat nisl, ac venenatis massa rutrum sed. Mauris
  massa tortor, volutpat vel nisl a, consectetur molestie sapien. Quisque eu elit nulla. Praesent at eros vehicula, lobortis purus quis, efficitur velit. Donec eget faucibus nisl. Praesent pharetra mattis porta. Donec volutpat lacinia dui non maximus.
  Vivamus eu sodales leo. Ut eu ipsum scelerisque, consectetur turpis condimentum, malesuada elit. Proin tincidunt mauris metus, eu tincidunt ex ultrices ut. Sed sollicitudin leo nunc, in pharetra ligula egestas ut. Etiam suscipit eget ligula ut convallis.
  Ut tempus tellus id ultrices rutrum. Nam accumsan fermentum metus, tristique gravida eros ultricies eget. Integer tortor diam, posuere ut ornare quis, bibendum ut tellus. Maecenas imperdiet lacus vitae felis viverra, nec dignissim lacus volutpat. Curabitur
  et elit vehicula ipsum luctus tempor et sed enim. Fusce ultrices eget ante nec consectetur. Donec commodo nunc eget diam tristique, at euismod nisl commodo. Fusce felis neque, vulputate ut tincidunt sed, commodo in risus. Quisque sed magna sodales tortor
  condimentum aliquam. Phasellus mattis justo eget diam tincidunt luctus. Cras pharetra ultrices sem, sed sollicitudin purus feugiat sed. Vivamus vitae tempor velit.
  <!-- end original document -->
  <div class='overlay'>
    <!-- this div is my overlay. It should size to the content of the document body, not the viewport. Careful setting the body's position to relative, the other div will change!-->
  </div>
</body>

最佳答案

我认为你最好将一个元素附加到正文(除非你有权访问可用于扩展的一些更高的堆叠元素)并简单地使用 element.getClientBoundingRect()获取位置和尺寸。

function applyStyle(element, styles) {
  for (var key in styles) {
    element.style[key] = styles[key];
  }
}

var overlay = document.body.appendChild(document.createElement('div')),
    indicator = overlay.appendChild(document.createElement('div'));

//  apply the styles
applyStyle(overlay, {
  position: 'absolute',
  top: 0,
  left: 0,
  right: 0,
  bottom: 0,
  zIndex: 2147483647,  //  it doesn't get higher than this
  pointerEvents: 'none'
});

applyStyle(indicator, {
  position: 'absolute',
  border: '1px dotted red',
  backgroundColor: 'rgba(255,0,0,0.2)'
});
      

window.addEventListener('mouseover', function(event) {
  var bound = event.target.getBoundingClientRect();

  applyStyle(indicator, {
    top: bound.top + 'px',
    left: bound.left + 'px',
    width: bound.width + 'px',
    height: bound.height + 'px'
  });
});
.foo {
  position: absolute;
  top: 30px;
  left: 10px;
  width: 300px;
  border: 1px solid gold;
}

.bar {
  position: relative;
  width: 40%;
  margin: 200px auto 0;
  max-height: 10em;
  overflow: hidden;
  border: 1px solid green;
}
<div class=foo>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ut nibh dapibus tellus varius tristique vitae id elit. Fusce vestibulum neque a scelerisque pellentesque. Vestibulum eu odio risus. Aliquam id tellus in mauris sollicitudin vestibulum. Aenean vestibulum et massa vel dapibus. Pellentesque eu lectus odio. Aliquam vitae fermentum mauris. Pellentesque feugiat sem vel dolor imperdiet tempor.
</div>

<div class=bar>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ut nibh dapibus tellus varius tristique vitae id elit. Fusce vestibulum neque a scelerisque pellentesque. Vestibulum eu odio risus. Aliquam id tellus in mauris sollicitudin vestibulum. Aenean vestibulum et massa vel dapibus. Pellentesque eu lectus odio. Aliquam vitae fermentum mauris. Pellentesque feugiat sem vel dolor imperdiet tempor.
</div>

这里的“诡计”涉及:

  • 使用最大 z 索引与覆盖元素相结合 <body> 内的最后一个元素使得任何页面几乎不可能超越它
  • 鲜为人知的getBoundingClientRect宝藏
  • pointer-events: none css,从覆盖元素中删除交互性(只需在指示器上添加 pointer-events: auto 即可重新启用)

由于您的目标是一种特定的浏览器和一种(常青的)现代浏览器,我认为您不应该使用 jQuery。你不需要它。

关于javascript - 为任意 html 文档创建不显眼的覆盖层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37053460/

相关文章:

javascript - 对于ngRepeat, Angular 编译执行 “only once”是什么意思?

javascript - 没有目标的 HREF 链接,不想使用 hash 或 void(0)

html - 单击卡片时打开链接

javascript - 如何在将表格发送到@media print CSS 之前缩放表格

css - div底部透明(包括div的包含)

javascript - 在Javascript中获取文件夹和文件列表的最佳方法

javascript - Django:从静态文件目录中的js引用静态文件

javascript - jQuery/JS : Sorting array based upon another array?

jquery - 当窗口小于 900px 时,有没有办法只调用一次函数

javascript - 从具有 2 个不同输入的数组中获取值