埋点SDK
pv(page viwe)
同一用户对同一页面的访问次数
uv
独立用户访问次数,根据IP区分访客数
收集用户的隐私信息,优化性能体验,进行A/B业务决策
vite与webpack区别
- webpack npm run dev 先打包一次 webpack 入口文件 js
- vite npm run dev
no bundle模式启动不需要打包 入口文件是html 原生esm - vite esbuild开发模式 rollDown rust版本的 速度非常快
type="moudle"
- 模块化 可以使用import export
- 静态解析
- 异步加载
- 顶级await 作用域隔离
nevigator.sendBeacon
navigator.sendBeacon() 方法可用于通过 HTTP POST 将少量数据 异步 传输到 Web 服务器。
url
url 参数表明 data 将要被发送到的网络地址。
data 可选
data 参数是将要发送的 ArrayBuffer、ArrayBufferView、Blob、DOMString、FormData 或 URLSearchParams 类型的数据。
js
document.addEventListener("visibilitychange", function logData() {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});- 关闭页面时也能发送请求,相较于ajax,fetch,xhr等方法,sendBeacon不会阻塞页面的卸载,也不会在页面关闭时停止发送
- 但是不支持跨域 不支持json
nevigator.userAgent
- userAgent 是一个只读的属性,返回一个字符串,包含了用户代理头的值。
- navigator.userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值。
手写vite plugin
js
import type { Plugin } from "vite"
const plugin = ():Plugin =>{
return {
name:'vite-plugin-tracker',
transform(code,id){
// console.log(code,id)
}
}
}API Element.getBoundingClientRect()
Element.getBoundingClientRect() 方法返回一个 DOMRect 对象,其提供了元素的大小及其相对于视口的位置。
getBoundingClientRect()
返回值是一个 DOMRect 对象,是包含整个元素的最小矩形(包括 padding 和 border-width)。该对象使用 left、top、right、bottom、x、y、width 和 height 这几个以像素为单位的只读属性描述整个矩形的位置和大小。除了 width 和 height 以外的属性是相对于视图窗口的左上角来计算的。

API getAttribute()
getAttribute() 返回元素上一个指定的属性值。如果指定的属性不存在,则返回 null 或 "" (空字符串)
API MutationObserver
MutationObserver 接口提供了监视对DOM树所做更改的能力。
js
// 选择需要观察变动的节点
const targetNode = document.getElementById("some-id");
// 观察器的配置(需要观察什么变动)
const config = { attributes: true, childList: true, subtree: true };
// 当观察到变动时执行的回调函数
const callback = function (mutationsList, observer) {
// Use traditional 'for loops' for IE 11
for (let mutation of mutationsList) {
if (mutation.type === "childList") {
console.log("A child node has been added or removed.");
} else if (mutation.type === "attributes") {
console.log("The " + mutation.attributeName + " attribute was modified.");
}
}
};
// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(callback);
// 以上述配置开始观察目标节点
observer.observe(targetNode, config);
// 之后,可停止观察
observer.disconnect();EventTarget.addEventListener()
EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。
error 事件在资源加载失败,如 无法加载时触发。
- e.lineno 行数
- e.colno 列数
- e.filename 文件名
- e.message 错误信息
Vue 路由模式 history和hash
hash
- hash模式下,url中的hash值是不会被包含在HTTP请求中的,所以改变hash不会重新加载页面
- hash模式下,hash值改变会触发hashchange事件
- hash模式下,hash值改变会在浏览器的访问历史中增加一个记录,点击后退按钮会导航到前一个记录
js
window.addEventListener('hashchange',function(e){
send({
type:'pv-hash',
data:{
oldur:e.oldURL,
newurl:e.newURL
},
text:'pv-hash'
})
})history
- popstate 事件在使用 history.pushState() 或 history.replaceState() 方法时,通过浏览器的前进或后退按钮触发。(每当激活同一文档中不同的历史记录条目时,popstate 事件就会在对应的 window 对象上触发。
- pushstate不支持直接监听 需要重写
pushstate
- 导航到新页面:当用户点击一个链接或按钮时,你可以使用 pushState 方法来更新 URL,并加载新页面的内容,而无需重新加载整个页面。
- 动态加载内容:在单页应用中,当你通过 AJAX 请求加载新内容时,可以使用 pushState 方法来更新 URL,以便用户可以通过浏览器的前进和后退按钮导航。
- 表单提交:在处理表单提交时,可以使用 pushState 方法来更新 URL,而不重新加载页面。
js
//手写pushState
const pushstate = history.pushState
window.history.pushState = function(state:any,title:string,url?:string | null){
const res = pushstate.call(this,arguments)
const e = new Event('pushState')
window.dispatchEvent(e)
return res
}
window.addEventListener('pushState',function(e){
send({
type:'pv-pushState',
data:{
href:location.href
},
text:'pv-pushState'
})
})ajax fetch 监听
需要重写XMLHttpRequest.prototype.open/send/fetch方法
js
export default function request(send:send){
//重写ajax
const OriginOpen = XMLHttpRequest.prototype.open
const OriginSend = XMLHttpRequest.prototype.send
XMLHttpRequest.prototype.open = function(method:string, url:string | URL, async:boolean = true, user?:string | null, password?:string | null){
send({
type:'ajax',
data:{
method,
url,
async,
user,
password
},
text:'ajax'
})
OriginOpen.call(this,method,url,async,user,password)
}
XMLHttpRequest.prototype.send = function(data:any){
send({
type:'ajax',
data,
text:'ajax'
})
OriginSend.call(this,data)
}
const OrginFetch = window.fetch
window.fetch = function(...args:any[]): Promise<Response> {
send({
type:'fetch',
data:args,
text:'fetch'
})
return OrginFetch.apply(this, args)
}
}