day-030-thirty-20230318-交叉信息监听事件IntersectionObserver-AJAX基础-瀑布流
交叉信息监听事件IntersectionObserver
-
IntersectionObserver:监听器,监控盒子在视口中出现的交叉信息
-
语法: IntersectionObserver(函数,对象)
-
入参
-
函数
(changes)=>{}-
有参数 changes
-
changes—是一个数组
-
changes[0]—对象,box的交叉信息
- isIntersecting: 元素是否在视口中出现 true 出现 false 未出现
- target: 监控的目标元素
- boundingClientRect:元素的某些信息
-
-
-
对象 {threshold:[]} 省略时默认值为{threshold:[0]} 用来控制元素与视口的交叉监听情况
-
用于控制监听对象与视口交叉程度,才触发的事件
-
触发情况举例
-
触发情况(0)
- 一打开页面立刻触发一次
- 元素在视口中出现一个边,触发一次
- 元素在视口中完全消失,触发一次。
- 之后2与3根据情况出现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body style="height:3000px;"> <div id="box" style="height:400px;width:100px;background-color: red;margin-top:1000px;margin-left:100px;"></div> <script> var ob=new IntersectionObserver((changes)=>{ console.log(changes,'changes') if(changes[0].isIntersecting){ console.log('按要求显示了') ob.unobserve(changes[0].target)//取消监控 } },{ threshold:[0] }) ob.observe(document.querySelector('#box'))//启动监听 </script> </body> </html> -
触发情况(0.5)
- 一打开页面立刻触发一次
- 元素在视口中出现一半,触发一次
- 元素在视口中消失一半,触发一次。
- 之后2与3根据情况出现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body style="height:3000px;"> <div id="box" style="height:400px;width:100px;background-color: red;margin-top:1000px;margin-left:100px;"></div> <script> var ob=new IntersectionObserver((changes)=>{ console.log(changes,'changes') if(changes[0].isIntersecting){ console.log('按要求显示了') ob.unobserve(changes[0].target)//取消监控 } },{ threshold:[0.5] }) ob.observe(document.querySelector('#box'))//启动监听 </script> </body> </html> -
触发情况(1)
- 一打开页面立刻触发一次
- 元素在视口中完全出现,触发一次
- 元素在视口中消失一个边,触发一次。
- 之后2与3根据情况出现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body style="height:3000px;"> <div id="box" style="height:400px;width:100px;background-color: red;margin-top:1000px;margin-left:100px;"></div> <script> var ob=new IntersectionObserver((changes)=>{ console.log(changes,'changes') if(changes[0].isIntersecting){ console.log('按要求显示了') ob.unobserve(changes[0].target)//取消监控 } },{ threshold:[1] }) ob.observe(document.querySelector('#box'))//启动监听 </script> </body> </html>
-
-
-
-
出参
-
一个监听器对象
-
监听器对象.observe(DOM元素对象)//启动监听对应的DOM元素对象
-
监听器对象.unobserve(changes[下标].target)//取消监控changes[下标].target对应的DOM元素对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body style="height:3000px;"> <div id="box" style="height:400px;width:100px;background-color: red;margin-top:1000px;margin-left:100px;"></div> <script> var ob=new IntersectionObserver((changes)=>{ console.log(changes,'changes') if(changes[0].isIntersecting){ console.log('按要求显示了') ob.unobserve(changes[0].target)//取消监控 } },{ threshold:[1] }) console.log(ob) ob.observe(document.querySelector('#box'))//启动监听 </script> </body> </html>
-
-
-
-
IntersectionObserver配合图片懒加载
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <style> body { height: 3000px; } .imgbox { width: 300px; height: 400px; margin-top: 1300px; margin-left: 100px; background-color: #ccc; background-position: center; background-repeat: no-repeat; background-image: linear-gradient(to bottom, yellow, skyblue); } .imgbox img { width: 300px; height: 400px; } img[src=""] { display: none; } </style> </head> <body> <div class="imgbox"> <img src="" data-src="linear-gradient(to bottom,blue)" alt="" /> </div> <script> var canvas = document.createElement("canvas"); canvas.width = "300"; canvas.height = "300"; const ctx = canvas.getContext("2d"); // 在 canvas 上绘制一些内容 ctx.fillStyle = "red"; ctx.fillText('在 canvas 上绘制一些内容;获取图片的 Base64 编码数据', 50, 50); ctx.fillRect(10, 10, 50, 50); const dataURL = canvas.toDataURL();//获取图片的 Base64 编码数据 var imgbox = document.querySelector(".imgbox"); var img = document.querySelector(".imgbox img"); console.log(ctx); img.setAttribute("data-src", dataURL); console.log(dataURL); var ob = new IntersectionObserver( (changes) => { console.log("111"); if (changes[0].isIntersecting) { //加载图片 if (img.flag) { ob.unobserve(imgbox); return; } showimg(); } }, { threshold: [1], } ); ob.observe(imgbox); function showimg() { console.log("2222"); var dataSrc = img.getAttribute("data-src"); var newimg = new Image(); newimg.src = dataSrc; newimg.onload = function () { img.src = dataSrc; img.removeAttribute("data-src"); newimg = null; img.flag = true; }; } </script> </body> </html>
-
AJAX基础
-
ajax是一个前后端进行数据交互的协议格式
- json格式的数据 —> 也是后台的数据格式
-
通过ajax ->获取json格式的数据
- 一般只能通过ajax才能将json数据获取到页面中
-
json格式数据
-
最外层 可以是数组,对象(键值对—key必须加双引号)
-
也可以用基础数据类型
[1,"str",true,null,{ "name": "lili", "age": 18},[]]{ "name":"lili", "age":18, "arr":[ { "a":10 }, { "a":20 } ] } -
也可以用基础数据类型
-
-
数据类型 数组,对象,数值,布尔值,字符串,null
- 字符串必须用双引号
-
json格式数据使用
//或<!-- -->或/**/进行注释- 但可以用无用属性名间接进行注释
-
通过ajax拿到的json本身就是字符串
-
只不过可以通过一些方法将json字符串变成json对象
-
json对象是一个普通对象的一个子集
- 所以json对象可以看作是普通对象,它内部的数据都可以通过普通对象的方法来获取
-
-
JSON.parse(json字符串) 将json字符串变成json对象
-
JSON.stringify(json对象)
-
-
-
ajax的步骤
-
得要用到
Open with Live Server,而不是Open In Default Browser-
因为
Open with Live Server是本地创建一个小型服务器-
数据协议为
http://http://127.0.0.1:5500/JS部分/day0318/ajax.html
-
-
Open In Default Browser是直接本地打开html文件-
数据协议为
http://file:///C:/Users/fangc/Desktop/myWork/2023_01/JS部分/day0318/ajax.html
-
-
-
操作步骤
-
创建
XMLHttpRequest核心对象let xhr = new XMLHttpRequest();
-
建立连接
-
XMLHttpRequest核心对象.open(
建立连接的方式,请求路径,是否同步异步)-
例子
xhr.open("GET", "./fang.json", false);
-
请求路径是以引用该js代码的html文档的所在目录为当前路径来进行相对查找的。 -
是否同步异步里false为同步
-
-
-
注册监听
-
发送数据
-
-
例子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>ajax</title> </head> <body></body> <script> let data = null; // 1. 第一步创建XMLHttpRequest核心对象 let xhr = new XMLHttpRequest(); // 2. 建立连接 open(建立连接的方式,连接路径,是否同步异步) false 同步 xhr.open("GET", "./fang.json", false); // 3. 注册监听 xhr.onreadystatechange = function () { //readyState 状态值---4 //status 状态码---200 if (xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.response, "默认通过ajax得到的json,是字符串"); data = JSON.parse(xhr.response) console.log(data, "对象"); console.log(JSON.stringify(data), "字符串"); } }; // 4. 发送数据 xhr.send(); </script> </html>
-
ES6基础
-
箭头函数
-
简写
var f1 = function (a) { return a + 1; }; //正常函数 var f2 = (a) => { return a + 1; }; //只有一个入参 var f3 = (a) => a + 1; //函数体内只有一条return语句 var f4 = (a) => a + 1; // 只有一个入参 并且 函数体内只有一条return语句 -
不能使用arguments
- 用剩余运算符代替
-
-
剩余运算符与展开运算符
-
剩余运算 将零散内容,放到一块
//剩余运算,将零散内容,放到一块 var show = (...args) => { console.log(args); //[1,2,3,4] }; show(1, 2, 3, 4); -
展开运算 将一个整体,变成单独个体
//展开运算 将一个整体,变成单独个体 var arr = [1, 2, 3, 4]; console.log(...arr); //1 2 3 4//相当于console.log(1, 2, 3, 4);
-
-
字符串模板
-
符号为反引号
- 可以换行
- 可以加变量
- 可以加运算表达式
- 可以用三元运算符
//es6字符串模板 var name="丽丽",age=18; var str="我叫"+name+",今年"+18+"岁,<ul><li>11</li><li>222</li><li>3333</li></ul>"; console.log(str); var name="丽丽",age=18; var str=`我叫${name},今年${age+1}岁,${age>=18?"成年":"未成年"} <ul> <li>可以换行</li> <li>222</li> <li>3333</li> </ul>`; console.log(str);
-
-
解构赋值
-
左右格式必须一样
- 左边是对象,右边也是对象
- 左边是数组,那右边也要为数组
-
左边没对应右边的,则左边的变量对应的变量值为undefined
-
左边变量名可以等号赋值默认值
- 只有右边属性值为undefined时才会使用默认值
-
左边可以通过
冒号:来取别名//解构赋值 (对象,数组) var obj={ name:"lili", Compotedage:18, job1:null, job4:undefined, } var { name = "Tom",//只有右边属性值为undefined时才会使用默认值 Compotedage: age, // 可以通过 : 取别名 job1 = "ceo",// 可以通过 等号 赋值默认值 job2,//没有的解构出来为undefined job3 = "job3", job4 = "job4",//赋值默认值(undefined) } = obj; //左右格式必须一样,左右都为对象 console.log(name, age, job1, job2, job3, job4);
-
-
一般用来解构对象与数组
//数组 var arr=[10,20,30,49,46]; var [a,b,c,d,e]=arr; console.log(a,e);//10,46 -
也可以用来进行交换赋值
//交换 a和b 的值 // var a=10; // var b=20; // var c; // c=b; // b=a; // a=c; // console.log(a,b) var a=10; var b=20; [a,b]=[b,a]; console.log(a,b);//20,10
-
瀑布流
-
与后端数据交互
- 客户端通过ajax发送到服务器得到json字符串数据
- 通过JSON.parse()把得到的json字符串数据转成json对象
-
得到json对象数据后,循环插入html中
-
根据观察,发现数据,不适合直接渲染;修改数据
-
对数据进行分组,根据图片大小依次反向插入对应列中
var data=null;//存储未来获取的数据 //注意,获取的cloumns是类数组,无法使用sort //******将类数组,转换为数组的方法 Array.from(类数组) var cloumns=Array.from(document.querySelectorAll(".cloumn"));//获取三列 //1. 获取数据 function getData(){ var xhr=new XMLHttpRequest; //文件路径,以html为基准找 xhr.open("GET","data.json",false); xhr.onreadystatechange=function(){ if(xhr.readyState===4&&xhr.status===200){ data=JSON.parse(xhr.response) } } xhr.send(); } getData() //2.循环渲染 function render(){ //2.1根据观察,发现数据,不适合直接渲染 数据图片宽度300,样式图片宽度240 //修改数据 var newData=data.map(item=>{ //拿出每条数据的 height(433)和width(300) let {width:w,height:h}=item; item.width=240;//将240重新覆盖原来的width item.height=240*h/w;//重新覆盖原来的height return item;//返回覆盖原来的每一项 }) var groups=[]; for(var i=0;i<newData.length;i+=3){//i=0, i=3, i=6 //i=0 slice(i,i+3) slice(0,3) [0,1,2] //i=3 slice(i,i+3) slice(3,6) [3,4,5] //i=6 slice(i,i+3) slice(6,9) [6,7,8] groups=newData.slice(i,i+3); //console.log(groups);//[0,1,2] [3,4,5] [6,7,8] //每一组数据,从大到小排序(按照高度) groups.sort((a,b)=>{ return b.height-a.height }) //检查一下,每组数据的高度,是否是由大到小 //console.log(groups); //按照每列的高度,排序 小中大 cloumns.sort((a,b)=>{ return a.offsetHeight-b.offsetHeight }) //检查一下,每列数据的高度,是否是 小中大 //console.log(cloumns); //groups: [大 中 小] //cloumns:[小 中 大] //已经排好顺序,只需要按照索引下标插入就可以 groups.forEach((item,index) => { let {id,pic,title,link,height,width}=item; let str=`<div class="item" data-id="${id}"> <a href="${link}"> <div class="imgbox" style="height:${height}px;width:${width}px"> <img src="${pic}" style="height:${height}px;width:${width}px"> </div> <p>${title}</p> </a> </div>`; cloumns[index].innerHTML+=str; }); } } render()
-
循环插入html
<!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>
<ul id="ulbox"></ul>
<script>
var data = [
{
id: 0,
pic: "images/3.jpg",
width: 300,
height: 170,
title:
"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证",
link: "https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89",
},
{
id: 1,
pic: "images/9.jpg",
width: 300,
height: 433,
title:
"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证",
link: "https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89",
},
{
id: 2,
pic: "images/5.jpg",
width: 300,
height: 200,
title:
"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证",
link: "https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89",
},
];
function render() {
var str = "";
data.forEach((item) => {
let { width, height } = item;
str += `<li>
<a href="#">height:${height}</a>
<span>width:${width}</span>
</li>`;
});
ulbox.innerHTML = str;
}
render();
</script>
</body>
</html>