批改状态:合格
老师批语:以后不要这样提交作业了, 多天作业一天提交
写现懒加载的实现原理,并代码实例演示
* 可视区高度: 用户可以看到的窗口高宽,通常小于文档高度
* 滚动距离: 有滚动条的情况下,元素滚动条顶部到窗口顶部的距离
* 自定义属性: data-为前缀的自定义元素属性
* 滚动事件`scroll`: 当窗口滚动时触动发
* 加载事件`load`: 当html文档与资源全部加载完成时触发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>懒加载</title>
</head>
<body style="height: 2000px">
<script>
var container=document.createElement('div');
container.setAttribute('align','center');
// 创建文档片段, 可以理解为保存在内存中的页面中的小组件
// createdocumentfragment()方法创建了一虚拟的节点对象,节点对象包含所有属性和方法。
var frag=document.createDocumentFragment();
// 页面中的图片,我们全部动态创建,使用文档片段提升加载效率
for(var i=1;i<=8;i++){
var imgUrl='images/'+i+'.jpg';
var img=document.createElement('img');
// 设置统一显示的占位图片
img.setAttribute('src','images/loading.gif');
// 将真实的图片地址保存到自定义属性data-src中
img.setAttribute('data-src',imgUrl);
// 自定义图片样式
img.setAttribute('style','width:600px;height:300px;margin:5px;');
// 先把图片添加到文档片段中, 因为是在内存中操作, 不会引起页面抖动,也不会触发大量的DOM操作
frag.appendChild(img);
}
// 将保存在文档片段中的所有图片添加到容器中
container.appendChild(frag);
// 再把容器,插入到页面的唯一元素<script>之前
document.body.insertBefore(container,document.body.firstElementChild);
// 监听窗口的滚动事件, 当用户拉到滚动条时, 自动触发自定义的图片懒加载事件方法
window.addEventListener('scroll',lazyLoaded,false);
// 自定义懒加载事件方法
function lazyLoaded() {
// documentElement 属性可返回文档的根节点。<html>
// console.log(document.documentElement);//获取<html>
// 获取滚动高度
var scrollTop=document.documentElement.scrollTop;
// 可视区高度
var clientHeight=document.documentElement.clientHeight;
// 图片懒加载
// 获取所有图片,并转为数组
var imgs = document.images;
var imgArr=Array.prototype.slice.call(imgs,0);
// 遍历所有图片,确定哪些需要显示出来
imgArr.forEach(function (img) {
// 关键步骤: 当图片进入到窗口可视区时需要显示出来
// 图片顶部的距离如果小于可视区高度与可视区滚动距离之和时,说明已进入可视区
if(img.offsetTop<=(scrollTop+clientHeight)){
// 设置img真实的src图片地址,并显示出来
img.setAttribute('src',img.dataset.src);
}
});
}
// 发现首次显示的时候,没有图片被加载,需要再添加一个load事件的监听器
// load: 当页面加载完成会自动调用
window.addEventListener('load',lazyLoaded,false);
</script>
</body>
</html>点击 "运行实例" 按钮查看在线实例
运行结果:
2. 写出选项卡的实现原理, 并代码实例演示
* 自定义属性: 标签页与详情页通过`data-index`建立关联
* classList: 优雅的操作元素的类样式
* forEach(): 优雅的遍历数组对象,注意参数是一个回调函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>选项卡</title>
<style>
ul,li{
margin: 0;
padding: 0;
list-style: none;
}
a{
text-decoration: none;
}
a:hover{
color: red;
text-decoration-color: red;
text-decoration-line:underline ;/*underline 定义文本下的一条线。*/
}
.tab-container{
width: 450px;
height: 300px;
}
.tab-nav{
/*清浮动*/
overflow: hidden;
}
.tab-nav ul li{
float: left;
width: 150px;
height: 60px;
line-height: 60px;
text-align: center;
font-size: 1.2rem;
}
.tab-nav .active{
background-color: lightblue;
border-bottom: 1px solid red;
}
.tab-content .detail{
line-height: 35px;
min-height: 200px;
padding: 20px 10px;
display: none;
}
.tab-content .detail.active{
background-color: lightblue;
display: block;
}
</style>
</head>
<body>
<div class="tab-container">
<!-- tab标签导航-->
<div class="tab-nav">
<ul>
<li class="active" data-index="1">HTML/CSS</li>
<li data-index="2">JavaScript</li>
<li data-index="3">服务端</li>
</ul>
</div>
<!-- tab标签对应的内容-->
<div class="tab-content">
<div class="detail active" data-index="1">
<ul>
<li><a href="">HTML</a></li>
<li><a href="">CSS</a></li>
<li><a href="">LayUI</a></li>
</ul>
</div>
<div class="detail" data-index="2">
<ul>
<li><a href="">JavaScript</a></li>
<li><a href="">jQuery</a></li>
<li><a href="">Ajax</a></li>
</ul>
</div>
<div class="detail" data-index="3">
<ul>
<li><a href="">PHP</a></li>
<li><a href="">Java</a></li>
<li><a href="">C++</a></li>
</ul>
</div>
</div>
</div>
<script>
// 获取标签页导航tab,以及可点击的所有标签页<li>,并转为数组对象
var tabnav=document.getElementsByClassName('tab-nav')[0];
// console.log(tabnav.firstElementChild.children);
//获取导航tab的所有li标签
var tabList=tabnav.firstElementChild.children;
var tabArr=Array.prototype.slice.call(tabList,0);
// 获取所有详情页,并转为数组对象
var detail=document.getElementsByClassName('detail');
var detailArr=Array.prototype.slice.call(detail,0);
// 利用事件冒泡机制, 将标签页tab的点击事件委托给父级导航条处理
tabnav.addEventListener('click',showDetail,false);
// 监听标签tab点击事件
function showDetail(event) {
//event.target: 当前被点击的li, event.currentTarget: 被添加的事件的对象,<div.tab_nav>
// console.log(event.target);
// console.log(event.currentTarget);
// 1. 清空原导航标签的样式,并设置当前正在被点击的标签页为当前页
tabArr.forEach(function (tab) {
tab.classList.remove('active');
});
event.target.classList.add('active');
// 2. 清空所在详情页样式,并根据与导航data-index属性的对应关系,显示对应的详情页面
detailArr.forEach(function (detail) {
detail.classList.remove('active');
});
detailArr.forEach(function (detail) {
// 详情页的index与导航标签的index相同时, 显示该页面
if(detail.dataset.index===event.target.dataset.index){
detail.classList.add('active');
}
});
}
// 还可以添加鼠标移入监听事件
// tabnav.addEventListener('mouseover',showDetail,false);
</script>
</body>
</html>点击 "运行实例" 按钮查看在线实例
运行结果:

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号