是否可以编写一个给出任何HTML元素的JavaScript函数 (在屏幕上可见)它创建了另一个HTML元素堆叠在它上面(以便覆盖它)?然后,如果我调整页面大小,它就会像它所覆盖的组件一样移动。
(例如,如果我使用的是getBoundingClientRect,如果原始组件的宽度以百分比表示,它将无效)
该函数应该处理任何情况,无论元素(在输入中)是否有边距,填充,边框,它的显示是块还是内联等等。
我尝试添加一个位置:相对于父组件,然后在" cover"上创建一个位置:absolute;零件。这不起作用,因为它不处理填充或边距等情况。
注意:没有jQuery。纯粹的跨浏览器' JavaScript,如果可能的话
答案 0 :(得分:2)
我建议你将元素添加到你想要“覆盖”的元素,给父元素位置:relative,并给出附加元素位置:absolute;顶部:0;左:0;底部:0;右:0;
...示例
标记:
...
<div id="content">
<div class="cover"></div>
<div></div>
</div>
...
的CSS:
.cover { position: relative; }
.cover .mask { position: absolute; top:0; left:0; bottom: 0; right: 0; }
的jQuery
$(function(){
$('.cover').append('<div class="mask" />');
});
这种方法可以让你忽略任何调整大小......
=========================
基于反馈的改进......
填充shoudl按位置绝对排序,对于边框和边距,您需要使用一些js并在遮罩元素上设置负边距。我所包含的演示链接只处理带有填充/边距均匀的元素 - 如果你的每边都有不同填充/边距的元素,那么你将不得不做更多的解析。
额外的javascript看起来像:
var $hideme = $('.cover');
$('.mask',$hideme).css("margin", "-="+$hideme.css('border-width'));
$('.mask',$hideme).css("margin", "-="+$hideme.css('margin'));
答案 1 :(得分:2)
下面写的封面功能使用jQuery请试试,如果这项工作为你
您好我已经更新了满足您需求的代码......
function coverDiv(sourceId, targetId){
var source = document.getElementById(sourceId);
var sourceComputed = window.getComputedStyle(source);
var target = document.getElementById(targetId);
var positioningProps = ["float","width","height","left","top","marginLeft","marginTop","paddingLeft","paddingTop"];
var cssText = "";
for(var i in positioningProps){
cProp = positioningProps[i];
if(source.style[cProp] == "" || source.style[cProp] == null)
target.style[cProp] = sourceComputed[cProp];
else
target.style[cProp] = source.style[cProp];
}
source.style['position'] = "absolute";
source.style['zIndex'] = "1";
target.style['position'] = "absolute";
target.style['zIndex'] = "999";
}
答案 2 :(得分:1)
添加位置:相对于父组件和位置:封面上的绝对听起来可行,实际上,只要考虑填充,边距和边框。设置顶部等于-1 *(填充顶部+边缘顶部+边框宽度顶部),依此类推另一侧。在没有设置宽度或高度的情况下执行此操作,并且它会自行调整大小以将其边缘粘在您放置它们的位置。但是,这将无法处理不能包含div的组件。
详细说明:
您使用此方法遇到的问题是,如果您尝试覆盖宽度为100px的元素;填充:10px的;边框:1px纯黑色,封面仅100像素宽,不覆盖10个像素的填充或1像素边框。您可以通过向左和向右设置为-11px而不是0来对此进行补偿。除非您感兴趣的所有内容都具有相同的填充,边框和边距,否则您必须在添加封面的javascript函数中对此进行补偿。
答案 3 :(得分:1)
function addCover(id) {
var element = document.getElementById(id);
var wrapper = document.createElement('div');
var cover = document.createElement('div');
wrapper.setAttribute('style', 'position: relative;');
cover.setAttribute('style','position:absolute; top: 0; bottom:0; right: 0; left: 0; width: 100%; height: 100%; z-index:10;')
element.parentElement.replaceChild(wrapper, element);
wrapper.appendChild(element);
wrapper.appendChild(cover);
}
答案 4 :(得分:1)
那么,一个元素应该完全隐藏另一个元素?直到什么?隐藏的给定时间是否显示其下方的元素?
为什么不用 替换 元素,直到您希望原始元素可见?这将解决滚动问题。
使用纯JavaScript更容易。
除非您要更换框架网站上的元素,否则您首先不应该这样做,恕我直言。
答案 5 :(得分:0)
这是一个适用于固定或绝对定位元素的版本,当滚动或重排改变元素的位置或大小时,它不会中断:
function cover(el, filling) {
var c = document.createElement('div');
c.style.background = filling;
var els = window.getComputedStyle(el)
c.style.position = els.position=='fixed' ? 'fixed':'absolute';
c.style.zIndex = parseInt(els.zIndex)+1;
document.body.appendChild(c);
var place = function() {
c.style.width = el.offsetWidth+'px';
c.style.height = el.offsetHeight+'px';
c.style.left = el.offsetLeft+'px';
c.style.top = el.offsetTop+'px';
};
place();
window.addEventListener('resize', place);
}
你这样称呼它:
cover(myElement, 'black');
<强> Demonstration 强>
有两个限制:
答案 6 :(得分:0)
假设我理解正确,最简单(最好)的方法是在要覆盖的元素中嵌入一个元素。外部元素应具有相对位置,嵌套元素应具有绝对定位(每边设置为0)。对每个元素使用ung z-index,无论填充或边距如何,都可以将它们叠加在一起。
<style>
.layer-1 {
width: 100px;
height: 100px;
background: red;
position: relative;
z-index: 1;
}
.layer-2 {
background: blue;
position: absolute;
z-index:2;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
<div class="layer-1">
<span class="layer-2"></span>
</div>
仅包含几行代码的实例,仅限CSS / HTML:http://jsfiddle.net/3hBsZ/
编辑:重新阅读问题后,我确实误解了它。您正在寻找一个JavaScript解决方案,而不是基于CSS的解决方案。但是,这个CSS解决方案比基于javascript的解决方案更有效和跨浏览器。只是我的意见......答案 7 :(得分:0)
我希望这就是你想要的
//https://stackoverflow.com/a/442474/1989562
function getOffset(el) {
var _x = 0;
var _y = 0;
while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
el = el.offsetParent;
}
return {
top: _y,
left: _x
};
}
function overlap(element) {
this.element = element;
this.overlapper = document.createElement("Div");
this.__constructor = function () {
var left = getOffset(this.element).left;
var top = getOffset(this.element).top;
var width = this.element.offsetWidth;
var height = this.element.offsetHeight;
this.overlapper.style.position = "absolute";
this.overlapper.style.width = width + "px";
this.overlapper.style.height = height + "px";
this.overlapper.style.left = left + "px";
this.overlapper.style.top = top + "px";
this.overlapper.style.background = "black";
this.overlapper.style.zIndex = 999;
document.body.appendChild(this.overlapper);
}
this.update = function () {
var left = getOffset(this.element).left;
var top = getOffset(this.element).top;
var width = this.element.offsetWidth;
var height = this.element.offsetHeight;
this.overlapper.style.top = top + "px";
this.overlapper.style.left = left + "px";
this.overlapper.style.width = width + "px";
this.overlapper.style.height = height + "px";
}
this.__constructor();
}
元素函数的偏移量来自此帖子 https://stackoverflow.com/a/442474/1989562
我做了一个小提琴作为例子
http://jsfiddle.net/takedownbig/ASuEJ/
它将获得元素的屏幕上的实际位置,为了使元素更新你必须触发对象的更新功能,我建议像我的例子一样使用。 适用于ie9 +我想在ie8上也有这个工作:/
@edit:该功能没有所有更新方式,但如果你找到它们,你可以简单地触发更新功能来修复实际的位置和宽度。
答案 8 :(得分:0)
通常情况下,这是一个看起来更简单的问题,然后当你开始尝试解决这个问题时。我试了一下,虽然还不是我喜欢的100%,但我会和你分享我的成果。
首先我应该注意jQuery是完全有效的跨浏览器JavaScript,所以我想不出任何有理由不使用它。当然,如果您从Google CDN或类似设备加载它,它可能已经在您的用户缓存中。所以我继续编写了一个小的jQuery插件(老实说,JavaScript只是生锈的方式)。
首先是代码:
// jQuery plugin to create overlays
// apply to any container that contains DOM elements to be overlayed
$.fn.overlayDiv = function() {
// remove any old overlays (could be there on resize)
$(this).find('.overlay').remove();
// loop trough the remaining children
$(this).find('*').each(function() {
// cache some variables
var $el = $(this);
var $parent = $el.parent();
// make the parent relative, if not yet absolute or fixed, for easy positioning
if ($parent.css('position') !== 'fixed' && $parent.css('position') !== 'absolute') {
$parent.css('position', 'relative');
}
// prepare the css
var css = {};
css.zIndex = $el.css('z-index');
css.position = $el.css('position') == 'fixed' ? 'fixed' : 'absolute';
css.display = 'block';
// check if inline or block, and calculate settings appropriately
if ($el.css('display') == 'inline') {
// -- inline
// clone the element and render it on one line
var $clone = $el.clone();
$clone.css({
width: 'auto',
display: 'block',
whiteSpace: 'nowrap'
});
$clone.insertAfter($el);
// compare height of element and clone
if ($el.outerHeight(true) == $clone.outerHeight(true)) {
// if the $el is on a single line
css.width = $el.outerWidth(true);
css.height = $el.outerHeight(true);
css.top = $el.position().top;
css.left = $el.position().left;
// apply the styling to an overlay div and include it in the DOM
$('<div class="overlay"></div>').css(css).insertAfter($el);
} else {
// if the $el is on multiple lines (we need up to 3 divs to overlay)
// -- this part of the code needs improving --
var lineHeight = $clone.outerHeight();
var totalWidth = $clone.outerWidth();
var lines = $el.outerHeight() / lineHeight;
var maxWidth = $parent.width();
// top overlay
css.width = maxWidth - $el.position().left;
css.height = lineHeight;
css.top = $el.position().top;
css.left = $el.position().left;
$('<div class="overlay top"></div>').css(css).insertAfter($el);
// bottom overlay
css.width = totalWidth - css.width - ((lines-2) * maxWidth);
css.top = css.top + (lineHeight*lines);
css.left = 0;
$('<div class="overlay bottom"></div>').css(css).insertAfter($el);
// center overlay
css.width = maxWidth;
css.height = (lines- 2) * lineHeight;
// -- /needs improving -- //
}
$clone.remove();
} else {
// -- block
css.width = $el.outerWidth(true);
css.left = $el.position().left;
// -- height and top might need to improved if you want collapsing margins taken into account
css.height = $el.outerHeight(true);
css.top = $el.position().top;
// apply the styling to an overlay div and include it in the DOM
$('<div class="overlay"></div>').css(css).insertAfter($el);
}
});
}
// when the window is loaded or resized (not just ready, the images need to be there to copy their position and size)
$(window).on('load resize', function() {
// apply the overlay plugin to the body to cover all elements, or recalculate their positioning
$('body').overlayDiv();
});
那里有很多评论,所以我认为这应该是可以理解的,但随时可以询问你是否需要澄清。
您可以在此处查看代码: http://jsfiddle.net/pP96f/7/
关于剩下的2个问题:
希望我的意见有所帮助!
修改强>
对于允许您选择要覆盖的特定元素的版本,而不仅仅是选择一个父级并让所有子级(递归)重叠,请查看这个略微更改的代码版本:{{3 }}
答案 9 :(得分:0)
在google搜索其他内容时,遇到了这个旧帖子。
如果您要做的只是突出显示要覆盖的元素并在叠加层中放置一些文本,那么您可以在没有任何javascript的情况下执行此操作,只需使用CSS:after(要覆盖的元素需要位置) :相对虽然)。
div#source {
position: relative;
}
div#source:after {
content: "Covered";
background: purple;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
答案 10 :(得分:0)
使用jquery用户界面position尝试一下:
_overlapTwoElements(topElement, baseElement) {
if(baseElement.length && topElement.length) {
topElement.width(baseElement.width());
topElement.height(baseElement.height());
topElement.position({ my: "left bottom", at: "left bottom", of: baseElement });
}
}