图片懒加载
<!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>.viewport {width: 300px;height: 200px;border: 1px solid blue;overflow: auto;}.box1 {height: 600px;width: 100%;}.observed {width: 100px;height: 100px;border: 1px solid green;}.imgs {width: 100px;height: 100px;}</style>
</head><body><div class="viewport" id="viewport"><div class="box1"><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /><img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" /></div></div><script>let viewport = document.getElementById("viewport"); // 可视区域let imgList = document.querySelectorAll(".imgs"); // 被观察元素/* 开启观察者 */// var IO = new IntersectionObserver(回调,配置项)var IO = new IntersectionObserver(fn, {})function fn (entry) {console.log(entry, 'fn');entry.forEach(item => {if (item.isIntersecting) {/* 表示进入可是区域 */console.log(item.target.getAttribute('data-src'));// item.target.src = item.target.getAttribute('data-src')item.target.src = item.target.dataset.srcIO.unobserve(item.target)} else {/* 离开 */}})}// console.dir(IO.observe());/* 观察img */imgList.forEach(item => {// console.log(item);IO.observe(item)})</script>
</body></html>
对象数据扁平化处理
const obj1 = {a: 1,b: {f: '2',g: '3',},c: {d: [1,2,{e: true,},],},
}
转换成这样
const obj2 = {a: 1,'b.f': '2','b.g': '3','c.d.0': 1,'c.d.1': 2,'c.d.2.e': true
}
实现代码
let result = {}
let comType = ['object', 'array']function plat(obj, prekey, resobj) {prekey = prekey ? prekey + '.' : ''let keys = Object.keys(obj)keys.forEach((item) => {let val = obj[item]let type = typeof valif (comType.indexOf(type) != -1 && val) {plat(val, prekey + item, resobj)} else {if (val !== null && val !== undefined) {resobj[prekey + item] = val}}})
}
plat(obj1, '', result)
ES6中的class类?
es6中的class可以把它看成是es5中构造函数的语法糖,它简化了构造函数的写法, 类的共有属性放到 constructor 里面
1、通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
2、类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
3、constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数
4、多个函数方法之间不需要添加逗号分隔
5、生成实例 new 不能省略
6、语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需要加function 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则) 如果子类想要继承父类的方法,同时在自己内部扩展自己的方法,利用super 调用 父类的构造函数,super 必须在子类this之前调用
7、时刻注意this的指向问题,类里面的共有的属性和方法一定要加this使用. constructor中的this指向的是new出来的实例对象 自定义的方法,一般也指向的new出来的实例对象 绑定事件之后this指向的就是触发事件的事件源 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象
跨域的几种解决方案
1-jsonp 【前端后端实现】
jsonp: 利用 <script> 标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。
JSONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性,不安全可能会遭受XSS攻击。
声明一个回调函数,其函数名(如show)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。
创建一个<script>标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=show)。
服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是show,它准备好的数据是show('我不爱你')。
最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(show),对返回的数据进行操作。
2-CORS 【后端实现】
CORS:跨域资源共享(CORS)是一种机制;当一个资源访问到另外一个资源(这个资源放在
不同的域名或者不同的协议或者端口),资源就会发起一个跨域的HTTP请求需要浏览器和服务器同时支持;
整个CORS通信,都是浏览器自动完成。浏览器发现了AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉;
实现CORS的关键是服务器,只要服务器实现了CORS接口,就可以跨源通信
服务器对于不同的请求,处理方式不一样; 有简单请求和非简单请求
3-proxy 【前端实现 只适用于本地development开发环境】
// 配置反向代理proxy: {// 当地址中有/api的时候会触发代理机制'/api': {target: 'http://ihrm-java.itheima.net/', // 要代理的服务器地址 这里不用写 apichangeOrigin: true // 是否跨域// 重写路径// pathRewrite: {}}}
4-nginx 【后端实现】