js原生--放大镜(基础版)

目录

正文部分

自用库引用部分 :


正文部分

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app"></div>
    <script src="/lianxi/JavaScript练习/自用库01.js"></script>
    <script>
        //将图片与元素直接写在页面中,通过css写样式
        //封装一个工具库插件,可以在不同页面中使用
        var app = document.getElementById('app');
        //使用插件//注:原生图片大小为400
        imageZoom(app, './图片/10.jpg', 400, 400);

        //将视图绘制出来
        function imageZoom(dom, url, width, height) {
            //创建图片的两种方式 : new Image () ; document.createElement('img')
            var mask = document.createElement('div');
            //放大的元素
            var big = document.createElement('div');
            //将元素放入app中
            app.appendChild(mask);
            app.appendChild(big);
            //设置样式
            css(app, {
                width: width + 'px',
                height: height + 'px',
                position: 'relative',
                backgroundImage: 'url(' + url + ')',
                backgroundSize: 'cover',
                // border: '1px solid red',
                // top: '20px',
                // left: '20px'
            })
            //遮罩层
            css(mask, {
                width: width / 2 + 'px',
                height: height / 2 + 'px',
                position: 'absolute',
                top: 0,
                left: 0,
                backgroundColor: 'yellow',
                opacity: 0.5,
                cursor: 'move',
                display: 'none'
            })
            //设置右侧放大器
            css(big, {
                width: width + 'px',
                height: height + 'px',
                position: 'absolute',
                top: 0,
                left: '100%',
                backgroundImage: 'url(' + url + ')',
                // border: '1px solid red',
                // display: 'none'
            })

            //函数体中局部的变量
            var x, y, top, left, maskWidth, maskHeight, domWidth, domHeight;
            //mask显隐效果交互
            //一个会触发冒泡,一个不会触发冒泡且只执行一次
            //鼠标移出mouseover(冒泡多次执行),mouseout   鼠标移入mouseenter,mouseleave
            // bindEvent(dom, 'mouseover', function (e) {
            //     console.log(e.target);
            // })
            var pos = offset(dom);
            function demo(e) {
                // //如果用mousemouve且位置获取为offset的话,(如果获取位置用client则无此问题)
                // //它会冒泡,即每次移动,mask都会复原到初始位置 ,所以需要阻止冒泡;
                //   e.stopPropagation();
                // //经测试,阻止冒泡后,仍mask会归位再移到指定位置,不是该原因,(该知识点?√×)
                // 鼠标位置的offset因为是在大盒子和mask中,它会获取这两个的位置,
                // 并都会执行,由于大盒子位置是固定的,所以mask会闪现到初始位置
                // 又因为获取了鼠标在mask中的位置,它会闪现到正确的位置
                //注意:由于使用client获取位置,获取的是页面中的位置
                //      而图片往往不在页面的左上角,会出现偏移量
                //      所以,需要对鼠标的位置校正,(即可以把图片位置减到左上角就行计算)
                //e.client - offset(dom)  offset为封装的函数(获取定位元素(的左上角)在页面中的位置)

                //鼠标的位置就是 mask 的位置(mask的中心点)
                //获取鼠标位置
                //
                var x = e.clientX - pos.left;
                var y = e.clientY - pos.top;
                // console.log(x, y);
                //将中心点位置换算到顶点位置,mask的基准位置就是左上角的顶点位置
                x -= width / 4;//x=x-w/4
                y -= height / 4;
                //边界处理
                if (x < 0) {
                    x = 0
                    //优化 } else if (x + width / 2 > width) {
                } else if (x > width / 2) {
                    //超出右边框
                    x = width / 2;
                }
                if (y < 0) {
                    y = 0
                } else if (y > height / 2) {
                    y = height / 2;
                }
                //设置样式
                css(mask, {
                    left: x + 'px',
                    top: y + 'px'
                })
                //设置大盒子图片的移动
                css(big, {
                    backgroundPositionX: x * -2 + 'px',
                    backgroundPositionY: y * -2 + 'px'
                })
            }
            bindEvent(dom, 'mouseenter', function (e) {
                // console.log(e.target);
                //显示遮罩层
                css(mask, 'display', 'block')
                css(big, 'display', 'block')
                //直接绑定鼠标移动事件
                bindEvent(dom, 'mousemove', demo)
            })
            bindEvent(dom, 'mouseleave', function (e) {
                // console.log(e.target);
                //显示遮罩层
                css(mask, 'display', 'none')
                css(big, 'display', 'none')
                //删除事件
                removeEvent(document, 'mousemove', demo)
            })
        }
    </script>
</body>

</html>

自用库引用部分 :

//bindEvent
// dom:元素  type:事件类型 fn:事件回调函数
//都在冒泡阶段触发

function bindEvent(dom, type, fn) {
    // 能力检测,判断方法是否存在,存在则使用,不存在则不使用
    if (dom.addEventListener) {
        //使用dom2级 绑定方式,都在冒泡阶段触发
        dom.addEventListener(type, fn)
    } else if (dom.attachEvent) {
        //在IE浏览器环境中绑定事件,需要是 on +事件
        dom.attachEvent('on' + type, function (e) {
            //兼任性
            e.target = e.srcElement;
            e.currentTarget = this;
            fn.call(dom, e)//此处dom更改this对象为dom
        })
    } else {
        // 缓存
        var oldFn = dom['on' + type];
        //最原始的 dom0级 
        dom['on' + type] = function (e) {
            //如果已经绑定过相同事件,则先执行缓存(已经绑定过的事件)
            oldFn && oldFn(e || window.event);
            //再执行新的
            fn(e || window.event);
        }
    }
}
//removeEvent(dom, eventName, demo)
// dom:对象;eventName事件名;demo函数
// 移除事件,封装
function removeEvent(dom, type, fn) {
    if (dom.detachEvent) {
        //IE
        dom.detachEvent("on" + type, function () {
            fn.call(dom)
        })//此处使用回调函数call(),让this指向dom 
    } else if (dom.removeEventListener) {
        //DOM2
        dom.removeEventListener(type, fn, false);
    } else {
        //dom0
        dom['on' + type] = null;
    }
}

//function offset(dom)//dom元素
//获取定位元素在页面中的位置
function offset(dom) {
    // console.log(dom.offsetParent, dom.offsetNode);
    //获取当前元素的定位值
    var result = {
        left: dom.offsetLeft,
        top: dom.offsetTop
    };
    // console.log(result);//{left: 300, top: 200}
    //依次遍历每一个元素的定位元素,直到body
    while (dom.offsetParent) {
        //获取当前元素的定位元素
        dom = dom.offsetParent;
        //累加结果
        //在高级浏览器下,dom.offsetLeft不包括边框
        // console.log(dom.offsetLeft, 111, result.left, 222, dom);
        result.left += dom.offsetLeft + dom.clientLeft;
        result.top += dom.offsetTop + dom.clientTop;
        //如果有兼任性问题,阔以适配
    }
    //返回结果
    return result;
}
//封装一个设置样式的方法
//两种用法:css(dom,width,'200px')
//         css(dom,{color:'red',width:'200px'})
function css(dom, key, value) {
    //判断 key 是对象or字符串
    if (typeof key === 'string') {
        //说明是第一种使用方式,设置样式;
        dom.style[key] = value;
    } else {
        //遍历每组样式
        for (var name in key) {
            //name表示属性名称,key[name]表示样式值
            css(dom, name, key[name])
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值