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


Posted in Javascript onFebruary 08, 2017

弹窗是网页中经常看到的效果,以前的弹窗是用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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js AspxButton的客户端操作
Jun 26 Javascript
前端开发部分总结[兼容性、DOM操作、跨域等](持续更新)
Mar 04 Javascript
jquery 仿QQ校友的DIV模拟窗口效果源码
Mar 24 Javascript
javascript 弹出层组件(升级版)
May 12 Javascript
浅析onsubmit校验表单时利用ajax的return false无效问题
Jul 10 Javascript
javascript + jquery实现定时修改文章标题
Mar 19 Javascript
深入理解javascript中concat方法
Dec 12 Javascript
jquery中each循环的简单回滚操作
May 05 jQuery
原生JavaScript来实现对dom元素class的操作方法(推荐)
Aug 16 Javascript
layui点击数据表格添加或删除一行的例子
Sep 12 Javascript
Vue3项目打包后部署到服务器 请求不到后台接口解决方法
Feb 06 Javascript
利用H5api实现时钟的绘制(javascript)
Sep 13 Javascript
JavaScript中的子窗口与父窗口的互相调用问题
Feb 08 #Javascript
深入理解js中的加载事件
Feb 08 #Javascript
滚动条的监听与内容随着滚动条动态加载的实现
Feb 08 #Javascript
JQuery页面随滚动条动态加载效果的简单实现(推荐)
Feb 08 #Javascript
setTimeout学习小结
Feb 08 #Javascript
jquery uploadify如何取消已上传成功文件
Feb 08 #Javascript
js/jquery控制页面动态加载数据 滑动滚动条自动加载事件的方法
Feb 08 #Javascript
You might like
PHP读取xml方法介绍
2013/01/12 PHP
PHP时间戳与日期之间转换的实例介绍
2013/04/19 PHP
深入php中var_dump方法的使用详解
2013/06/24 PHP
PHP eval函数使用介绍
2013/12/08 PHP
免费手机号码归属地API查询接口和PHP使用实例分享
2014/04/10 PHP
Windows Server 2008 R2和2012中PHP连接MySQL过慢的解决方法
2016/07/02 PHP
PHP完全二叉树定义与实现方法示例
2017/10/09 PHP
PHP检查端口是否可以被绑定的方法示例
2018/08/09 PHP
CCPry JS类库 代码
2009/10/30 Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
2012/09/14 Javascript
给页面渲染时间加速 干掉Dom Level 0 Event
2012/12/19 Javascript
js propertychange和oninput事件
2014/09/28 Javascript
JavaScript实现弹出子窗口并传值给父窗口
2014/12/18 Javascript
微信内置浏览器私有接口WeixinJSBridge介绍
2015/05/25 Javascript
jquery实现根据浏览器窗口大小自动缩放图片的方法
2015/07/17 Javascript
jquery常用函数与方法汇总
2015/09/01 Javascript
聊一聊jQuery插件uploadify使用方法
2016/08/24 Javascript
常用的几个JQuery代码片段
2017/03/13 Javascript
vue项目中jsonp跨域获取qq音乐首页推荐问题
2018/05/30 Javascript
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
[01:11:11]Alliance vs RNG 2019国际邀请赛淘汰赛 败者组BO1 8.20.mp4
2020/07/19 DOTA
[52:40]完美世界DOTA2联赛PWL S2 Magma vs GXR 第一场 11.29
2020/12/02 DOTA
Python中用sleep()方法操作时间的教程
2015/05/22 Python
Python实现视频下载功能
2017/03/14 Python
win10系统下Anaconda3安装配置方法图文教程
2018/09/19 Python
Django框架HttpResponse对象用法实例分析
2019/11/01 Python
IGK Hair官网:喷雾、洗发水、护发素等
2020/11/03 全球购物
物流管理专业应届生求职信
2013/11/21 职场文书
最受欢迎的自我评价
2013/12/22 职场文书
销售人员自我评价
2014/02/01 职场文书
优秀团队获奖感言
2014/02/19 职场文书
《陶罐和铁罐》教学反思
2014/02/19 职场文书
多媒体编辑专业毕业生求职信
2014/06/13 职场文书
私营公司诉讼代理委托书范本
2014/09/13 职场文书
劳动者解除劳动合同通知书
2015/04/16 职场文书
解决go在函数退出后子协程的退出问题
2021/04/30 Golang