Lightbox effect (also called Windows shutdown some effect), but need not be so complicated, can display a content box on the list. Is a full-screen coverage of the layer, add a layer to display the content. Use position: fixed the new features

ps: "location effects" means that the screen can scroll fixed position.

Procedure Description:

To achieve a simple lightbox effect, has two main parts: cover and highlight layer.

【Cross-browser fixed positioning】

First things first talk about this position: fixed, its role is to cross-browser fixed positioning.

Extracted from the detailed positioning and location-based applications:
"Let an element such as possible with the page scroll constantly change their position in the browser. And now I can through the CSS positioning of a property to achieve such an effect, once the element of property is not to be supported by position: fixed; him the meaning is: a fixed location. this much like a fixed and absolute positioning, the only difference is that absolute positioning is fixed at a certain page in the location where the fixed location is fixed in the browser's position as the box. "

Procedures in place to use a lot of the css, ie7, ff support the css, but ie6 does not support, procedures are only at the effect of Analog ie6.

【Cover】

Cover the role are to focus on limiting the highlight layer, principles are adopted by an absolute positioning of the layer (usually use div), set its width and height which can cover the entire screen (including zoom and scroll browser) and give it to set up a higher zIndex to layering in the original content (but smaller than the highlight layer), so users can only point to the layer above the content.

If initialization does not provide cover object, the program will automatically create:

this.Lay = $(this.options.Lay) || document.body.insertBefore(document.createElement("div"), document.body.childNodes[0]);


Because one of document.body.appendChild () cause the termination of operation of IE has bug, so using the insertBefore. .

【Coverage】 screen

Cover the key is how to do cover the entire screen (lock the entire page), to support the position: fixed, then is simple:

with(this.Lay.style){ display = "none"; zIndex = this.zIndex; left = top = 0; position = "fixed"; width = height = "100%"; }


Such as the browser can box covers, including the use of a fixed pattern, where the mean is positioning in the browser's frame, and 100% coverage.
Attention not to mistake understanding for this layer covers the entire page, it just put the browser part of visual cover to achieve the desired effect.

No support ie6 how to do? There is some method:
One, to do a cover layer, as the box, and when the corresponding mobile onscroll, re-established at onresize size;
2, depending on the box to do a cover layer, in the style on Analog fixed effects;
3, make a layer covering all of the pages layer and re-established at onresize size;
One disadvantage of the Ways are moving easily露出马脚, and not look good; Ways disadvantage are the 2 pages required structural changes and changes to body style, is definitely not good architecture; and my methods are used in 3, there is a better Ways welcomed.

Use this method as long as the position as absolute, and _resize using a method of setting the width and height can be:

this.Lay.style.position = "absolute";
this._resize = Bind(this, function(){
    this.Lay.style.width = Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth) + "px";
    this.Lay.style.height = Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight) + "px";
});

It should be noted that the distinction between scrollHeight and clientHeight (Height easy to use test), incidentally, have offsetHeight, Handbook on the Description:
scrollHeight: Retrieves the scrolling height of the object.
clientHeight: Retrieves the height of the object including padding, but not including margin, border, or scroll bar.
offsetHeight: Retrieves the height of the object relative to the layout or coordinate parent, as specified by the offsetParent property.

My understanding is:
scrollHeight are the height of the contents of the object;
clientHeight are part of a high degree of visual objects;
offsetHeight are clientHeight add border and scroll bar height.

For example it first to give clientHeight and offsetHeight difference (in ie7 test):

Measurements are outside the div, offsetHeight and clientHeight difference between the 17 (respectively 83 and 100), this difference is that the height of the scroll bar itself.

ClientHeight and scrollHeight look at the difference (The following is a simulation of the situation in ie):

ClientHeight can see from the contents of the impact, are 83, that is, the content does not exceed the target has a high degree would not be affected, but scrollHeight will be affected by the content of high-impact, but also from the test can be aware of:
When there is a scroll bar, the cover should check the height of scrollHeight (high content); when there is no scroll bar, the cover should check the height of clientHeight (depending on box height).
The two cases are taking precisely the two relatively large value, so there is the following procedure:

Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight) + "px";


Set width does not include the scroll bar are part of the documentElement generally NOT border, so do not need offsetWidth.

Can be seen above my documentElement are used rather than the body, manuals are up like this:
Retrieves a reference to the root node of the document.
The meaning of the root node of the document is actually a html node (body on the level), noted that this is at the standard XHTML. Above we can see the object of our values are not just the entire document body, so here documentElement.

It should be noted that in the window of the case onresize Medium scrollWidth and clientWidth value will produce changes in the procedures used in onresize Ways to re-set the width of _resize Height:

