代码改变世界

原创JS图片放大效果(二) — 多图点击切换,鼠标移上放大

2012-04-25 11:58  VVG  阅读(11465)  评论(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;
})();