Vue路由中我想用前进和后退怎么实现
-
go, 正数前进,负数后退。
-
back,相当于
go(-1)
-
forward,相当于
go(1)
location对象有哪些部分
-
href
-
protocol,结尾有个
:
-
host,会加上端口号。
-
hostname
-
port
-
pathname,开头有个
/
-
search, 开头有个
?
-
hash, 开头有个
#
-
origin, 完整域名, 会加上端口号。
-
reload(boolean), boolean为true, 清空缓存加载, boolean为false: 本地缓存加载。
-
assign(url)指定一个url覆盖该页面,保存浏览器栈中的历史记录,类似于
history.pushState()
。同给href
赋值一样的效果。 -
replace(url)指定一个url覆盖该页面,不保存浏览器栈中的历史记录,类似于
history.replaceState()
。 -
toString(),读取效果和href一样,但是不能修改url值。
解析search
const queryString = '?name=zh&age=22'
const queryParams = new URLSearchParams(queryString)
console.log(queryParams)
const paramObj = Object.fromEntries(queryParams)
console.log(paramObj)
URL
URL 接口也是和url有关的
也可以调用url.searchParams
去获取search中的内容
const parsedUrl = new URL(window.location.href);
console.log(parsedUrl.searchParams.get("id"));
他有两个静态方法,对于本地预览文件是非常有用的。
-
URL.createObjectURL(file)
,接受一个文件类型对象,返回一个blob:
预览地址。 -
URL.revokeObjectURL(url)
,在不需要使用预览地址的时候,可以调用该方法进行删除,释放内存。
URL 编码和解码
该方法可以对URI(通用资源标识符)进行编码,以便发送给浏览器。有效的URI中不能包含某些特殊的字符,例如空格。则该方法用特殊的UTF-8编码替换掉这些特殊字符。
-
encodeURI() 主要用于整个URI,因为它不会对本身属于URI的特殊字符进行编码。
-
encodeURIComponent() 主要用于编码URI中某一段,因为他会对URI中任何非标准字符进行编码。协议的
://
也会被编码。 -
decodeURI()用于对encodeURI编码的字符解码,不会解码url中的标准字符被编码的内容。
-
decodeURIComponent()能够解码任何特殊字符的编码
let uri1 = 'https://www.bai du.com'
console.log(encodeURI(uri1))
console.log(encodeURIComponent(uri1))
let uri2 = 'https%3A%2F%2Fwww.bai%20du.com'
console.log(decodeURI(uri2))
console.log(decodeURIComponent(uri2))
一般来说,我们使用encodeURIComponent()
方法更多,因为在实践中更常见的是查询字符串参数而不是对基础URI进行编码
hash模式怎么实现前进和后退
如果是vue的话,它内部的api也是支持hash模式的。如果问我原生实现,我觉得应该是将用户访问的hash保存在数组中,当想要后退和前进的时候,可以通过findIndex
查找到当前hash在数组中的位置进行操作。
浏览器为什么只能建立6个连接
浏览器限制并行连接数的原因主要是出于性能和资源管理的考虑。在HTTP/1.1协议中,浏览器通常限制每个域名下的并行连接数,以避免过多的连接占用系统资源并降低性能。
-
性能管理:每个打开的连接都需要占用系统资源,包括网络带宽、内存和CPU。如果允许大量并行连接,系统资源可能会迅速耗尽,导致性能下降。
-
防止过度竞争:当多个连接尝试从同一域名获取资源时,会发生竞争条件。通过限制并行连接数,可以减少竞争,从而更有效地加载网页。
-
遵守规范:HTTP/1.1规范推荐每个浏览器最多同时建立6个连接,以平衡性能和资源消耗。这个数字在不同浏览器中可能有轻微的差异,但通常是一个合理的默认值。
需要指出的是,随着HTTP/2和HTTP/3的出现,这些限制有所松动。这两个新的HTTP协议支持多路复用,允许多个请求和响应在同一个连接上并行传输,而不需要多个连接。因此,它们在提高性能和减少连接管理方面更为高效,不再需要像HTTP/1.1那样强制限制并行连接数。
一些常见但迷惑元素类型
需要注意的是,虽然有些元素符合行内块特性,但是display并不是inline-block,一些元素符合块级元素,但是display并不是block...
display: block
-
option
-
form
-
ul
-
ol
-
dd
-
dl
-
dt
display: inline-block
-
input
-
select
-
button
-
textarea
display: inline
-
img
-
vedio
伪类伪元素
伪类: 选择处于特定状态的元素。
伪元素:虚拟出一个元素,允许你对被选择元素的特定部分修改样式。
如何获取伪元素,使用`getComputedStyle`
window.getComputedStyle(element, "::after")
阻止冒泡,阻止默认行为
-
preventDefault()
阻止默认行为,但是不阻止冒泡。 -
event.stopPropagation()
,同一个dom元素的事件监听器添加的全部事件不会被阻止,只会阻止不同元素的。 -
event.stopImmediatePropagation()
,同一dom元素的事件监听器中添加的全部事件也会被阻止。 但是根据js代码执行顺序,写在前面有阻止的事件监听器的事件是不会被阻止的。 -
return false
阻止冒泡和默认行为。阻止的冒泡好像是阻止相同类型不同dom元素,不相同类型和同一个dom元素的不会被阻止。
loaded和DOMContentLoaded区别
DOMContentLoaded
和 load
都是与页面加载和渲染相关的事件,但它们在触发时机和内容上有一些不同。
DOMContentLoaded
事件:
DOMContentLoaded
事件在文档的 HTML 和相关资源(如CSS、脚本等)都已经被下载解析完毕,但在图片和其他媒体资源加载之前触发。这意味着文档的结构(DOM)已经准备好,可以被 JavaScript 操作,但页面的所有资源(如图片)可能还在加载中。
通常,DOMContentLoaded
事件用于执行与文档结构相关的 JavaScript 操作,如添加事件处理程序、修改 DOM 元素等。这个事件的目的是在页面加载期间执行初始化脚本,而无需等待所有资源完全加载。
load
事件:
load
事件在整个页面及其所有资源(包括图片、样式表、脚本等)都已经完全加载和渲染之后触发。这意味着页面已经准备好供用户交互和浏览,所有内容都已经可见。
load
事件通常用于执行那些依赖于页面所有资源已经加载完毕的操作,如测量页面元素的尺寸、启动动画或执行需要确保所有内容已加载的功能。这通常发生在用户可以与页面进行交互之前。
DOMContentLoaded
事件在文档结构就绪后触发,而 load
事件在整个页面及其所有资源都加载完毕后触发。通常,如果你的 JavaScript 代码只需要访问和修改文档的结构,你可以使用 DOMContentLoaded
事件,因为它会更早触发,而不需要等待所有资源加载完成。如果你的代码依赖于页面上的资源,例如图片或样式表,那么你应该等待 load
事件触发。
闭包和作用域区别
作用域(Scope):
-
作用域定义了变量或标识符的可见性和生命周期。它确定了代码中的哪些部分可以访问特定变量。
-
JavaScript 中有两种主要类型的作用域:全局作用域和局部作用域。全局作用域定义在整个程序中,而局部作用域通常在函数内定义。
-
在作用域内,内部变量可以访问外部变量,但外部变量不能直接访问内部变量。
-
作用域链定义了在变量查找过程中的顺序,它是由嵌套的作用域决定的。
闭包(Closure):
-
闭包是函数以及其周围作用域的组合。它可以在函数定义之后访问外部作用域的变量。
-
闭包可以捕获包含它的函数的局部变量,即使包含函数已经执行完毕,这些局部变量依然可以被闭包函数引用。
-
闭包通常用于创建私有变量,模拟块级作用域,以及保存函数状态。
-
闭包可以使函数在不同的作用域中运行,它不仅可以访问自己的作用域,还可以访问包含它的函数的作用域。
关键区别:
-
作用域是定义变量的可见性和生命周期,它决定了哪些变量在特定作用域中可用。
-
闭包是函数和其包围的作用域的组合,它允许函数访问包含它的作用域的变量,即使包含函数已经执行完毕。就是延长作用域生命周期。
在实际编程中,闭包常常用于处理异步操作、封装私有数据、创建工厂函数等,而作用域是 JavaScript 中变量的可见性和生命周期的基础,它们共同构建了 JavaScript 代码的结构和行为。
packages.json中peerDependencies和peerDependenciesMeta详细说明
在 package.json
, peerDependencies
和 peerDependenciesMeta
是与依赖项管理相关的字段,用于描述模块间的特殊依赖关系,尤其在开发库或框架时非常有用。
peerDependencies
用于声明一组对等依赖关系(Peer Dependencies)。它表明你的模块在运行时需要另一个模块作为“对等”依赖关系,因为你的模块是为与之有互操作性的特定版本的那个模块而设计的。
"peerDependencies": {
"module-name": "1.x"
}
这里的示例说明你的模块需要与 "module-name" 的 1.x 版本兼容。它告诉使用者,如果他们安装了你的模块,也必须安装并使用特定版本的 "module-name"。一般指定版本都是模糊版本。
使用项目侧模块依赖。打包时可以部将其打包进入。
peerDependenciesMeta
提供有关对等依赖关系的额外元信息。
"peerDependenciesMeta": {
"module-name": {
"optional": true
}
}
在此示例中,peerDependenciesMeta
允许你提供额外的信息。例如,"optional": true
表示 module-name
是可选的对等依赖。这意味着你的模块可以与 module-name
有更松散的互操作性,而不一定需要强制依赖于特定版本。
这两个字段通常在开发复杂模块时使用,尤其当你的模块需要与其他模块特定版本保持兼容时非常有用。它们确保使用者知道他们必须安装的对等依赖,并为这些依赖提供一些额外的元信息,例如对可选依赖的处理方式。
@import导入css的缺点
@import
是一种用于在CSS中导入外部样式表的方式,但它具有一些缺点,这些缺点可能会影响性能和开发过程的效率:
-
性能问题:
-
@import
是同步加载的,这意味着在加载主CSS文件时,会等待导入的外部CSS文件全部下载完成后再继续加载页面。这会导致页面加载速度较慢,特别是当有多个@import
嵌套时。
-
-
不适用于异步加载:
-
@import
不支持异步加载,这使得难以在页面加载后动态加载CSS文件,例如通过JavaScript。这在一些情况下可能不方便,尤其是在需要按需加载CSS的单页应用程序中。
-
-
可维护性:
-
使用
@import
可能导致样式表的可维护性下降。当样式表嵌套多个@import
规则时,不容易追踪依赖关系和理解整个样式表结构,这可能使样式表变得混乱和难以管理。
-
-
浏览器兼容性:
-
一些古老的浏览器可能不支持
@import
或支持有限,这可能会导致兼容性问题。虽然现代浏览器通常支持@import
,但如果您需要支持较旧的浏览器,就需要谨慎使用。
-
-
附加HTTP请求:
-
使用
@import
会导致额外的HTTP请求,因为每个导入的外部CSS文件都需要单独的HTTP请求。这可能会导致性能瓶颈,尤其是在移动设备上或在慢速网络连接下。
-
-
顺序问题:
-
@import
导入的样式表会按照它们在主样式表中的顺序被加载。这可能会导致样式层叠顺序出现问题,因为后导入的样式表可能会覆盖前导入的样式表规则。
-
由于上述缺点,现在通常更倾向于使用 <link>
元素来引入外部样式表,因为它们是并行加载的,对异步加载更友好,并提供更好的性能和可维护性。如果您要使用 @import
,请谨慎使用,确保仅在适当的情况下使用,以避免性能和维护问题。
sort返回值
经过排序的原始数组的引用。
const tempArray = [1, 2, 3, 4, 5];
tempArray.unshift(6);
tempArray.splice(1, 2);
tempArray.pop(1);
tempArray.slice(2);
tempArray.concat([3, 4]);
const result = tempArray.sort((a, b) => {
return b - a;
});
result.push(5);
result.splice(2);
console.log(tempArray);
如何让不在可视界面的元素平滑滚动到可视区域
让非可见元素平滑滚动到可见区域内
const element = document.getElementsByClassName("bottom")[0]
element.scrollIntoView({behavior: 'smooth'})