if(isIE6){ this._resize(); window.attachEvent("onresize", this._resize); }


Select】 【coverage

Custom layer to select blocked is an old problem, but good news is that ie7 and ff have to support select the zIndex, as long as the layer settings to high zIndex can select a coverage, but for the ie6 problem or need to be resolved .

Select coverage as far as I know there is both good methods of comparison:
1, showing layer, first hidden select, layer and re-turn off display;
2, with an iframe as the bottom layer to cover select.

Method 1 should all understand that Method 2 is to use iframe can select the characteristics of coverage, as long as put a iframe as the bottom layer can cover the following select, the process is used:

this.Lay.innerHTML = '<iframe"position:absolute;top:0;left:0;width:100%;height:100%;filter:alpha(opacity=0);"></iframe>'


We can see that this transparent iframe also cover the same page, if the contents are displayed on the page have the best set z-index: -1; to ensure that the iframe at the bottom layer.

Personally feel that the use of Method 2 is better, but always changed the page structure, and sometimes it would be more refractory, as one Ways Convenience easier.

Highlight layer 【】

Highlight layer is used to display the contents of the layer, there is nothing worth, so add some special effects at the top to attract some eyeballs.
Are interested can be combined with drag-and-drop effects and gradient effects, and make better results.

【Location】 fixed

Here a "fixed location" means that when rolling the scroll bar, the highlight layer remains in the browser corresponding to the location on the Fixed Set to open this effect will be true.

Same for fixed Supported browser is very simple, as long as the position is set to fixed on the line, this style is already used, but the poor can only be simulated ie6.

Analog ie6 principle are at onscroll case, the constant distance from the amendment in accordance with a rolling top and left.
First of all, set up position for the absolute, it should be noted that position in the tectum suggests that the previous show, otherwise the calculation cover wide high when calculating deviation (such as pages put up big).
Add Event to give onscroll positioning function to fix Scroll _fixed parameters:

this.Fixed && window.attachEvent("onscroll", this._fixed);
positioning _fixed function like this:

this._fixed = Bind(this, function(){ this.Center ? this.SetCenter() : this.SetFixed(); });


As can be seen at _fixed, when setting the middle will show the implementation of SetCenter procedures (behind will explain), or on the implementation of procedures SetFixed.
SetFixed first talk about the principle of the procedure is to put the current scrollTop value minus _top (last scrollTop value) plus the current offsetTop, would be to set a top value:

this.Box.style.top = document.documentElement.scrollTop - this._top + this.Box.offsetTop + "px";
this.Box.style.left = document.documentElement.scrollLeft - this._left + this.Box.offsetLeft + "px";
 
this._top = document.documentElement.scrollTop; this._left = document.documentElement.scrollLeft;


【Middle】 show

"Center display" layers of meaning are highlighted, as the box is located around the middle from top to bottom position.
There are two ways to achieve this:
1, depending on the width of box minus the highlight layer is half the width of the left center required value;
2, first set the left value of 50%, then set marginLeft negative half the width of highlight layer.

1 Relative Ways Ways 2 required one more frame width, and at 2 Ways zoom browser also able to maintain the middle, the obvious way 2 are better, but the margin will be affected by the left and top of the calculation, it should be noted (such as amendments to SetFix the place). Here I select the method 2, but also required the attention of offsetWidth and offsetHeight highlighted at show after layer to get, so positioning procedures required on the highlight shows after layer:
this.Box.style.top = this.Box.style.left = "50%";
if(this.Fixed){
    this.Box.style.marginTop = - this.Box.offsetHeight / 2 + "px";
    this.Box.style.marginLeft = - this.Box.offsetWidth / 2 + "px";
}else{
    this.SetCenter();
}


One of, if not a fixed position, with necessary procedures to amend SetCenter Scroll parameters, SetCenter procedure is as follows:

this.Box.style.marginTop = document.documentElement.scrollTop - this.Box.offsetHeight / 2 + "px";
this.Box.style.marginLeft = document.documentElement.scrollLeft - this.Box.offsetWidth / 2 + "px";


【Location】 comparison document

Ie6 do not show when at cover when necessary to hide the other select, here used the term "cover select" method 1, it is worth noting here are select Whether or not add a layer at the judge highlighted:

this._select.length = 0;
Each(document.getElementsByTagName("select"), Bind(this, function(o){
    if(!Contains(this.Box, o)){ o.style.visibility = "hidden"; this._select.push(o); }
}))


Contains one of the procedures are as follows:

var Contains = function(a, b){
    return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(b) & 16);
}


Role is to back a Whether or not it contains b, it uses two functions, ie are separately and contains the ff (dom) of compareDocumentPosition.
Contains one of manual reads:
Checks whether the given element is contained within the object.
Give the meaning of the object are detected by Whether or not included in the designated object inside. Note If the object is to give the specified object itself will also return true, even though it not quite reasonable.
Ff the compareDocumentPosition and more powerful.

