JS图片灯箱(lightBox)效果基本原理和demo
到年底了,项目不怎么忙,所以有空特地研究了下KISSY中源码JS灯箱效果,感觉代码比较简单,所以就按照他们的思路依赖于Jquery框架也封装了一个,特地分享给大家,以前经常看到网上很多这样的插件,感觉很多人很牛逼的样子,这样的效果也能做出来,碰巧今天自己也能研究出来一个,代码也不多,就300多行代码,嘿嘿!如果写的不够好,或者还不够的,希望大家多多指教!或者多多发表意见,那些需要值得改进的地方!共同学习!
基本原理
点击缩略图浮层显示大图,可点击键盘←、→键切换图片,也可以鼠标点击左右箭头切换。按下键盘Esc键和点击关闭按钮效果一致。
配置项如下:
| container |
'#container', container 容器标识,父级盒子ID |
| targetCls | '.J_lightbox', targetCls 元素选择器,需要弹出的图片链接dom节点 |
| layer | '#lightbox', 浮层模版选择器 |
| closebtn | '.closebtn', 关闭浮层的X按钮 |
| prev | '.prevbtn', 上一张触发器 |
| next | '.nextbtn', 下一张触发器 |
| easing | 'linear' jquery 动画函数 默认为 'linear' 或者 'swing' 或者jquery自带的动画效果 |
JSFiddle效果如下
代码中需要了解的知识点如下:
1. getBoundingClientRect()方法:该方法获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置,他返回的是一个对象,即Object,该对象有是个属 性:top,left,right,bottom;这里的top、left和css中的理解很相似,但是right,bottom和css中的理解有点不 一样,看示意图:


