原创JS图片放大效果(二) — 多图点击切换,鼠标移上放大
2012-04-25 11:58 VVG 阅读(11463) 评论(27) 编辑 收藏 举报继 javascript 简单的图片放大效果(一) 之后,把这个效果完善了一下,支持多图轮流切换,如下:
本次采用代码封装到一个对象的模式,和第一次函数式写法不一下,这样更清晰,添加自定义属性更方便,全部代码如下:
大图的地址用自定义属性的方式显示在<img>标签如
<li><img src="images/small.jpg" width="70" height="70" zoom="images/big.jpg"></li>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>图片放大实例</title> <script type="text/javascript" src="js/vvgbase.1.0.js"></script> <style type="text/css"> * { margin: 0; padding: 0; } #zoomWarp { width: 1000px; margin: 20px auto; overflow: hidden; } #smallwarp { position: relative; border: 1px solid #000; width: 300px; height: 300px; float: left; overflow: hidden; } #minImg { float: left; display: inline; margin-right: 5px; } #minImg li { width: 70px; height: 70px; overflow: hidden; background: #ccc; margin-bottom: 5px; border: 1px solid #333; cursor: pointer; list-style: none; } #minImg li.lastChild { margin-bottom: 0; } </style> </head> <body> <iframe src="http://greencat.w211141.fxdns.cn/jsplay/ImgZoomTest.html"></iframe> <div id="zoomWarp"> <ul id="minImg"> <li><img src="images/small.jpg" width="70" height="70" zoom="images/big.jpg"></li> <li><img src="images/small1.jpg" width="70" height="70" zoom="images/big1.jpg"></li> <li><img src="images/small.jpg" width="70" height="70" zoom="images/big.jpg"></li> <li class="lastChild"><img src="images/small1.jpg" width="70" height="70" zoom="images/big1.jpg"></li> </ul> <div id="smallwarp"> <img src="images/small.jpg" id="smallImg" zoom="images/big.jpg"/> </div> </div> <script type="text/javascript"> var zoomImg = function () { return { init:function (warpId, options) { this.zoomWarp = VVG.$(warpId); //获取外层包裹层 var sWarp = options.smallWarp || 'smallwarp'; //小图包裹层ID var smallWarp = this.smallWarp = VVG.$(sWarp); //获取小图包裹层 this.targetImg = VVG.$$('img', smallWarp)[0]; //获取放大的目标图片对象 this.bigImgUrl = this.targetImg.getAttribute('zoom'); //从目标图片对象的自定义属性读取大图的URL this.bindMove(); this.bindMinImg(); }, createMask:function () { var mask = this.mask = document.createElement("div"); //创建MASK层 mask.id = "mask"; // 设置CSS VVG.setStyleById(mask, { "position":"absolute", "z-index":100, "display":"none", "width":"100px", "height":"100px", "background":"#999", "border":"1px solid #000", "cursor":"crosshair", "opacity":80, "left":0, "top":0 }); this.smallWarp.appendChild(mask); //添加MASK层 }, createBigDiv:function () { var bigDiv = this.bigDiv = document.createElement("div"); //创建大图显示层 bigDiv.id = "big"; VVG.setStyleById(bigDiv, { "float":"left", "border":"1px solid #000", "display":"none", "width":"300px", "height":"300px", "overflow":"hidden", "border-left":"none", "position":"relative", "z-index":"100" }); // 创建大图 var bigImg = this.bigImg = document.createElement('img'); bigImg.setAttribute('src', this.bigImgUrl); bigImg.id = 'bigImg'; bigImg.style.position = 'absolute'; bigDiv.appendChild(bigImg); this.zoomWarp.appendChild(bigDiv); //添加大图显示层 }, show:function () { // 显示悬浮遮罩层和放大图片层 this.mask.style.display = 'block'; this.bigDiv.style.display = 'block'; }, hidden:function () { //隐藏层 this.mask.style.display = 'none'; this.bigDiv.style.display = 'none'; }, zoomIng:function (event) { //开始放大 this.show(); //显示 event = VVG.getEvent(event); //获取事件 var target = this.mask; var maskW = target.offsetWidth; var maskH = target.offsetHeight; //console.log(maskW +':'+maskH); var sTop = document.documentElement.scrollTop || document.body.scrollTop; var mouseX = event.clientX; var mouseY = event.clientY + sTop; var smallX = this.smallWarp.offsetLeft; var smallY = this.smallWarp.offsetTop; var smallW = this.smallWarp.offsetWidth; var smallH = this.smallWarp.offsetHeight; //console.log('x=' + mouseX + ':y=' + mouseY + ':' + sTop + 'smallX:' + smallX); target.style.left = (mouseX - smallX - maskW / 2 ) + "px"; target.style.top = (mouseY - smallY - maskH / 2 ) + "px"; //显示位置计算 if ((mouseX - smallX) < maskW / 2) { target.style.left = "0px"; } else if ((mouseX - smallX) > (smallW - maskW + maskW / 2)) { target.style.left = (smallW - maskW ) + "px"; } if ((mouseY - smallY) < maskH / 2) { target.style.top = "0px"; } else if ((mouseY - smallY) > (smallH - maskH + maskH / 2)) { target.style.top = (smallH - maskH) + "px"; } this.showBig(parseInt(target.style.left), parseInt(target.style.top)); }, showBig:function (left, top) { left = Math.ceil(left * 3); top = Math.ceil(top * 3); this.bigImg.style.left = -left + "px"; this.bigImg.style.top = -top + "px"; }, bindMove:function () { this.createMask(); this.createBigDiv(); VVG.bindEvent(this.smallWarp, 'mousemove', VVG.bindFunction(this, this.zoomIng)); VVG.bindEvent(this.smallWarp, 'mouseout', VVG.bindFunction(this, this.hidden)); }, // 以下是左侧小图鼠标放上去后右侧显示相应的大图 bindMinImg:function () { var minImgUl = VVG.$('minImg'); //获取左侧的UL var minImgLis = VVG.$$('li', minImgUl); //获取左侧的li var thisObj = this; //this 赋值 for (var i = 0, n = minImgLis.length; i < n; i++) { var liImg = VVG.$$('img', minImgLis[i])[0]; var imgSrc = liImg.src; var bImgSrc = liImg.getAttribute('zoom'); //以下闭包传值imgSrc,与bImgSrc,并绑定左侧迷你图点击事件 VVG.bindEvent(liImg, 'click', function (t,f) { return function () { thisObj.changeImg.call(thisObj,t,f); //此处调用changeImg方法 } }(imgSrc,bImgSrc)); } }, changeImg:function (imgSrc, bImgSrc) { //改变右边的图片地址 this.targetImg.src = imgSrc; this.bigImg.setAttribute('src', bImgSrc); } } }(); zoomImg.init('zoomWarp', {}); </script> </body> </html>
VVG.base库代码:
View Code
/* * 简单JS库封装 By VVG * @namespace VVG * E-mail:mysheller@163.com QQ:83816819 */ if (!String.trim) { String.prototype.trim = function () { var reg = /^\s+|\s+$/g; return this.replace(reg, ''); } } (function () { // create namespace VVG if (!window.VVG) { window.VVG = {}; } function isCompatible(other) { // Use capability detection to check requirements if (other === false || !Array.prototype.push || !Object.hasOwnProperty || !document.createElement || !document.getElementsByTagName) { alert('你的浏览器不支持某些特性!'); return false; } return true; } window.VVG.isCompatible = isCompatible; // getElementById function function $() { var elements = new Array(); for (var i = 0; i < arguments.length; i++) { var element = arguments[i]; if (typeof element == 'string') { element = document.getElementById(element); } if (!element) { continue; } // 如果只有一个参数,则返回 if (arguments.length == 1) { return element; } // 多个参数的时候存为数组 elements.push(element); } // 返回数组 return elements; } window.VVG.$ = $; // 获取Parent父元素下标签名为child 的 Tags function $$(tag, parent) { parent = parent || document; return $(parent).getElementsByTagName(tag); } window.VVG.$$ = $$; // getElementsByClassName function $$$(str, parent, tag) { //父节点存在 if (parent) { parent = $(parent); } else { // 未传值时,父节点为body parent = document; } // tagContent为节点类型,未传值时为all节点 tag = tag || '*'; // 在父节点查找子节点,建立空数组arr var els = parent.getElementsByTagName(tag), arr = []; for (var i = 0, n = els.length; i < n; i++) { // 查找每个节点下的classname,以空格分离为一个k数组 for (var j = 0, k = els[i].className.split(' '), l = k.length; j < 1; j++) { // 当K数组中有一个值与str值相等时,记住这个标签并推入arr数组 if (k[j] == str) { arr.push(els[i]); break; } } } // 返回数组 return arr; } window.VVG.$$$ = $$$; window.VVG.getElementsByClassName = $$$; // Event事件绑定:绑定type事件到element元素,触发func函数 function bindEvent(element, type, func) { if (element.addEventListener) { element.addEventListener(type, func, false); //false 表示冒泡 } else if (element.attachEvent) { element.attachEvent('on' + type, func); } else { element['on' + type] = func; } } window.VVG.bindEvent = bindEvent; // 解除Event事件绑定 function unbindEvent(element, type, func) { if (element.removeEventListener) { element.removeEventListener(type, func, false); } else if (element.detachEvent) { element.detachEvent('on' + type, func); } else { element['on' + type] = null; } } window.VVG.unbindEvent = unbindEvent; // 获取事件 function getEvent(event) { return event || window.event; } window.VVG.getEvent = getEvent; // 获取事件目标 function getTarget(event) { return event.target || event.srcElement; } window.VVG.getTarget = getTarget; // 获取鼠标位于文档的坐标 function getMousePositionInPage(event) { event = getEvent(event); return { 'x':event.pageX || event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft), 'y':event.pageY || event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) } } window.VVG.getMousePositionInPage = getMousePositionInPage; // 停止事件冒泡 function stopPropagation(event) { if (event.stopPropagation) { event.stopPropagation(); } else { event.cancelBubble = true; } } window.VVG.stopPropagation = stopPropagation; // 阻止默认事件 function preventDefault(event) { if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } } window.VVG.preventDefault = preventDefault; // apply从新定义函数的执行环境 function bindFunction(obj, func) { return function () { return func.apply(obj, arguments); }; } window.VVG.bindFunction = bindFunction; // 设置透明度 function setOpacity(node, level) { node = $(node); if (document.all) { node.style.filter = 'alpha(opacity=' + level + ')'; } else { node.style.opacity = level / 100; } } window.VVG.setOpacity = setOpacity; // 获取可视窗口尺寸 function getWindowSize() { var de = document.documentElement; return { 'width':( window.innerWidth || (de && de.clientWidth) || document.body.clientWidth), 'height':( window.innerHeight || (de && de.clientHeight) || document.body.clientHeight) } } window.VVG.getWindowSize = getWindowSize; // 数字转化为千分位格式函数 function thousandsNumberFormat(str) { var n = str.length; var c = n % 3; var reg = /\d{3}(?!$)/g; if (n > 3) { var str1 = str.slice(0, c); var str2 = str.slice(c, n); str1 = str1 ? str1 + ',' : ''; str = str1 + str2.replace(reg, function (p1) { return p1 + ','; }) } return str; } window.VVG.thousandsNumberFormat = thousandsNumberFormat; // 带横杠的字符形式转化为驼峰式命名 function camelize(string) { return string.replace(/-(\w)/g, function (strMatch, p1) { return p1.toUpperCase(); }); } window.VVG.camelize = camelize; // 驼峰式转化为横杠分隔 function uncamelize(string, sep) { sep = sep || '-'; return string.replace(/([a-z])([A-Z])/g, function (strMatch, p1, p2) { return p1 + sep + p2.toLowerCase(); }); } window.VVG.uncamelize = uncamelize; // 设置根据ID设置样式 function setStyleById(element, cssjson) { element = $(element); for (property in cssjson) { if (!cssjson.hasOwnProperty(property)) continue; if (property == 'opacity') { setOpacity(element, cssjson[property]); } else { element.style[camelize(property)] = cssjson[property]; } } } window.VVG.setStyleById = setStyleById; window.VVG.setStyle = setStyleById; // 根据Class类设置样式 function setStyleByClassName(classname, cssjson, parent, tag) { var elements = $$$(classname, parent, tag); for (i = 0, n = elements.length; i < n; i++) { setStyleById(elements[i], cssjson); } } window.VVG.setStyleByClassName = setStyleByClassName; // 根据HTML标签TAG设置样式 function setStyleByTagName(tag, cssjson, parent) { var tags = $$(tag, parent); for (var i = 0; i < tags.length; i++) { setStyleById(tags[i], cssjson); } } window.VVG.setStyleByTagName = setStyleByTagName; // 获取Element元素的className function getClassNames(element) { if (!(element = $(element))) return false; return element.className.replace(/\s+/g, ' ').split(' '); } window.VVG.getClassNames = getClassNames; // 查找element元素是否含有class function hasClassName(element, classname) { if (!(element = $(element))) return false; var classNames = getClassNames(element); for (var i = 0; i < classNames.length; i++) { if (classNames[i] === classname) return true; } return false; } window.VVG.hasClassName = hasClassName; // 增加class function addClassName(element, classname) { if (!(element = $(element))) return false; element.className += (element.className ? ' ' : '') + classname; } window.VVG.addClassName = addClassName; // 删除其中一个className function removeClassName(element, classname) { if (!(element = $(element))) return false; if (hasClassName(element, classname)) { var classtexts = getClassNames(element); for (var i = 0; i < classtexts.length; i++) { if (classtexts[i] == classname) { delete(classtexts[i]); } } element.className = classtexts.join(' '); } } window.VVG.removeClassName = removeClassName; // 增加一个外部链接CSS function addStyleSheet(url, media) { media = media || 'screen'; var link = document.createElement('LINK'); link.setAttribute('rel', 'stylesheet'); link.setAttribute('type', 'text/css'); link.setAttribute('href', url); link.setAttribute('media', media); document.getElementsByTagName('head')[0].appendChild(link); } window.VVG.addStyleSheet = addStyleSheet; // 删除一个外部链接CSS function removeStyleSheet(url) { var stylesheets = document.getElementsByTagName('link'); for (var i = 0; i < stylesheets.length; i++) { if (!(stylesheets[i].href.indexOf(url) == -1)) { stylesheets[i].parentNode.removeChild(stylesheets[i]); return true; } } return false; } window.VVG.removeStyleSheet = removeStyleSheet; // COOKIE 操作 function getCookie(name) { var start = document.cookie.indexOf(name + "="); var len = start + name.length + 1; if ((!start) && (name != document.cookie.substring(0, name.length))) { return null; } if (start == -1) return null; var end = document.cookie.indexOf(";", len); if (end == -1) end = document.cookie.length; return unescape(document.cookie.substring(len, end)); } window.VVG.getCookie = getCookie; function setCookie(name, value, expires, path, domain, secure) { var today = new Date(); today.setTime(today.getTime()); if (expires) { expires = expires * 1000 * 60 * 60 * 24; } var expires_date = new Date(today.getTime() + (expires)); document.cookie = name + "=" + escape(value) + ((expires) ? ";expires=" + expires_date.toGMTString() : "") + ((path) ? ";path=" + path : "") + ((domain) ? ";domain=" + domain : "") + ((secure) ? ";secure" : ""); } window.VVG.setCookie = setCookie; function deleteCookie(name, path, domain) { if (getCookie(name)) document.cookie = name + "=" + ((path) ? ";path=" + path : "") + ((domain) ? ";domain=" + domain : "") + ";expires=Thu, 01-Jan-1970 00:00:01 GMT"; } window.VVG.deleteCookie = deleteCookie; // ajax对象操作 // 安全过滤JSON的函数parseJSON function parseJSON(s, filter) { var j; function walk(k, v) { var i; if (v && typeof v === 'object') { for (i in v) { if (v.hasOwnProperty(i)) { v[i] = walk(i, v[i]); } } } return filter(k, v); } if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(s)) { try { j = eval('(' + s + ')'); } catch (e) { throw new SyntaxError("parseJSON"); } } else { throw new SyntaxError("parseJSON"); } if (typeof filter === 'function') { j = walk('', j); } return j; } // 创建一个XMLHttpRequest对象 function getRequestObject(url, options) { var req = false; if (window.XMLHttpRequest) { req = new window.XMLHttpRequest(); } else if (window.ActiveXObject) { req = new window.ActiveXObject('Microsoft.XMLHTTP'); } if (!req) return false; // 设置默认数据 options = options || {}; options.method = options.method || 'GET'; options.send = options.send || null; // 定义事件侦听函数 req.onreadystatechange = function () { switch (req.readyState) { case 1: // 正在载入 if (options.loadListener) { options.loadListener.apply(req, arguments); } break; case 2: // 载入完成 if (options.loadedListener) { options.loadedListener.apply(req, arguments); } break; case 3: // 正在交互 if (options.ineractiveListener) { options.ineractiveListener.apply(req, arguments); } break; case 4: // 交互完成 try { if (req.status && req.status == 200) { // 获取文件格式 // 为不同的content-type设置对应的方法 var contentType = req.getResponseHeader('Content-Type'); var mimeType = contentType.match(/\s*([^;]+)\s*(;|$)/i)[1]; switch (mimeType) { case 'text/plain': if (options.txtResponseListener) { options.txtResponseListener.call(req, req.responseText); } break; case 'text/javascript': case 'application/javascript': if (options.jsResponseListener) { options.jsResponseListener.call(req, req.responseText); } break; case 'application/json': if (options.jsonResponseListener) { try { var json = parseJSON(req.responseText); } catch (e) { json = false; } options.jsonResponseListener.call(req, json); } break; case 'text/xml': case 'application/xml': case 'application/xhtml+xml': if (options.xmlResponseListener) { options.xmlResponseListener.call(req, req.responseXML); } break; case 'text/html': if (options.htmlResponseListener) { options.htmlResponseListener.call(req, req.responseText); } break; } if (options.completeListener) { options.completeListener.apply(req, arguments); } } else { if (options.errorListener) { options.errorListener.apply(req, arguments); } } } catch (e) { //ignore errors //alert('Response Error: ' + e); } break; } }; // Open the request req.open(options.method, url, true); // 添加一个header识别标记 req.setRequestHeader('VVG-Base-Ajax-Request', 'AjaxRequest'); return req; } window.VVG.getRequestObject = getRequestObject; // 简易包装send方法与发送XMLHttpRequest请求 function ajaxRequest(url, options) { var req = getRequestObject(url, options); return req.send(options.send); } window.VVG.ajaxRequest = ajaxRequest; })();
转载请注明出处:http://www.cnblogs.com/NNUF/