Web API(五)元素偏移量和立即函数
一、元素偏移量 offset系列
1、概念
offset 翻译过来就是偏移量,可以动态的得到该元素的位置(偏移)、大小等。
- 获得元素距离带有定位父元素的位置
- 获得元素自身的大小(宽度高度)
- 注意:返回的数值都不带单位
2、offset 与 style 区别
- offsetWidth 返回元素应用的布局宽度(padding+border+width),style.width 返回元素内联样式的宽度属性值(不包含padding和border 的值)
2. offsetWidth 返回的是一个数值, style.width 返回的是字符串,带有单位
3. offset 是只读属性,style 是可读写的
总结:offset 是用来获取元素大小和位置,style 主要用来设置元素大小和位置
3、模态框案例:
// 1. 获取元素
var login = document.querySelector('.login');
var mask = document.querySelector('.login-bg');
var link = document.querySelector('#link');
var closeBtn = document.querySelector('#closeBtn');
var title = document.querySelector('#title');
// 2. 点击弹出层这个链接 link 让mask 和login 显示出来
link.addEventListener('click', function() {
mask.style.display = 'block';
login.style.display = 'block';
})
// 3. 点击 closeBtn 就隐藏 mask 和 login
closeBtn.addEventListener('click', function() {
mask.style.display = 'none';
login.style.display = 'none';
})
// 4. 开始拖拽
// (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
title.addEventListener('mousedown', function(e) {
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
// (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
document.addEventListener('mousemove', move)
function move(e) {
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
}
// (3) 鼠标弹起,就让鼠标移动事件移除
document.addEventListener('mouseup', function() {
document.removeEventListener('mousemove', move);
})
})
4、案例:京东放大镜
window.addEventListener('load', function() {
var preview_img = document.querySelector('.preview_img');
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
// 1. 当我们鼠标经过 preview_img 就显示和隐藏 mask 遮挡层 和 big 大盒子
preview_img.addEventListener('mouseover', function() {
mask.style.display = 'block';
big.style.display = 'block';
})
preview_img.addEventListener('mouseout', function() {
mask.style.display = 'none';
big.style.display = 'none';
})
// 2. 鼠标移动的时候,让黄色的盒子跟着鼠标来走
preview_img.addEventListener('mousemove', function(e) {
// (1). 先计算出鼠标在盒子内的坐标
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
// console.log(x, y);
// (2) 减去盒子高度 300的一半 是 150 就是我们mask 的最终 left 和top值了
// (3) 我们mask 移动的距离
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
// (4) 如果x 坐标小于了0 就让他停在0 的位置
// 遮挡层的最大移动距离
var maskMax = preview_img.offsetWidth - mask.offsetWidth;
if (maskX <= 0) {
maskX = 0;
} else if (maskX >= maskMax) {
maskX = maskMax;
}
if (maskY <= 0) {
maskY = 0;
} else if (maskY >= maskMax) {
maskY = maskMax;
}
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
// 3. 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
// 大图
var bigIMg = document.querySelector('.bigImg');
// 大图片最大移动距离
var bigMax = bigIMg.offsetWidth - big.offsetWidth;
// 大图片的移动距离 X Y
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
bigIMg.style.left = -bigX + 'px';
bigIMg.style.top = -bigY + 'px';
})
})
二、元素可视区 client 系列
1、client概述
client 翻译过来就是客户端,通过 client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。
var box = document.querySelector('.box');
// 获取元素的宽度(包括padding 不包括 border)
console.log(box.clientWidth);
// 获取元素的高度(包括padding 不包括 border)
console.log(box.clientHeight);
// 获取元素左边框的大小
console.log(box.clientLeft);
// 获取元素右边框的大小
console.log(box.offsetWidth - box.clientWidth - box.clientLeft);
三、元素滚动scroll系列
1、scroll 概述
2、scroll 事件
页面滚动条发生变化触发的事件
window.pageYOffset 返回整个页面滚动的距离
四、立即执行函数
1、立即执行函数的概念
不需要手动进行调用,直接执行的函数。
2、两种立即执行函数的写法
(1)!(function () {})(传入的参数)
(2)!(function () {}(传入的参数))
!起到分割符作用,相当于;号,如果保持写;习惯可以不写
五、三大系列总结
他们主要用法:
1.offset系列 经常用于获得元素位置 offsetLeft offsetTop
2.client经常用于获取元素大小 clientWidth clientHeight
3.scroll 经常用于获取滚动距离 scrollTop scrollLeft
4.注意页面滚动的距离通过 window.pageXOffset 获得
六、mouseenter 和mouseover的区别
- mouseover 鼠标经过事件 (存在事件冒泡)
- mouserout 鼠标离开事件 (存在事件冒泡)
- mouseenter 鼠标经过事件 (不存在事件冒泡)
- mouseleave 鼠标离开事件 (不存在事件冒泡)
七、动画函数封装
1、原理
实现步骤:
- 获得盒子当前位置
- 让盒子在当前位置加上1个移动距离
- 利用定时器不断重复这个操作
- 加一个结束定时器的条件
- 注意此元素需要添加定位,才能使用element.style.left
2、动画函数给不同元素记录不同定时器
function animate(obj, target) {
// 当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
// 解决方案就是 让我们元素只有一个定时器执行
// 先清除以前的定时器,只保留当前的一个定时器执行
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if (obj.offsetLeft >= target) {
// 停止动画 本质是停止定时器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}