20240229筆記

瀏覽器預加載器

手動:prefetch preload

<link rel="prefetch" href="next.html"> 
<link rel="preload" as="style" href="styles.css">
<link rel="preload" as="javascript" href="1.js">  

會盡早加載但不會過早執行script
自動:瀏覽器自身的智能預測和預先加載下一頁內容的功能。瀏覽器內部策略決定。

動態加載腳本
通過script標簽實現
缺點:對瀏覽器預加載器是不可見的

https2優點

  1. 多路復用
  2. 二進制分幀
  3. 頭部壓縮
  4. 服務器推送
  5. 優先級和流量控制

下載圖片并不一定要將image添加到dom中,只要添加了src就會下載。
下載Js需要添加src,并添加到dom中。

load事件和DOMContentLoaded事件的區別

load:整個頁面的所有資源已完成加載后觸發。
DOMContentLoaded:HTML文檔被完全加載和解析完成時觸發,不用等樣式表、img、js、其他資源加載完畢。在load之前觸發。

代理模式的作用

1.跟蹤屬性的訪問,設置get set函數,來跟蹤什么時候去獲取屬性,什么時候設置屬性,并進行攔截
2.隱藏屬性,在get set函數中進行判斷,來隱藏屬性,外部不能訪問這些屬性
3.屬性驗證,在get set函數中,set時進行屬性驗證,來決定是否允許還是拒絕賦值
4.函數參數與構造函數參數的驗證
在apply中,判斷arguments參數的類型
在construct中,判斷arguments參數的類型
5.數據綁定與可觀察對象
在construct中,將所有的proxy對象添加到list集合中,再把集合通過new Proxy中的set函數,來進行事件綁定程序
代理是object的透明抽象層,代理的反射Reflect的api,封裝了攔截的相對應的方法

const target = {
foo: "bar",
};const handler = {//定義一個get捕獲器,在獲取屬性和Object.create時候會調用,在代理對象上執行操作時才會調用,在目標對象上執行操作是正常行為
get() {return "handler";
},
};
const proxy = new Proxy(target, handler);
console.log(target.foo);
console.log(proxy.foo);console.log(Object.create(target)['foo']);
console.log(Object.create(proxy)['foo']);

捕獲器參數和反射api

