offset 翻译过来就是偏移量, 我们使用 offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
-
获得元素距离带有定位父元素的位置
-
获得元素自身的大小(宽度高度)
-
注意:返回的数值都不带单位
常用属性
| 偏移量 offset 属性 | 作用 |
|---|---|
| element.offsetParent | 返回作为该元素带有定位的父级元素,如果父级都没有定位则返回body |
| element.offsetTop | 返回元素相对带有定位父元素上方的偏移 |
| element.offsetLeft | 返回元素相对带有定位父元素左边的偏移 |
| element.offsetWidth | 返回自身包括padding 、边框、内容区的宽度,返回数值不带单位 |
| element.offsetHeight | 返回自身包括padding 、边框、内容区的高度,返回数值不带单位 |
-
offset 可以得到任意样式表中的样式值
-
offset 系列获得的数值是没有单位的
-
offsetWidth 包含padding+border+width
-
offsetWidth 等属性是只读属性,只能获取不能赋值
-
所以,我们想要获取元素大小位置,用offset更合适
-
style 只能得到行内样式表中的样式值
-
style.width 获得的是带有单位的字符串
-
style.width 获得不包含padding和border 的值
-
style.width 是可读写属性,可以获取也可以赋值
-
所以,我们想要给元素更改值,则需要用style改变
- 我们在盒子内点击,想要得到鼠标距离盒子左右的距离。
- 首先得到鼠标在页面中的坐标(e.pageX, e.pageY)
- 其次得到盒子在页面中的距离 ( box.offsetLeft, box.offsetTop)
- 用鼠标距离页面的坐标减去盒子在页面中的距离,得到 鼠标在盒子内的坐标
- 如果想要移动一下鼠标,就要获取最新的坐标,使用鼠标移动
Document
案例:模态框拖拽
弹出框,我们也称为模态框。
1.点击弹出层,会弹出模态框, 并且显示灰色半透明的遮挡层。
2.点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层。
3.鼠标放到模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动。
4.鼠标松开,可以停止拖动模态框移动
案例分析:
- 点击弹出层, 模态框和遮挡层就会显示出来 display:block;
- 点击关闭按钮,模态框和遮挡层就会隐藏起来 display:none;
- 在页面中拖拽的原理:鼠标按下并且移动, 之后松开鼠标
- 触发事件是鼠标按下mousedown,鼠标移动mousemove 鼠标松开 mouseup
- 拖拽过程: 鼠标移动过程中,获得最新的值赋值给模态框的left和top值,这样模态框可以跟着鼠标走了
- 鼠标按下触发的事件源是最上面一行,就是 id 为 title
- 鼠标的坐标减去 鼠标在盒子内的坐标, 才是模态框真正的位置。
- 鼠标按下,我们要得到鼠标在盒子的坐标。
- 鼠标移动,就让模态框的坐标 设置为 :鼠标坐标 减去盒子坐标即可,注意移动事件写到按下事件里面。
- 鼠标松开,就停止拖拽,就是可以让鼠标移动事件解除
Document
案例:仿京东放大镜
- 整个案例可以分为三个功能模块
- 鼠标经过小图片盒子, 黄色的遮挡层 和 大图片盒子显示,离开隐藏2个盒子功能
- 黄色的遮挡层跟随鼠标功能。
- 移动黄色遮挡层,大图片跟随移动功能。
案例分析:
- 黄色的遮挡层跟随鼠标功能。
- 把鼠标坐标给遮挡层不合适。因为遮挡层坐标以父盒子为准。
- 首先是获得鼠标在盒子的坐标。
- 之后把数值给遮挡层做为left 和top值。
- 此时用到鼠标移动事件,但是还是在小图片盒子内移动。
- 发现,遮挡层位置不对,需要再减去盒子自身高度和宽度的一半。
- 遮挡层不能超出小图片盒子范围。
- 如果小于零,就把坐标设置为0
- 如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离
- 遮挡层的最大移动距离:小图片盒子宽度 减去 遮挡层盒子宽度
html
css
.detail .detail-left .pic {
position: relative;
width: 400px;
height: 400px;
border: 1px solid #ededed;
}
.detail .detail-left .pic .mask {
display: none;
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
background-color: blanchedalmond;
opacity: .5;
cursor: move;
}
.detail .detail-left .pic .big {
display: none;
position: absolute;
top: 0;
left: 410px;
width: 500px;
height: 500px;
border: 1px solid #ccc;
overflow: hidden;
}
.detail .detail-left .pic .big img {
position: absolute;
top: 0;
left: 0;
width: 200%;
}
js
window.addEventListener('load', function () {
var pic = document.querySelector('.pic');
var mask = this.document.querySelector('.mask');
var big = this.document.querySelector('.big');
pic.addEventListener('mouseover', function () {
mask.style.display = 'block';
big.style.display = 'block';
})
pic.addEventListener('mouseout', function () {
mask.style.display = 'none';
big.style.display = 'none';
})
//盒子跟随鼠标移动
pic.addEventListener('mousemove', function (e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
//遮挡层移动距离
var maskMax = pic.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';
//大图片的移动距离 = 遮挡层移动距离*大图片最大移动距离/遮挡层的 最大移动距离
var big_p = document.querySelector('.big_p');
// console.log(big_p);
var bigMax = big_p.offsetWidth - big.offsetWidth;
// console.log(bigMax);
//大图片的移动距离
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
big_p.style.left = -bigX + 'px';
big_p.style.top = -bigY + 'px';
})
})
元素可视区 client
client概述
client 翻译过来就是客户端,我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client
系列的相关属性可以动态的得到该元素的边框大小、元素大小等。
| client系列属性 | 说明 |
|---|---|
| element.clientTop | 返回元素上边框的大小 |
| element.clientLeft | 返回元素左边框的大小 |
| element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 |
| element.clientHeight | 返回自身包括padding、内容区的高度,不含边框,返回数值不带单位 |
scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。
| scroll系列属性 | 说明 |
|---|---|
| element.scrollTop | 返回被卷去的上侧距离,返回数值不带单位 |
| element.scrollLeft | 返回被卷去的左侧距离,返回数值不带单位 |
| element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
| element.scrollHeight | 返回自身实际的高度,不含边框,返回数值不带单位 |
三大系列总结页面被卷去的头部: 可以通过window.pageYOffset获得
页面被卷去的左侧 window.pageXOffset
他们主要用法:
-
offset系列 经常用于获得元素位置 offsetLeft offsetTop
-
client经常用于获取元素大小 clientWidth clientHeight
-
scroll 经常用于获取滚动距离 scrollTop scrollLeft
-
注意页面滚动的距离通过 window.pageXOffset 获得
| 事件 | 说明 |
|---|---|
| touchstart | 手指触摸到一个dom元素时触发 |
| touchmove | 手指在一个dom元素上滑动时触发 |
| touchend | 手指从一个dom元素上移开时触发 |
touchstart、touchmove、touchend 三个事件都会各自有事件对象。
| 事件 | 说明 |
|---|---|
| touches | 正在触摸屏幕的所有手指的一个列表 |
| targetTouches | 正在触摸当前dom元素的手指 的一个列表 |
| changedTouches | 手指状态发生了改变的列表,从无到有,从有到无变化 |
因为平时我们都是给元素注册触摸事件,所以重点记住 targetTocuhes
移动端拖动元素- touchstart、touchmove、touchend 可以实现拖动元素
- 但是拖动元素需要当前手指的坐标值 我们可以使用 targetTouches[0] 里面的pageX 和 pageY
- 移动端拖动的原理: 手指移动中,计算出手指移动的距离。然后用盒子原来的位置 + 手指移动的距离
- 手指移动的距离: 手指滑动中的位置 减去 手指刚开始触摸的位置
拖动元素三步曲:
(1) 触摸元素 touchstart: 获取手指初始坐标,同时获得盒子原来的位置
(2) 移动手指 touchmove: 计算手指的滑动距离,并且移动盒子
(3) 离开手指 touchend:
注意: 手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动 e.preventDefault();
移动端常用开发插件JS 插件是 js 文件,它遵循一定规范编写,方便程序展示效果,拥有特定功能且方便调用。如轮播图和瀑布流插件。
特点:它一般是为了解决某个问题而专门存在,其功能单一,并且比较小。
插件的使用-
引入 js 插件文件。
-
按照规定语法使用。
-
fastclick 插件解决 300ms 延迟。 使用延时
-
GitHub官网地址: https://github.com/ftlabs/fastclick
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
Swiper 插件的使用
中文官网地址:https://www.swiper.com.cn/
- 引入插件相关文件。
- 按照规定语法使用
lsuperslide: http://www.superslide2.com/
l iscroll: https://github.com/cubiq/iscroll
本地存储特性-
数据存储在用户浏览器中
-
设置、读取方便、甚至页面刷新不丢失数据
-
容量较大,sessionStorage约5M、localStorage约20M
-
只能存储字符串,可以将对象JSON.stringify() 编码后存储
-
生.命周期为关闭浏览器窗口
-
在同一个窗口(页面)下数据可以共享
-
以键值对的形式存储使用
存储数据:
sessionStorage.setItem(key, value)
获取数据:
sessionStorage.getItem(key)
删除数据:
sessionStorage.removeItem(key)
清空数据:(所有都清除掉)
sessionStorage.clear()window.localStorage
-
声明周期永久生效,除非手动删除 否则关闭页面也会存在
-
可以多窗口(页面)共享(同一浏览器可以共享)
-
以键值对的形式存储使用
存储数据:
localStorage.setItem(key, value)
获取数据:
localStorage.getItem(key)
删除数据:
localStorage.removeItem(key)
清空数据:(所有都清除掉)
localStorage.clear()



