jQuery实现优雅的弹窗效果(6)

弹窗是网页中经常看到的效果,以前的弹窗是用window.open()等方式在浏览器窗口新建另一个新窗口来完成的,这种弹窗方式现在已经被很多浏览器所拦截。今天我们来用更加友好的方式来实现弹窗效果。完成的功能效果如图:

jQuery实现优雅的弹窗效果(6)

如图,在浏览器的左上方是两个button按钮,按下之后分别弹出左下角的窗口和中间的窗口,右下角的窗口当页面加载完成之后自动慢慢显示,之后又徐徐的淡出。基于div+css的模式,我们的先来建立html页面。

window.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>jQuery实战:窗口效果</title>
<link type="text/css" rel="stylesheet" href="../css/window.css" rel="external nofollow" />
<script type="text/javascript" src="../js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="../js/window.js"></script>
</head>
<body>
 <input type="button" value="左下角显示窗口" id="leftpop" />
 <input type="button" value="屏幕中间显示窗口" id="centerpop" />

 <div class="window" id="left">
 <div class="title">
  <img alt="关闭" src="../image/close.gif" />
  我是左边显示窗口的标题栏
 </div>
 <div class="content">
  我是左边显示窗口的内容区
 </div>
 </div>
 <div class="window" id="center">
 <div class="title">
  <img alt="关闭" src="../image/close.gif" />
  我是中间显示窗口的标题栏
 </div>
 <div class="content">
  <p>我是中间显示窗口的内容区</p>
 </div>
 </div> 
 <div class="window" id="right">
 <div class="title">
  <img alt="关闭" src="../image/close.gif" />
  我是右边显示窗口的标题栏
 </div>
 <div class="content">
  我是右边显示窗口的内容区
 </div>
 </div>
</body>
</html>

从html代码中可以看到,这里的窗口是用div来实现的,目前的html代码只是描绘了页面的基本骨架,能够效果离窗口效果还相差甚远,不过别急,添加上css代码,页面相对就好看多了。

window.css

.window {
 background-color: #D0DEF0;
 width: 250px;
 /*padding: 2px;*/
 margin: 5px;
 /*控制窗口绝对定位*/
 position: absolute;
 display: none;
}
.content {
 height: 150px;
 background-color: white;
 border: 2px solid #D0DEF0;
 padding: 2px;
 /*控制区域内容超过指定高度和宽度时显示滚动条*/
 overflow: auto;
}
.title {
 padding: 4px;
 font-size: 14px;
}
.title img {
 width: 14px;
 height: 14px;
 float: right;
 cursor: pointer;
}

为了看到当前效果,先将.window的display属性注释掉,或者将它的属性值改为”block”,看到的效果如图:

jQuery实现优雅的弹窗效果(6)

其实三个窗口是由三个div组成,每个div分为title和content两部分,title是标题栏区域,content是内容区域。为了达到窗口的视觉效果,给我们的title标题栏区域加背景颜色background-color,然后给我们的content内容区域加边框border: 2px solid #D0DEF0;,边框的颜色与标题栏一致。此时的效果如上图,目前只能看到一个窗口的原因是三个div占据了相同的位置,第三个窗口遮盖住了前两个窗口。不过没关系,我们可以用JavaScript代码来控制三个div的位置。

jQuery库函数提供了丰富多彩的插件功能,今天我们来编写自己的插件,简单的案例如下:

$.fn.hello = function() {
 alert("hello:" + this.val());
 return this;
}

只需要在需要的地方注册上本插件就行了。相应的,这里我们编写的插件mywin来专门处理我们的窗口功能效果。

window.js

/**
* 窗口位置的插件
*/
$.fn.mywin = function() {
 var windowobj = $(window);
 var browserWidth = $(window).width();
 var browserHeight = $(window).height();
 var scrollLeft = $(window).scrollLeft();
 var scrollTop = $(window).scrollTop();
 var cwinwidth = this.width();
 var cwinheight = this.height();
 var left = scrollLeft + (browserWidth - cwinwidth)/2;
 var top = cwinheight + (browserHeight - cwinheight)/2;
 this.css("left", left).css("top", top);
 $(this.children(".title").children("img")).click(function() {
 $(this).parent().parent().hide("slow");
 });

 return this;
}

上诉代码编写了本应用中中间窗口案例的插件,调用代码如下:

window.js

$(document).ready(function() {
 $("#centerpop").click(function() {
 $("#center").mywin().show("slow");
 });
});

插件中的代码思路是:为了计算窗口div的left和top属性值,我们需要拿到浏览器窗口的长browserWidth和宽browserHeight,以及窗口是否因为内容过多而又滚动条的位置scrollLeft和scrollTop。窗口div的left值=滚动条横坐标+(浏览器窗口的横向长度-窗口div横向长度)/2,top值=滚动条纵坐标+(浏览器窗口的纵向长度-窗口div纵向长度)/2。

最终完成完整的jQuery代码如下:

