前端面试基础知识整理【Day-8】

目录


前言

CSS篇

1.什么是BFC

2.flex布局里,flex:1代表什么

3.移动端1px边框问题是什么

4.rem和vw/vh的区别

手写代码篇

1.使用IntersectionObserver实现图片懒加载

2.模拟Object.create()


前言

前端面试基础知识整理【Day-1】-CSDN博客

前端面试基础知识整理【Day-2】-CSDN博客

前端面试基础知识整理【Day-3】-CSDN博客

前端面试基础知识整理【Day-4】-CSDN博客

前端面试基础知识整理【Day-5】-CSDN博客

前端面试基础知识整理【Day-6】-CSDN博客

前端面试基础知识整理【Day-7】-CSDN博客

CSS篇

1.什么是BFC

BFC是块级格式化上下文,在这个上下文内部的元素无论怎么改变,都不会影响到上下文外部的元素,反之亦然

常见的触发BFC的四种方法

  1. overflow:不为visible
  2. display:flex、grid、inline-block
  3. position:absolute、fixed
  4. float:不为none

BFC可以用来解决三个问题

  1. 解决父子元素Margin塌陷:子元素设置margin-top会把父元素也一起拽下来。可以给父元素触发BFC来解决
  2. 清除浮动:当父元素的高度依赖于子元素的高度时,子元素使用float:left,那么父元素高度会变成0,此时给父元素触发BFC即可解决
  3. 阻止文本环境:左边一个定宽浮动元素,右边元素如果不做处理,文字会环绕左侧,此时让右侧元素触发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,但在手机上看却非常粗

解决方案

  1. 利用伪类和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;
}
相关推荐
a1117761 小时前
优雅简历(html开源)
前端·开源·html
Cache技术分享1 小时前
330. Java Stream API - 处理 Optional 对象:像流一样优雅地使用 Optional
前端·后端
感性的程序员小王1 小时前
别再手撸架构图了!我写了个 AI 工具,把 Spring Boot 代码一键变成 Draw.io 流程图
前端·后端
猪头男2 小时前
【从零开始学习Vue|第七篇】深入组件——Props
前端
孟健2 小时前
AI 团队翻车之后,我想告诉你这 3 件事
前端
木斯佳2 小时前
前端八股文面经大全:字节前端一面(2026-2-1)·面经深度解析
前端·状态模式
宇木灵2 小时前
C语言基础-四、函数
c语言·开发语言·前端·学习
We་ct2 小时前
LeetCode 114. 二叉树展开为链表:详细解题思路与 TS 实现
前端·数据结构·算法·leetcode·链表·typescript
追随者永远是胜利者2 小时前
(LeetCode-Hot100)461. 汉明距离
java·算法·leetcode·职场和发展·go