Comparing Document Position facie reference table:
From NodeA.compareDocumentPosition (NodeB) return results:
Bits Number Meaning
000000 0 Elements are identical.
000001 1 The nodes are in different documents (or one is outside of a document).
000010 2 Node B precedes Node A.
000100 4 Node A precedes Node B.
001000 8 Node B contains Node A.
010000 16 Node A contains Node B.
100000 32 For private use by the browser.

As can be seen from here NodeA.compareDocumentPosition (NodeB) & 16 means that when the first 5 digits are "1" when the back 16, that is, only when the NodeB contains NodeA back 16 (& is with the operator).
ps: why do we not simply a.compareDocumentPosition (b) == 16, I am not sure.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>JavaScript 仿LightBox内容显示效果</title>
</head>

<body>





<script>

var isIE = (document.all) ? true : false;

var isIE6 = isIE && ([/MSIE (\d)\.0/i.exec(navigator.userAgent)][0][1] == 6);

var $ = function (id) {
	return "string" == typeof id ? document.getElementById(id) : id;
};

var Class = {
	create: function() {
		return function() { this.initialize.apply(this, arguments); }
	}
}

var Extend = function(destination, source) {
	for (var property in source) {
		destination[property] = source[property];
	}
}

var Bind = function(object, fun) {
	return function() {
		return fun.apply(object, arguments);
	}
}

var Each = function(list, fun){
	for (var i = 0, len = list.length; i < len; i++) { fun(list[i], i); }
};

var Contains = function(a, b){
	return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(b) & 16);
}


var OverLay = Class.create();
OverLay.prototype = {
  initialize: function(options) {

	this.SetOptions(options);
	
	this.Lay = $(this.options.Lay) || document.body.insertBefore(document.createElement("div"), document.body.childNodes[0]);
	
	this.Color = this.options.Color;
	this.Opacity = parseInt(this.options.Opacity);
	this.zIndex = parseInt(this.options.zIndex);
	
	with(this.Lay.style){ display = "none"; zIndex = this.zIndex; left = top = 0; position = "fixed"; width = height = "100%"; }
	
	if(isIE6){
		this.Lay.style.position = "absolute";
		//ie6设置覆盖层大小程序
		this._resize = Bind(this, function(){
			this.Lay.style.width = Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth) + "px";
			this.Lay.style.height = Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight) + "px";
		});
		//遮盖select
		this.Lay.innerHTML = '<iframe"position:absolute;top:0;left:0;width:100%;height:100%;filter:alpha(opacity=0);"></iframe>'
	}
  },
  //设置默认属性
  SetOptions: function(options) {
    this.options = {//默认值
		Lay:		null,//覆盖层对象
		Color:		"#fff",//背景色
		Opacity:	50,//透明度(0-100)
		zIndex:		1000//层叠顺序
    };
    Extend(this.options, options || {});
  },
  //显示
  Show: function() {
	//兼容ie6
	if(isIE6){ this._resize(); window.attachEvent("onresize", this._resize); }
	//设置样式
	with(this.Lay.style){
		//设置透明度
		isIE ? filter = "alpha(opacity:" + this.Opacity + ")" : opacity = this.Opacity / 100;
		backgroundColor = this.Color; display = "block";
	}
  },
  //关闭
  Close: function() {
	this.Lay.style.display = "none";
	if(isIE6){ window.detachEvent("onresize", this._resize); }
  }
};



