js-鼠标事件-放大镜效果

js-鼠标事件-放大镜效果

js-鼠标事件-放大镜效果_第1张图片
事前准备
在这里插入图片描述
两张长宽比1:2的图

css部分
1.外部一个大盒子
2.里面有两个等宽高的小盒子(小盒子宽高跟小图片一样大) 分别装两个图片,且分别浮动在左右两侧
3.给装大图片的小盒子一个overflow:hidden,且给大图片定位在小盒子的左上角,为什么要定位,后面会讲到。
4.再向装小图片的小盒子中定位一个b标记(代表放大镜的位置)暂时定位到左上角

<style>
    *{margin:0;padding: 0}
    #box{
        width:1200px;
        height: 700px;
        border:1px solid #ccc;
        margin:150px;
    }
    #min{
        float:left;
        width:400px;
        height: 400px;
        position: relative;
    }
    b{
        position: absolute;
        left:0;
        top:0;
        width:200px;
        height: 200px;
        background: blue;
        opacity: 0.5;
        display: none;
    }
    #max{
        float:right;
        width:400px;
        height: 400px;
        overflow: hidden;
        display: none;
        position: relative;
    }
    #imgs{
        position: absolute;
        left:0;
        top:0;
        
    }
</style>

html部分

<body>

<div id="box">

    <div id="min"><img src="imgs/min.jpg" alt=""><b></b></div>
    <div id="max"><img src="imgs/max.jpg" alt="" id="imgs"></div>

</div>

<script src="script.js"></script>

</body>

js部分
1.鼠标经过左边小图片,b阴影标记和大图片显示,鼠标脱离左边小图片,b阴影标记和大图片隐藏。

var min = document.querySelector('#min');
var max = document.querySelector('#max');
var b = document.querySelector('b');

min.onmousemove = function() {
    max.style.display = 'block';
    b.style.display = 'block';

}

min.onmouseout = function() {
    max.style.display = 'none';
    b.style.display = 'none'
}

这里为什么不用onmouseover而用onmousemove会在后面说

2.b阴影标记跟鼠标一起走,且鼠标一直在b阴影标记中间

min.onmousemove = function(e) {
    max.style.display = 'block';
    b.style.display = 'block';
    var x = e.clientX - min.offsetLeft ;
    var y = e.clientY - min.offsetTop ;
    b.style.left = x + 'px';
    b.style.top = y + 'px'
//注意这里的x是b标记绝对定位在左边小盒子的 而不是整个页面
}

js-鼠标事件-放大镜效果_第2张图片
但此时发现鼠标不在b阴影标记的中间,我们只需x,y在减去b阴影标记自身盒子的一半即可

min.onmousemove = function(e) {
    max.style.display = 'block';
    b.style.display = 'block';
    var x = e.clientX - min.offsetLeft - b.offsetWidth / 2;
    var y = e.clientY - min.offsetTop - b.offsetHeight / 2;
    b.style.left = x + 'px';
    b.style.top = y + 'px'

}

到这还有一个问题,会发现b阴影标记在边框位置会溢出
js-鼠标事件-放大镜效果_第3张图片
我们要进行限制:

var x = e.clientX - min.offsetLeft - b.offsetWidth / 2;
    var y = e.clientY - min.offsetTop - b.offsetHeight / 2;
    if (x > min.offsetWidth - b.offsetLeft) {
        x = min.offsetWidth - b.offsetLeft
    } else if (x < 0) {
        x = 0
    };
    if (y > min.offsetHeight - b.offsetTop) {
        y = min.offsetHeight - b.offsetTop
    } else if (y < 0) {
        y = 0
    };
    b.style.left = x + 'px';
    b.style.top = y + 'px'

3.大图片随着鼠标放大镜经行移动:这就是我们对刚开始对大图片进行定位的原因,然后我们发现放大镜从左向右移动时,大图片从右向左移动,两者正好相反,又因为大图片比例是小图片的两倍,所以移动距离应该也为两倍。代码如下:

    b.style.left = x + 'px';
    b.style.top = y + 'px'
    imgs.style.left = -2 * x + 'px';
    imgs.style.top = -2 * y + 'px'
}

4.解决bug:
会有一个小bug 当页面内容过多,滚动页面行动条时,鼠标移出小图片再移入会发生bug。

原因如下:
e.clientY 指的是当前位置于当前页面的距离,注意,不是整个网页的距离,当页面滚动是,e.clientY会发生变化,当e.clientY

解决方法
利用滚动距离和e.clientY相结合的方法:

 var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    var x = e.clientX+scrollLeft-min.offsetLeft- b.offsetWidth/2;
    var y = e.clientY+scrollTop-min.offsetTop - b.offsetHeight/2;
 var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;

此处为解决兼容问题

js部分整体代码如下:

var min = document.querySelector('#min');
var max = document.querySelector('#max');
var b = document.querySelector('b');
var imgs = document.querySelector('#imgs')

min.onmousemove = function(e) {
    max.style.display = 'block';
    b.style.display = 'block';
    var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    var x = e.clientX + scrollLeft - min.offsetLeft - b.offsetWidth / 2;
    var y = e.clientY + scrollTop - min.offsetTop - b.offsetHeight / 2;
    if (x > min.offsetWidth - b.offsetLeft) {
        x = min.offsetWidth - b.offsetLeft
    } else if (x < 0) {
        x = 0
    };
    if (y > min.offsetHeight - b.offsetTop) {
        y = min.offsetHeight - b.offsetTop
    } else if (y < 0) {
        y = 0
    };
    b.style.left = x + 'px';
    b.style.top = y + 'px'
    imgs.style.left = -2 * x + 'px';
    imgs.style.top = -2 * y + 'px'
}

min.onmouseout = function() {
    max.style.display = 'none';
    b.style.display = 'none'
}

-----------------------------------------------------------------------------------------------------

做这道案例时遇到的问题:
1.为什么用onmousemove而不是onmouseover
因为
时间上 onmousemove 事件触发后,再触发 onmouseover 事件。

按钮上 不区分鼠标按钮。

动作上 onmouseover 只在刚进入区域时触发。onmousemove 除了刚进入区域触发外,在区域内移动鼠标,也会触发该事件。

在动作上的区别可知,我们必须用onmousemove

2.offsetWidth和style.width的区别

①、offsetWidth > width
element.offsetWidth = element.style.width + element.style.padding + element.style.border;(不包括margin)

②、offsetWidth 属性仅仅可读,而style.width 是可写的;
所以通常用 style.width用作进JavaScript中设置元素的宽度,而offsetWidth不可以。

③、offsetWidth 属性返回值是整数,如果实际值是小数,会根据实际值进行四舍五入操作,返回处理后的整数。width=44.499px;输出结果为49;
width=44.5px;输出结果为45;
而style.width的返回值是字符串,并且带有单位
width=44.499px;输出结果为44.499px;

④、style.width仅仅能返回以style方式定义的内部样式表的width属性值。
因此样式写在行内的时候,在这里插入图片描述
用style.width或者offsetWidth都可以获取元素的宽度;
如果写在css样式表中的时候,.box{width:100px;},此时只能用offsetWidth来获取元素的宽度,而style.width所返回的值为空。

你可能感兴趣的:(#,js-事件案例)