鍍金池/ 問答/HTML/ 在vue中關于鼠標滑動事件

在vue中關于鼠標滑動事件

如下圖,想要做一個鼠標在圖片滑動,網(wǎng)狀框跟隨鼠標一起移動。遇到了很奇怪的問題,圖1是正常的樣子,但是當我鼠標再次移動的時候,就變成了圖2。如果連續(xù)移動的話,網(wǎng)狀框就會閃動,說白了就是第1秒網(wǎng)狀框會跟著鼠標走,但是下一秒網(wǎng)狀框就會回到左上角。如圖3

圖1圖1

圖2圖2

網(wǎng)狀框和商品圖片都在一個div里,父級有的相對定位,網(wǎng)狀框子級用的絕對定位。而且就此我還打印了網(wǎng)狀框的left值,如圖3

圖3圖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>

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)
            }
    }
}

肯定是有哪個地方疏忽了,謝謝大家?guī)臀铱匆幌?,咱們一起學習進步

主要的問題已經(jīng)找到了,如果在最外層的div上面加上mousemove事件,那么就相當于在img和span上分別加了mousemove事件,他們就會根據(jù)鼠標在自己的元素上進行重新定位,從而導致了第一秒在這里,下一秒又在另一個地方的情況。

問題已經(jīng)解決,謝謝各位大神幫忙,我會嘗試另外幾種方法

回答
編輯回答
墨小羽

offsetXoffsetY是鼠標相對于事件源元素的X,Y坐標
(事件源:當前操作的那個元素就是事件源)

而此時在div中的還有imgspan,都會成為事件源,它就GG了,不知道以哪個為參考。

怎么辦~~!把@mousemove事件改為@mousemove.self,再把img刪掉(此時鼠標事件只針對div,不刪掉的話,鼠標移到img上不會觸發(fā)div的鼠標事件),然后就會發(fā)現(xiàn)“正?!绷?/p>

但是!這也是有缺陷的,當鼠標在遮罩上小幅度移動的時候,遮罩并不會跟著走,因為span(遮罩)也會阻止鼠標事件的觸發(fā)?。ù蠓纫苿拥臅r候鼠標接觸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'
    }

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

2017年8月24日 13:58
編輯回答
神經(jīng)質

e.offsetX 確定是相對于窗口的距離么?
應該是相對于鼠標位置元素上層父級定位為相對或絕對的元素距離 沒找到就相對于body
感覺你這offsetX在 相對于網(wǎng)狀框和相對于div盒子來回切換了 所以在變

2017年10月25日 23:20
編輯回答
避風港

修改后的表述有問題。mousemove 是冒泡的,所以相當于接收到不同 target 發(fā)送來的事件,所以當你使用 offsetX offsetY 這種跟元素相關的屬性,定位就會變化。于是,浮層就跑掉了,然后鼠標又回到原始圖片上面,定位恢復,浮層又回來。如此反復。

解決方案有兩個:

  1. 使用 MouseEvent.x 這種元素無關的屬性,配合 div.getBoundingClientRect() 計算位置
  2. 禁掉不想觸發(fā)事件的元素,比如 <span>,方法參考下面
span {
  pointer-events: none;
}

關于 pointer-events。

2018年9月17日 10:43
編輯回答
念舊

問題已經(jīng)解決,我的思路是再單拉出來一個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;
        }
    }
}
2017年5月24日 11:32