var LightBox = Class.create();
LightBox.prototype = {
  initialize: function(box, options) {
	
	this.Box = $(box);//显示层
	
	this.OverLay = new OverLay(options);//覆盖层
	
	this.SetOptions(options);
	
	this.Fixed = !!this.options.Fixed;
	this.Over = !!this.options.Over;
	this.Center = !!this.options.Center;
	this.onShow = this.options.onShow;
	
	this.Box.style.zIndex = this.OverLay.zIndex + 1;
	this.Box.style.display = "none";
	
	//兼容ie6用的属性
	if(isIE6){
		this._top = this._left = 0; this._select = [];
		this._fixed = Bind(this, function(){ this.Center ? this.SetCenter() : this.SetFixed(); });
	}
  },
  //设置默认属性
  SetOptions: function(options) {
    this.options = {//默认值
		Over:	true,//是否显示覆盖层
		Fixed:	false,//是否固定定位
		Center:	false,//是否居中
		onShow:	function(){}//显示时执行
	};
    Extend(this.options, options || {});
  },
  //兼容ie6的固定定位程序
  SetFixed: function(){
	this.Box.style.top = document.documentElement.scrollTop - this._top + this.Box.offsetTop + "px";
	this.Box.style.left = document.documentElement.scrollLeft - this._left + this.Box.offsetLeft + "px";
	
	this._top = document.documentElement.scrollTop; this._left = document.documentElement.scrollLeft;
  },
  //兼容ie6的居中定位程序
  SetCenter: function(){
	this.Box.style.marginTop = document.documentElement.scrollTop - this.Box.offsetHeight / 2 + "px";
	this.Box.style.marginLeft = document.documentElement.scrollLeft - this.Box.offsetWidth / 2 + "px";
  },
  //显示
  Show: function(options) {
	//固定定位
	this.Box.style.position = this.Fixed && !isIE6 ? "fixed" : "absolute";

	//覆盖层
	this.Over && this.OverLay.Show();
	
	this.Box.style.display = "block";
	
	//居中
	if(this.Center){
		this.Box.style.top = this.Box.style.left = "50%";
		//设置margin
		if(this.Fixed){
			this.Box.style.marginTop = - this.Box.offsetHeight / 2 + "px";
			this.Box.style.marginLeft = - this.Box.offsetWidth / 2 + "px";
		}else{
			this.SetCenter();
		}
	}
	
	//兼容ie6
	if(isIE6){
		if(!this.Over){
			//没有覆盖层ie6需要把不在Box上的select隐藏
			this._select.length = 0;
			Each(document.getElementsByTagName("select"), Bind(this, function(o){
				if(!Contains(this.Box, o)){ o.style.visibility = "hidden"; this._select.push(o); }
			}))
		}
		//设置显示位置
		this.Center ? this.SetCenter() : this.Fixed && this.SetFixed();
		//设置定位
		this.Fixed && window.attachEvent("onscroll", this._fixed);
	}
	
	this.onShow();
  },
  //关闭
  Close: function() {
	this.Box.style.display = "none";
	this.OverLay.Close();
	if(isIE6){
		window.detachEvent("onscroll", this._fixed);
		Each(this._select, function(o){ o.style.visibility = "visible"; });
	}
  }
};

</script>


<style>
.lightbox{width:300px;background:#FFFFFF;border:1px solid #ccc;line-height:25px; top:20%; left:20%;}
.lightbox dt{background:#f4f4f4; padding:5px;}
</style>

<dl>
  <dt><b>LightBox</b> </dt>
  <dd>
    内容显示
    <br /><br />
    <input name="" type="button" value=" 关闭 " />
    <br /><br />
  </dd>
</dl>


<div>

<input type="button" value="关闭覆盖层" />
<input type="button" value="黑色覆盖层" />
<input type="button" value="全透覆盖层" />
<input type="button" value="定位效果" />
<input type="button" value="居中效果" />
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<select>
<option>覆盖select测试</option>
</select> 
<input name="" type="button" value=" 打开 " />

</div>



<script>

var box = new LightBox("idBox");

$("idBoxCancel").onclick = function(){ box.Close(); }
$("idBoxOpen").onclick = function(){ box.Show(); }

$("btnOverlay").onclick = function(){
	box.Close();
	if(box.Over){
		box.Over = false;
		this.value = "打开覆盖层";
	} else {
		box.Over = true;
		this.value = "关闭覆盖层";
	}
}

$("btnOverColor").onclick = function(){
	box.Close();
	box.Over = true;
	if(box.OverLay.Color == "#fff"){
		box.OverLay.Color = "#000";
		this.value = "白色覆盖层";
	} else {
		box.OverLay.Color = "#fff"
		this.value = "黑色覆盖层";
	}
}

$("btnOverOpacity").onclick = function(){
	box.Close();
	box.Over = true;
	if(box.OverLay.Opacity == 0){
		box.OverLay.Opacity = 50;
		this.value = "全透覆盖层";
	} else {
		box.OverLay.Opacity = 0;
		this.value = "半透覆盖层";
	}
}

$("btnFixed").onclick = function(){
	box.Close();
	if(box.Fixed){
		box.Fixed = false;
		this.value = "定位效果";
	} else {
		box.Fixed = true;
		this.value = "取消定位";
	}
}

$("btnCenter").onclick = function(){
	box.Close();
	if(box.Center){
		box.Center = false;
		box.Box.style.left = box.Box.style.top = "20%";
		box.Box.style.marginTop = box.Box.style.marginLeft = "0";
		this.value = "居中效果";
	} else {
		box.Center = true;
		this.value = "重新定位";
	}
}
</script>

</body>
</html>


Transfer from: http://www.cnblogs.com/cloudgamer/archive/2008/09/15/1290954.html

Black hair: http://heisetoufa.javaeye.com/