Heim >Web-Frontend >js-Tutorial >Javascript公共脚本库系列(一): 弹出层脚本_javascript技巧

Javascript公共脚本库系列(一): 弹出层脚本_javascript技巧

WBOY
WBOYOriginal
2016-05-16 18:10:20891Durchsuche
一.摘要
本系列文章是为了抽象通用的,跨浏览器的脚本方法.

本篇文章讲解弹出浮动层的javascript函数, 以及函数的原理和使用注意事项.

二.实现效果
用脚本弹出浮动层是我们最常用的脚本方法之一.下面是效果图:

image 
点击图中的"航空公司"后,会在"航空公司"下面弹出浮动层.

在网上弹出框的脚本相当多, 而且还有各种第三方JS框架可供我们使用.但是其中有的脚本过于简单,仅仅粗略的实现弹出效果而忽略了灵活性,通用性和跨浏览器特性. 使用JS框架又有些杀鸡用牛刀.所以在收集整理了一些资料后, 写出了下文中的ScriptHelper类的弹出层方法.

主要特点有:
支持多浏览器
使用面向对象方法封装
使用简单,通用性强.
将计算位置等函数进行提取, 所有的相关函数都可以单独调用, 可根据具体项目继续二次开发.
三.脚本方法
下面我先将脚本方法贡献出来,然后举例如何使用. 最后讲解脚本的原理.

复制代码 代码如下:

/* ==================== ScriptHelper 开始 ==================== */
/* scriptHelper 脚本帮助对象.
创建人: ziqiu.zhang 2008.3.5
添加函数:
getScroll():得到鼠标滚过的距离-兼容XHTML
getClient():得到浏览器当前显示区域的大小-兼容XHTML
showDivCommon():显示图层.
使用举例:


*/
function scriptHelper()
{
}

