为了账号安全,请及时绑定邮箱和手机立即绑定

在vue中关于鼠标滑动事件

在vue中关于鼠标滑动事件

守候你守候我 2019-03-14 14:15:16
如下图,想要做一个鼠标在图片滑动,网状框跟随鼠标一起移动。遇到了很奇怪的问题,图1是正常的样子,但是当我鼠标再次移动的时候,就变成了图2。如果连续移动的话,网状框就会闪动,说白了就是第1秒网状框会跟着鼠标走,但是下一秒网状框就会回到左上角。如图3网状框和商品图片都在一个div里,父级有的相对定位,网状框子级用的绝对定位。而且就此我还打印了网状框的left值,如图3下面是代码模板<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>jsexport 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事件,他们就会根据鼠标在自己的元素上进行重新定位,从而导致了第一秒在这里,下一秒又在另一个地方的情况。问题已经解决,谢谢各位大神帮忙,我会尝试另外几种方法
查看完整描述

4 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

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

查看完整回答
反对 回复 2019-03-29
?
森林海

TA贡献2011条经验 获得超2个赞

offsetX,offsetY是鼠标相对于事件源元素的X,Y坐标

(事件源:当前操作的那个元素就是事件源)


而此时在div中的还有img和span,都会成为事件源,它就GG了,不知道以哪个为参考。


怎么办~~!把@mousemove事件改为@mousemove.self,再把img删掉(此时鼠标事件只针对div,不删掉的话,鼠标移到img上不会触发div的鼠标事件),然后就会发现“正常”了


但是!这也是有缺陷的,当鼠标在遮罩上小幅度移动的时候,遮罩并不会跟着走,因为span(遮罩)也会阻止鼠标事件的触发!(大幅度移动的时候鼠标接触div,span才会跟过去)


所以~鼠标跟随移动还是使用下面这种方法吧,给你写了例子,仅供参考,边缘判断还需要你自己写一下哦,


<div class='box'

     ref='box'

     @mousemove="handleMousemove">

     <img src="xxx" />

     <span class='mask'

           :style="{left: isLeft, top: isTop}"></span>

</div>

    handleMousemove() {

      // 图片离body的距离

      const boxL = this.$refs.box.offsetLeft

      const boxT = this.$refs.box.offsetTop

      // 75为半透明遮罩高度(宽度)的一半(假设它为正方形)

      this.isLeft = event.clientX - boxL - 75 + 'px'

      this.isTop = event.clientY - boxT - 75 + 'px'

    }

另外,希望你能知其然也知其所以然~(* ̄︶ ̄)


查看完整回答
反对 回复 2019-03-29
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

修改后的表述有问题。mousemove 是冒泡的,所以相当于接收到不同 target 发送来的事件,所以当你使用 offsetX offsetY 这种跟元素相关的属性,定位就会变化。于是,浮层就跑掉了,然后鼠标又回到原始图片上面,定位恢复,浮层又回来。如此反复。


解决方案有两个:


使用 MouseEvent.x 这种元素无关的属性,配合 div.getBoundingClientRect() 计算位置

禁掉不想触发事件的元素,比如 <span>,方法参考下面

span {

  pointer-events: none;

}

关于 pointer-events

查看完整回答
反对 回复 2019-03-29
?
青春有我

TA贡献1784条经验 获得超8个赞

问题已经解决,我的思路是再单拉出来一个div,宽度和高度都与图片窗口div一样,鼠标移动事件在单拉出来的div上设置。代码如下


模板


<div 

    class="goods_description_pic"

    @mouseenter="showcheckeddetailelement=true"

    @mouseleave="showcheckeddetailelement=false">

    <img 

        class="productimg" 

        :src="productinformation.productimg">

        <span

            v-show="showcheckeddetailelement"

            @mouseenter="showcheckeddetailelement=true"

            class="goods_description_detailed_see"

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

        <div 

            class="detial_see_wrap"

            @mousemove="checkeddetailproduct($event)">

        </div>

</div>

js


methods: {

    checkeddetailproduct (e){

        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;

        }

    }

}


查看完整回答
反对 回复 2019-03-29
  • 4 回答
  • 0 关注
  • 1798 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号