const target = {foo:'bar'
}const handler = {//get捕獲器的參數get(target,property[,receiver])get(trapTarget,property,receiver){console.log(trapTarget===target);console.log(property);console.log(receiver===proxy);return trapTarget[property];}}
const proxy = new Proxy(target,handler);
console.log(target.foo);
console.log(proxy.foo);

空代理對象:指的是使用反射Reflect的api來定義捕獲器

const target = {foo:'bar'
}const handler = {//get捕獲器的參數get(target,property[,receiver])// get(trapTarget,property,receiver){//     return Reflect.get(...arguments)// }//簡潔的寫法get:Reflect.get}const proxy = new Proxy(target,handler);//捕獲所有方法,利用Reflect轉發給對應反射API的空代理來實現const proxy1 = new Proxy(target,Reflect);console.log(target.foo);console.log(proxy1.foo);console.log(proxy.foo);const target = {foo:'bar',baz:'121212'
}const handler = {//get捕獲器的參數get(target,property[,receiver])get(trapTarget,property,receiver){let decoration = '';if(property==='foo'){decoration='!!!';}return Reflect.get(...arguments)+decoration;//獲取foo和baz屬性時,顯示的結果不一樣}}const proxy = new Proxy(target,handler);console.log(target.foo);console.log(proxy.foo);console.log(target.baz);console.log(proxy.baz);

捕獲器不變式 每個捕獲的方法都知道目標對象的上下文,捕獲函數簽名

target的屬性不可配置時,在捕獲器中去修改屬性會報錯

  const target = {};Object.defineProperty(target,'foo',{configurable:false,writable:false,value:'bar'})const handler = {get(){return 'quz'}}const proxy = new Proxy(target,handler);console.log(proxy.a);
//   console.log(proxy.foo);

可撤銷代理 Proxy.revocable方法

const target = {foo:'bar'
}   
const handler = {get(){return 'inter'}
}
const {proxy,revoke} = Proxy.revocable(target,handler);// 撤銷函數和代理對象是在實例化的時候同時產生的
console.log(proxy.foo);
revoke();//撤銷后,Proxy與target之間的管理取消,而且不可恢復
console.log(proxy.foo);

使用反射API

  1. 反射API與對象API
    1.反射api并不限于捕獲處理程序
    2.大多數反射API在Object類型上有對應的方法
    Object上的方法適用于通用程序,反射方法適用于細粒度的對象控制與操作
  2. 狀態標記:表示執行操作是否成功,return true/false
    Reflect.defineProperty()
    Reflect.preventExtensions()
    Reflect.setPrototypeOf()
    Reflect.set()
    Reflect.deleteProperty()
  3. 用一等函數替代操作符
    Reflect.get():替代屬性訪問操作符
    Reflect.set():替代=賦值操作符
    Reflect.has():替代in或者with()
    Reflect.deleteProperty():替代delete操作符():
    Reflect.construct():替代new操作符
  4. 安全的應用函數
    Reflect.apply(myFunc,this.val,argumentsList)

代理另一個代理

const target = {foo: "bar",
};
const firstProxy = new Proxy(target,{get(){console.log('first proxy');return Reflect.get(...arguments);}
})
const secondProxy = new Proxy(firstProxy,{get(){console.log('second proxy');return Reflect.get(...arguments);q}
})
console.log(secondProxy.foo);

代理的問題與不足

  1. this的執行問題 解決: 重新配置代理,把代理實例改為代理本身
  2. 代理與內部槽位 有些內置ECMAScript內置類型可能會依賴代理無法控制的機制,比如Date類型方法的執行依賴this值上的內部槽位[[NumberDate]],且不能通過get set來訪問
const target = {thisValEqualsProxy() {return this === proxy;},
};
const proxy = new Proxy(target, {});
console.log(target.thisValEqualsProxy());//false
console.log(proxy.thisValEqualsProxy());//trueconst target = new Date();
const proxy = new Proxy(target,{});
console.log(target instanceof Date);
target.getDate();
console.log(proxy instanceof Date);
proxy.getDate();//報錯

BOM

  1. window對象
  2. location 對象

獲取query參數

let getQueryStringArgs = function () {//?a=1&b=2let location = {};location.search = "?a=1&b=2";let qs = location.search.length > 0 ? location.search.substring(1) : "";let args = {};//[a=1,b=2]qs.split("&").map((item) => item.split("=")).map((item) => {let name = decodeURIComponent(item[0]),value = decodeURIComponent(item[1]);name.length > 0 ? (args[name] = value) : "";});console.log(args);return args;
};let res = getQueryStringArgs();
console.log(res.c);

encodeURL encodeURIComponent

encodeURL對整個url進行編碼,但是會保留某些字符不變,不會對=&編碼,適用于整個URL編碼
更嚴格的編碼,會編碼所有非字母數字符號,確保所有引起解析問題的字符都被正確編碼,適用于URL的各個部分編碼

let url = 'https://example.com/path?name=John Doe&age=30';
console.log(encodeURI(url));
console.log(encodeURIComponent(url));
let name = encodeURIComponent('j A');
let age = encodeURIComponent(30);
let query = `name=${name}&age=${age}`;
console.log(query);

URLSearchParams構造函數,來創建search實例,實例有set get delete has方法,且實例是迭代對象

const s= new URLSearchParams('?a=1&b=2');
console.log(s.get('a'));
s.set('c',3);
console.log(s.has('a'))
s.delete('a');

navigator對象 瀏覽器對象

history

history.pushState() history.replaceState() popstate事件

客戶端檢測

  1. 能力檢測:在js運行時中使用一套簡單的檢測邏輯,測試瀏覽器是否支持某種特性。
    基于能力檢測進行瀏覽器分析:
    1. 檢測特性
    2. 檢測瀏覽器
    3. 能力檢測的局限:適合用于決定下一步該怎么做,不一定能夠作為辨識瀏覽器的標志。
  2. 用戶代理檢測:通過瀏覽器的用戶代理字符串確定使用的是什么瀏覽器。用戶代理字符串包含在每個http請求的頭部。
    navigator.userAgent
    1. 偽造用戶代理
    2. 分析瀏覽器
  3. 軟件與硬件檢測
    navigator.vendor 瀏覽器開發商信息
    navigator.platform 瀏覽器所在的操作系統
    screen.colorDepth screen.pixelDepth 設備中每像素用于顯示顏色的位數
    screen.orientation 屏幕信息
    瀏覽器元數據
    1. Geolocation API
      navigator.geolocation.getCurrentPosition()獲取position對象
    2. connection state和NetworkInformation API
      navigator.online
      online事件和offline事件
      navigator.connection 連接對象
      navigator.connection.onchange事件
    3. Battery Status API
      navigator.getBattery().then().catch()
    4. 硬件
      1. navigator.hardwareConcurrency:處理器核心數,不一定是實際的CPU核心數,而是表示瀏覽器可以并行執行的最大工作線程數量。
      2. navigator.deviceMemory:設備內存大小,>8時還是顯示為8。
      3. navigator.mediaDevices:獲取設備最大觸摸點數。

DOM:文檔對象模型

是W3C制定的一系列接口和協議,用于標識XML或HTML文檔的結構,允許開發者通過js等腳本語言動態訪問和操作網頁內容

  1. DOM 1:document.createElement() document.getElementById() node.appendChild()
  2. DOM 2:增加了對css樣式操作的支持element.style,遍歷文檔樹NodeIterator,TreeeWalker接口,事件處理模型addEvenetListener(),removeEventListener()
  3. DOM 3:DOMParser XMLSerializer,命名空間,DocumentType,Notation,Entity等節點接口,文本范圍操作,完善選擇器API,允許使用css選擇器來查找元素

DOM:節點層級

document:根節點
元素:html文檔元素,為根節點的唯一子節點
DOM中有12種節點類型,這些類型都繼承一種基本類型

  1. Node類型
     Node.ElEMENT_NODE(1)someNode.nodeType==Node.ELEMENT_NODE
   1. nodeName與nodeValue屬性2. 節點關系:每個節點都有childNodes屬性,為一個NodeList的實例,是一個實時的活動對象。一個節點不會在文檔中有兩個位置。length,hasChildNodes(),firstChild,lastChild,previousSibling,nextSibling,patentNode3.操作節點:appendChild(),insertBefore(),replaceChild(),removeChild(),cloneNode(false/true表示深復制還是淺復制)
  1. Document類型:文檔對象document是HTMLDocument的實例。
    文檔子節點:
     document.documentElement //htmldocument.body //bodydocument.doctype //doctype
    
    文檔信息
     document.titledocument.URLdocument.domaindocument.referrer
    
    定位元素
      document.getElementById()document.getElementByTagName()  document.getElementByTagName('div')['value']即為document.getElementByTagName('div').namedItem('value')document.getElementByTagName('*')document.getElementsByName()
    
    文檔寫入
      document.write() //在window.onload之后write則會覆蓋全Htmldocument.writeIn()document.open()document.close()
    
3. Element類型```javascriptdiv.nodeType //1div.tagName==div.nodeName//truediv.iddiv.titlediv.classNamediv.datasetdiv.getAttribute('class')//getAttribute用于取得自定義屬性的值div.getAttribute('id')div.getAttribute('title')div.getAttribute('xx')div.setAttribute(key,value)//設置屬性div.abcd=value//通過此種方法設置的屬性無法通過getAttribute獲取div.removeAttribute(key)div.attributes//是一個NamedNodeMap實例div.attributes.getNamedItem(name)div.attributes.removeNamedItem(name)div.attributes.setNamedItem(node)div.attributes.getNamedItem('id').nodeValue//返回的是id的值div.attributes['id'].nodeValue//返回的是id的值div.attributes['title'].nodeValue='1'//設置title的值為1document.createElement('div')element.childNodes```
4. Text類型```javascriptdiv.nodeType //3div.appendData(text)div.insertData(offset,text)div.deleteData(offset,count)div.replaceDate(offset,count,text)div.splitText(offset)div.substringData(offset,count)div.lengthdocument.createTextNode(text)element.normalize()//規范化文本節點,即合并兩個相鄰文本節點```
5. Comment類型```javascriptdiv.nodeType //8div.data//為注釋的文字document.createComment('這是注釋')```
6. CDATASection類型
7. DocumentType類型```javascriptdiv.nodeType //10document.doctype//<!DOCTYPE html>document.doctype.name//html```
8. DocumentFragment類型```javascriptdiv.nodeType //11document.createDocumentFragment()```
9. Attr類型```javascriptdiv.nodeType //2let attr = document.createAttribute('align')attr.value="left"element.setAttributeNode(attr)element.attributes['align'].value//leftelement.getAttributeNode('align').value//leftelement.getAttribute('align')//left//推薦使用getAttribute() removeAttribute() setAttribute()來操作屬性```

DOM編程

  1. 動態腳本
    document.createElement('script')
    
  2. 動態樣式
     document.createElement('link')
    
    NodeList是基于DOM文檔的實時查詢,使用時需緩存NodeList
  3. MutationObserver接口,可觀察的范圍包括屬 性變化、文本變化和子節點變化。可添加觀察范圍的白名單。
    使用:
     let observer = new MutationObserver(()=>console.log('change'))observer.observe(document.body,{attributes:true})
    
    回調與MutationRecord
    let observer = new MutationObserver((mutationRecords,mutationObserver)=>console.log(mutationRecords,mutationObserver));
    observer.disconnect()//提前終止執行回調,一刀切。終止后可重新關聯
    observer.observe(childA,{attributes:true});
    observer.observe(childB,{attributes:true});//observer可復用
    
  4. MutationObserverInit與觀察范圍:
    1. 觀察屬性
      attributes:true //所有的屬性
      attributeFilter:[‘foo’]//白名單
      attributeOldValue:true//是否保存舊值
    2. 觀察字符數據:Text Comment 的添加、刪除和修改
      characterData:true
      characterDataOldValue:true
    3. 觀察子節點
      childList:true
    4. 觀察子樹
      subtree:true
  5. 異步回調與記錄隊列:每個隊列對每一個mutationObserver實例都是唯一的,是所有DOM變化事件的有序列表
    記錄隊列:回調執行后,MutationRecord用不到了,記錄隊列會被清空,內容會被丟棄
    takeRecords:
      let observer = new MutationObserver((mutationRecords, mutationObserver) => {console.log(mutationRecords, mutationObserver);});observer.observe(document.body,{attributes:true});document.body.className='a';document.body.className='b';document.body.className='c';console.log(observer.takeRecords());//返回所有的MutationRecords實例,并清空 記錄隊列//observer.takeRecords();//希望斷開與目標對象的聯系,但又希望處理由于調用disconnect()而被拋棄的記錄隊列中的MutationRecord實例console.log(observer.takeRecords());
    
  6. 性能、內存與垃圾回收
    1. MutationObserver的引用
      MutationObserver實例與目標節點之間的引用關系是非對稱的。
      MutationObserver對目標節點是弱引用,不會妨礙垃圾回收程序回收目標節點。
      目標節點對MutationObserver是強引用,目標節點被刪除被回收,則MutationObserver也會被垃圾回收。
    2. MutationRecord的引用
      每個MutationRecord至少包含對已有DOM節點的一個引用。記錄隊列和回調處理的默認行為是耗盡這個隊列,并被回收。建議從MutationRecord中抽取最有用的信息并保存在新對象中,最后拋棄MutationRecord。

重繪和回流

  1. 重繪:dom外觀變化,但不影響其在文檔流中的位置時,需要重繪。修改顏色、背景色、border樣式等視覺屬性,會重繪dom及其子元素的像素,不會改變頁面布局。
    重繪比回流快,只涉及視覺層面的更新。
  2. 回流:回流也稱為布局或重排。DOM的position、size、display變化時,需要重新計算dom的布局、寬高等,并可能導致其他dom的position變化,觸發回流。
    回流操作代價大,瀏覽器要重新計算受影響的dom的幾何信息和相關節點,可能引發后續的重繪。
    觸發回流的操作:add/delete dom、修改width/height/fontSize/margin/padding等影響布局的熟悉,window的resize等。

優化網頁性能,盡量減少不必要的重繪和回流:

  1. 動態需要更改的樣式,盡量使用css類進行批量修改而非直接操作style屬性。
  2. 將涉及布局的樣式改動集中在一起一次性更新,而不是頻繁的分散修改。
  3. 使用css3硬件加速特性來提升渲染性能。如transform/opacity/will-change/backface-visibility/position:fixed||sticky/composite

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711424.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711424.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711424.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

調試工具vue,react,redux

React Developer Tools Redux DevTools Vue devtools 使用瀏覽器官方組件擴展搜索安裝

C語言練習:(力扣645)錯誤的集合

題目鏈接&#xff1a;645. 錯誤的集合 - 力扣&#xff08;LeetCode&#xff09; 集合 s 包含從 1 到 n 的整數。不幸的是&#xff0c;因為數據錯誤&#xff0c;導致集合里面某一個數字復制了成了集合里面的另外一個數字的值&#xff0c;導致集合 丟失了一個數字 并且 有一個數字…

枚舉和聯合(共用體)

目錄 枚舉枚舉類型的定義枚舉的優點 聯合&#xff08;共用體&#xff09;聯合類型的定義聯合的特點聯合大小的計算 枚舉 枚舉顧名思義就是一一列舉&#xff0c;把可能的取值一一列舉 枚舉類型的定義 enum Day &#xff0c; enum Sex &#xff0c;enum Color 都是枚舉類型{}中…

springboot生成圖片驗證碼(借鑒并分析)

目錄 一、CaptchaUtil代碼展示二、CaptchaController 代碼展示 一、CaptchaUtil代碼展示 package com.minster.yanapi.utils;import com.google.code.kaptcha.impl.DefaultKaptcha;import com.google.code.kaptcha.util.Config; import org.springframework.context.annotatio…

MMDetection3D v1.3.0安裝教程

MMDetection3D v1.3.0安裝教程 1. 系統環境2. 安裝2.1 基本環境安裝2.2 調整具體版本2.3 驗證2.4 安裝MinkowskiEngine和TorchSparse 3. 最終環境配置 根據 v1.3.0版本官方手冊測試后的安裝配置&#xff0c;親測可行。 1. 系統環境 項目版本日期Ubuntu18.04.06 LTS-顯卡RTX 2…

曾桂華:車載座艙音頻體驗探究與思考| 演講嘉賓公布

智能車載音頻 I 分論壇將于3月27日同期舉辦&#xff01; 我們正站在一個前所未有的科技革新的交匯點上&#xff0c;重塑我們出行體驗的變革正在悄然發生。當人工智能的磅礴力量與車載音頻相交融&#xff0c;智慧、便捷與未來的探索之旅正式揚帆起航。 在駕駛的旅途中&#xff0…

安裝 Distribution Registry

Distribution Registry是由容器部署&#xff0c;所有前提是需要安裝docker 參考文檔&#xff1a;https://docs.docker.com/engine/install/centos/ Registry 官網文檔 https://distribution.github.io/distribution/ 安裝Registry倉庫 docker run -d -p 5000:5000 --restartalw…

通過css修改video標簽的原生樣式

通過css修改video標簽的原生樣式 描述實現結果 描述 修改video標簽的原生樣式 實現 在控制臺中打開設置&#xff0c;勾選顯示用戶代理 shadow DOM&#xff0c;就可以審查video標簽的內部樣式了 箭頭處標出來的就是shodow DOM的內容&#xff0c;這些內容正常不可見的&#x…

MySQL 用了哪種默認隔離級別,實現原理是什么?

MySQL 的默認隔離級別是 RR - 可重復讀&#xff0c;可以通過命令來查看 MySQL 中的默認隔離級別。 RR - 可重復讀是基于多版本并發控制&#xff08;Multi-Version Concurrency Control&#xff0c;MVCC &#xff09;實現的。MVCC&#xff0c;在讀取數據時通過一種類似快照的方…

視覺三維重建colmap框架的現狀與未來

注&#xff1a;該文章首發3D視覺工坊&#xff0c;鏈接如下3D視覺工坊 前言 眾所周知&#xff0c;三維重建的發展已經進入了穩定期&#xff0c;尤其是離線方案的發展幾乎處于停滯期&#xff0c;在各大論刊上也很少見到傳統sfmmvs亮眼的文章。這也不難理解&#xff0c;傳統的多視…

MYSQL 解釋器小記

解釋器的結果通常通過上述表格展示&#xff1a; 1. select_type 表示查詢的類型 simple: 表示簡單的選擇查詢&#xff0c;沒有子查詢或連接操作 primary:表示主查詢&#xff0c;通常是最外層的查詢 subquery :表示子查詢&#xff0c;在主查詢中嵌套的查詢 derived: 表示派…

【王道數據結構】【chapter8排序】【P360t2】

試編寫一個算法&#xff0c;使之能夠在數組L[1……n]中找出第k小的元素&#xff08;即從小到大排序后處于第k個位置的元素&#xff09;&#xff08;可以直接采用排序&#xff0c;但下面的排序的代碼只是為了方便核對是不是第k小的元素&#xff0c;k從0開始計算&#xff09; #in…

出海手游收入一路高歌,營銷上如何成功?

出海手游收入一路高歌&#xff0c;營銷上如何成功&#xff1f; 以RPG和SLG為代表的中重度游戲一直是國內廠商在海外市場的傳統優勢品類&#xff0c;因為它們具有較高的投資回報率&#xff0c;是國內廠商在國際市場上取得成功的“吸金”利器。 據伽馬數據發布的《2023全球移動游…

SpringCloud搭建微服務之Consul服務配置

1. 概述 前面有介紹過Consul既可以用于服務注冊和發現&#xff0c;也可以用于服務配置&#xff0c;本文主要介紹如何使用Consul實現微服務的配置中心&#xff0c;有需要了解如何安裝Consul的小伙伴&#xff0c;請查閱SpringCloud搭建微服務之Consul服務注冊與發現 &#xff0c…

steam怎么付款

信用卡支付 登錄Steam賬戶&#xff0c;選擇需要購買的游戲或其他物品&#xff0c;點擊“加入購物車”。在購物車頁面點擊“去結賬”按鈕&#xff0c;進入付款頁面。在付款頁面選擇信用卡付款方式&#xff0c;填寫信用卡信息&#xff0c;輸入驗證碼&#xff0c;點擊確認付款。 …

Servlet 新手村引入-編寫一個簡單的servlet項目

Servlet 新手村引入-編寫一個簡單的servlet項目 文章目錄 Servlet 新手村引入-編寫一個簡單的servlet項目一、編寫一個 Hello world 項目1.創建項目2.引入依賴3.手動創建一些必要的目錄/文件4.編寫代碼5.打包程序6.部署7.驗證程序 二、更方便的處理方案&#xff08;插件引入&am…

autocrlf和safecrlf

git遠程拉取及提交代碼&#xff0c;windows和linux平臺換行符轉換問題&#xff0c;用以下兩行命令進行配置&#xff1a; git config --global core.autocrlf false git config --global core.safecrlf true CRLF是windows平臺下的換行符&#xff0c;LF是linux平臺下的換行符。…

98 greenplum 集群搭建過程中碰到的幾個問題

前言 最近有搭建 greenplum 集群的需求 然后 在搭建的過程中碰到了一些問題, 還是有一些時間開銷 并且問題也稍微有些復雜, 因此記錄一下 1. Do not have enough valid segments to start the array. 報錯日志信息如下 20220408:14:15:29:021638 gpstart:gp1:gpadmin-[I…

基于springboot+vue的公交線路查詢系統

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…

Find My運動相機|蘋果Find My技術與相機結合,智能防丟,全球定位

運動相機設計用于在各種運動和極限環境中使用&#xff0c;如徒步、登山、攀巖、騎行、滑翔、滑雪、游泳和潛水等&#xff0c;它們通常具有防抖防震、深度防水和高清畫質的特點&#xff0c;能夠適應顛簸劇烈的環境&#xff0c;甚至可以承受一定程度的摔落&#xff0c;一些運動相…