$(document).ready(function(){
 var centerwin = $("#center");
 var leftwin = $("#left");
 var rightwin = $("#right");
 $("#centerpop").click(function(){
 //鼠标点击按钮之后,把id为center的窗口显示在页面中间
 //计算位于屏幕中间的窗口的左边界和上边界的值
 //浏览器可视区域的宽和高,当前窗口的宽和高
 //需要考虑到横向滚动条的当前左边界值以及纵向滚动条的当前上边界值
 centerwin.show("slow");
 });
 $("#leftpop").click(function() {
 leftwin.slideDown("slow");
 });

 setTimeout(function () {
 centerwin.mywin({left: "center", top: "center"});
 leftwin.mywin({left: "left", top: "bottom"}, function(){
  leftwin.slideUp("slow");
 });
 var windowobj = $(window);
 var cwinwidth = rightwin.outerWidth(true);
 var cwinheight = rightwin.outerHeight(true);
 var browserwidth = windowobj.width();
 var browserheight = windowobj.height();
 var scrollLeft = windowobj.scrollLeft();
 var scrollTop = windowobj.scrollTop();
 var rleft = scrollLeft + browserwidth - cwinwidth;
 if ($.browser.safari) {
  rleft = rleft - 15;
 }
 if ($.browser.opera) {
  rleft = rleft + 15;
 }
 if ($.browser.msie && $.browser.version.indexOf("8") >= 0) {
  rleft = rleft - 20;
 }
 rightwin.mywin({left: "right", top: "bottom"}, function() {
  rightwin.hide();
 },{left: rleft, top: scrollTop + browserheight}).fadeOut(15000).dequeue();
 },500);

});

/**
 *@param position表示窗口的最终位置,包含两个属性,一个是left,一个是top
 *@param hidefunc表示执行窗口隐藏的方法
 *@param initPos表示窗口初始位置,包含两个属性,一个是left,一个是top
 */
$.fn.mywin = function(position, hidefunc, initPos) {
 if (position && position instanceof Object) {
 var positionleft = position.left;
 var positiontop = position.top;

 var left;
 var top;
 var windowobj = $(window);
 var currentwin = this;
 var cwinwidth;
 var cwinheight;

 var browserwidth;
 var browserheight;
 var scrollLeft;
 var scrollTop;
 //计算浏览器当前可视区域的宽和高,以及滚动条左边界,上边界的值
 function getBrowserDim() {
  browserwidth = windowobj.width();
  browserheight = windowobj.height();
  scrollLeft = windowobj.scrollLeft();
  scrollTop = windowobj.scrollTop(); 
 } 
 //计算窗口真实的左边界值
 function calLeft(positionleft, scrollLeft, browserwidth, cwinwidth) {
  if (positionleft && typeof positionleft == "string") {
  if (positionleft == "center") {
   left = scrollLeft + (browserwidth - cwinwidth) / 2; 
  } else if (positionleft == "left") {
   left = scrollLeft; 
  } else if (positionleft == "right") {
   left = scrollLeft + browserwidth - cwinwidth;
   if ($.browser.safari) {
   left = left - 15;
   }
   if ($.browser.opera) {
   left = left + 15;
   }
   if ($.browser.msie && $.browser.version.indexOf("8") >= 0) {
   left = left - 20;
   }
  } else {
   left = scrollLeft + (browserwidth - cwinwidth) / 2; 
  }
  } else if (positionleft && typeof positionleft == "number") {
  left = positionleft;
  } else {
  left = 0;
  }
 }
 //计算窗口真实的上边界值 
 function calTop(positiontop, scrollTop, browserheight, cwinheight) {
  if (positiontop && typeof positiontop == "string") {
  if (positiontop == "center") {
   top = scrollTop + (browserheight - cwinheight) / 2;
  } else if (positiontop == "top") {
   top = scrollTop;
  } else if (positiontop == "bottom") {
   top = scrollTop + browserheight - cwinheight;
   if ($.browser.opera) {
   top = top - 25;
   }
  } else {
   top = scrollTop + (browserheight - cwinheight) / 2;
  }
  } else if (positiontop && typeof positiontop == "number") {
  top = positiontop;
  } else {
  top = 0;
  }
 }
 //移动窗口的位置
 function moveWin() {
  calLeft(currentwin.data("positionleft"), scrollLeft, browserwidth, cwinwidth);
  calTop(currentwin.data("positiontop"), scrollTop, browserheight, cwinheight);
  currentwin.animate({
  left: left,
  top: top
  },600); 
 }

 //定义关闭按钮的动作
 currentwin.children(".title").children("img").click(function() {
  if (!hidefunc) {
  currentwin.hide("slow") ;
  } else {
  hidefunc();
  }
 });

 if (initPos && initPos instanceof Object) {
  var initLeft = initPos.left;
  var initTop = initPos.top;
  if (initLeft && typeof initLeft == "number") {
  currentwin.css("left", initLeft); 
  } else {
  currentwin.css("left", 0);
  }
  if (initTop && typeof initTop == "number") {
  currentwin.css("top", initTop); 
  } else {
  currentwin.css("top", 0);
  }
  currentwin.show();
 }
 cwinwidth = currentwin.outerWidth(true);
 cwinheight = currentwin.outerHeight(true);
 currentwin.data("positionleft", positionleft);
 currentwin.data("positiontop", positiontop);
 getBrowserDim();
 moveWin();

 var scrollTimeout;
 //浏览器滚动条滚动时,移动窗口的位置
 $(window).scroll(function(){
  //判断一下当前窗口是否可见
  if (!currentwin.is(":visible")) {
  return; 
  }
  clearTimeout(scrollTimeout);
  scrollTimeout = setTimeout(function(){
  getBrowserDim(); 
  moveWin();
  },300);
 });
 //浏览器大小改变时,移动窗口的位置
 $(window).resize(function(){
  //判断一下当前窗口是否可见
  if (!currentwin.is(":visible")) {
  return; 
  }
  getBrowserDim(); 
  moveWin(); 
 });
 //返回当前对象,以便可以级联的执行其他方法
 return currentwin;
 }
}

左下角和中间窗口的div是靠触发click事件来显示窗口,在滚动条滚动时触发scroll事件来重新调用计算div的top和left的函数。右下角的窗口是徐徐升起的窗口,所以在文档加载完成的时候就显示窗口,处理的代码是放在setTimeout()事件里面,setTimeout函数里面的fadeOut让窗口达到渐变透明的效果。

案例代码托管地址:https://github.com/shizongger/JqueryInAction

相关推荐