关于给悬浮框绝对定位后,设置了left,但是与悬浮框实际的left不一致问题

目的:写一个悬浮框,让这个悬浮框跟随鼠标移动

问题:当设置了left为鼠标位置clientX后,页面中实际的悬浮框left并不等于clientX,甚至随着鼠标往右移的时候,悬浮框与鼠标之间的距离越来越远。

首先,我们需要知道CSS中position的定义。

1.static: 默认值,静态定位,表示没有定位,元素会按照正常的位置显示,此时的left、top、bottom、right这四个定位属性不会被应用。

2. relative:相对定位,相对于元素的正常位置进行定位,此时可以通过left、top、bottom、right这四个定位属性来设置元素相对于正常位置的偏移量,在此过程中不会对其他元素造成影响。

3.absolute:绝对位置,相对于第一个非static定位的父级元素进行定位,可以通过left、top、bottom、right这四个定位属性来设置相对于父级元素位置的偏移量。如果没有满足条件的父级元素,则会相对于浏览器窗口来进行定位,使用绝对定位的元素无论如何滚动浏览器窗口,元素的位置都是不变的。(子绝父相)

4.fixed:固定定位,相对于浏览器的创建进行定位,可以使用left、top、bottom、right这四个定位属性来定义元素相对于浏览器窗口的位置。使用固定定位的元素无论如何滚动浏览器窗口,元素的位置都是固定不变的。

5.sticky:粘性定位,是relative和fixed的结合体,能够实现类似吸附的效果,当滚动页面时它的效果与relative相同,当要滚动到屏幕之外时则会自动变成fixed的效果。

 

想要实现的效果,设置一个悬浮框float-tip,让鼠标移动到card1内时显示,并且悬浮框跟随鼠标移动

修改前的代码:

<div>
    ...
    <div class="workShopMold" @mousemove="showTip($event)">
        <div class="card1">
            ...
        </div>
        <div class="float-tip" v-show="floatTipData.show" :style="floatTipData.style">
            ...
        </div>
    </div>
</div>    
data() {
   return {
      floatTipData: {
        show: false,
        text:'',
        style: {
            left:'',
            top:'',
        }
     }        
   }          
}       
methods: {
    showTip(e) {
//关键代码部分,具体显示悬浮框所需要满足的条件写在if中
        if(显示悬浮框的条件) {
            this.floatTipData.show = true
            let x = e.offsetX
            let y = e.offsetY
            let x2 = e.clientX
            let y2 = e.clientY
            let mouseOffsetX = 20
            let mouseOffsetY = 0
            let left = x2 + mouseOffsrtX  //用鼠标的位置+偏移量做left
            let top = y2 + mouseOffsetY
            this.floatTipData.style = {
                left: left + 'px',
                top: top + 'px'
            }
        } else {
             this.floatTipData.show = false
        }
    }      
}        

css:

.workShopMold{
    width: 915px;
    height: 322px;
    margin: 0 3px;
}

.float-tip {
    position: absolute;
    background-color: #0d1426;
    width: 147px;
    height: 101px;
    padding: 10px 0;
    border-radius: 8px;
}

修改后的代码:主要是css与method有一些变化

methods: {
    showTip(e) {
//关键代码部分
        if(显示悬浮框的条件) {
            this.floatTipData.show = true
            let x = e.offsetX
            let y = e.offsetY
            let mouseOffsetX = 20
            let mouseOffsetY = 0
            let left = x + mouseOffsrtX  //用鼠标的位置+偏移量做left
            let top = y + mouseOffsetY
            this.floatTipData.style = {
                left: left + 'px',
                top: top + 'px'
            }
        } else {
             this.floatTipData.show = false
        }
    }      
}        

区别在于x的值,修改前x是clientX,鼠标的坐标到页面左侧的位置,修改后我将x赋值为offsetX,鼠标坐标到元素左侧的位置。

修改后的css:

.workShopMold{
    position: relative;
    width: 915px;
    height: 322px;
    margin: 0 3px;
}

.float-tip {
    position: absolute;
    background-color: #0d1426;
    width: 147px;
    height: 101px;
    padding: 10px 0;
    border-radius: 8px;
}

为悬浮窗的父元素添加了position:relative。

要注意的是,要为card1添加悬浮窗,写悬浮窗的位置就不能包含在card1内。

虽然不知道修改前出现这个问题具体的原因是什么,但这么修改后还是解决了。

 

说到绝对位置,其中还涉及到了一个“包含块”的知识点。

什么是包含块?

一个元素的位置经常受包含块的影响,包含块就是里当前元素最近的祖先块元素

比如:

<div class="div1">
    <div class="div2"></div>
</div>

div1就是div2的包含块

当div2开启绝对定位,div1没有开相对定位时,那么div2便是相对于根元素html布局

比如为他们设置css,开启绝对定位的div2的left设置为50px,如果此时div1未开启相对定位,那么div2的left就是相对于html偏移了50px,如果div1设置了相对定位,那么div2就是相对于div1偏移了50px。总而言之,就是开启绝对定位的元素,他的偏移是取决于第一个非static定位的父级元素的。

 

posted on 2023-09-06 14:03  zy89898976  阅读(63)  评论(0编辑  收藏  举报