1. offset属性
1.1
offset系列
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>* {margin: 0;padding: 0;}.father {/* position: relative; */width: 200px;height: 200px;background-color: pink;margin: 150px;}.son {width: 100px;height: 100px;background-color: purple;margin-left: 45px;}.w {height: 200px;width: 200px;background-color: skyblue;margin: 0 auto 200px;padding: 10px;border: 15px solid red;}</style>
</head><body><div class="father"><div class="son"></div></div><div class="w"></div><script>// offset 系列var father = document.querySelector('.father');var son = document.querySelector('.son');// 1.可以得到元素的偏移 位置 返回的不带单位的数值 console.log(father.offsetTop); //150console.log(father.offsetLeft); //150// 如果没有父亲 或 父亲没有定位, 则以 body 为准; console.log(son.offsetLeft); //195/***************************************************************************/ // 2.可以得到元素的大小 宽度和高度, 是包含padding + border + width; var w = document.querySelector('.w');console.log(w.offsetWidth); //250console.log(w.offsetHeight); //250/***************************************************************************/ // 3. 返回带有定位的父亲 否则返回的是bodyconsole.log(son.offsetParent); // 返回带有定位的父亲 否则返回的是bodyconsole.log(son.parentNode); // 返回最近一级的父亲, 亲爸爸, 不管父亲有没有定位</script>
</body></html>
1.2
区别
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><!--
使用offset系列相关属性可以动态的得到该元素的位置(偏移),大小等。1. 获得元素距离带有定位父元素的位置; 2. 获得元素自身的大小(宽度高度); 3. 注意:返回的数值都不带单位;
offset系列属性:.offsetParent: 返回作为该元素带有定位的父级元素,如果父级都没有定位,则返回body; .offsetTop: 返回元素相对于带有定位父元素上方的偏移; (没有父亲 或 父亲没有定位则以body为准).offsetLeft: 返回元素相对于带有定位元素左边框的偏移; (没有父亲 或 父亲没有定位则以body为准).offsetWidth: 返回自身包括 padding+边框+内容区 => 宽度,返回数值无单位; .offsetHeight: 返回自身包括 padding+边框+内容区 => 高度,返回数值无单位; offset和style的区别:offset:1. offset可以得到任意样式表中的样式值; 2. offset系列获得的数值是没有单位的; 3. offsetWidth包含padding+border+width; 4. offsetWidth等属性是只读属性; 5. 所以,要想获取元素大小位置,用offset系列更为合适; style:1 style只能得到行内样式表(<div style=""></div>)中的样式值; 2. style.width获得的是带有单位的字符串; 3. style.width获得是不包含padding和border的值; 4. style.width具有读写属性; 5. 所以,要想给元素更改值,则需要用style改变; -->
</body></html>
2. client属性
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><!-- client:我们可以通过client系列的相关属性来获取元素可视区的相关信息; 通过client系列的相关属性可以动态的得到该元素的边框大小,元素大小等; client系列属性:.clientTop: 返回元素上边框的宽度; .clientLeft: 返回元素左边框的宽度; .clientWidth: 返回自身包含 padding + 内容区宽度 + 不含边框 => 返回数值不带单位; .clientHeight: 同上; --><style>div {width: 200px;height: 200px;background-color: pink;border: 10px solid red;padding: 10px;margin-top: 100px;}</style>
</head><body><div></div><script>// client的宽度 和我们 offsetWidth 最大的区别就是 不包含边框(但包含padding); var div = document.querySelector('div');console.log(div.clientWidth); //220 console.log(div.clientTop); //10</script>
</body></html>
3. scroll属性
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><!-- 使用scroll系列的相关属性可以动态的得到该元素的大小,滚动距离等等!scroll属性系列:.scrollTop 返回被卷去的上侧距离,返回数值不带单位; .scrollLeft 返回被卷去的左侧距离,返回数值不带单位; .scrollWidth 返回自身实际的宽度,不含边框,但包含padding,返回数值不带单位; .scrollHeight 返回自身实际的高度,不含边框,但包含padding,返回数值不带单位; --><style>div {width: 200px; height: 200px; background-color: pink; border: 10px solid red; padding: 10px; overflow: auto; }</style>
</head><body><div>我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容</div><script>// scroll 属性:var div = document.querySelector('div');console.log(div.scrollHeight);console.log(div.clientHeight);// scroll滚动事件当我们滚动条发生变化会触发的事件div.addEventListener('scroll', function () {console.log(div.scrollTop);}); </script>
</body></html>
4. 其他
4.1
立即执行函数
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- 立即执行函数:不需要自己调用, 它自己会立马调用函数; 1. (funtion() {})(); 2. (funtion(){} ()); 记忆方式: (function(){}) 式1剩下的一对括号在式1的里面 或 外面均可!3. 立即执行函数的最大作用就是 独立创建了一个作用域, 里面所有的变量都是局部变量, 不会存在命名冲突的问题; --><script>(function(a, b){console.log(a+b);var num = 10; //num是局部变量})(1,3);(function(a, b){console.log(a-b);} (1,6));</script>
</body>
</html>
4.2
flexible.js源码分析
(function flexible(window, document) {// 获取的html 的根元素var docEl = document.documentElement// dpr 物理像素比var dpr = window.devicePixelRatio || 1// adjust body font size 设置我们body 的字体大小function setBodyFontSize() {// 如果页面中有body 这个元素 就设置body的字体大小if (document.body) {document.body.style.fontSize = (12 * dpr) + 'px'} else {// 如果页面中没有body 这个元素,则等着 我们页面主要的DOM元素加载完毕再去设置body// 的字体大小document.addEventListener('DOMContentLoaded', setBodyFontSize)}}setBodyFontSize();// set 1rem = viewWidth / 10 设置我们html 元素的文字大小function setRemUnit() {var rem = docEl.clientWidth / 10docEl.style.fontSize = rem + 'px'}setRemUnit()// reset rem unit on page resize 当我们页面尺寸大小发生变化的时候,要重新设置下rem 的大小window.addEventListener('resize', setRemUnit)// pageshow 是我们重新加载页面触发的事件window.addEventListener('pageshow', function(e) {// e.persisted 返回的是true 就是说如果这个页面是从缓存取过来的页面,也需要从新计算一下rem 的大小if (e.persisted) {setRemUnit()}})// detect 0.5px supports 有些移动端的浏览器不支持0.5像素的写法if (dpr >= 2) {var fakeBody = document.createElement('body')var testElement = document.createElement('div')testElement.style.border = '.5px solid transparent'fakeBody.appendChild(testElement)docEl.appendChild(fakeBody)if (testElement.offsetHeight === 1) {docEl.classList.add('hairlines')}docEl.removeChild(fakeBody)}
}(window, document))/* 下面3种事件都会刷新页面触发load事件; 1. a标签的超链接; 2. F5或者刷新按钮; 3. 前进后退按钮; 但是在火狐浏览器中, 存在“往返缓存”,这个缓存里面不仅保存着页面数据,而且还保存了DOM和JavaScript的状态;实际上是将整个页面都保存在了内存里面; 所以此时进行后退操作不能刷新页面;此时可以使用pageshow事件来触发;这个事件在页面显示时触发,无论页面是否来自缓存,在重新加载页面时,pageshow会在load事件触发后触发;根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件,注意这个事件给window添加;
*/
4.3
mouseenter和mouseover区别
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>.father {width: 300px;height: 300px;background-color: pink;margin: 100px auto;}.son {width: 200px;height: 200px;background-color: purple;}</style>
</head><body><div class="father"><div class="son"></div></div><!-- 1. 鼠标移动到元素上时就会触发mouseenter事件; 2. mouseover, 类似mouseenter事件; 3. 区别:mouseover: 鼠标进入父盒子自身会触发,进入子盒子同样会触发; mouseenter: 鼠标进入盒子自身才会触发; 4. why? => mouseenter 不会冒泡; --><script>var father = document.querySelector('.father'); var son = document.querySelector('.son'); father.addEventListener('mouseenter', function() {console.log(11);}); </script>
</body></html>
5. 动画
5.1 动画原理
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>div {position: absolute;/* 必须添加定位,距离父亲的左边距(body) */left: 0;width: 100px;height: 100px;background-color: pink;}</style>
</head><body><div></div><script>/* 动画原理1. 获得盒子当前位置 ;2. 让盒子在当前位置加上1个移动距离 ; 3. 利用定时器不断重复这个操作 ; 4. 加一个结束定时器的条件 ; [5.] 注意此元素需要添加定位, 才能使用element.style.left ; */var div = document.querySelector('div');var timer = setInterval(function () {if (div.offsetLeft >= 400) {clearInterval(timer);}console.log(div.style.left);div.style.left = div.offsetLeft + 1 + 'px';}, 30);</script>
</body></html>
5.2 动画函数封装
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>div {position: absolute;left: 0;width: 100px;height: 100px;background-color: red;}span {position: absolute;left: 0;top: 200px;display: block;width: 150px;height: 150px;background-color: purple;}</style>
</head><body><div></div><span></span><script>function animation(obj, target) {var timer = setInterval(function () {if (obj.offsetLeft >= target) {clearInterval(timer);}obj.style.left = obj.offsetLeft + 1 + 'px';}, 30);};var div = document.querySelector('div');var span = document.querySelector('span');animation(div, 400);animation(span, 400);/* 存在问题:如果多个元素都使用这个动画函数,那么每次都要var声明定时器(开辟内存),,,,,,改进:给当前对象添加属性;obj.timer = setInterval( ... );*/</script>
</body></html>
5.3 缓动动画
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- 缓动动画:就是让元素运动速度有所变化,最常见的就是让慢慢减速停下来;思路:1. 让盒子每次移动的距离慢慢变小,速度就会慢慢减下来; 2. 公式:(目标值 - 当前位置) / 10 来作为每次移动的步长; 3. 停止条件:当前盒子位置等于目标位置时就关闭定时器; 4. 步长值需要取整; --><style>div {position: absolute;left: 0;width: 100px;height: 100px;background-color: red;}</style>
</head><body><button class="btn500">500</button><button class="btn800">800</button><div></div><script>function animation(obj, target, callback) {clearInterval(obj.timer);obj.timer = setInterval(function () {//步长公式:(目标值-现在的位置)/10var step = (target - obj.offsetLeft) / 10;// console.log(step);step = step > 0 ? Math.ceil(step) : Math.floor(step);if (obj.offsetLeft == target) {clearInterval(obj.timer);if (callback) {callback();}}obj.style.left = obj.offsetLeft + step + 'px';}, 15); //推荐为15ms};var div = document.querySelector('div');var btn500 = document.querySelector('.btn500');var btn800 = document.querySelector('.btn800');btn500.addEventListener('click', function () {animation(div, 500);});btn800.addEventListener('click', function () {animation(div, 800);});</script>
</body></html>
5.4 动画回调函数
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- 给动画函数添加回调函数:回调函数原理: 函数可以作为一个参数;将这个函数作为参数传到另一个函数里面,当那个函数执行完毕后,再执行传进去的函数,这个过程就叫回调;--><style>div {position: absolute;left: 0;width: 100px;height: 100px;background-color: red;}</style>
</head><body><button class="btn500">500</button><button class="btn800">800</button><div></div><script>function animation(obj, target, callback) {clearInterval(obj.timer);obj.timer = setInterval(function () {var step = (target - obj.offsetLeft) / 10;step = step > 0 ? Math.ceil(step) : Math.floor(step);if (obj.offsetLeft == target) { //此时达到终点,启用回调函数clearInterval(obj.timer);if (callback) {callback();}}obj.style.left = obj.offsetLeft + step + 'px';}, 15); };var div = document.querySelector('div');var btn500 = document.querySelector('.btn500');var btn800 = document.querySelector('.btn800');btn500.addEventListener('click', function () {animation(div, 500);});btn800.addEventListener('click', function () {animation(div, 800, function () { /* 添加了回调函数 */div.style.backgroundColor = 'green';});});</script>
</body></html>
5.5 引用动画函数
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><!-- 因为可能以后经常使用这个动画函数, 所以可以单独封装到一个js文件当中, 使用的时候直接引用这个js文件即可; --><style>.sliderbar {position: fixed;right: 0;bottom: 100px;width: 40px;height: 40px;text-align: center;line-height: 40px;cursor: pointer;color: #fff;}.con {position: absolute;left: 0;top: 0;width: 200px;height: 40px;background-color: purple;z-index: -1;}</style><script src="./animation.js"></script>
</head><body><div class="sliderbar"><span>←</span><div class="con">问题反馈</div></div><script>// 1. 获取元素var sliderbar = document.querySelector('.sliderbar');var con = document.querySelector('.con');// 当我们鼠标经过 sliderbar 就会让 con这个盒子滑动到左侧 ; // 当我们鼠标离开 sliderbar 就会让 con这个盒子滑动到右侧 ; sliderbar.addEventListener('mouseenter', function () {animate(con, -160, function () {sliderbar.childrn[0].innerHTML = '→'; });}); sliderbar.addEventListener('mouseleave', function () {animate(con, 0, function () {sliderbar.children[0].innerHTML = '←';});}); </script>
</body></html>
// animation.js
function animate(obj, target, callback) {clearInterval(obj.timer);obj.timer = setInterval(function() {var step = (target - obj.offsetLeft) / 10;console.log(obj.offsetLeft);step = step > 0 ? Math.ceil(step) : Math.floor(step);if (obj.offsetLeft == target) {clearInterval(obj.timer);callback && callback(); }obj.style.left = obj.offsetLeft + step + 'px';}, 15);
}
6. 轮播图案例
gitee地址:https://gitee.com/studyCodingEx/studys
7. 筋斗云案例
gitee地址:https://gitee.com/studyCodingEx/studys
8. 计算鼠标在盒子内的位置
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>.box {width: 300px;height: 300px;background-color: pink;margin: 200px;}</style>
</head><body><div class="box"></div><script>// 我们在盒子内点击, 想要得到鼠标距离盒子左右的距离。// 首先得到鼠标在页面中的坐标( e.pageX, e.pageY)// 其次得到盒子在页面中的距离(box.offsetLeft, box.offsetTop)// 用鼠标距离页面的坐标减去盒子在页面中的距离, 得到 鼠标在盒子内的坐标var box = document.querySelector('.box');box.addEventListener('mousemove', function(e) {// console.log(e.pageX);// console.log(e.pageY);// console.log(box.offsetLeft);var x = e.pageX - this.offsetLeft;var y = e.pageY - this.offsetTop;this.innerHTML = 'x坐标是' + x + ' y坐标是' + y;})</script>
</body></html>
9. 对话框拖动
<!DOCTYPE html>
<html><head lang="en"><meta charset="UTF-8"><title></title><style>.login-header {width: 100%;text-align: center;height: 30px;font-size: 24px;line-height: 30px;}ul,li,ol,dl,dt,dd,div,p,span,h1,h2,h3,h4,h5,h6,a {padding: 0px;margin: 0px;}.login {display: none;width: 512px;height: 280px;position: fixed;border: #ebebeb solid 1px;left: 50%;top: 50%;background: #ffffff;box-shadow: 0px 0px 20px #ddd;z-index: 9999;transform: translate(-50%, -50%);}.login-title {width: 100%;margin: 10px 0px 0px 0px;text-align: center;line-height: 40px;height: 40px;font-size: 18px;position: relative;cursor: move;}.login-input-content {margin-top: 20px;}.login-button {width: 50%;margin: 30px auto 0px auto;line-height: 40px;font-size: 14px;border: #ebebeb 1px solid;text-align: center;}.login-bg {display: none;width: 100%;height: 100%;position: fixed;top: 0px;left: 0px;background: rgba(0, 0, 0, .3);}a {text-decoration: none;color: #000000;}.login-button a {display: block;}.login-input input.list-input {float: left;line-height: 35px;height: 35px;width: 350px;border: #ebebeb 1px solid;text-indent: 5px;}.login-input {overflow: hidden;margin: 0px 0px 20px 0px;}.login-input label {float: left;width: 90px;padding-right: 10px;text-align: right;line-height: 35px;height: 35px;font-size: 14px;}.login-title span {position: absolute;font-size: 12px;right: -20px;top: -30px;background: #ffffff;border: #ebebeb solid 1px;width: 40px;height: 40px;border-radius: 20px;}</style>
</head><body><div class="login-header"><a id="link" href="javascript:;">点击,弹出登录框</a></div><div id="login" class="login"><div id="title" class="login-title">登录会员<span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span></div><div class="login-input-content"><div class="login-input"><label>用户名:</label><input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input"></div><div class="login-input"><label>登录密码:</label><input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input"></div></div><div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div></div><!-- 遮盖层 --><div id="bg" class="login-bg"></div><script>// 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);});});</script>
</body></html>
10. 固定侧边栏
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>.slider-bar {position: absolute;left: 50%;top: 300px;margin-left: 600px;width: 45px;height: 130px;background-color: pink;}.w {width: 1200px;margin: 10px auto;}.header {height: 150px;background-color: purple;}.banner {height: 250px;background-color: skyblue;}.main {height: 1000px;background-color: yellowgreen;}span {display: none;position: absolute;bottom: 0;}</style>
</head><body><div class="slider-bar"><span class="goBack">返回顶部</span></div><div class="header w">头部区域</div><div class="banner w">banner区域</div><div class="main w">主体部分</div><script>//1. 获取元素var sliderbar = document.querySelector('.slider-bar');var banner = document.querySelector('.banner');// banner.offestTop 就是banner上边框到页面顶部的距离var bannerTop = banner.offsetTop; // 当我们侧边栏固定定位之后的top值var sliderbarTop = sliderbar.offsetTop - bannerTop;// 获取main 主体元素var main = document.querySelector('.main');var goBack = document.querySelector('.goBack');var mainTop = main.offsetTop;// 2. 页面滚动事件 scrolldocument.addEventListener('scroll', function() {// window.pageYOffset 页面被卷去的头部// 3 .当我们页面被卷去的头部大于等于了 172 此时 侧边栏就要改为固定定位if (window.pageYOffset >= bannerTop) {sliderbar.style.position = 'fixed';sliderbar.style.top = sliderbarTop + 'px';} else {sliderbar.style.position = 'absolute';sliderbar.style.top = '300px';}// 4. 当我们页面滚动到main盒子,就显示 goback模块if (window.pageYOffset >= mainTop) {goBack.style.display = 'block';} else {goBack.style.display = 'none';}})</script>
</body></html>
11. 返回顶部
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>.slider-bar {position: absolute;left: 50%;top: 300px;margin-left: 600px;width: 45px;height: 130px;background-color: pink;}.w {width: 1200px;margin: 10px auto;}.header {height: 150px;background-color: purple;}.banner {height: 250px;background-color: skyblue;}.main {height: 1000px;background-color: yellowgreen;}span {display: none;position: absolute;bottom: 0;}</style>
</head><body><div class="slider-bar"><span class="goBack">返回顶部</span></div><div class="header w">头部区域</div><div class="banner w">banner区域</div><div class="main w">主体部分</div><script>//1. 获取元素var sliderbar = document.querySelector('.slider-bar');var banner = document.querySelector('.banner');// banner.offestTop 就是被卷去头部的大小 一定要写到滚动的外面var bannerTop = banner.offsetTop// 当我们侧边栏固定定位之后应该变化的数值var sliderbarTop = sliderbar.offsetTop - bannerTop;// 获取main 主体元素var main = document.querySelector('.main');var goBack = document.querySelector('.goBack');var mainTop = main.offsetTop;// 2. 页面滚动事件 scrolldocument.addEventListener('scroll', function() {// console.log(11);// window.pageYOffset 页面被卷去的头部// console.log(window.pageYOffset);// 3 .当我们页面被卷去的头部大于等于了 172 此时 侧边栏就要改为固定定位if (window.pageYOffset >= bannerTop) {sliderbar.style.position = 'fixed';sliderbar.style.top = sliderbarTop + 'px';} else {sliderbar.style.position = 'absolute';sliderbar.style.top = '300px';}// 4. 当我们页面滚动到main盒子,就显示 goback模块if (window.pageYOffset >= mainTop) {goBack.style.display = 'block';} else {goBack.style.display = 'none';}})// 3. 当我们点击了返回顶部模块,就让窗口滚动的页面的最上方goBack.addEventListener('click', function() {// 里面的x和y 不跟单位的 直接写数字即可// window.scroll(0, 0);// 因为是窗口滚动 所以对象是windowanimate(window, 0);});// 动画函数function animate(obj, target, callback) {// console.log(callback); callback = function() {} 调用的时候 callback()// 先清除以前的定时器,只保留当前的一个定时器执行clearInterval(obj.timer);obj.timer = setInterval(function() {// 步长值写到定时器的里面// 把我们步长值改为整数 不要出现小数的问题// var step = Math.ceil((target - obj.offsetLeft) / 10);var step = (target - window.pageYOffset) / 10;step = step > 0 ? Math.ceil(step) : Math.floor(step);if (window.pageYOffset == target) {// 停止动画 本质是停止定时器clearInterval(obj.timer);// 回调函数写到定时器结束里面// if (callback) {// // 调用函数// callback();// }callback && callback();}// 把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10// obj.style.left = window.pageYOffset + step + 'px';window.scroll(0, window.pageYOffset + step);}, 15);}</script>
</body></html>