猿问

在vue中关于鼠标滑动事件

如下图,想要做一个鼠标在图片滑动,网状框跟随鼠标一起移动。遇到了很奇怪的问题,图1是正常的样子,但是当我鼠标再次移动的时候,就变成了图2。如果连续移动的话,网状框就会闪动,说白了就是第1秒网状框会跟着鼠标走,但是下一秒网状框就会回到左上角。如图3

https://img1.mukewang.com/5c9dbf710001a0d803170323.jpg

网状框和商品图片都在一个div里,父级有的相对定位,网状框子级用的绝对定位。而且就此我还打印了网状框的left值,如图3

https://img4.mukewang.com/5c9dbf7400012d9a02630302.jpg

下面是代码

模板

<div 

    class="goods_description_pic"

    @mouseenter="showcheckeddetailelement=true"

    @mouseleave="showcheckeddetailelement=false"

    @mousemove="checkeddetailproduct($event)">

    <img :src="productinformation.productimg">

    <span

        v-show="showcheckeddetailelement"

        @mouseenter="showcheckeddetailelement=true"

        class="goods_description_detailed_see"

        :style="{ left: followcheckedx+'px', top: followcheckedy+'px'}"></span>

</div>

js


export default{

    data(){

        return {

            followcheckedx: 0,

            followcheckedy: 0

        }

    },

    methods: {

        checkeddetailproduct (e){

            // offsetX是鼠标相对于窗口的距离

            // e.clientX - e.offsetX 标签距浏览器左端的距离

            this.followcheckedx = e.offsetX - 75;

            this.followcheckedy = e.offsetY - 75;

            if(this.followcheckedx>=150){

                this.followcheckedx=150;

            }

            if(this.followcheckedy>=150){

                this.followcheckedy=150;

            }

            if(this.followcheckedx<0){

                this.followcheckedx=0;

            }

            if(this.followcheckedy<0){

                this.followcheckedy=0;

            }

            console.log('left:' + this.followcheckedx)

            }

    }

}

肯定是有哪个地方疏忽了,谢谢大家帮我看一下,咱们一起学习进步


主要的问题已经找到了,如果在最外层的div上面加上mousemove事件,那么就相当于在img和span上分别加了mousemove事件,他们就会根据鼠标在自己的元素上进行重新定位,从而导致了第一秒在这里,下一秒又在另一个地方的情况。


问题已经解决,谢谢各位大神帮忙,我会尝试另外几种方法


守候你守候我
浏览 1799回答 4
4回答

萧十郎

e.offsetX 确定是相对于窗口的距离么?应该是相对于鼠标位置元素上层父级定位为相对或绝对的元素距离 没找到就相对于body感觉你这offsetX在 相对于网状框和相对于div盒子来回切换了 所以在变

森林海

offsetX,offsetY是鼠标相对于事件源元素的X,Y坐标(事件源:当前操作的那个元素就是事件源)而此时在div中的还有img和span,都会成为事件源,它就GG了,不知道以哪个为参考。怎么办~~!把@mousemove事件改为@mousemove.self,再把img删掉(此时鼠标事件只针对div,不删掉的话,鼠标移到img上不会触发div的鼠标事件),然后就会发现“正常”了但是!这也是有缺陷的,当鼠标在遮罩上小幅度移动的时候,遮罩并不会跟着走,因为span(遮罩)也会阻止鼠标事件的触发!(大幅度移动的时候鼠标接触div,span才会跟过去)所以~鼠标跟随移动还是使用下面这种方法吧,给你写了例子,仅供参考,边缘判断还需要你自己写一下哦,<div class='box'&nbsp; &nbsp; &nbsp;ref='box'&nbsp; &nbsp; &nbsp;@mousemove="handleMousemove">&nbsp; &nbsp; &nbsp;<img src="xxx" />&nbsp; &nbsp; &nbsp;<span class='mask'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:style="{left: isLeft, top: isTop}"></span></div>&nbsp; &nbsp; handleMousemove() {&nbsp; &nbsp; &nbsp; // 图片离body的距离&nbsp; &nbsp; &nbsp; const boxL = this.$refs.box.offsetLeft&nbsp; &nbsp; &nbsp; const boxT = this.$refs.box.offsetTop&nbsp; &nbsp; &nbsp; // 75为半透明遮罩高度(宽度)的一半(假设它为正方形)&nbsp; &nbsp; &nbsp; this.isLeft = event.clientX - boxL - 75 + 'px'&nbsp; &nbsp; &nbsp; this.isTop = event.clientY - boxT - 75 + 'px'&nbsp; &nbsp; }另外,希望你能知其然也知其所以然~(* ̄︶ ̄)

肥皂起泡泡

修改后的表述有问题。mousemove 是冒泡的,所以相当于接收到不同 target 发送来的事件,所以当你使用 offsetX offsetY 这种跟元素相关的属性,定位就会变化。于是,浮层就跑掉了,然后鼠标又回到原始图片上面,定位恢复,浮层又回来。如此反复。解决方案有两个:使用 MouseEvent.x 这种元素无关的属性,配合 div.getBoundingClientRect() 计算位置禁掉不想触发事件的元素,比如 <span>,方法参考下面span {&nbsp; pointer-events: none;}关于&nbsp;pointer-events。

青春有我

问题已经解决,我的思路是再单拉出来一个div,宽度和高度都与图片窗口div一样,鼠标移动事件在单拉出来的div上设置。代码如下模板<div&nbsp;&nbsp; &nbsp; class="goods_description_pic"&nbsp; &nbsp; @mouseenter="showcheckeddetailelement=true"&nbsp; &nbsp; @mouseleave="showcheckeddetailelement=false">&nbsp; &nbsp; <img&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; class="productimg"&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; :src="productinformation.productimg">&nbsp; &nbsp; &nbsp; &nbsp; <span&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v-show="showcheckeddetailelement"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @mouseenter="showcheckeddetailelement=true"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; class="goods_description_detailed_see"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :style="{ left: followcheckedx+'px', top: followcheckedy+'px'}"></span>&nbsp; &nbsp; &nbsp; &nbsp; <div&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; class="detial_see_wrap"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @mousemove="checkeddetailproduct($event)">&nbsp; &nbsp; &nbsp; &nbsp; </div></div>jsmethods: {&nbsp; &nbsp; checkeddetailproduct (e){&nbsp; &nbsp; &nbsp; &nbsp; this.followcheckedx = e.offsetX -75;&nbsp; &nbsp; &nbsp; &nbsp; this.followcheckedy = e.offsetY - 75;&nbsp; &nbsp; &nbsp; &nbsp; /* 边缘判断*/&nbsp; &nbsp; &nbsp; &nbsp; if(this.followcheckedx>=150){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.followcheckedx=150;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if(this.followcheckedy>=150){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.followcheckedy=150;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if(this.followcheckedx<0){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.followcheckedx=0;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if(this.followcheckedy<0){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.followcheckedy=0;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答