一、什么是虚拟dom
描述真实dom的js对象。
二、DOM操作——怎样添加、移除、移动、复制、创建和查找节点
(1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
(2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore() //在已有的子节点前插入一个新的子节点
(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
getElementById() //通过元素Id,唯一性
三、dom曝光
(1)IntersectionObserver。
(2)window.scroll 监听滚动 + 使用 getBoundingClientRect() 相对于视口位置。
客户端可视区域:宽高不包括边框
相对距离: 宽高包括边框
滚动距离:
四、判断元素是否在可视区域的三种方法
(1) getBoundingClientRect
const getBoundingClientRectJudge = () => {
let domRect = card.getBoundingClientRect();
console.log(domRect)
let ch = document.documentElement.clientHeight;
let cw = document.documentElement.clientWidth;
let isInsert = true;
if (domRect.bottom < 0 || domRect.top > ch || domRect.right < 0 || domRect.left > cw) {
isInsert = false;
}
let background = null
if (isInsert) {
background = "green"
} else {
background = "red"
}
circle.style.background = background
}
window.addEventListener("scroll", _.throttle(getBoundingClientRectJudge, 500))
getBoundingClientRectJudge()
(2)IntersectionObserver
const card = document.querySelector(".card");
const circle = document.querySelector(".circle");
const observer = new IntersectionObserver((changes) => {
// changes是数组
changes.forEach(one => {
console.log(one)
let isIntersecting = one.isIntersecting
let background = null
if (isIntersecting) {
background = "green"
} else {
background = "red"
}
circle.style.background = background
})
})
observer.observe(card)
(3)offsetTop、scrollTop
function isInViePortOfOne(el){
const viewPortHeight = window.innerHeight || document.documentElement.clientHeight||document.body.clientHeight
const offsetTop = el.offsetTop;
const scollTop = document.documentElement.scrollTop
const top = offsetTop - scollTop;
return top <= viewPortHeight && top >= 0
}
五、路由实现原理
(1)hash:
hashChange
(2)history
pushState、popState方法
六、typeof输出
(1)typeof null => 'object'
(2)typeof undefined => 'undefined'
七、flex的三个简写属性是什么
(1)flex-grow:根据排列方向宽度或高度不够时,加上加权空白来调整子元素宽。
(2)flex-shrink:根据排列方向宽度或高度不够时,减去加权超出部分来调整子元素宽。
(3)flex-basis:指定调整前的子元素宽度,与width属性的作用完全相同
八、手写join,传入join(["1",undefined,null,false]"_")要输出"1---false"
function convert(value) {
if (value === undefined || value === null) {
return '';
}
return value;
}
function join(arr, separator) {
if (!separator) separator = ',';
return arr.reduce((result, value, index) => {
result += convert(value);
if (index < arr.length - 1) result += separator;
return result;
}, '');
}
(1)null、undefined调用toString会报错
九、给定了标签,用flex布局画一个五简出来
display 为 flex
:弹性盒子justify-content
:水平对齐方式
flex-start
:主轴靠左对齐(默认值)flex-end
:主轴靠右对齐center
:主轴水平居中对齐space-around
:两端对齐,两端间距是中间距离的一半space-between
:两端靠边对齐,中间等距space-evenly
:两端对齐,两端间距与中间距离等距align-items 为 center
:侧轴垂直居中对齐flex-wrap 为 wrap
, wrap 是换行,默认 nowrap 不换行flex-direction 为 column
:主轴和侧轴换位置,名字不变align-self 为 center
:自身侧轴垂直居中对齐(设置给弹性盒子的子元素)
<template>
<ul class="ul5">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</template>
<style>
/* ◆公共样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
float: left;
margin: 10px 0 0 10px;
width: 80px;
height: 100px;
background-color: #ccc;
border-radius: 5px;
}
li {
list-style: none;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: red;
}
.ul5 {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
}
.ul5 li:nth-child(3) {
margin: 0 30px;
}
</style>
参考:
我用 flex 布局 写了 9 个麻将
十、手写一个数组反转不使用rerevert函数
function reverse(arr) {
const newArr = [];
// eslint-disable-next-line no-restricted-syntax
for (let i = arr.length - 1; i >= 0; i--) newArr.push(arr[i]);
return newArr;
}
十一、溢出展示...的css单行文本代码
.ellipsis {
white-space: nowrap; /* 确保文本在一行内显示 */
overflow: hidden; /* 隐藏溢出的内容 */
text-overflow: ellipsis; /* 使用省略号表示文本溢出 */
}