以前getBoundingClientRect()是IE特有的,目前FF3+,opera9.5+,safari 4,都已经支持这个方法。所以兼容性都支持的。
2. 判断图片是否加载完成时 标准浏览器用onload触发,IE用私有属性onreadystatechange触发,需要了解更深入的话 可以阅读这篇文章:想看我,先点击我!ok!
代码简单的分析下:
1.页面初始化时候 调用init方法,执行点击_click()函数。如下代码:
init: function(options) {
this.config = $.extend(this.config, options || {});
var self = this,
_config = self.config;
// 点击
self._click();
},
2. 点击_click()函数做了如下事情:
1. 点击缩略图:调用 self._showLoadMask(); // 显示loading加载效果 就是页面未加载或者网速慢的时候 显示加载转圈那种效果。
2. self._onLoad($(this).attr('href'),this); // 执行此方法加载大图片。
3. 鼠标mouerover事件和mouseout事件触发 如下代码:
// 鼠标mouseover事件(移到动画层)
$(_config.layer).mouseover(function(){
if(_cache.currentImg != 0) {
$(_config.prev).css('display','block');
}
if(_cache.currentImg != ($(_config.targetCls).length - 1)) {
$(_config.next).css('display','block');
}
});
// 鼠标移出 隐藏上一页按钮 下一页按钮
$(_config.layer).mouseout(function(){
$(_config.prev).css('display','none');
$(_config.next).css('display','none');
});
4. 点击上一页按钮 或 下一页按钮 图片切换做相应的操作:如下代码:
// 点击上一页按钮
$(_config.prev).unbind('click').bind('click',function(){
_cache.currentImg -= 1;
self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]);
if(_cache.currentImg == 0) {
$(_config.prev).css('display','none');
}else {
$(_config.prev).css('display','block');
}
$(_config.next).css('display','block');
});
// 点击下一页按钮
$(_config.next).unbind('click').bind('click',function(){
_cache.currentImg += 1;
self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]);
if(_cache.currentImg == ($(_config.targetCls).length - 1)) {
$(_config.next).css('display','none');
}else {
$(_config.next).css('display','block');
}
$(_config.prev).css('display','block');
});
5. 点击关闭按钮触发关闭事件,代码如下:
$(_config.closebtn).unbind('click').bind('click',function(){
var position = self._getPos($(_config.targetCls)[_cache.currentImg]),
width = $($(_config.targetCls)[_cache.currentImg]).width(),
height = $($(_config.targetCls)[_cache.currentImg]).height();
$('img',_config.layer).attr('src','http://m2.img.papaapp.com/farm5/d/2014/0126/14/E6520E9D47F0FE8AB04B93BE922C6707_ORIG_1_1.gif');
$(_config.layer).animate({
'left' : position.x,
'top' : position.y,
'width' : width,
'height' : height,
"borderWidth": 0
},0.2,_config.easing,function(){
$(_config.layer).css('display','none');
_cache.isShow = false;
});
});
6.键盘左右键除法事件代码如下:
/*
* 键盘左右键触发 Esc键码27 键盘右移键39 左移键 37
*/ $(document).unbind('keydown').bind('keydown',function(e){
var keyCode = e.keyCode;
if(_cache.isShow) {
if(keyCode == 27) {
$(_config.closebtn).click();
}else if(keyCode == 37) {
if(_cache.currentImg == 0) {
return;
} $("#maskLayer").css('display','block');
$(_config.prev).click();
}else if(keyCode == 39) {
if(_cache.currentImg == ($(_config.targetCls).length - 1)) {
return;
}
$("#maskLayer").css('display','block');
$(_config.next).click();
}
}
});
7. 窗口缩放事件 代码如下:
// 窗口缩放事件
$(window).resize(function(){
if(_cache.isShow){
if(self.isrun && $(self.isrun).is(":animated")) {
$(self.isrun).stop();
}
self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]);
}
});
3. 下面还有几个方法不一一解析了 有兴趣的童鞋可以看看代码,下面会提供demo下载或在看看上面Jsfiddle链接效果或者源码:分别是:
_showLoadMask().显示loading加载效果
_onLoad() 加载大图片
_getCenter() 层居中对齐
下面是所有的JS代码如下:
/**
* JS灯箱效果
* @time 2014-1-24
* @author tugenhua
*/ function LightBox(options) { /**
* 参数说明
* @container 容器标识,父级盒子ID
* @targetCls 元素选择器,需要弹出的图片链接dom节点
* @layer 浮层模版选择器
* @closebtn 关闭浮层的X按钮
* @prev 上一张触发器
* @next 下一张触发器
* @easing jquery 动画函数 默认为 'linear' 或者 'swing' 或者jquery自带的动画效果
*/
this.config = {
container : '#container',
targetCls : '.J_lightbox',
layer : '#lightbox',
closebtn : '.closebtn',
prev : '.prevbtn',
next : '.nextbtn',
easing : 'linear'
}; this.cache = {
isShow : false,
currentImg : null
};
// 初始化
this.init(options);
} LightBox.prototype = { constructor: LightBox, init: function(options) {
this.config = $.extend(this.config, options || {});
var self = this,
_config = self.config; // 点击
self._click();
},
/*
* 获取元素的位置
* @method _getPos()
* @param node 元素的节点
* {private}
*/
_getPos: function(node) {
var pos = {},
xy = $(node)[0].getBoundingClientRect(),
sl = $(window).scrollLeft(),
st = $(window).scrollTop();
pos.x = xy.left + sl;
pos.y = xy.top + st;
return pos;
},
/*
* 点击页面上图片
* @method _click();
* {private}
*/
_click: function() {
var self = this,
_config = self.config,
_cache = self.cache; $(_config.targetCls,_config.container).each(function(index,item) {
$(item).unbind('click');
$(item).bind('click',function(e){
e.preventDefault();
_cache.currentImg = $(_config.targetCls).index($(this)); // 显示loading加载效果
self._showLoadMask(); // 加载内容
self._onLoad($(this).attr('href'),this);
}); // 鼠标mouseover事件(移到动画层)
$(_config.layer).mouseover(function(){
if(_cache.currentImg != 0) {
$(_config.prev).css('display','block');
}
if(_cache.currentImg != ($(_config.targetCls).length - 1)) {
$(_config.next).css('display','block');
}
});
// 鼠标移出 隐藏上一页按钮 下一页按钮
$(_config.layer).mouseout(function(){
$(_config.prev).css('display','none');
$(_config.next).css('display','none');
}); // 点击上一页按钮
$(_config.prev).unbind('click').bind('click',function(){
_cache.currentImg -= 1;
self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]);
if(_cache.currentImg == 0) {
$(_config.prev).css('display','none');
}else {
$(_config.prev).css('display','block');
}
$(_config.next).css('display','block');
}); // 点击下一页按钮
$(_config.next).unbind('click').bind('click',function(){
_cache.currentImg += 1; self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]);
if(_cache.currentImg == ($(_config.targetCls).length - 1)) {
$(_config.next).css('display','none');
}else {
$(_config.next).css('display','block');
}
$(_config.prev).css('display','block');
}); // 点击关闭按钮X 隐藏lightBox图片
$(_config.closebtn).unbind('click').bind('click',function(){
var position = self._getPos($(_config.targetCls)[_cache.currentImg]),
width = $($(_config.targetCls)[_cache.currentImg]).width(),
height = $($(_config.targetCls)[_cache.currentImg]).height(); $('img',_config.layer).attr('src','http://m2.img.papaapp.com/farm5/d/2014/0126/14/E6520E9D47F0FE8AB04B93BE922C6707_ORIG_1_1.gif');
$(_config.layer).animate({
'left' : position.x,
'top' : position.y,
'width' : width,
'height' : height,
"borderWidth": 0
},0.2,_config.easing,function(){
$(_config.layer).css('display','none');
_cache.isShow = false;
});
}); /*
* 键盘左右键触发 Esc键码27 键盘右移键39 左移键 37
*/
$(document).unbind('keydown').bind('keydown',function(e){
var keyCode = e.keyCode;
if(_cache.isShow) {
if(keyCode == 27) {
$(_config.closebtn).click();
}else if(keyCode == 37) {
if(_cache.currentImg == 0) {
return;
}
$("#maskLayer").css('display','block');
$(_config.prev).click();
}else if(keyCode == 39) {
if(_cache.currentImg == ($(_config.targetCls).length - 1)) {
return;
}
$("#maskLayer").css('display','block');
$(_config.next).click();
}
}
}); // 窗口缩放事件
$(window).resize(function(){
if(_cache.isShow){
if(self.isrun && $(self.isrun).is(":animated")) {
$(self.isrun).stop();
}
self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]);
}
});
});
},
/*
* 显示loading加载效果
* @method _showLoadMask()
* {private}
*/
_showLoadMask: function(){
var self = this,
_config = self.config,
_cache = self.cache;
var maskLayer = $('#maskLayer'),
left,
top;
// 有的话 不需要创建 否则的话 创建load图标层
if(maskLayer.length > 0) {
left = ($(window).width() - $(maskLayer).width()) / 2 + $(window).scrollLeft(),
top = ($(window).height() - $(maskLayer).height()) / 2 + $(window).scrollTop();
$(maskLayer).css({'left':left + 'px','top':top + 'px','display':'block'});
}else {
var mask = $("<div id='maskLayer' class='maskLayer'></div>");
// 加载loading图标
$(mask).html("<img src='http://img02.taobaocdn.com/tps/i2/T115PmXipeXXaY1rfd-32-32.gif'>");
$('body').append(mask);
maskLayer = $('#maskLayer');
left = ($(window).width() - $(maskLayer).width()) / 2 + $(window).scrollLeft(),
top = ($(window).height() - $(maskLayer).height()) / 2 + $(window).scrollTop();
$(maskLayer).css({'left':left + 'px','top':top + 'px','display':'block'});
}
},
/*
* 加载大图片
* @method _onLoad()
* @param {href,this} 当前的大图片的src 当前点击图片元素节点
*/
_onLoad: function(src,$this){
var self = this,
_config = self.config,
_cache = self.cache; // 创建img
var img = new Image(),
isIE = navigator.userAgent.match(/MSIE/)!= null; if(!isIE) {
img.onload = function() {
if(img.complete == true) { // 图片定位居中
self._getCenter(img,$this);
}
}
}else {
/*
* ie6,7,8
* readyState:complete 动态创建的 IMG 标记可以触发 onreadystatechange 事件
*/
img.onreadystatechange = function() { if(img.readyState == 'loaded' || img.readyState == 'complete') { // 图片定位居中
self._getCenter(img,$this);
}
}
}
img.src = src;
},
/*
* 层居中对齐
* @method _getCenter();
* @param {img,$this} 动态创建img 当前点击图片元素节点
*/
_getCenter: function(img,$this) { var self = this,
_config = self.config,
_cache = self.cache;
// 先隐藏load图标
$("#maskLayer") && $("#maskLayer").css('display','none');
var img_w = img.width,
img_h = img.height,
win_w = $(window).width(),
win_h = $(window).height(),
left = $(window).scrollLeft(),
top = $(window).scrollTop();
img_w = (img_w > win_w - 20) ? win_w - 20 : img_w;
var layer_left = (win_w - img_w)/2 + left,
layer_top = (win_h - img_h)/2 + top;
var position = self._getPos($this),
layer_width = $($this).width(),
layer_height = $($this).height();
var layer_img = $('img',_config.layer);
$(layer_img).attr('src','http://m2.img.papaapp.com/farm5/d/2014/0126/14/E6520E9D47F0FE8AB04B93BE922C6707_ORIG_1_1.gif');
$(layer_img).css({'width':img_w,'height':img_h});
$(layer_img).fadeOut(0.3); layer_left = layer_left < 0 ? 0 : layer_left;
layer_top = layer_top < 0 ? 0 : layer_top;
if(!_cache.isShow) {
$(_config.layer).css({
'width' : layer_width,
'height' : layer_height,
'left' : position.x,
'top' : position.y,
'display' : 'block'
});
_cache.isShow = true;
if(self.isrun && $(self.isrun).is(":animated")) {
$(self.isrun).stop();
}
self.isrun = $(_config.layer).animate({
'left' : layer_left,
'top' : layer_top,
'width' : img_w,
'height' : img_h,
"borderWidth": "10px"
}, 0.3,_config.easing,function(){
$(layer_img).attr('src',$(img).attr('src'));
$(layer_img).fadeIn(0.3);
});
}else {
if(self.isrun && $(self.isrun).is(":animated")) {
$(self.isrun).stop();
}
self.isrun = $(_config.layer).animate({
'left' : layer_left,
'top' : layer_top,
'width' : img_w,
'height' : img_h
}, 0.3,_config.easing,function(){
$(layer_img).attr('src',$(img).attr('src'));
$(layer_img).fadeIn(0.3);
});
}
}
}; // 初始化
$(function(){
new LightBox({});
});
总结:
春节前是最后一篇博客,嘿嘿!28号凌晨2点的火车,今天晚上动身回家了!呵呵!羡慕嫉妒恨吧!哈哈.....
JS图片灯箱(lightBox)效果基本原理和demo的更多相关文章
- js图片轮播效果实现代码
首先给大家看一看js图片轮播效果,如下图 具体思路: 一.页面加载.获取整个容器.所有放数字索引的li及放图片列表的ul.定义放定时器的变量.存放当前索引的变量index 二.添加定时器,每隔2秒钟i ...
- Jquery+ajax+json+servlet原理和Demo
Jquery+ajax+json+servlet原理和Demo 大致过程: 用户时间点击,触发js,设置$.ajax,开始请求.服务器响应,获取ajax传递的值,然后处理.以JSON格式返回给ajax ...
- js图片瀑布流效果
要实现图片瀑布流效果,首先得准备几张图片. html的部分比较简单就是将图片加载到浏览器就可以了 代码如下(注意放的图片多一点要不然之后无法滑动鼠标就无法达到瀑布流效果): <!DOCTYPE ...
- js鼠标移入移出效果【原】
<HTML> <HEAD> <!-- meta 解释 : http://www.haorooms.com/post/html_meta_ds --> <met ...
- js图片加载效果(延迟加载+瀑布流加载)
概述 两种图片加载的效果:一种是遇到图片较多时,带读条效果的加载提示:另一种是根据滑块的位置进行预加载,用户不察觉的情况下,实现瀑布流的加载效果 详细 代码下载:http://www.demodash ...
- js图片放大境效果
放大境效果如下图所示,当鼠标放到小图时,就会出现浅黄色的小块,而右边方框也出现了,并且右边方框的内容时根据浅黄色小块的内容变换而变换: 原理: 1,准备2张图,一大一小,如上图所示,小图的盒子div1 ...
- js图片跑马灯效果
<style. type="text/css">body{margin:0px auto; padding:0px;}ul,li{margin:0px; padding ...
- js 图片瀑布流效果实现
/** * Created by wwtliu on 14/9/5. */$(document).ready(function(){ $(window).on("load",fun ...
- js图片轮播效果常见的产品无缝轮播
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
随机推荐
- JavaScript--DOM操作表格及样式(21)
一 操作表格 // <table>标签是HTML中结构最为复杂的一个,我们可以通过DOM来创建生成它,或者HTMLDOM来操作它; // 使用DOM来创建表格; var table = d ...
- js 复制粘贴
input输入框<div id="top-title" style="position: relative"> <img class=&quo ...
- if语句格式及流程
if语句是条件判断功能 1. if 条件: if语句块 执行流程:判断条件是否为真. 如果真. 执行if语句块 2. if 条件: if语句块 else: else语句块 执行流程:判断条件是否为真. ...
- js-权威指南-Web套接字
HTTP是一种无状态的协议,,由客户端请求和服务端响应组成.HTTP实际上是比较特殊的网络协议. 大多数基于因特网的网络连接通常包含长连接和基于TCP套接字的双向消息交换.让不信任的客户端脚本访问底层 ...
- 原生css 中变量的使用
前两天看到阮大神的一篇在css中使用变量的文章,整理了一下. 这个重要的 CSS 新功能,所有主要浏览器已经都支持了.本文全面介绍如何使用它,你会发现原生 CSS 从此变得异常强大. 一.变量的声明 ...
- 数据库查询字段为null 时,返回0
oracle select nvl(字段名,0) from 表名; sqlserver select isnull(字段名,0) from 表名; mysql select ifnull(字段名,0) ...
- Application_Start 多次启动问题
最近在重构一个项目,在重构过程中出现了Application_Start 多次启动的问题,查询资料说是应用程序池内的修改会导致这个问题,后来发现确实如此 因为在重构过程中,我将数据库文件(sqlite ...
- 更改Outlook 2013中Exchange数据文件存放路径
昨天新入职目前所在的公司,在原公司一直都是直接使用Outlook设置用户名和密码后,然后将*.pst邮件的数据文件保存在其他盘符,以防止在更新操作系统时出现邮件丢失的情况:但是目前公司使用的是Exch ...
- Oracle 用户、角色管理简介
Oracle 用户.角色管理简介 by:授客 QQ:1033553122 创建用户 形式1:创建名为testacc2的用户 CREATE USER testacc2 IDENTIFIED BY abc ...
- 2018-10-17 22:20:39 c language
2018-10-17 22:20:39 c language C语言中的空白符 空格.制表符.换行符等统称为空白符,它们只用来占位,并没有实际的内容,也显示不出具体的字符. 制表符分为水平制表符和垂 ...