目录
1.使用IntersectionObserver实现图片懒加载
前言
CSS篇
1.什么是BFC
BFC是块级格式化上下文,在这个上下文内部的元素无论怎么改变,都不会影响到上下文外部的元素,反之亦然。
常见的触发BFC的四种方法:
- overflow:不为visible
- display:flex、grid、inline-block
- position:absolute、fixed
- float:不为none
BFC可以用来解决三个问题:
- 解决父子元素Margin塌陷:子元素设置margin-top会把父元素也一起拽下来。可以给父元素触发BFC来解决
- 清除浮动:当父元素的高度依赖于子元素的高度时,子元素使用float:left,那么父元素高度会变成0,此时给父元素触发BFC即可解决
- 阻止文本环境:左边一个定宽浮动元素,右边元素如果不做处理,文字会环绕左侧,此时让右侧元素触发BFC即可解决
2.flex布局里,flex:1代表什么
flex:1 是一个复合属性 (flex-grow、flex-shrink、flex-basis ),flex:1会被解析成:flex:1 1 0%;
| 拆解属性 | 设定的值 | 大白话解释 |
|---|---|---|
| flex-grow | 1 | 放大比例,如果有剩余空间,那么元素会按比例放大 |
| flex-shrink | 1 | 缩小比例,如果空间不够,那么元素会按比例缩小 |
| flex-basis | 0% | 基础大小,在分配多余空间之前,元素的初始体积是0(父元素的所有空间都被当做是剩余空间来参与分配) |
而flex:auto 等同于flex:1 1 auto;它的初始体积(flex-basis)是内容本身的宽度,这意味着,如果文字长的盒子,分到的最终空间会比文字短的盒子更大,而flex:1是无视内容长短,强制等分
3.移动端1px边框问题是什么
在移动端中,屏幕的物理像素非常密集,在CSS里写的:"border:1px solid black",浏览器会用2个或3个物理发光点来渲染这1个CSS像素,导致明明写的是1px,但在手机上看却非常粗
解决方案:
- 利用伪类和transfrom:scale(0.5)把边框整体缩小
javascript
.box {
position: relative;
}
.box::after {
content: '';
position: absolute;
top: 0; left: 0;
width: 200%;
height: 200%;
border: 1px solid #000;
transform-origin: 0 0;
transform: scale(0.5);
box-sizing: border-box;
pointer-events: none;
}
4.rem和vw/vh的区别
| 维度 | rem | vw/vh |
|---|---|---|
| 参照物 | HTML根标签(<html>)的font-size | 浏览器窗口的宽度和高度 |
| 原理 | 1rem永远等于html的font-size | 1vw/1vh永远等于视口宽度的1%、高度的1% |
| 适用范围 | 过去式 | 现代标准 |
| 复杂度 | 较高,需要配置JS脚本计算font-size | 极简,直接使用即可 |
手写代码篇
1.使用IntersectionObserver实现图片懒加载
javascript
const observer = new IntersectionObserver((entries, obs) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log('元素进入视口');
const img = entry.target;
img.src = img.dataset.src;
obs.unobserve(entry.target);
}
})
})
document.querySelectorAll('img').forEach(img => {
observer.observe(img);
})
一个完整的案例:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>懒加载真实案例</title>
<style>
body {
font-family: sans-serif;
text-align: center;
background-color: #f4f4f4;
padding: 0;
margin: 0;
}
.header {
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #333;
color: white;
}
.image-container {
max-width: 600px;
margin: 50px auto;
padding: 20px;
background: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.lazyload {
width: 100%;
height: 400px;
object-fit: cover;
background-color: #eee;
border-radius: 4px;
opacity: 0.3;
transition: opacity 0.5s ease-in-out;
}
.lazyload.loaded {
opacity: 1;
}
</style>
</head>
<body>
<div class="header">
<h1>图片懒加载演示</h1>
<p>向下滚动屏幕,注意观察下方图片的加载过程</p>
</div>
<div class="image-container">
<h3>第一张图</h3>
<img
class="lazyload"
src="https://via.placeholder.com/10x10?text=..."
data-src="https://picsum.photos/id/1018/800/400"
alt="风景1"
>
</div>
<div class="image-container">
<h3>第二张图</h3>
<img
class="lazyload"
src="https://via.placeholder.com/10x10?text=..."
data-src="https://picsum.photos/id/1015/800/400"
alt="风景2"
>
</div>
<div class="image-container">
<h3>第三张图</h3>
<img
class="lazyload"
src="https://via.placeholder.com/10x10?text=..."
data-src="https://picsum.photos/id/1019/800/400"
alt="风景3"
>
</div>
<script>
const options = {
rootMargin: '0px 0px 200px 0px'
};
const observer = new IntersectionObserver((entries, obs) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.getAttribute('data-src');
img.onload = () => {
console.log("oik");
img.classList.add('loaded');
};
obs.unobserve(img);
}
});
}, options);
document.querySelectorAll('.lazyload').forEach(img => {
observer.observe(img);
});
</script>
</body>
</html>
效果:

2.模拟Object.create()
老辈子写法:
javascript
function myObjectCreate(proto) {
if (typeof proto !== 'object' && typeof proto !== 'function') {
return proto;
}
function F() {};
F.prototype = proto;
return new F();
}
小辈子写法:
javascript
function myObjectCreate(proto) {
if (typeof proto !== 'object' && typeof proto !== 'function') {
return proto;
}
const obj = {};
Object.setPrototypeOf(obj, proto);
return obj;
}