三大家族易忘点和案例

pageX、clientX、screenX的区别


offset

offsetTop/offsetLeft

返回距离上级盒子(最近的带有定位)左边的位置,如果没有父亲或者父亲没有定位则以 body 为准

图一:父盒子没有开启定位

图二:父盒子开启定位


offsetWidth/offsetHeight

偏移量 = padding + border +width(height)


案例

计算鼠标在盒子中的位置

参考代码

1.首先得到鼠标在页面中的坐标(e.pageX, e.pageY)
2.其次得到盒子在页面中的距离(box.offsetLeft, box.offsetTop)
3.用鼠标距离页面的坐标减去盒子在页面中的距离, 得到 鼠标在盒子内的坐标

拖拽

参考代码
移动端拖拽

过程:鼠标在移动的过程中不断将最新的值赋值为盒子
思路:

  1. 先获取鼠标按下时距离盒子的距离x,y【鼠标与盒子的位置x,y是不会发生变化的,只是盒子的位置与页面发生变化】
var x = e.pageX - box.offsetLeft;
var y = e.pageY - box.offsetTop;
  1. 鼠标点击title之后需要给title绑定事件(鼠标移动和鼠标抬起事件)
title.addEventListener('mousedown', function(e) {
    // (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
    document.addEventListener('mousemove', function(){})

    // (3) 鼠标弹起,就让鼠标移动事件移除
    document.addEventListener('mouseup', function() {
        document.removeEventListener('mousemove', function(){});
    })
})
  1. 模态框box需要开启定位position才能设置盒子距离页面的距离
box.style.left = e.pageX - x + 'px';
box.style.top = e.pageY - y + 'px';

mouseenter 和 mouseover 的区别
mouseover 鼠标经过自身盒子会触发事件,经过子盒子还会触发事件;
mouseenter 只有经过自身盒子会触发事件,因为不会冒泡;
mouseenter 与 mouseleave 一样,都是不会冒泡

放大镜

参考视频
参考代码

思路:

  1. 鼠标移入box区域内mask显示和隐藏;
  2. 计算鼠标在box的坐标x,y;
var x = e.pageX - this.offsetLeft
var y = e.pageY - this.offsetTop;
  1. 调整mask中鼠标的位置位于中心,即将鼠标的值x,y减去mask高度和宽度的一半然后赋值给mask,maskX代表mask在box的左侧距离,maskY代表mask在box的上方距离
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
  1. 判断临界值,mask不能在box外移动
    移动最小值: 0
    移动最大值:box.offsetWidth(offsetHeight) - mask.offsetWidth(offsetHeight)

因为box和mask是正方形:box.offsetWidth - mask.offsetWidth = box.offsetHeight - mask.offsetHeight
所以将这两个值设置一个即可:maskMax = preview_img.offsetWidth - mask.offsetWidth

要设置left和top必须开启定位

if (maskX <= 0) {
    maskX = 0;
} else if (maskX >= maskMax ) { // maskMax = box.offsetWidth - mask.offsetWidth
    maskX = maskMax;
}
if (maskY <= 0) {
    maskY = 0;
} else if (maskY >= maskMax) { //maskMax = box.offsetHeight - mask.offsetHeight
    maskY = maskMax;
}
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
  1. 按比例移动大图

计算大图移动距离 => 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
遮挡层移动距离:maskX
大图片最大移动距离(大图比大盒子大):bigIMg.offsetWidth - big_box.offsetWidth
遮挡层的最大移动距离:maskMax

// 大图片的移动距离 X Y
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
  1. mask向左移动,而bigImg需要向右移动,设置的值应为负数,

要设置left和top必须开启定位

bigIMg.style.left = -bigX + 'px';
bigIMg.style.top = -bigY + 'px';

client

与offset区别【偏移量不包含border】
偏移量clientWidth = padding + width(height)


scroll

scrollHeight:内容的高度【不包含边框border】
scrollTop:被卷去的内容高度

scroll滚动事件当我们滚动条发生变化会触发的事件

注:元素被卷去的高度:scrollTop;页面被卷去的高度:pageYOffset
pageYOffset存在兼容性写法
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;

参考代码

案例

淘宝右侧导航条

参考代码

实现思路:

  1. 当 window.pageYOffset >= bannerTop 时,右侧的slidebar变为固定定位,同时需要获取slidebar距离顶部的距离sliderbarTop = sliderbar.offsetTop - bannerTop,修改slidebar的top值【要开启定位才能设置top】
  2. 当 window.pageYOffset >= mainTop 时,出现 backTop
  3. 点击 backTop, 回答文档中的特定位置 window.scroll(0, 0),里面的x和y 不跟单位的 直接写数字即可【不添加滑动前面三步就能解决】
  4. 添加滚动动画,与页面滚动距离pageYOffset有关,封装滑动的函数【添加滑动效果】
function animate(obj, target, callback) {
    // 先清除以前的定时器,只保留当前的一个定时器执行
    clearInterval(obj.timer);
    obj.timer = setInterval(function() {
        // 步长值写到定时器的里面
        var step = (target - window.pageYOffset) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (window.pageYOffset == target) {
            // 停止动画 本质是停止定时器
            clearInterval(obj.timer);
            callback && callback();
        }
        // 把每次加1 这个步长值改为一个慢慢变小的值  步长公式:(目标值 - 现在的位置) / 10
        window.scroll(0, window.pageYOffset + step);
    }, 15);
}
  1. 调用函数添加滑动效果
goBack.addEventListener('click', function() {
    // 因为是窗口滚动 所以对象是window
    animate(window, 0);
});

效果图


导航栏滑动动画

参考代码

思路:

  1. 给所有的小li绑定事件
  2. 鼠标经过li, 把当前 小li 的位置做为目标值,即获取当前li的offsetLeft =>this.offsetLeft
  3. 鼠标离开就回到0 offsetLeft = 0
  4. 鼠标点击某个li的时候,用变量current = 0 记录当前li的offsetLeft, 并将其赋值给变量current = this.offsetLeft
  5. 鼠标离开就回到起始的位置 ,修改 3 中的 offsetLeft = current


三大家族区别


三大家族主要用法

offset:用于获取元素位置 offsetLeft offsetTop
client:用于获取元素大小 clientWidth clientHeight
scroll:用于获取滚动距离 scrollTop scrollLeft

页面滚动高度 var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;

posted @ 2020-06-21 15:41  yx1102  阅读(186)  评论(0编辑  收藏  举报