通常,这是一个看起来要简单得多的问题,但当您开始尝试解决它时就会发现它。我试了一下,虽然它还不是我喜欢的 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 个问题:
- 最大的问题是跨多行的内联元素。如果您只想覆盖元素内的文本,则最多需要三个单独的叠加层才能实现此目的。我一直在努力解决尺寸问题(尤其是底部 div 的宽度),最终我放弃了。任何输入将不胜感激!
- 一个较小的问题是边距塌陷。这应该不难解决,但我不确定您希望如何处理。(而且我已经在这个问题上花费了很多时间......)
希望我的意见能对您有所帮助!
编辑:
对于允许您选择要覆盖的特定元素的版本,而不仅仅是选择一个父项并让所有子项(递归地)覆盖,请查看代码的略微更改版本:http://jsfiddle。净/ARWBD/2/