一、封装 win 方法
- 获取或者设置浏览器的窗口的盒模型属性:
 
let winW = document.documentElement.clientWidth || document.body.clientWidth;let winH = document.documentElement.clientHeight || document.body.clientHeight;
- 因为获取浏览器的窗口的盒子模型属性都需要兼容写法,为了提高效率封装一个方法;
 
function win(attr, val) {if (typeof val !== "undefined") {// 传2个值的时候是设置,传一个值是获取document.documentElement[attr] = document.body[attr] = val;}return document.documentElement[attr] || document.body[attr];}console.log(win('scrollTop'));console.log(win('screenTop', 1000));
二、跑马灯
- html代码
 
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><style>* {margin: 0;padding: 0;}.box {width: 800px;height: 200px;overflow: hidden;border: 1px dashed deeppink;margin: 40px auto;}.box ul {height: 200px;}.box ul li {float: left;width: 200px;height: 200px;overflow: hidden;}.box ul li img {width: 100%;height: 100%;}.clearfix:after {display: block;content: '';height: 0;visibility: hidden;clear: both;}</style></head><body><div class="box"><ul class="ulBox clearfix" id="ulBox"><li><img src="./img/1.jpg" alt=""></li><li><img src="./img/2.jpg" alt=""></li><li><img src="./img/3.jpg" alt=""></li><li><img src="./img/4.jpg" alt=""></li></ul></div><script src="1-跑马灯.js"></script></body></html>
- js代码
 
let ul = document.querySelector('#ulBox');let box = document.querySelector('.box');ul.innerHTML += ul.innerHTML; // 为了实现无缝轮播需要把 ul 里面的所有 li 复制一份放到 ul 中;ul.style.width = '1600px';let timer = setInterval(() => {box.scrollLeft += 1;if (box.scrollLeft >= 800) {// 当满足这个条件时,说明此时正好滚出去 4 个 li,在 box 里展示的正是我们复制出来的 4 个 li,这个时候需要把 box.scrollLeft 设置成 0,但是因为设置成 0 时展示的也是这 4 张图片,给人的感觉好像没有换,所以还是无缝的轮播的box.scrollLeft = 0;}}, 10);
三、计算生效的样式
1. ele.style (可读可写)只能获取或者设置行内样式
let box = document.getElementById('box');
- 获取、设置元素的样式
 
box.style.xxxbox.style.xxx = xxx;
2. 获取浏览器最终计算生效后的样式
- window.getComputedStyle() 方法用于获取元素对象经计算生效后的样式;
 - 语法:window.getComputedStyle(元素对象, 伪类)
 - 如果不需要伪类:window.getComputedStyle(元素对象, null) 不需要写伪类时,第二个参数写null
 - 返回值:一个对象,对象中包含该元素所有的样式,并且该对象是 CSSStyleDeclaration 的实例
 - 获取元素样式
 
let styles = window.getComputedStyle(box, null);console.log(styles);console.log(styles.width); // 200pxconsole.log(styles.height); // 300pxconsole.log(styles.marginTop); // 10px css 连字符样式需要使用驼峰命名法console.log(styles['margin-top']); // 10px 不用驼峰命名法需要这样写
- 获取伪类样式:
 
let fakeStyles = window.getComputedStyle(box, 'before');console.log(fakeStyles);console.log(fakeStyles.content); // helloconsole.log(fakeStyles.color); // rgb(0, 255, 255)console.log(fakeStyles.height); // auto
- IE 低版本 6-8 不支持这个语法
 - IE中有的元素对象获取计算过的生效的样式:
 - 元素对象.currentStyle 属性,该属性是一个对象,上面记录这个该元素生效的样式
 - 获取生效的样式:
标准浏览器下: window.getComputedStyle 方法;window.getComputedStyle(元素对象, 伪类) 返回一个对象
IE浏览器下:元素对象.currentStyle 属性; 该属性值是一个对象,里面存储了该元素所有的样式 
3. 封装getCss方法,并且处理单位和IE兼容
// 优化:去除单位、同一 透明度样式:function getCss(ele, attr) {var value;if ('getComputedStyle' in window) {value = window.getComputedStyle(ele, null)[attr];} else {// 判读获取的属性是否是透明度,如果是需要给IE的透明度属性进行特殊处理if (attr === 'opacity') {value = ele.currentStyle['filter'];var reg2 = /^alpha\(opacity=(.+)\)$/;value = reg2.exec(value)[1] / 100;} else {value = ele.currentStyle[attr];}}// 去除单位: 只有是数字带单位的情况下才需要去除单位var reg = /^-?\d+(\.\d+)?(px|pt|rem|em)$/i;if (reg.test(value)) {value = parseFloat(value);}}console.log(getCss(box, 'width'));console.log(getCss(box, 'opacity'));
四、图片懒加载
图片延时加载(图片懒加载)
真实项目中,为了提升页面的加载速度,我们一般将图片处理成延时加载;
- 效果:
页面中的图片在页面刚刚打开时,浏览器会立刻去请求这张图片资源。但是延时加载是页面打开时,不是立刻去加载图片,而是在某个合适的时机去加载这张图片(一般是图片进入浏览器可视区域或者即将进入可视区域); - 原理:
img 标签有一个 src 属性,值是这张图片的资源路径;只要浏览器检测到 img 有这个属性就会立刻去加载,为了实现延时加载,不直接给 img 标签设置 src 属性,而是选择自定义其他属性保存其图片资源路径;等到何时的时机,再获取这个自定义属性值,再赋值给图片的 src 属性,此时,浏览器会根据这个 src 去加载图片。 
1. 单张图片延时加载
- 单张图片延时加载:
 - 时机:图片即将进入浏览器可视窗口
 - 监听页面的滚动事件,当页面滚动时,计算图片什么时候进入可视窗口;
 - 进入浏览器可视窗口条件:(图片上外边距离页面顶端的距离 - 浏览器的可视窗口的高度 - 页面纵向滚动条卷去的距离) <= 0
 - html:
 
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><style>* {margin: 0;padding: 0;}.top {width: 500px;margin: 0 auto;height: 1000px;border: 10px solid #00b38a;}.img-wrapper {width: 500px;min-height: 200px;border: 1px solid #000;margin: 100px auto;}</style></head><body><div id="top" class="top">这个盒子就是用来占位的,我是一个很长很长的盒子</div><div class="img-wrapper"><img data-src="img/1.jpg" alt="" id="first"></div><div class="img-wrapper"><img data-src="img/2.jpg" alt=""></div><div class="img-wrapper"><img data-src="img/3.jpg" alt=""></div><script src="js/utils.js"></script><script src="js/3-多张图片延时加载.js"></script></body></html>
// 1. 获取该图片let singleImg = document.querySelector('#first');// 2. 获取浏览器可视窗口的高度let winH = utils.win('clientHeight');// 3. 监听 window 的 onscroll 事件,在事件函数中计算图片是否进入浏览器的可视窗口window.onscroll = function () {// 1. 获取图片的自定义属性保存的图片资源路径let dataSrc = singleImg.getAttribute('data-src');// 2. 获取当前页面滚动条卷去的高度let winScrollTop = utils.win('scrollTop');// 3. 获取图片的上外边框距离页面顶部的距离;let imgOffsetTop = utils.offset(singleImg).top;// 4. 判断图片是否进入浏览器的可是窗口if (imgOffsetTop - winH - winScrollTop <= 0) {// 满足这个条件说明图片即将或者已经进入了可视窗口,此时给 img 的 src 赋值singleImg.src = dataSrc;}};
优化
真实项目中,因为网络或者其他因素可能导致图片加载失败,所以一般不是直接给图片赋值,而是先动态创建一个 img 标签,用动态创建的 img 去尝试加载,如果加载成功就再给页面中的图片 src 属性赋值。
// 1. 获取该图片let singleImg = document.querySelector('#first');// 2. 获取浏览器可视窗口的高度let winH = utils.win('clientHeight');// 3. 监听 window 的 onscroll 事件,在事件函数中计算图片是否进入浏览器的可视窗口window.onscroll = function () {// 1. 获取图片的自定义属性保存的图片资源路径let dataSrc = singleImg.getAttribute('data-src');// 2. 获取当前页面滚动条卷去的高度let winScrollTop = utils.win('scrollTop');// 3. 获取图片的上外边框距离页面顶部的距离;let imgOffsetTop = utils.offset(singleImg).top;// 4. 判断图片是否进入浏览器的可是窗口if (imgOffsetTop - winH - winScrollTop <= 0) {// 满足这个条件说明图片即将或者已经进入了可视窗口,此时给 img 的 src 赋值// 4.1 动态创建 imglet newImg = document.createElement('img');// 4.2 尝试加载newImg.src = dataSrc;// 4.3 监听临时图片的 onload 事件,如果加载成功会触发这个事件newImg.onload = function () {singleImg.src = dataSrc;newImg = null; // 手动释放内存}}};
多张图片延时加载
- 多张图片延时加载:
 - 获取页面中所有的图片(或者某个容器元素下的所有需要延时加载的图片),
 - 监听页面中 onscroll 事件,在事件函数中,计算每张图片的是否即将出现在浏览器的可视窗口中
 - 如果当前图片即将进入,就进行该图片的加载。在加载之前需要判断该图片是否有 src 属性,如果有了 src 属性,说明该图片已经加载过了,不需要重新加载
 
// 1. 获取图片集合let imgList = document.querySelectorAll('img');// 2. 获取当前浏览器可视窗口的高度let winH = utils.win('clientHeight');// 3. 监听窗口的滚动事件window.onscroll = function () {// 3.1 获取当前页面滚动条卷去的高度let winSctp = utils.win('scrollTop');// 3.2 遍历图片集合,在遍历过程中计算每张图片是否进入可视区域for (let i= 0; i < imgList.length; i++) {let imgItem = imgList[i];if (imgItem.src) continue; // 如果图片的 src 属性存在且不为空,说明该图片已经加载过了,后面的加载不需要再执行了let imgOffsetTop = utils.offset(imgItem).top;let dataSrc = imgItem.getAttribute('data-src');if (imgOffsetTop - winH - winSctp <= 0) {let newImg = new Image(); // 新建图片,等效于 document.createElement('img')newImg.src = dataSrc;newImg.onload = function () {imgItem.src = dataSrc;newImg = null;}}}};
【发上等愿,结中等缘,享下等福,择高处立,寻平处住,向宽处行】