// 得到鼠标滚过的距离 scrollTop 与 scrollLeft
/* 用法与测试:
var myScroll = getScroll();
alert("myScroll.scrollTop:" + myScroll.scrollTop);
alert("myScroll.scrollLeft:" + myScroll.scrollLeft);
*/
scriptHelper.prototype.getScroll = function ()
{
var scrollTop = 0, scrollLeft = 0;
scrollTop = (document.body.scrollTop > document.documentElement.scrollTop)? document.body.scrollTop:document.documentElement.scrollTop;
if( isNaN(scrollTop) || scrollTop scrollLeft = (document.body.scrollLeft > document.documentElement.scrollLeft )? document.body.scrollLeft:document.documentElement.scrollLeft;
if( isNaN(scrollLeft) || scrollLeft return { scrollTop:scrollTop, scrollLeft: scrollLeft};
}
// 得到浏览器当前显示区域的大小 clientHeight 与 clientWidth
/* 用法与测试:
var myScroll = getScroll();
alert("myScroll.sTop:" + myScroll.sTop);
alert("myScroll.sLeft:" + myScroll.sLeft);
*/
scriptHelper.prototype.getClient = function ()
{
//判断页面是否符合XHTML标准
var isXhtml = true;
if( document.documentElement == null || document.documentElement.clientHeight {
if( document.body.clientHeight>0 )
{
isXhtml = false;
}
}
this.clientHeight = isXhtml?document.documentElement.clientHeight:document.body.clientHeight;
this.clientWidth = isXhtml?document.documentElement.clientWidth:document.body.clientWidth;
return {clientHeight:this.clientHeight,clientWidth:this.clientWidth};
}

// 显示图层,再次调用则隐藏
/* 参数说明:
sObj : 要弹出图层的事件源
divId : 要显示的图层ID
sObjHeight : 事件源的高度,默认为20.需要手工传入是因为对于由于事件源对象可能是各种HTML元素,有些元素高度的计算无法跨浏览器通用.
moveLeft : 手工向左移动的距离.不移动则为0(默认).
divObjHeight: 弹出层的高度.如果传入大于0的此参数, 则当事件源下方空间不足时,在事件源上方弹出层.如果不传此参数则一直在事件源下方弹出.
用法与测试:

*/
scriptHelper.prototype.showDivCommon = function (sObj,divId, sObjHeight, moveLeft, divObjHeight)
{
//取消冒泡事件
if( typeof(window)!='undefined' && window != null && window.event != null )
{
window.event.cancelBubble = true;
}
else if( ScriptHelper.showDivCommon.caller.arguments[0] != null )
{
ScriptHelper.showDivCommon.caller.arguments[0].cancelBubble = true;
}
//参数检测.如果没有传入参数则设置默认值
if( moveLeft == null )
{
moveLeft = 0;
}
if( sObjHeight == null )
{
sObjHeight = 20;
}
if(divObjHeight == null)
{
divObjHeight = 0;
}

var divObj = document.getElementById(divId); //获得图层对象
var sObjOffsetTop = 0; //事件源的垂直距离
var sObjOffsetLeft = 0; //事件源的水平距离
var myClient = this.getClient();
var myScroll = this.getScroll();
var sWidth = sObj.width; //事件源对象的宽度
var sHeight = sObjHeight; //事件源对象的高度
var bottomSpace; //距离底部的距离
/* 获取事件源控件的高度和宽度.*/
if( sWidth == null )
{
sWidth = 100;//无法获取则为100
}
else
{
sWidth = sWidth + 1; //留出1px的距离
}

if( divObj.style.display.toLowerCase() != "none" )
{
//隐藏图层
divObj.style.display = "none";
}
else
{
if( sObj == null )
{
alert("事件源对象为null");
return false;
}
/* 获取事件源对象的偏移量 */
var tempObj = sObj; //用于计算事件源坐标的临时对象
while( tempObj && tempObj.tagName.toUpperCase() != "BODY" )
{
sObjOffsetTop += tempObj.offsetTop;
sObjOffsetLeft += tempObj.offsetLeft;
tempObj = tempObj.offsetParent;
}
tempObj = null;

/* 获取距离底部的距离 */
bottomSpace = parseInt(myClient.clientHeight) - ( parseInt(sObjOffsetTop) - parseInt(myScroll.scrollTop)) - parseInt(sHeight);
/* 设置图层显示位置 */
//如果事件源下方空间不足且上方控件足够容纳弹出层,则在上方显示.否则在下方显示
if( divObjHeight>0 && bottomSpace divObjHeight )
{
divObj.style.top = ( parseInt( sObjOffsetTop ) - parseInt( divObjHeight ) - 10).toString() + "px";
}
else
{
divObj.style.top = ( parseInt( sObjOffsetTop ) + parseInt( sHeight ) ).toString() + "px";
}
divObj.style.left = ( parseInt( sObjOffsetLeft ) - parseInt( moveLeft ) ).toString() + "px";
divObj.style.display="block";
}
}

// 关闭图层
/* 参数说明:
divId : 要隐藏的图层ID
用法与测试:
ScriptHelper.closeDivCommon('testDiv');
*/
scriptHelper.prototype.closeDivCommon = function (divId)
{
//
var divObj = document.getElementById(divId); //获得图层对象
if( divObj != null )
{
divObj.style.display = "none";
}
}
//建立scriptHelper类的一个实例对象.全局使用.
var ScriptHelper = new scriptHelper();
/* ==================== ScriptHelper 结束 ==================== */

四.使用举例
接下来我们创建HTML页面演示如何使用此脚本.此实例是一个菜单,当点击时显示子菜单图层.
1.引用脚本文件
将上面的代码保存在ScriptHelper.js文件中.在页面中添加引用:

2.编写子菜单
先编写两个子菜单图层.
复制代码 代码如下:






对于子菜单, 最重要的就是要设置两个样式:position和display.
position:absolute 让此图层能够精确定位显示.从而控制他的显示位置.
display:none 让图层在加载时不显示.
3.编写主菜单
主菜单代码如下:
复制代码 代码如下:

我们创建了三个菜单.其中Menu1和Menu2拥有子菜单, NoSubMenu没有子菜单.
我们使用了a元素创建菜单对象, 但是因为没有为其添加href属性,所以默认情况下鼠标放上去不会变成hand图形.需要为其添加样式cursorHand,次样式的代码如下:

最关键的是为菜单添加的onclick事件, 此事件调用ScriptHelper.showDivCommon方法用于显示图层.
方法第一个参数值为this表示将事件源对象传入, 在函数中会根据事件源计算显示位置.
方法第二个参数表示弹出图的Id
方法第三个参数是可选参数, 用于设置向下的偏移量.因为我们计算的位置是"Menu1"这个元素的左上角坐标.需要设置一个向下的偏移量.一般设置为事件源的高度,默认为20px.
方法第四个参数是可选参数,用于设置向左的偏移量.原因同上.默认为0px;
方法第五个参数是可选参数,需要传入弹出层的高度.如果使用了此属性则弹出层可能弹出在事件源上方.不传递此属性则始终在事件源下方弹出图层.
4.效果与完整代码

image 
完整实例代码如下:

复制代码 代码如下:




ScriptHelper 类测试页面














五.注意事项:
1.要给Body元素加上position:relative样式:

不增加的话在IE6下有时会出现无法精确定位事件源的情况.比如在menu的
上添加几个
,则弹出层的位置就发生错误了.
如果在Body元素上增加此样式仍然弹出位置错误,则请在事件源对象的容器元素中也添加此样式
2.不传递最后一个参数则弹出层只在事件源下面弹出.否则将会计算事件源底部的举例, 如果底部控件不足并且上部控件充足,则弹出层显示在事件源上方.
3.在页面上要添加DOCTYPE元素.不添加的话很可能在某些浏览器中出现错误.有关DOCTYPE的作用,请查看下面的文章:
DOCTYPE元素解析
六.总结
兼容多浏览器真的是一件让人头疼的事情.我估计此函数还是会有问题.本来想写脚本分析的, 但是在写作的时候又发现了一些Bug并且进行了修正.兼容来兼容去最后把自己兼容晕了.其实如果一个项目能使用脚本库将会是一个很好的选择.本系列文章只是希望构建一个轻量级的脚本类库.大家使用中有任何问题希望多多交流, 一起打造简单易用的脚本库!
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn