[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdom-bom":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdom-bom":4580,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdom-bom":4606},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":4576,"stem":4577,"id":4578,"extension":4579},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdom-bom","浏览器相关 API","DOM 事件、存储、fetch、Worker、Observer 等由浏览器提供的 Web API（非 ECMAScript 核心）。HTML 结构见 标签。","技能小册",[12,13],"javascript","dom","2025-07-10",false,{"type":17,"value":18,"toc":4520},"minimark",[19,23,38,43,48,51,80,87,101,239,245,259,263,273,278,286,291,427,435,438,589,597,600,804,812,815,984,990,998,1005,1119,1123,1131,1151,1229,1236,1239,1277,1285,1305,1313,1527,1531,1535,1727,1744,1748,1751,1789,1793,1803,1850,1856,1942,1949,1952,2148,2153,2164,2168,2210,2235,2239,2243,2909,2913,3087,3091,3336,3340,3442,3446,3450,3453,3606,3616,3620,3764,3774,3777,3896,3900,3906,4091,4095,4099,4204,4208,4318,4321,4421,4424,4427,4430,4516],[20,21,8],"h1",{"id":22},"浏览器相关-api",[24,25,26,27,31,32,37],"p",{},"DOM 事件、存储、",[28,29,30],"code",{},"fetch","、Worker、Observer 等由浏览器提供的 Web API（非 ECMAScript 核心）。HTML 结构见 ",[33,34,36],"a",{"href":35},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fhtml\u002Ftag","标签","。",[39,40,42],"h2",{"id":41},"一dom-与事件","一、DOM 与事件",[44,45,47],"h3",{"id":46},"_1-事件流捕获-目标-冒泡","1. 事件流（捕获 → 目标 → 冒泡）",[24,49,50],{},"事件传播分为三个阶段：",[52,53,54,66,72],"ul",{},[55,56,57,61,62,65],"li",{},[58,59,60],"strong",{},"捕获阶段（capture phase）","：从 ",[28,63,64],{},"window"," 向下传播到目标元素。",[55,67,68,71],{},[58,69,70],{},"目标阶段（target phase）","：到达目标元素。",[55,73,74,77,78,37],{},[58,75,76],{},"冒泡阶段（bubble phase）","：从目标元素向上传播回 ",[28,79,64],{},[24,81,82,83,86],{},"默认情况下，事件在冒泡阶段触发。通过 ",[28,84,85],{},"addEventListener"," 的第三个参数可调整。",[44,88,90,91,93,94,97,98],{"id":89},"_2-addeventlistener-的-usecapture-与-once","2. ",[28,92,85],{}," 的 ",[28,95,96],{},"useCapture"," 与 ",[28,99,100],{},"once",[102,103,108],"pre",{"className":104,"code":105,"language":106,"meta":107,"style":107},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","element.addEventListener(\"click\", handler, {\n    capture: true, \u002F\u002F 在捕获阶段触发（默认为 false 冒泡阶段）\n    once: true, \u002F\u002F 触发一次后自动移除监听\n});\n\n\u002F\u002F 旧版写法：第三个参数为布尔值表示 useCapture\nelement.addEventListener(\"click\", handler, true);\n","js","",[28,109,110,150,170,185,197,204,210],{"__ignoreMap":107},[111,112,115,119,123,126,129,133,137,139,142,145,147],"span",{"class":113,"line":114},"line",1,[111,116,118],{"class":117},"su5hD","element",[111,120,122],{"class":121},"sP7_E",".",[111,124,85],{"class":125},"sGLFI",[111,127,128],{"class":117},"(",[111,130,132],{"class":131},"sjJ54","\"",[111,134,136],{"class":135},"s_sjI","click",[111,138,132],{"class":131},[111,140,141],{"class":121},",",[111,143,144],{"class":117}," handler",[111,146,141],{"class":121},[111,148,149],{"class":121}," {\n",[111,151,153,157,160,164,166],{"class":113,"line":152},2,[111,154,156],{"class":155},"skxfh","    capture",[111,158,159],{"class":121},":",[111,161,163],{"class":162},"syTEX"," true",[111,165,141],{"class":121},[111,167,169],{"class":168},"sutJx"," \u002F\u002F 在捕获阶段触发（默认为 false 冒泡阶段）\n",[111,171,173,176,178,180,182],{"class":113,"line":172},3,[111,174,175],{"class":155},"    once",[111,177,159],{"class":121},[111,179,163],{"class":162},[111,181,141],{"class":121},[111,183,184],{"class":168}," \u002F\u002F 触发一次后自动移除监听\n",[111,186,188,191,194],{"class":113,"line":187},4,[111,189,190],{"class":121},"}",[111,192,193],{"class":117},")",[111,195,196],{"class":121},";\n",[111,198,200],{"class":113,"line":199},5,[111,201,203],{"emptyLinePlaceholder":202},true,"\n",[111,205,207],{"class":113,"line":206},6,[111,208,209],{"class":168},"\u002F\u002F 旧版写法：第三个参数为布尔值表示 useCapture\n",[111,211,213,215,217,219,221,223,225,227,229,231,233,235,237],{"class":113,"line":212},7,[111,214,118],{"class":117},[111,216,122],{"class":121},[111,218,85],{"class":125},[111,220,128],{"class":117},[111,222,132],{"class":131},[111,224,136],{"class":135},[111,226,132],{"class":131},[111,228,141],{"class":121},[111,230,144],{"class":117},[111,232,141],{"class":121},[111,234,163],{"class":162},[111,236,193],{"class":117},[111,238,196],{"class":121},[24,240,241,244],{},[58,242,243],{},"常用模式","：",[52,246,247,253],{},[55,248,249,250],{},"阻止冒泡：",[28,251,252],{},"event.stopPropagation()",[55,254,255,256],{},"阻止默认行为：",[28,257,258],{},"event.preventDefault()",[44,260,262],{"id":261},"_3-事件委托原理与性能优化","3. 事件委托原理与性能优化",[24,264,265,268,269,272],{},[58,266,267],{},"原理","：利用事件冒泡，在父元素上监听事件，通过 ",[28,270,271],{},"event.target"," 判断实际触发的子元素。",[24,274,275,244],{},[58,276,277],{},"优点",[52,279,280,283],{},[55,281,282],{},"减少内存占用（无需为每个子元素绑定监听）。",[55,284,285],{},"动态添加的子元素自动拥有事件响应。",[24,287,288,244],{},[58,289,290],{},"示例",[102,292,294],{"className":104,"code":293,"language":106,"meta":107,"style":107},"document.getElementById(\"list\").addEventListener(\"click\", e => {\n    if (e.target.matches(\"li.item\")) {\n        console.log(\"点击了\", e.target.textContent);\n    }\n});\n",[28,295,296,341,378,414,419],{"__ignoreMap":107},[111,297,298,301,303,306,308,310,313,315,317,319,321,323,325,327,329,331,335,339],{"class":113,"line":114},[111,299,300],{"class":117},"document",[111,302,122],{"class":121},[111,304,305],{"class":125},"getElementById",[111,307,128],{"class":117},[111,309,132],{"class":131},[111,311,312],{"class":135},"list",[111,314,132],{"class":131},[111,316,193],{"class":117},[111,318,122],{"class":121},[111,320,85],{"class":125},[111,322,128],{"class":117},[111,324,132],{"class":131},[111,326,136],{"class":135},[111,328,132],{"class":131},[111,330,141],{"class":121},[111,332,334],{"class":333},"s99_P"," e",[111,336,338],{"class":337},"sbsja"," =>",[111,340,149],{"class":121},[111,342,343,347,350,353,355,358,360,363,365,367,370,372,375],{"class":113,"line":152},[111,344,346],{"class":345},"sVHd0","    if",[111,348,349],{"class":155}," (",[111,351,352],{"class":117},"e",[111,354,122],{"class":121},[111,356,357],{"class":117},"target",[111,359,122],{"class":121},[111,361,362],{"class":125},"matches",[111,364,128],{"class":155},[111,366,132],{"class":131},[111,368,369],{"class":135},"li.item",[111,371,132],{"class":131},[111,373,374],{"class":155},")) ",[111,376,377],{"class":121},"{\n",[111,379,380,383,385,388,390,392,395,397,399,401,403,405,407,410,412],{"class":113,"line":172},[111,381,382],{"class":117},"        console",[111,384,122],{"class":121},[111,386,387],{"class":125},"log",[111,389,128],{"class":155},[111,391,132],{"class":131},[111,393,394],{"class":135},"点击了",[111,396,132],{"class":131},[111,398,141],{"class":121},[111,400,334],{"class":117},[111,402,122],{"class":121},[111,404,357],{"class":117},[111,406,122],{"class":121},[111,408,409],{"class":117},"textContent",[111,411,193],{"class":155},[111,413,196],{"class":121},[111,415,416],{"class":113,"line":187},[111,417,418],{"class":121},"    }\n",[111,420,421,423,425],{"class":113,"line":199},[111,422,190],{"class":121},[111,424,193],{"class":117},[111,426,196],{"class":121},[44,428,430,431,434],{"id":429},"_4-自定义事件customevent","4. 自定义事件（",[28,432,433],{},"CustomEvent","）",[24,436,437],{},"用于组件通信或解耦逻辑。",[102,439,441],{"className":104,"code":440,"language":106,"meta":107,"style":107},"\u002F\u002F 创建并派发\nconst event = new CustomEvent(\"myEvent\", { detail: { id: 123 } });\nelement.dispatchEvent(event);\n\n\u002F\u002F 监听\nelement.addEventListener(\"myEvent\", e => {\n    console.log(e.detail.id);\n});\n",[28,442,443,448,506,520,524,529,553,580],{"__ignoreMap":107},[111,444,445],{"class":113,"line":114},[111,446,447],{"class":168},"\u002F\u002F 创建并派发\n",[111,449,450,453,457,461,464,467,469,471,474,476,478,481,484,486,488,491,493,497,500,502,504],{"class":113,"line":152},[111,451,452],{"class":337},"const",[111,454,456],{"class":455},"s_hVV"," event",[111,458,460],{"class":459},"smGrS"," =",[111,462,463],{"class":459}," new",[111,465,466],{"class":125}," CustomEvent",[111,468,128],{"class":117},[111,470,132],{"class":131},[111,472,473],{"class":135},"myEvent",[111,475,132],{"class":131},[111,477,141],{"class":121},[111,479,480],{"class":121}," {",[111,482,483],{"class":155}," detail",[111,485,159],{"class":121},[111,487,480],{"class":121},[111,489,490],{"class":155}," id",[111,492,159],{"class":121},[111,494,496],{"class":495},"srdBf"," 123",[111,498,499],{"class":121}," }",[111,501,499],{"class":121},[111,503,193],{"class":117},[111,505,196],{"class":121},[111,507,508,510,512,515,518],{"class":113,"line":172},[111,509,118],{"class":117},[111,511,122],{"class":121},[111,513,514],{"class":125},"dispatchEvent",[111,516,517],{"class":117},"(event)",[111,519,196],{"class":121},[111,521,522],{"class":113,"line":187},[111,523,203],{"emptyLinePlaceholder":202},[111,525,526],{"class":113,"line":199},[111,527,528],{"class":168},"\u002F\u002F 监听\n",[111,530,531,533,535,537,539,541,543,545,547,549,551],{"class":113,"line":206},[111,532,118],{"class":117},[111,534,122],{"class":121},[111,536,85],{"class":125},[111,538,128],{"class":117},[111,540,132],{"class":131},[111,542,473],{"class":135},[111,544,132],{"class":131},[111,546,141],{"class":121},[111,548,334],{"class":333},[111,550,338],{"class":337},[111,552,149],{"class":121},[111,554,555,558,560,562,564,566,568,571,573,576,578],{"class":113,"line":212},[111,556,557],{"class":117},"    console",[111,559,122],{"class":121},[111,561,387],{"class":125},[111,563,128],{"class":155},[111,565,352],{"class":117},[111,567,122],{"class":121},[111,569,570],{"class":117},"detail",[111,572,122],{"class":121},[111,574,575],{"class":117},"id",[111,577,193],{"class":155},[111,579,196],{"class":121},[111,581,583,585,587],{"class":113,"line":582},8,[111,584,190],{"class":121},[111,586,193],{"class":117},[111,588,196],{"class":121},[44,590,592,593,596],{"id":591},"_5-mutationobserver-监听-dom-变化","5. ",[28,594,595],{},"MutationObserver"," – 监听 DOM 变化",[24,598,599],{},"异步监听 DOM 树的变化（属性、子节点、文本等）。",[102,601,603],{"className":104,"code":602,"language":106,"meta":107,"style":107},"const observer = new MutationObserver(mutationsList => {\n    for (const mutation of mutationsList) {\n        if (mutation.type === \"childList\") {\n            console.log(\"子节点变化\");\n        }\n    }\n});\nobserver.observe(targetNode, {\n    attributes: true,\n    childList: true,\n    subtree: true,\n});\n\u002F\u002F 停止监听\nobserver.disconnect();\n",[28,604,605,628,651,681,703,708,712,720,737,750,762,774,783,789],{"__ignoreMap":107},[111,606,607,609,612,614,616,619,621,624,626],{"class":113,"line":114},[111,608,452],{"class":337},[111,610,611],{"class":455}," observer",[111,613,460],{"class":459},[111,615,463],{"class":459},[111,617,618],{"class":125}," MutationObserver",[111,620,128],{"class":117},[111,622,623],{"class":333},"mutationsList",[111,625,338],{"class":337},[111,627,149],{"class":121},[111,629,630,633,635,637,640,643,646,649],{"class":113,"line":152},[111,631,632],{"class":345},"    for",[111,634,349],{"class":155},[111,636,452],{"class":337},[111,638,639],{"class":455}," mutation",[111,641,642],{"class":459}," of",[111,644,645],{"class":117}," mutationsList",[111,647,648],{"class":155},") ",[111,650,377],{"class":121},[111,652,653,656,658,661,663,666,669,672,675,677,679],{"class":113,"line":172},[111,654,655],{"class":345},"        if",[111,657,349],{"class":155},[111,659,660],{"class":117},"mutation",[111,662,122],{"class":121},[111,664,665],{"class":117},"type",[111,667,668],{"class":459}," ===",[111,670,671],{"class":131}," \"",[111,673,674],{"class":135},"childList",[111,676,132],{"class":131},[111,678,648],{"class":155},[111,680,377],{"class":121},[111,682,683,686,688,690,692,694,697,699,701],{"class":113,"line":187},[111,684,685],{"class":117},"            console",[111,687,122],{"class":121},[111,689,387],{"class":125},[111,691,128],{"class":155},[111,693,132],{"class":131},[111,695,696],{"class":135},"子节点变化",[111,698,132],{"class":131},[111,700,193],{"class":155},[111,702,196],{"class":121},[111,704,705],{"class":113,"line":199},[111,706,707],{"class":121},"        }\n",[111,709,710],{"class":113,"line":206},[111,711,418],{"class":121},[111,713,714,716,718],{"class":113,"line":212},[111,715,190],{"class":121},[111,717,193],{"class":117},[111,719,196],{"class":121},[111,721,722,725,727,730,733,735],{"class":113,"line":582},[111,723,724],{"class":117},"observer",[111,726,122],{"class":121},[111,728,729],{"class":125},"observe",[111,731,732],{"class":117},"(targetNode",[111,734,141],{"class":121},[111,736,149],{"class":121},[111,738,740,743,745,747],{"class":113,"line":739},9,[111,741,742],{"class":155},"    attributes",[111,744,159],{"class":121},[111,746,163],{"class":162},[111,748,749],{"class":121},",\n",[111,751,753,756,758,760],{"class":113,"line":752},10,[111,754,755],{"class":155},"    childList",[111,757,159],{"class":121},[111,759,163],{"class":162},[111,761,749],{"class":121},[111,763,765,768,770,772],{"class":113,"line":764},11,[111,766,767],{"class":155},"    subtree",[111,769,159],{"class":121},[111,771,163],{"class":162},[111,773,749],{"class":121},[111,775,777,779,781],{"class":113,"line":776},12,[111,778,190],{"class":121},[111,780,193],{"class":117},[111,782,196],{"class":121},[111,784,786],{"class":113,"line":785},13,[111,787,788],{"class":168},"\u002F\u002F 停止监听\n",[111,790,792,794,796,799,802],{"class":113,"line":791},14,[111,793,724],{"class":117},[111,795,122],{"class":121},[111,797,798],{"class":125},"disconnect",[111,800,801],{"class":117},"()",[111,803,196],{"class":121},[44,805,807,808,811],{"id":806},"_6-intersectionobserver-懒加载无限滚动","6. ",[28,809,810],{},"IntersectionObserver"," – 懒加载、无限滚动",[24,813,814],{},"异步观察目标元素与视口（或指定祖先元素）的交叉状态。",[102,816,818],{"className":104,"code":817,"language":106,"meta":107,"style":107},"const observer = new IntersectionObserver(\n    entries => {\n        entries.forEach(entry => {\n            if (entry.isIntersecting) {\n                \u002F\u002F 进入视口，加载图片或更多数据\n                loadImage(entry.target);\n                observer.unobserve(entry.target); \u002F\u002F 一次加载后停止观察\n            }\n        });\n    },\n    { threshold: 0.1 }\n);\nobserver.observe(imgElement);\n",[28,819,820,836,845,864,882,887,904,930,935,944,949,965,971],{"__ignoreMap":107},[111,821,822,824,826,828,830,833],{"class":113,"line":114},[111,823,452],{"class":337},[111,825,611],{"class":455},[111,827,460],{"class":459},[111,829,463],{"class":459},[111,831,832],{"class":125}," IntersectionObserver",[111,834,835],{"class":117},"(\n",[111,837,838,841,843],{"class":113,"line":152},[111,839,840],{"class":333},"    entries",[111,842,338],{"class":337},[111,844,149],{"class":121},[111,846,847,850,852,855,857,860,862],{"class":113,"line":172},[111,848,849],{"class":117},"        entries",[111,851,122],{"class":121},[111,853,854],{"class":125},"forEach",[111,856,128],{"class":155},[111,858,859],{"class":333},"entry",[111,861,338],{"class":337},[111,863,149],{"class":121},[111,865,866,869,871,873,875,878,880],{"class":113,"line":187},[111,867,868],{"class":345},"            if",[111,870,349],{"class":155},[111,872,859],{"class":117},[111,874,122],{"class":121},[111,876,877],{"class":117},"isIntersecting",[111,879,648],{"class":155},[111,881,377],{"class":121},[111,883,884],{"class":113,"line":199},[111,885,886],{"class":168},"                \u002F\u002F 进入视口，加载图片或更多数据\n",[111,888,889,892,894,896,898,900,902],{"class":113,"line":206},[111,890,891],{"class":125},"                loadImage",[111,893,128],{"class":155},[111,895,859],{"class":117},[111,897,122],{"class":121},[111,899,357],{"class":117},[111,901,193],{"class":155},[111,903,196],{"class":121},[111,905,906,909,911,914,916,918,920,922,924,927],{"class":113,"line":212},[111,907,908],{"class":117},"                observer",[111,910,122],{"class":121},[111,912,913],{"class":125},"unobserve",[111,915,128],{"class":155},[111,917,859],{"class":117},[111,919,122],{"class":121},[111,921,357],{"class":117},[111,923,193],{"class":155},[111,925,926],{"class":121},";",[111,928,929],{"class":168}," \u002F\u002F 一次加载后停止观察\n",[111,931,932],{"class":113,"line":582},[111,933,934],{"class":121},"            }\n",[111,936,937,940,942],{"class":113,"line":739},[111,938,939],{"class":121},"        }",[111,941,193],{"class":155},[111,943,196],{"class":121},[111,945,946],{"class":113,"line":752},[111,947,948],{"class":121},"    },\n",[111,950,951,954,957,959,962],{"class":113,"line":764},[111,952,953],{"class":121},"    {",[111,955,956],{"class":155}," threshold",[111,958,159],{"class":121},[111,960,961],{"class":495}," 0.1",[111,963,964],{"class":121}," }\n",[111,966,967,969],{"class":113,"line":776},[111,968,193],{"class":117},[111,970,196],{"class":121},[111,972,973,975,977,979,982],{"class":113,"line":785},[111,974,724],{"class":117},[111,976,122],{"class":121},[111,978,729],{"class":125},[111,980,981],{"class":117},"(imgElement)",[111,983,196],{"class":121},[24,985,986,989],{},[58,987,988],{},"应用","：图片懒加载、无限滚动列表、曝光统计。",[44,991,993,994,997],{"id":992},"_7-resizeobserver-监听元素尺寸变化","7. ",[28,995,996],{},"ResizeObserver"," – 监听元素尺寸变化",[24,999,1000,1001,1004],{},"比 ",[28,1002,1003],{},"window.resize"," 更精确，可观察任意元素。",[102,1006,1008],{"className":104,"code":1007,"language":106,"meta":107,"style":107},"const resizeObserver = new ResizeObserver(entries => {\n    for (let entry of entries) {\n        console.log(entry.contentRect.width, entry.contentRect.height);\n    }\n});\nresizeObserver.observe(someElement);\n",[28,1009,1010,1033,1054,1093,1097,1105],{"__ignoreMap":107},[111,1011,1012,1014,1017,1019,1021,1024,1026,1029,1031],{"class":113,"line":114},[111,1013,452],{"class":337},[111,1015,1016],{"class":455}," resizeObserver",[111,1018,460],{"class":459},[111,1020,463],{"class":459},[111,1022,1023],{"class":125}," ResizeObserver",[111,1025,128],{"class":117},[111,1027,1028],{"class":333},"entries",[111,1030,338],{"class":337},[111,1032,149],{"class":121},[111,1034,1035,1037,1039,1042,1045,1047,1050,1052],{"class":113,"line":152},[111,1036,632],{"class":345},[111,1038,349],{"class":155},[111,1040,1041],{"class":337},"let",[111,1043,1044],{"class":117}," entry",[111,1046,642],{"class":459},[111,1048,1049],{"class":117}," entries",[111,1051,648],{"class":155},[111,1053,377],{"class":121},[111,1055,1056,1058,1060,1062,1064,1066,1068,1071,1073,1076,1078,1080,1082,1084,1086,1089,1091],{"class":113,"line":172},[111,1057,382],{"class":117},[111,1059,122],{"class":121},[111,1061,387],{"class":125},[111,1063,128],{"class":155},[111,1065,859],{"class":117},[111,1067,122],{"class":121},[111,1069,1070],{"class":117},"contentRect",[111,1072,122],{"class":121},[111,1074,1075],{"class":117},"width",[111,1077,141],{"class":121},[111,1079,1044],{"class":117},[111,1081,122],{"class":121},[111,1083,1070],{"class":117},[111,1085,122],{"class":121},[111,1087,1088],{"class":117},"height",[111,1090,193],{"class":155},[111,1092,196],{"class":121},[111,1094,1095],{"class":113,"line":187},[111,1096,418],{"class":121},[111,1098,1099,1101,1103],{"class":113,"line":199},[111,1100,190],{"class":121},[111,1102,193],{"class":117},[111,1104,196],{"class":121},[111,1106,1107,1110,1112,1114,1117],{"class":113,"line":206},[111,1108,1109],{"class":117},"resizeObserver",[111,1111,122],{"class":121},[111,1113,729],{"class":125},[111,1115,1116],{"class":117},"(someElement)",[111,1118,196],{"class":121},[39,1120,1122],{"id":1121},"二bom-操作浏览器对象模型","二、BOM 操作（浏览器对象模型）",[44,1124,1126,1127,1130],{"id":1125},"_1-history-对象-spa-路由核心","1. ",[28,1128,1129],{},"history"," 对象 – SPA 路由核心",[52,1132,1133,1139,1145],{},[55,1134,1135,1138],{},[28,1136,1137],{},"history.pushState(state, title, url)","：添加历史记录，不刷新页面。",[55,1140,1141,1144],{},[28,1142,1143],{},"history.replaceState(state, title, url)","：替换当前历史记录。",[55,1146,1147,1150],{},[28,1148,1149],{},"window.onpopstate","：监听浏览器前进\u002F后退。",[102,1152,1154],{"className":104,"code":1153,"language":106,"meta":107,"style":107},"\u002F\u002F 简易 SPA 路由\nwindow.addEventListener(\"popstate\", () => {\n    const path = location.pathname;\n    renderView(path);\n});\n",[28,1155,1156,1161,1187,1207,1221],{"__ignoreMap":107},[111,1157,1158],{"class":113,"line":114},[111,1159,1160],{"class":168},"\u002F\u002F 简易 SPA 路由\n",[111,1162,1163,1165,1167,1169,1171,1173,1176,1178,1180,1183,1185],{"class":113,"line":152},[111,1164,64],{"class":117},[111,1166,122],{"class":121},[111,1168,85],{"class":125},[111,1170,128],{"class":117},[111,1172,132],{"class":131},[111,1174,1175],{"class":135},"popstate",[111,1177,132],{"class":131},[111,1179,141],{"class":121},[111,1181,1182],{"class":121}," ()",[111,1184,338],{"class":337},[111,1186,149],{"class":121},[111,1188,1189,1192,1195,1197,1200,1202,1205],{"class":113,"line":172},[111,1190,1191],{"class":337},"    const",[111,1193,1194],{"class":455}," path",[111,1196,460],{"class":459},[111,1198,1199],{"class":117}," location",[111,1201,122],{"class":121},[111,1203,1204],{"class":117},"pathname",[111,1206,196],{"class":121},[111,1208,1209,1212,1214,1217,1219],{"class":113,"line":187},[111,1210,1211],{"class":125},"    renderView",[111,1213,128],{"class":155},[111,1215,1216],{"class":117},"path",[111,1218,193],{"class":155},[111,1220,196],{"class":121},[111,1222,1223,1225,1227],{"class":113,"line":199},[111,1224,190],{"class":121},[111,1226,193],{"class":117},[111,1228,196],{"class":121},[44,1230,90,1232,1235],{"id":1231},"_2-navigator-浏览器与设备信息",[28,1233,1234],{},"navigator"," – 浏览器与设备信息",[24,1237,1238],{},"常用属性：",[52,1240,1241,1247,1253,1259,1265,1271],{},[55,1242,1243,1246],{},[28,1244,1245],{},"navigator.userAgent","：用户代理字符串。",[55,1248,1249,1252],{},[28,1250,1251],{},"navigator.language","：当前语言。",[55,1254,1255,1258],{},[28,1256,1257],{},"navigator.onLine","：是否在线。",[55,1260,1261,1264],{},[28,1262,1263],{},"navigator.geolocation","：地理位置。",[55,1266,1267,1270],{},[28,1268,1269],{},"navigator.clipboard","：剪贴板 API（见下文）。",[55,1272,1273,1276],{},[28,1274,1275],{},"navigator.serviceWorker","：Service Worker 注册。",[44,1278,1280,1281,1284],{"id":1279},"_3-screen-屏幕信息","3. ",[28,1282,1283],{},"screen"," – 屏幕信息",[52,1286,1287,1293,1299],{},[55,1288,1289,1292],{},[28,1290,1291],{},"screen.width\u002Fheight","：屏幕分辨率。",[55,1294,1295,1298],{},[28,1296,1297],{},"screen.availWidth\u002FavailHeight","：可用区域（排除任务栏）。",[55,1300,1301,1304],{},[28,1302,1303],{},"screen.colorDepth","：色彩深度。",[44,1306,1308,1309,1312],{"id":1307},"_4-location-url-精细操作","4. ",[28,1310,1311],{},"location"," – URL 精细操作",[102,1314,1316],{"className":104,"code":1315,"language":106,"meta":107,"style":107},"\u002F\u002F 获取参数\nconst urlParams = new URLSearchParams(location.search);\nconst id = urlParams.get(\"id\");\n\n\u002F\u002F 跳转\nlocation.href = \"https:\u002F\u002Fexample.com\";\nlocation.assign(\"https:\u002F\u002Fexample.com\");\nlocation.replace(\"https:\u002F\u002Fexample.com\"); \u002F\u002F 无历史记录\nlocation.reload();\n\n\u002F\u002F 获取各部分\nlocation.protocol; \u002F\u002F \"https:\"\nlocation.host; \u002F\u002F \"example.com:8080\"\nlocation.pathname; \u002F\u002F \"\u002Fpath\"\nlocation.hash; \u002F\u002F \"#section\"\n",[28,1317,1318,1323,1347,1374,1378,1383,1404,1425,1449,1462,1466,1471,1485,1499,1512],{"__ignoreMap":107},[111,1319,1320],{"class":113,"line":114},[111,1321,1322],{"class":168},"\u002F\u002F 获取参数\n",[111,1324,1325,1327,1330,1332,1334,1337,1340,1342,1345],{"class":113,"line":152},[111,1326,452],{"class":337},[111,1328,1329],{"class":455}," urlParams",[111,1331,460],{"class":459},[111,1333,463],{"class":459},[111,1335,1336],{"class":125}," URLSearchParams",[111,1338,1339],{"class":117},"(location",[111,1341,122],{"class":121},[111,1343,1344],{"class":117},"search)",[111,1346,196],{"class":121},[111,1348,1349,1351,1353,1355,1357,1359,1362,1364,1366,1368,1370,1372],{"class":113,"line":172},[111,1350,452],{"class":337},[111,1352,490],{"class":455},[111,1354,460],{"class":459},[111,1356,1329],{"class":117},[111,1358,122],{"class":121},[111,1360,1361],{"class":125},"get",[111,1363,128],{"class":117},[111,1365,132],{"class":131},[111,1367,575],{"class":135},[111,1369,132],{"class":131},[111,1371,193],{"class":117},[111,1373,196],{"class":121},[111,1375,1376],{"class":113,"line":187},[111,1377,203],{"emptyLinePlaceholder":202},[111,1379,1380],{"class":113,"line":199},[111,1381,1382],{"class":168},"\u002F\u002F 跳转\n",[111,1384,1385,1387,1389,1392,1395,1397,1400,1402],{"class":113,"line":206},[111,1386,1311],{"class":117},[111,1388,122],{"class":121},[111,1390,1391],{"class":117},"href ",[111,1393,1394],{"class":459},"=",[111,1396,671],{"class":131},[111,1398,1399],{"class":135},"https:\u002F\u002Fexample.com",[111,1401,132],{"class":131},[111,1403,196],{"class":121},[111,1405,1406,1408,1410,1413,1415,1417,1419,1421,1423],{"class":113,"line":212},[111,1407,1311],{"class":117},[111,1409,122],{"class":121},[111,1411,1412],{"class":125},"assign",[111,1414,128],{"class":117},[111,1416,132],{"class":131},[111,1418,1399],{"class":135},[111,1420,132],{"class":131},[111,1422,193],{"class":117},[111,1424,196],{"class":121},[111,1426,1427,1429,1431,1434,1436,1438,1440,1442,1444,1446],{"class":113,"line":582},[111,1428,1311],{"class":117},[111,1430,122],{"class":121},[111,1432,1433],{"class":125},"replace",[111,1435,128],{"class":117},[111,1437,132],{"class":131},[111,1439,1399],{"class":135},[111,1441,132],{"class":131},[111,1443,193],{"class":117},[111,1445,926],{"class":121},[111,1447,1448],{"class":168}," \u002F\u002F 无历史记录\n",[111,1450,1451,1453,1455,1458,1460],{"class":113,"line":739},[111,1452,1311],{"class":117},[111,1454,122],{"class":121},[111,1456,1457],{"class":125},"reload",[111,1459,801],{"class":117},[111,1461,196],{"class":121},[111,1463,1464],{"class":113,"line":752},[111,1465,203],{"emptyLinePlaceholder":202},[111,1467,1468],{"class":113,"line":764},[111,1469,1470],{"class":168},"\u002F\u002F 获取各部分\n",[111,1472,1473,1475,1477,1480,1482],{"class":113,"line":776},[111,1474,1311],{"class":117},[111,1476,122],{"class":121},[111,1478,1479],{"class":117},"protocol",[111,1481,926],{"class":121},[111,1483,1484],{"class":168}," \u002F\u002F \"https:\"\n",[111,1486,1487,1489,1491,1494,1496],{"class":113,"line":785},[111,1488,1311],{"class":117},[111,1490,122],{"class":121},[111,1492,1493],{"class":117},"host",[111,1495,926],{"class":121},[111,1497,1498],{"class":168}," \u002F\u002F \"example.com:8080\"\n",[111,1500,1501,1503,1505,1507,1509],{"class":113,"line":791},[111,1502,1311],{"class":117},[111,1504,122],{"class":121},[111,1506,1204],{"class":117},[111,1508,926],{"class":121},[111,1510,1511],{"class":168}," \u002F\u002F \"\u002Fpath\"\n",[111,1513,1515,1517,1519,1522,1524],{"class":113,"line":1514},15,[111,1516,1311],{"class":117},[111,1518,122],{"class":121},[111,1520,1521],{"class":117},"hash",[111,1523,926],{"class":121},[111,1525,1526],{"class":168}," \u002F\u002F \"#section\"\n",[39,1528,1530],{"id":1529},"三canvas-与-webgl-基础简要","三、Canvas 与 WebGL 基础（简要）",[44,1532,1534],{"id":1533},"_1-canvas-2d","1. Canvas 2D",[102,1536,1538],{"className":104,"code":1537,"language":106,"meta":107,"style":107},"const canvas = document.getElementById(\"myCanvas\");\nconst ctx = canvas.getContext(\"2d\");\nctx.fillStyle = \"red\";\nctx.fillRect(10, 10, 100, 50);\nctx.beginPath();\nctx.arc(200, 75, 40, 0, 2 * Math.PI);\nctx.stroke();\n",[28,1539,1540,1569,1598,1619,1652,1665,1714],{"__ignoreMap":107},[111,1541,1542,1544,1547,1549,1552,1554,1556,1558,1560,1563,1565,1567],{"class":113,"line":114},[111,1543,452],{"class":337},[111,1545,1546],{"class":455}," canvas",[111,1548,460],{"class":459},[111,1550,1551],{"class":117}," document",[111,1553,122],{"class":121},[111,1555,305],{"class":125},[111,1557,128],{"class":117},[111,1559,132],{"class":131},[111,1561,1562],{"class":135},"myCanvas",[111,1564,132],{"class":131},[111,1566,193],{"class":117},[111,1568,196],{"class":121},[111,1570,1571,1573,1576,1578,1580,1582,1585,1587,1589,1592,1594,1596],{"class":113,"line":152},[111,1572,452],{"class":337},[111,1574,1575],{"class":455}," ctx",[111,1577,460],{"class":459},[111,1579,1546],{"class":117},[111,1581,122],{"class":121},[111,1583,1584],{"class":125},"getContext",[111,1586,128],{"class":117},[111,1588,132],{"class":131},[111,1590,1591],{"class":135},"2d",[111,1593,132],{"class":131},[111,1595,193],{"class":117},[111,1597,196],{"class":121},[111,1599,1600,1603,1605,1608,1610,1612,1615,1617],{"class":113,"line":172},[111,1601,1602],{"class":117},"ctx",[111,1604,122],{"class":121},[111,1606,1607],{"class":117},"fillStyle ",[111,1609,1394],{"class":459},[111,1611,671],{"class":131},[111,1613,1614],{"class":135},"red",[111,1616,132],{"class":131},[111,1618,196],{"class":121},[111,1620,1621,1623,1625,1628,1630,1633,1635,1638,1640,1643,1645,1648,1650],{"class":113,"line":187},[111,1622,1602],{"class":117},[111,1624,122],{"class":121},[111,1626,1627],{"class":125},"fillRect",[111,1629,128],{"class":117},[111,1631,1632],{"class":495},"10",[111,1634,141],{"class":121},[111,1636,1637],{"class":495}," 10",[111,1639,141],{"class":121},[111,1641,1642],{"class":495}," 100",[111,1644,141],{"class":121},[111,1646,1647],{"class":495}," 50",[111,1649,193],{"class":117},[111,1651,196],{"class":121},[111,1653,1654,1656,1658,1661,1663],{"class":113,"line":199},[111,1655,1602],{"class":117},[111,1657,122],{"class":121},[111,1659,1660],{"class":125},"beginPath",[111,1662,801],{"class":117},[111,1664,196],{"class":121},[111,1666,1667,1669,1671,1674,1676,1679,1681,1684,1686,1689,1691,1694,1696,1699,1702,1705,1707,1710,1712],{"class":113,"line":206},[111,1668,1602],{"class":117},[111,1670,122],{"class":121},[111,1672,1673],{"class":125},"arc",[111,1675,128],{"class":117},[111,1677,1678],{"class":495},"200",[111,1680,141],{"class":121},[111,1682,1683],{"class":495}," 75",[111,1685,141],{"class":121},[111,1687,1688],{"class":495}," 40",[111,1690,141],{"class":121},[111,1692,1693],{"class":495}," 0",[111,1695,141],{"class":121},[111,1697,1698],{"class":495}," 2",[111,1700,1701],{"class":459}," *",[111,1703,1704],{"class":117}," Math",[111,1706,122],{"class":121},[111,1708,1709],{"class":455},"PI",[111,1711,193],{"class":117},[111,1713,196],{"class":121},[111,1715,1716,1718,1720,1723,1725],{"class":113,"line":212},[111,1717,1602],{"class":117},[111,1719,122],{"class":121},[111,1721,1722],{"class":125},"stroke",[111,1724,801],{"class":117},[111,1726,196],{"class":121},[24,1728,1729,1732,1733,1736,1737,1740,1741,37],{},[58,1730,1731],{},"常用","：像素处理 ",[28,1734,1735],{},"getImageData\u002FputImageData","、绘制图像 ",[28,1738,1739],{},"drawImage","、动画 ",[28,1742,1743],{},"requestAnimationFrame",[44,1745,1747],{"id":1746},"_2-webgl基于-opengl-es","2. WebGL（基于 OpenGL ES）",[24,1749,1750],{},"用于高性能 3D\u002F2D 图形渲染（如 Three.js 底层）。",[102,1752,1754],{"className":104,"code":1753,"language":106,"meta":107,"style":107},"const gl = canvas.getContext(\"webgl\");\n\u002F\u002F 编写着色器、缓冲区等，通常借助 Three.js 等库简化开发。\n",[28,1755,1756,1784],{"__ignoreMap":107},[111,1757,1758,1760,1763,1765,1767,1769,1771,1773,1775,1778,1780,1782],{"class":113,"line":114},[111,1759,452],{"class":337},[111,1761,1762],{"class":455}," gl",[111,1764,460],{"class":459},[111,1766,1546],{"class":117},[111,1768,122],{"class":121},[111,1770,1584],{"class":125},[111,1772,128],{"class":117},[111,1774,132],{"class":131},[111,1776,1777],{"class":135},"webgl",[111,1779,132],{"class":131},[111,1781,193],{"class":117},[111,1783,196],{"class":121},[111,1785,1786],{"class":113,"line":152},[111,1787,1788],{"class":168},"\u002F\u002F 编写着色器、缓冲区等，通常借助 Three.js 等库简化开发。\n",[39,1790,1792],{"id":1791},"四web-存储","四、Web 存储",[44,1794,1126,1796,1799,1800],{"id":1795},"_1-localstorage-sessionstorage",[28,1797,1798],{},"localStorage"," \u002F ",[28,1801,1802],{},"sessionStorage",[52,1804,1805,1811,1829,1839],{},[55,1806,1807,1810],{},[58,1808,1809],{},"容量","：约 5-10MB。",[55,1812,1813,244,1816,1819,1820,1819,1823,1819,1826,37],{},[58,1814,1815],{},"同步 API",[28,1817,1818],{},"setItem","、",[28,1821,1822],{},"getItem",[28,1824,1825],{},"removeItem",[28,1827,1828],{},"clear",[55,1830,1831,1834,1835,1838],{},[58,1832,1833],{},"存储类型","：字符串（其他类型需 ",[28,1836,1837],{},"JSON.stringify\u002Fparse","）。",[55,1840,1841,244,1844,1846,1847,1849],{},[58,1842,1843],{},"生命周期",[28,1845,1798],{}," 永久；",[28,1848,1802],{}," 为标签页关闭即清除。",[24,1851,1852,1855],{},[58,1853,1854],{},"监听 storage 事件","（仅在同源不同标签页间触发）：",[102,1857,1859],{"className":104,"code":1858,"language":106,"meta":107,"style":107},"window.addEventListener(\"storage\", e => {\n    console.log(e.key, e.oldValue, e.newValue, e.url);\n});\n",[28,1860,1861,1886,1934],{"__ignoreMap":107},[111,1862,1863,1865,1867,1869,1871,1873,1876,1878,1880,1882,1884],{"class":113,"line":114},[111,1864,64],{"class":117},[111,1866,122],{"class":121},[111,1868,85],{"class":125},[111,1870,128],{"class":117},[111,1872,132],{"class":131},[111,1874,1875],{"class":135},"storage",[111,1877,132],{"class":131},[111,1879,141],{"class":121},[111,1881,334],{"class":333},[111,1883,338],{"class":337},[111,1885,149],{"class":121},[111,1887,1888,1890,1892,1894,1896,1898,1900,1903,1905,1907,1909,1912,1914,1916,1918,1921,1923,1925,1927,1930,1932],{"class":113,"line":152},[111,1889,557],{"class":117},[111,1891,122],{"class":121},[111,1893,387],{"class":125},[111,1895,128],{"class":155},[111,1897,352],{"class":117},[111,1899,122],{"class":121},[111,1901,1902],{"class":117},"key",[111,1904,141],{"class":121},[111,1906,334],{"class":117},[111,1908,122],{"class":121},[111,1910,1911],{"class":117},"oldValue",[111,1913,141],{"class":121},[111,1915,334],{"class":117},[111,1917,122],{"class":121},[111,1919,1920],{"class":117},"newValue",[111,1922,141],{"class":121},[111,1924,334],{"class":117},[111,1926,122],{"class":121},[111,1928,1929],{"class":117},"url",[111,1931,193],{"class":155},[111,1933,196],{"class":121},[111,1935,1936,1938,1940],{"class":113,"line":172},[111,1937,190],{"class":121},[111,1939,193],{"class":117},[111,1941,196],{"class":121},[44,1943,90,1945,1948],{"id":1944},"_2-indexeddb-大型结构化数据存储",[28,1946,1947],{},"IndexedDB"," – 大型结构化数据存储",[24,1950,1951],{},"异步、事务、索引、支持大量数据。",[102,1953,1955],{"className":104,"code":1954,"language":106,"meta":107,"style":107},"const request = indexedDB.open(\"myDB\", 1);\nrequest.onsuccess = e => {\n    const db = e.target.result;\n    const transaction = db.transaction([\"users\"], \"readwrite\");\n    const store = transaction.objectStore(\"users\");\n    store.add({ id: 1, name: \"Alice\" });\n};\n",[28,1956,1957,1992,2010,2032,2074,2102,2143],{"__ignoreMap":107},[111,1958,1959,1961,1964,1966,1969,1971,1974,1976,1978,1981,1983,1985,1988,1990],{"class":113,"line":114},[111,1960,452],{"class":337},[111,1962,1963],{"class":455}," request",[111,1965,460],{"class":459},[111,1967,1968],{"class":117}," indexedDB",[111,1970,122],{"class":121},[111,1972,1973],{"class":125},"open",[111,1975,128],{"class":117},[111,1977,132],{"class":131},[111,1979,1980],{"class":135},"myDB",[111,1982,132],{"class":131},[111,1984,141],{"class":121},[111,1986,1987],{"class":495}," 1",[111,1989,193],{"class":117},[111,1991,196],{"class":121},[111,1993,1994,1997,1999,2002,2004,2006,2008],{"class":113,"line":152},[111,1995,1996],{"class":117},"request",[111,1998,122],{"class":121},[111,2000,2001],{"class":125},"onsuccess",[111,2003,460],{"class":459},[111,2005,334],{"class":333},[111,2007,338],{"class":337},[111,2009,149],{"class":121},[111,2011,2012,2014,2017,2019,2021,2023,2025,2027,2030],{"class":113,"line":172},[111,2013,1191],{"class":337},[111,2015,2016],{"class":455}," db",[111,2018,460],{"class":459},[111,2020,334],{"class":117},[111,2022,122],{"class":121},[111,2024,357],{"class":117},[111,2026,122],{"class":121},[111,2028,2029],{"class":117},"result",[111,2031,196],{"class":121},[111,2033,2034,2036,2039,2041,2043,2045,2048,2051,2053,2056,2058,2061,2063,2065,2068,2070,2072],{"class":113,"line":187},[111,2035,1191],{"class":337},[111,2037,2038],{"class":455}," transaction",[111,2040,460],{"class":459},[111,2042,2016],{"class":117},[111,2044,122],{"class":121},[111,2046,2047],{"class":125},"transaction",[111,2049,2050],{"class":155},"([",[111,2052,132],{"class":131},[111,2054,2055],{"class":135},"users",[111,2057,132],{"class":131},[111,2059,2060],{"class":155},"]",[111,2062,141],{"class":121},[111,2064,671],{"class":131},[111,2066,2067],{"class":135},"readwrite",[111,2069,132],{"class":131},[111,2071,193],{"class":155},[111,2073,196],{"class":121},[111,2075,2076,2078,2081,2083,2085,2087,2090,2092,2094,2096,2098,2100],{"class":113,"line":199},[111,2077,1191],{"class":337},[111,2079,2080],{"class":455}," store",[111,2082,460],{"class":459},[111,2084,2038],{"class":117},[111,2086,122],{"class":121},[111,2088,2089],{"class":125},"objectStore",[111,2091,128],{"class":155},[111,2093,132],{"class":131},[111,2095,2055],{"class":135},[111,2097,132],{"class":131},[111,2099,193],{"class":155},[111,2101,196],{"class":121},[111,2103,2104,2107,2109,2112,2114,2117,2119,2121,2123,2125,2128,2130,2132,2135,2137,2139,2141],{"class":113,"line":206},[111,2105,2106],{"class":117},"    store",[111,2108,122],{"class":121},[111,2110,2111],{"class":125},"add",[111,2113,128],{"class":155},[111,2115,2116],{"class":121},"{",[111,2118,490],{"class":155},[111,2120,159],{"class":121},[111,2122,1987],{"class":495},[111,2124,141],{"class":121},[111,2126,2127],{"class":155}," name",[111,2129,159],{"class":121},[111,2131,671],{"class":131},[111,2133,2134],{"class":135},"Alice",[111,2136,132],{"class":131},[111,2138,499],{"class":121},[111,2140,193],{"class":155},[111,2142,196],{"class":121},[111,2144,2145],{"class":113,"line":212},[111,2146,2147],{"class":121},"};\n",[24,2149,2150,244],{},[58,2151,2152],{},"关键概念",[52,2154,2155,2158,2161],{},[55,2156,2157],{},"对象存储（类似表）",[55,2159,2160],{},"索引（加速查询）",[55,2162,2163],{},"游标（遍历数据）",[44,2165,2167],{"id":2166},"_3-cookies-进阶属性","3. Cookies 进阶属性",[52,2169,2170,2190,2195,2201],{},[55,2171,2172,244,2175,2178,2179,2182,2183,2186,2187,1838],{},[28,2173,2174],{},"SameSite",[28,2176,2177],{},"Strict","（完全禁止第三方请求携带）、",[28,2180,2181],{},"Lax","（部分允许）、",[28,2184,2185],{},"None","（需配合 ",[28,2188,2189],{},"Secure",[55,2191,2192,2194],{},[28,2193,2189],{},"：仅 HTTPS 传输。",[55,2196,2197,2200],{},[28,2198,2199],{},"HttpOnly","：禁止 JavaScript 访问，防止 XSS 窃取。",[55,2202,2203,1799,2206,2209],{},[28,2204,2205],{},"Max-Age",[28,2207,2208],{},"Expires","：过期时间。",[102,2211,2213],{"className":104,"code":2212,"language":106,"meta":107,"style":107},"document.cookie = \"token=abc; Secure; SameSite=Strict; Max-Age=3600\";\n",[28,2214,2215],{"__ignoreMap":107},[111,2216,2217,2219,2221,2224,2226,2228,2231,2233],{"class":113,"line":114},[111,2218,300],{"class":117},[111,2220,122],{"class":121},[111,2222,2223],{"class":117},"cookie ",[111,2225,1394],{"class":459},[111,2227,671],{"class":131},[111,2229,2230],{"class":135},"token=abc; Secure; SameSite=Strict; Max-Age=3600",[111,2232,132],{"class":131},[111,2234,196],{"class":121},[39,2236,2238],{"id":2237},"五网络请求","五、网络请求",[44,2240,2242],{"id":2241},"_1-fetch-完全指南","1. Fetch 完全指南",[102,2244,2246],{"className":104,"code":2245,"language":106,"meta":107,"style":107},"\u002F\u002F 基本 GET\nfetch(\"\u002Fapi\u002Fdata\")\n    .then(res => {\n        if (!res.ok) throw new Error(\"HTTP error\");\n        return res.json();\n    })\n    .catch(err => console.error(err));\n\n\u002F\u002F POST with JSON\nfetch(\"\u002Fapi\u002Fpost\", {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application\u002Fjson\" },\n    body: JSON.stringify({ foo: \"bar\" }),\n});\n\n\u002F\u002F 请求\u002F响应拦截（可通过封装或 Proxy 实现）\nconst originalFetch = window.fetch;\nwindow.fetch = function (...args) {\n    console.log(\"Request:\", args);\n    return originalFetch(...args).then(res => {\n        console.log(\"Response:\", res);\n        return res;\n    });\n};\n\n\u002F\u002F 自定义 AbortSignal（中止请求）\nconst controller = new AbortController();\nfetch(\"\u002Fapi\u002Flong\", { signal: controller.signal });\nsetTimeout(() => controller.abort(), 1000);\n\n\u002F\u002F Stream API 处理大文件（例如逐块读取）\nconst response = await fetch(\"\u002Flarge-file\");\nconst reader = response.body.getReader();\nwhile (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n    console.log(\"Received chunk:\", value);\n}\n",[28,2247,2248,2253,2269,2286,2325,2342,2349,2376,2380,2385,2402,2418,2447,2484,2492,2496,2502,2521,2547,2574,2602,2628,2637,2646,2651,2656,2662,2681,2717,2747,2752,2758,2787,2813,2828,2860,2877,2903],{"__ignoreMap":107},[111,2249,2250],{"class":113,"line":114},[111,2251,2252],{"class":168},"\u002F\u002F 基本 GET\n",[111,2254,2255,2257,2259,2261,2264,2266],{"class":113,"line":152},[111,2256,30],{"class":125},[111,2258,128],{"class":117},[111,2260,132],{"class":131},[111,2262,2263],{"class":135},"\u002Fapi\u002Fdata",[111,2265,132],{"class":131},[111,2267,2268],{"class":117},")\n",[111,2270,2271,2274,2277,2279,2282,2284],{"class":113,"line":172},[111,2272,2273],{"class":121},"    .",[111,2275,2276],{"class":125},"then",[111,2278,128],{"class":117},[111,2280,2281],{"class":333},"res",[111,2283,338],{"class":337},[111,2285,149],{"class":121},[111,2287,2288,2290,2292,2295,2297,2299,2302,2304,2307,2309,2312,2314,2316,2319,2321,2323],{"class":113,"line":187},[111,2289,655],{"class":345},[111,2291,349],{"class":155},[111,2293,2294],{"class":459},"!",[111,2296,2281],{"class":117},[111,2298,122],{"class":121},[111,2300,2301],{"class":117},"ok",[111,2303,648],{"class":155},[111,2305,2306],{"class":345},"throw",[111,2308,463],{"class":459},[111,2310,2311],{"class":125}," Error",[111,2313,128],{"class":155},[111,2315,132],{"class":131},[111,2317,2318],{"class":135},"HTTP error",[111,2320,132],{"class":131},[111,2322,193],{"class":155},[111,2324,196],{"class":121},[111,2326,2327,2330,2333,2335,2338,2340],{"class":113,"line":199},[111,2328,2329],{"class":345},"        return",[111,2331,2332],{"class":117}," res",[111,2334,122],{"class":121},[111,2336,2337],{"class":125},"json",[111,2339,801],{"class":155},[111,2341,196],{"class":121},[111,2343,2344,2347],{"class":113,"line":206},[111,2345,2346],{"class":121},"    }",[111,2348,2268],{"class":117},[111,2350,2351,2353,2356,2358,2361,2363,2366,2368,2371,2374],{"class":113,"line":212},[111,2352,2273],{"class":121},[111,2354,2355],{"class":125},"catch",[111,2357,128],{"class":117},[111,2359,2360],{"class":333},"err",[111,2362,338],{"class":337},[111,2364,2365],{"class":117}," console",[111,2367,122],{"class":121},[111,2369,2370],{"class":125},"error",[111,2372,2373],{"class":117},"(err))",[111,2375,196],{"class":121},[111,2377,2378],{"class":113,"line":582},[111,2379,203],{"emptyLinePlaceholder":202},[111,2381,2382],{"class":113,"line":739},[111,2383,2384],{"class":168},"\u002F\u002F POST with JSON\n",[111,2386,2387,2389,2391,2393,2396,2398,2400],{"class":113,"line":752},[111,2388,30],{"class":125},[111,2390,128],{"class":117},[111,2392,132],{"class":131},[111,2394,2395],{"class":135},"\u002Fapi\u002Fpost",[111,2397,132],{"class":131},[111,2399,141],{"class":121},[111,2401,149],{"class":121},[111,2403,2404,2407,2409,2411,2414,2416],{"class":113,"line":764},[111,2405,2406],{"class":155},"    method",[111,2408,159],{"class":121},[111,2410,671],{"class":131},[111,2412,2413],{"class":135},"POST",[111,2415,132],{"class":131},[111,2417,749],{"class":121},[111,2419,2420,2423,2425,2427,2429,2433,2435,2437,2439,2442,2444],{"class":113,"line":776},[111,2421,2422],{"class":155},"    headers",[111,2424,159],{"class":121},[111,2426,480],{"class":121},[111,2428,671],{"class":131},[111,2430,2432],{"class":2431},"sZUrc","Content-Type",[111,2434,132],{"class":131},[111,2436,159],{"class":121},[111,2438,671],{"class":131},[111,2440,2441],{"class":135},"application\u002Fjson",[111,2443,132],{"class":131},[111,2445,2446],{"class":121}," },\n",[111,2448,2449,2452,2454,2457,2459,2462,2464,2466,2469,2471,2473,2476,2478,2480,2482],{"class":113,"line":785},[111,2450,2451],{"class":155},"    body",[111,2453,159],{"class":121},[111,2455,2456],{"class":455}," JSON",[111,2458,122],{"class":121},[111,2460,2461],{"class":125},"stringify",[111,2463,128],{"class":117},[111,2465,2116],{"class":121},[111,2467,2468],{"class":155}," foo",[111,2470,159],{"class":121},[111,2472,671],{"class":131},[111,2474,2475],{"class":135},"bar",[111,2477,132],{"class":131},[111,2479,499],{"class":121},[111,2481,193],{"class":117},[111,2483,749],{"class":121},[111,2485,2486,2488,2490],{"class":113,"line":791},[111,2487,190],{"class":121},[111,2489,193],{"class":117},[111,2491,196],{"class":121},[111,2493,2494],{"class":113,"line":1514},[111,2495,203],{"emptyLinePlaceholder":202},[111,2497,2499],{"class":113,"line":2498},16,[111,2500,2501],{"class":168},"\u002F\u002F 请求\u002F响应拦截（可通过封装或 Proxy 实现）\n",[111,2503,2505,2507,2510,2512,2515,2517,2519],{"class":113,"line":2504},17,[111,2506,452],{"class":337},[111,2508,2509],{"class":455}," originalFetch",[111,2511,460],{"class":459},[111,2513,2514],{"class":117}," window",[111,2516,122],{"class":121},[111,2518,30],{"class":117},[111,2520,196],{"class":121},[111,2522,2524,2526,2528,2530,2532,2535,2537,2540,2543,2545],{"class":113,"line":2523},18,[111,2525,64],{"class":117},[111,2527,122],{"class":121},[111,2529,30],{"class":125},[111,2531,460],{"class":459},[111,2533,2534],{"class":337}," function",[111,2536,349],{"class":121},[111,2538,2539],{"class":459},"...",[111,2541,2542],{"class":333},"args",[111,2544,193],{"class":121},[111,2546,149],{"class":121},[111,2548,2550,2552,2554,2556,2558,2560,2563,2565,2567,2570,2572],{"class":113,"line":2549},19,[111,2551,557],{"class":117},[111,2553,122],{"class":121},[111,2555,387],{"class":125},[111,2557,128],{"class":155},[111,2559,132],{"class":131},[111,2561,2562],{"class":135},"Request:",[111,2564,132],{"class":131},[111,2566,141],{"class":121},[111,2568,2569],{"class":117}," args",[111,2571,193],{"class":155},[111,2573,196],{"class":121},[111,2575,2577,2580,2582,2584,2586,2588,2590,2592,2594,2596,2598,2600],{"class":113,"line":2576},20,[111,2578,2579],{"class":345},"    return",[111,2581,2509],{"class":125},[111,2583,128],{"class":155},[111,2585,2539],{"class":459},[111,2587,2542],{"class":117},[111,2589,193],{"class":155},[111,2591,122],{"class":121},[111,2593,2276],{"class":125},[111,2595,128],{"class":155},[111,2597,2281],{"class":333},[111,2599,338],{"class":337},[111,2601,149],{"class":121},[111,2603,2605,2607,2609,2611,2613,2615,2618,2620,2622,2624,2626],{"class":113,"line":2604},21,[111,2606,382],{"class":117},[111,2608,122],{"class":121},[111,2610,387],{"class":125},[111,2612,128],{"class":155},[111,2614,132],{"class":131},[111,2616,2617],{"class":135},"Response:",[111,2619,132],{"class":131},[111,2621,141],{"class":121},[111,2623,2332],{"class":117},[111,2625,193],{"class":155},[111,2627,196],{"class":121},[111,2629,2631,2633,2635],{"class":113,"line":2630},22,[111,2632,2329],{"class":345},[111,2634,2332],{"class":117},[111,2636,196],{"class":121},[111,2638,2640,2642,2644],{"class":113,"line":2639},23,[111,2641,2346],{"class":121},[111,2643,193],{"class":155},[111,2645,196],{"class":121},[111,2647,2649],{"class":113,"line":2648},24,[111,2650,2147],{"class":121},[111,2652,2654],{"class":113,"line":2653},25,[111,2655,203],{"emptyLinePlaceholder":202},[111,2657,2659],{"class":113,"line":2658},26,[111,2660,2661],{"class":168},"\u002F\u002F 自定义 AbortSignal（中止请求）\n",[111,2663,2665,2667,2670,2672,2674,2677,2679],{"class":113,"line":2664},27,[111,2666,452],{"class":337},[111,2668,2669],{"class":455}," controller",[111,2671,460],{"class":459},[111,2673,463],{"class":459},[111,2675,2676],{"class":125}," AbortController",[111,2678,801],{"class":117},[111,2680,196],{"class":121},[111,2682,2684,2686,2688,2690,2693,2695,2697,2699,2702,2704,2706,2708,2711,2713,2715],{"class":113,"line":2683},28,[111,2685,30],{"class":125},[111,2687,128],{"class":117},[111,2689,132],{"class":131},[111,2691,2692],{"class":135},"\u002Fapi\u002Flong",[111,2694,132],{"class":131},[111,2696,141],{"class":121},[111,2698,480],{"class":121},[111,2700,2701],{"class":155}," signal",[111,2703,159],{"class":121},[111,2705,2669],{"class":117},[111,2707,122],{"class":121},[111,2709,2710],{"class":117},"signal ",[111,2712,190],{"class":121},[111,2714,193],{"class":117},[111,2716,196],{"class":121},[111,2718,2720,2723,2725,2727,2729,2731,2733,2736,2738,2740,2743,2745],{"class":113,"line":2719},29,[111,2721,2722],{"class":125},"setTimeout",[111,2724,128],{"class":117},[111,2726,801],{"class":121},[111,2728,338],{"class":337},[111,2730,2669],{"class":117},[111,2732,122],{"class":121},[111,2734,2735],{"class":125},"abort",[111,2737,801],{"class":117},[111,2739,141],{"class":121},[111,2741,2742],{"class":495}," 1000",[111,2744,193],{"class":117},[111,2746,196],{"class":121},[111,2748,2750],{"class":113,"line":2749},30,[111,2751,203],{"emptyLinePlaceholder":202},[111,2753,2755],{"class":113,"line":2754},31,[111,2756,2757],{"class":168},"\u002F\u002F Stream API 处理大文件（例如逐块读取）\n",[111,2759,2761,2763,2766,2768,2771,2774,2776,2778,2781,2783,2785],{"class":113,"line":2760},32,[111,2762,452],{"class":337},[111,2764,2765],{"class":455}," response",[111,2767,460],{"class":459},[111,2769,2770],{"class":345}," await",[111,2772,2773],{"class":125}," fetch",[111,2775,128],{"class":117},[111,2777,132],{"class":131},[111,2779,2780],{"class":135},"\u002Flarge-file",[111,2782,132],{"class":131},[111,2784,193],{"class":117},[111,2786,196],{"class":121},[111,2788,2790,2792,2795,2797,2799,2801,2804,2806,2809,2811],{"class":113,"line":2789},33,[111,2791,452],{"class":337},[111,2793,2794],{"class":455}," reader",[111,2796,460],{"class":459},[111,2798,2765],{"class":117},[111,2800,122],{"class":121},[111,2802,2803],{"class":117},"body",[111,2805,122],{"class":121},[111,2807,2808],{"class":125},"getReader",[111,2810,801],{"class":117},[111,2812,196],{"class":121},[111,2814,2816,2819,2821,2824,2826],{"class":113,"line":2815},34,[111,2817,2818],{"class":345},"while",[111,2820,349],{"class":117},[111,2822,2823],{"class":162},"true",[111,2825,648],{"class":117},[111,2827,377],{"class":121},[111,2829,2831,2833,2835,2838,2840,2843,2845,2847,2849,2851,2853,2856,2858],{"class":113,"line":2830},35,[111,2832,1191],{"class":337},[111,2834,480],{"class":121},[111,2836,2837],{"class":455}," done",[111,2839,141],{"class":121},[111,2841,2842],{"class":455}," value",[111,2844,499],{"class":121},[111,2846,460],{"class":459},[111,2848,2770],{"class":345},[111,2850,2794],{"class":117},[111,2852,122],{"class":121},[111,2854,2855],{"class":125},"read",[111,2857,801],{"class":155},[111,2859,196],{"class":121},[111,2861,2863,2865,2867,2870,2872,2875],{"class":113,"line":2862},36,[111,2864,346],{"class":345},[111,2866,349],{"class":155},[111,2868,2869],{"class":117},"done",[111,2871,648],{"class":155},[111,2873,2874],{"class":345},"break",[111,2876,196],{"class":121},[111,2878,2880,2882,2884,2886,2888,2890,2893,2895,2897,2899,2901],{"class":113,"line":2879},37,[111,2881,557],{"class":117},[111,2883,122],{"class":121},[111,2885,387],{"class":125},[111,2887,128],{"class":155},[111,2889,132],{"class":131},[111,2891,2892],{"class":135},"Received chunk:",[111,2894,132],{"class":131},[111,2896,141],{"class":121},[111,2898,2842],{"class":117},[111,2900,193],{"class":155},[111,2902,196],{"class":121},[111,2904,2906],{"class":113,"line":2905},38,[111,2907,2908],{"class":121},"}\n",[44,2910,2912],{"id":2911},"_2-xmlhttprequest-进阶进度监控","2. XMLHttpRequest 进阶（进度监控）",[102,2914,2916],{"className":104,"code":2915,"language":106,"meta":107,"style":107},"const xhr = new XMLHttpRequest();\nxhr.open(\"POST\", \"\u002Fupload\");\nxhr.upload.onprogress = e => {\n    console.log(`Uploaded ${e.loaded}\u002F${e.total}`);\n};\nxhr.onload = () => console.log(\"Done\");\nxhr.send(formData);\n",[28,2917,2918,2936,2966,2988,3035,3039,3073],{"__ignoreMap":107},[111,2919,2920,2922,2925,2927,2929,2932,2934],{"class":113,"line":114},[111,2921,452],{"class":337},[111,2923,2924],{"class":455}," xhr",[111,2926,460],{"class":459},[111,2928,463],{"class":459},[111,2930,2931],{"class":125}," XMLHttpRequest",[111,2933,801],{"class":117},[111,2935,196],{"class":121},[111,2937,2938,2941,2943,2945,2947,2949,2951,2953,2955,2957,2960,2962,2964],{"class":113,"line":152},[111,2939,2940],{"class":117},"xhr",[111,2942,122],{"class":121},[111,2944,1973],{"class":125},[111,2946,128],{"class":117},[111,2948,132],{"class":131},[111,2950,2413],{"class":135},[111,2952,132],{"class":131},[111,2954,141],{"class":121},[111,2956,671],{"class":131},[111,2958,2959],{"class":135},"\u002Fupload",[111,2961,132],{"class":131},[111,2963,193],{"class":117},[111,2965,196],{"class":121},[111,2967,2968,2970,2972,2975,2977,2980,2982,2984,2986],{"class":113,"line":172},[111,2969,2940],{"class":117},[111,2971,122],{"class":121},[111,2973,2974],{"class":117},"upload",[111,2976,122],{"class":121},[111,2978,2979],{"class":125},"onprogress",[111,2981,460],{"class":459},[111,2983,334],{"class":333},[111,2985,338],{"class":337},[111,2987,149],{"class":121},[111,2989,2990,2992,2994,2996,2998,3001,3004,3007,3009,3011,3014,3016,3019,3021,3023,3025,3028,3031,3033],{"class":113,"line":187},[111,2991,557],{"class":117},[111,2993,122],{"class":121},[111,2995,387],{"class":125},[111,2997,128],{"class":155},[111,2999,3000],{"class":131},"`",[111,3002,3003],{"class":135},"Uploaded ",[111,3005,3006],{"class":131},"${",[111,3008,352],{"class":117},[111,3010,122],{"class":131},[111,3012,3013],{"class":117},"loaded",[111,3015,190],{"class":131},[111,3017,3018],{"class":135},"\u002F",[111,3020,3006],{"class":131},[111,3022,352],{"class":117},[111,3024,122],{"class":131},[111,3026,3027],{"class":117},"total",[111,3029,3030],{"class":131},"}`",[111,3032,193],{"class":155},[111,3034,196],{"class":121},[111,3036,3037],{"class":113,"line":199},[111,3038,2147],{"class":121},[111,3040,3041,3043,3045,3048,3050,3052,3054,3056,3058,3060,3062,3064,3067,3069,3071],{"class":113,"line":206},[111,3042,2940],{"class":117},[111,3044,122],{"class":121},[111,3046,3047],{"class":125},"onload",[111,3049,460],{"class":459},[111,3051,1182],{"class":121},[111,3053,338],{"class":337},[111,3055,2365],{"class":117},[111,3057,122],{"class":121},[111,3059,387],{"class":125},[111,3061,128],{"class":117},[111,3063,132],{"class":131},[111,3065,3066],{"class":135},"Done",[111,3068,132],{"class":131},[111,3070,193],{"class":117},[111,3072,196],{"class":121},[111,3074,3075,3077,3079,3082,3085],{"class":113,"line":212},[111,3076,2940],{"class":117},[111,3078,122],{"class":121},[111,3080,3081],{"class":125},"send",[111,3083,3084],{"class":117},"(formData)",[111,3086,196],{"class":121},[44,3088,3090],{"id":3089},"_3-websocket-全双工实时通信","3. WebSocket – 全双工实时通信",[102,3092,3094],{"className":104,"code":3093,"language":106,"meta":107,"style":107},"const ws = new WebSocket(\"wss:\u002F\u002Fexample.com\u002Fsocket\");\nws.onopen = () => ws.send(\"Hello\");\nws.onmessage = e => console.log(\"Received:\", e.data);\nws.onerror = err => console.error(err);\nws.onclose = () => console.log(\"Closed\");\n\n\u002F\u002F 重连机制示例\nfunction connect() {\n    const ws = new WebSocket(url);\n    ws.onclose = () => setTimeout(connect, 1000);\n}\n",[28,3095,3096,3123,3158,3199,3226,3260,3264,3269,3281,3301,3332],{"__ignoreMap":107},[111,3097,3098,3100,3103,3105,3107,3110,3112,3114,3117,3119,3121],{"class":113,"line":114},[111,3099,452],{"class":337},[111,3101,3102],{"class":455}," ws",[111,3104,460],{"class":459},[111,3106,463],{"class":459},[111,3108,3109],{"class":125}," WebSocket",[111,3111,128],{"class":117},[111,3113,132],{"class":131},[111,3115,3116],{"class":135},"wss:\u002F\u002Fexample.com\u002Fsocket",[111,3118,132],{"class":131},[111,3120,193],{"class":117},[111,3122,196],{"class":121},[111,3124,3125,3128,3130,3133,3135,3137,3139,3141,3143,3145,3147,3149,3152,3154,3156],{"class":113,"line":152},[111,3126,3127],{"class":117},"ws",[111,3129,122],{"class":121},[111,3131,3132],{"class":125},"onopen",[111,3134,460],{"class":459},[111,3136,1182],{"class":121},[111,3138,338],{"class":337},[111,3140,3102],{"class":117},[111,3142,122],{"class":121},[111,3144,3081],{"class":125},[111,3146,128],{"class":117},[111,3148,132],{"class":131},[111,3150,3151],{"class":135},"Hello",[111,3153,132],{"class":131},[111,3155,193],{"class":117},[111,3157,196],{"class":121},[111,3159,3160,3162,3164,3167,3169,3171,3173,3175,3177,3179,3181,3183,3186,3188,3190,3192,3194,3197],{"class":113,"line":172},[111,3161,3127],{"class":117},[111,3163,122],{"class":121},[111,3165,3166],{"class":125},"onmessage",[111,3168,460],{"class":459},[111,3170,334],{"class":333},[111,3172,338],{"class":337},[111,3174,2365],{"class":117},[111,3176,122],{"class":121},[111,3178,387],{"class":125},[111,3180,128],{"class":117},[111,3182,132],{"class":131},[111,3184,3185],{"class":135},"Received:",[111,3187,132],{"class":131},[111,3189,141],{"class":121},[111,3191,334],{"class":117},[111,3193,122],{"class":121},[111,3195,3196],{"class":117},"data)",[111,3198,196],{"class":121},[111,3200,3201,3203,3205,3208,3210,3213,3215,3217,3219,3221,3224],{"class":113,"line":187},[111,3202,3127],{"class":117},[111,3204,122],{"class":121},[111,3206,3207],{"class":125},"onerror",[111,3209,460],{"class":459},[111,3211,3212],{"class":333}," err",[111,3214,338],{"class":337},[111,3216,2365],{"class":117},[111,3218,122],{"class":121},[111,3220,2370],{"class":125},[111,3222,3223],{"class":117},"(err)",[111,3225,196],{"class":121},[111,3227,3228,3230,3232,3235,3237,3239,3241,3243,3245,3247,3249,3251,3254,3256,3258],{"class":113,"line":199},[111,3229,3127],{"class":117},[111,3231,122],{"class":121},[111,3233,3234],{"class":125},"onclose",[111,3236,460],{"class":459},[111,3238,1182],{"class":121},[111,3240,338],{"class":337},[111,3242,2365],{"class":117},[111,3244,122],{"class":121},[111,3246,387],{"class":125},[111,3248,128],{"class":117},[111,3250,132],{"class":131},[111,3252,3253],{"class":135},"Closed",[111,3255,132],{"class":131},[111,3257,193],{"class":117},[111,3259,196],{"class":121},[111,3261,3262],{"class":113,"line":206},[111,3263,203],{"emptyLinePlaceholder":202},[111,3265,3266],{"class":113,"line":212},[111,3267,3268],{"class":168},"\u002F\u002F 重连机制示例\n",[111,3270,3271,3274,3277,3279],{"class":113,"line":582},[111,3272,3273],{"class":337},"function",[111,3275,3276],{"class":125}," connect",[111,3278,801],{"class":121},[111,3280,149],{"class":121},[111,3282,3283,3285,3287,3289,3291,3293,3295,3297,3299],{"class":113,"line":739},[111,3284,1191],{"class":337},[111,3286,3102],{"class":455},[111,3288,460],{"class":459},[111,3290,463],{"class":459},[111,3292,3109],{"class":125},[111,3294,128],{"class":155},[111,3296,1929],{"class":117},[111,3298,193],{"class":155},[111,3300,196],{"class":121},[111,3302,3303,3306,3308,3310,3312,3314,3316,3319,3321,3324,3326,3328,3330],{"class":113,"line":752},[111,3304,3305],{"class":117},"    ws",[111,3307,122],{"class":121},[111,3309,3234],{"class":125},[111,3311,460],{"class":459},[111,3313,1182],{"class":121},[111,3315,338],{"class":337},[111,3317,3318],{"class":125}," setTimeout",[111,3320,128],{"class":155},[111,3322,3323],{"class":117},"connect",[111,3325,141],{"class":121},[111,3327,2742],{"class":495},[111,3329,193],{"class":155},[111,3331,196],{"class":121},[111,3333,3334],{"class":113,"line":764},[111,3335,2908],{"class":121},[44,3337,3339],{"id":3338},"_4-server-sent-events-sse-服务器单向推送","4. Server-Sent Events (SSE) – 服务器单向推送",[102,3341,3343],{"className":104,"code":3342,"language":106,"meta":107,"style":107},"const evtSource = new EventSource(\"\u002Fevents\");\nevtSource.onmessage = e => console.log(\"Data:\", e.data);\nevtSource.addEventListener(\"customEvent\", e => {});\n",[28,3344,3345,3372,3412],{"__ignoreMap":107},[111,3346,3347,3349,3352,3354,3356,3359,3361,3363,3366,3368,3370],{"class":113,"line":114},[111,3348,452],{"class":337},[111,3350,3351],{"class":455}," evtSource",[111,3353,460],{"class":459},[111,3355,463],{"class":459},[111,3357,3358],{"class":125}," EventSource",[111,3360,128],{"class":117},[111,3362,132],{"class":131},[111,3364,3365],{"class":135},"\u002Fevents",[111,3367,132],{"class":131},[111,3369,193],{"class":117},[111,3371,196],{"class":121},[111,3373,3374,3377,3379,3381,3383,3385,3387,3389,3391,3393,3395,3397,3400,3402,3404,3406,3408,3410],{"class":113,"line":152},[111,3375,3376],{"class":117},"evtSource",[111,3378,122],{"class":121},[111,3380,3166],{"class":125},[111,3382,460],{"class":459},[111,3384,334],{"class":333},[111,3386,338],{"class":337},[111,3388,2365],{"class":117},[111,3390,122],{"class":121},[111,3392,387],{"class":125},[111,3394,128],{"class":117},[111,3396,132],{"class":131},[111,3398,3399],{"class":135},"Data:",[111,3401,132],{"class":131},[111,3403,141],{"class":121},[111,3405,334],{"class":117},[111,3407,122],{"class":121},[111,3409,3196],{"class":117},[111,3411,196],{"class":121},[111,3413,3414,3416,3418,3420,3422,3424,3427,3429,3431,3433,3435,3438,3440],{"class":113,"line":172},[111,3415,3376],{"class":117},[111,3417,122],{"class":121},[111,3419,85],{"class":125},[111,3421,128],{"class":117},[111,3423,132],{"class":131},[111,3425,3426],{"class":135},"customEvent",[111,3428,132],{"class":131},[111,3430,141],{"class":121},[111,3432,334],{"class":333},[111,3434,338],{"class":337},[111,3436,3437],{"class":121}," {}",[111,3439,193],{"class":117},[111,3441,196],{"class":121},[39,3443,3445],{"id":3444},"六多线程","六、多线程",[44,3447,3449],{"id":3448},"_1-web-worker专用线程","1. Web Worker（专用线程）",[24,3451,3452],{},"运行独立于主线程的脚本，用于密集计算。",[102,3454,3456],{"className":104,"code":3455,"language":106,"meta":107,"style":107},"\u002F\u002F worker.js\nself.onmessage = e => {\n    const result = heavyCalculation(e.data);\n    self.postMessage(result);\n};\n\n\u002F\u002F main.js\nconst worker = new Worker(\"worker.js\");\nworker.postMessage(input);\nworker.onmessage = e => console.log(e.data);\n",[28,3457,3458,3463,3480,3505,3523,3527,3531,3536,3563,3577],{"__ignoreMap":107},[111,3459,3460],{"class":113,"line":114},[111,3461,3462],{"class":168},"\u002F\u002F worker.js\n",[111,3464,3465,3468,3470,3472,3474,3476,3478],{"class":113,"line":152},[111,3466,3467],{"class":117},"self",[111,3469,122],{"class":121},[111,3471,3166],{"class":125},[111,3473,460],{"class":459},[111,3475,334],{"class":333},[111,3477,338],{"class":337},[111,3479,149],{"class":121},[111,3481,3482,3484,3487,3489,3492,3494,3496,3498,3501,3503],{"class":113,"line":172},[111,3483,1191],{"class":337},[111,3485,3486],{"class":455}," result",[111,3488,460],{"class":459},[111,3490,3491],{"class":125}," heavyCalculation",[111,3493,128],{"class":155},[111,3495,352],{"class":117},[111,3497,122],{"class":121},[111,3499,3500],{"class":117},"data",[111,3502,193],{"class":155},[111,3504,196],{"class":121},[111,3506,3507,3510,3512,3515,3517,3519,3521],{"class":113,"line":187},[111,3508,3509],{"class":117},"    self",[111,3511,122],{"class":121},[111,3513,3514],{"class":125},"postMessage",[111,3516,128],{"class":155},[111,3518,2029],{"class":117},[111,3520,193],{"class":155},[111,3522,196],{"class":121},[111,3524,3525],{"class":113,"line":199},[111,3526,2147],{"class":121},[111,3528,3529],{"class":113,"line":206},[111,3530,203],{"emptyLinePlaceholder":202},[111,3532,3533],{"class":113,"line":212},[111,3534,3535],{"class":168},"\u002F\u002F main.js\n",[111,3537,3538,3540,3543,3545,3547,3550,3552,3554,3557,3559,3561],{"class":113,"line":582},[111,3539,452],{"class":337},[111,3541,3542],{"class":455}," worker",[111,3544,460],{"class":459},[111,3546,463],{"class":459},[111,3548,3549],{"class":125}," Worker",[111,3551,128],{"class":117},[111,3553,132],{"class":131},[111,3555,3556],{"class":135},"worker.js",[111,3558,132],{"class":131},[111,3560,193],{"class":117},[111,3562,196],{"class":121},[111,3564,3565,3568,3570,3572,3575],{"class":113,"line":739},[111,3566,3567],{"class":117},"worker",[111,3569,122],{"class":121},[111,3571,3514],{"class":125},[111,3573,3574],{"class":117},"(input)",[111,3576,196],{"class":121},[111,3578,3579,3581,3583,3585,3587,3589,3591,3593,3595,3597,3600,3602,3604],{"class":113,"line":752},[111,3580,3567],{"class":117},[111,3582,122],{"class":121},[111,3584,3166],{"class":125},[111,3586,460],{"class":459},[111,3588,334],{"class":333},[111,3590,338],{"class":337},[111,3592,2365],{"class":117},[111,3594,122],{"class":121},[111,3596,387],{"class":125},[111,3598,3599],{"class":117},"(e",[111,3601,122],{"class":121},[111,3603,3196],{"class":117},[111,3605,196],{"class":121},[24,3607,3608,3611,3612,3615],{},[58,3609,3610],{},"Shared Worker","：多标签页共享一个 worker。\n",[58,3613,3614],{},"Service Worker","：代理网络请求，实现离线缓存（PWA）、消息推送。",[44,3617,3619],{"id":3618},"_2-service-worker离线缓存-消息推送","2. Service Worker（离线缓存 + 消息推送）",[102,3621,3623],{"className":104,"code":3622,"language":106,"meta":107,"style":107},"\u002F\u002F 注册\nnavigator.serviceWorker.register(\"\u002Fsw.js\");\n\u002F\u002F sw.js 中拦截 fetch 事件，返回缓存或网络响应\nself.addEventListener(\"fetch\", event => {\n    event.respondWith(\n        caches.match(event.request).then(resp => resp || fetch(event.request))\n    );\n});\n",[28,3624,3625,3630,3657,3662,3686,3698,3749,3756],{"__ignoreMap":107},[111,3626,3627],{"class":113,"line":114},[111,3628,3629],{"class":168},"\u002F\u002F 注册\n",[111,3631,3632,3634,3636,3639,3641,3644,3646,3648,3651,3653,3655],{"class":113,"line":152},[111,3633,1234],{"class":117},[111,3635,122],{"class":121},[111,3637,3638],{"class":117},"serviceWorker",[111,3640,122],{"class":121},[111,3642,3643],{"class":125},"register",[111,3645,128],{"class":117},[111,3647,132],{"class":131},[111,3649,3650],{"class":135},"\u002Fsw.js",[111,3652,132],{"class":131},[111,3654,193],{"class":117},[111,3656,196],{"class":121},[111,3658,3659],{"class":113,"line":172},[111,3660,3661],{"class":168},"\u002F\u002F sw.js 中拦截 fetch 事件，返回缓存或网络响应\n",[111,3663,3664,3666,3668,3670,3672,3674,3676,3678,3680,3682,3684],{"class":113,"line":187},[111,3665,3467],{"class":117},[111,3667,122],{"class":121},[111,3669,85],{"class":125},[111,3671,128],{"class":117},[111,3673,132],{"class":131},[111,3675,30],{"class":135},[111,3677,132],{"class":131},[111,3679,141],{"class":121},[111,3681,456],{"class":333},[111,3683,338],{"class":337},[111,3685,149],{"class":121},[111,3687,3688,3691,3693,3696],{"class":113,"line":199},[111,3689,3690],{"class":117},"    event",[111,3692,122],{"class":121},[111,3694,3695],{"class":125},"respondWith",[111,3697,835],{"class":155},[111,3699,3700,3703,3705,3708,3710,3713,3715,3717,3719,3721,3723,3725,3728,3730,3733,3736,3738,3740,3742,3744,3746],{"class":113,"line":206},[111,3701,3702],{"class":117},"        caches",[111,3704,122],{"class":121},[111,3706,3707],{"class":125},"match",[111,3709,128],{"class":155},[111,3711,3712],{"class":117},"event",[111,3714,122],{"class":121},[111,3716,1996],{"class":117},[111,3718,193],{"class":155},[111,3720,122],{"class":121},[111,3722,2276],{"class":125},[111,3724,128],{"class":155},[111,3726,3727],{"class":333},"resp",[111,3729,338],{"class":337},[111,3731,3732],{"class":117}," resp",[111,3734,3735],{"class":459}," ||",[111,3737,2773],{"class":125},[111,3739,128],{"class":155},[111,3741,3712],{"class":117},[111,3743,122],{"class":121},[111,3745,1996],{"class":117},[111,3747,3748],{"class":155},"))\n",[111,3750,3751,3754],{"class":113,"line":212},[111,3752,3753],{"class":155},"    )",[111,3755,196],{"class":121},[111,3757,3758,3760,3762],{"class":113,"line":582},[111,3759,190],{"class":121},[111,3761,193],{"class":117},[111,3763,196],{"class":121},[44,3765,1280,3767,3770,3771,434],{"id":3766},"_3-sharedarraybuffer-与原子操作atomics",[28,3768,3769],{},"SharedArrayBuffer"," 与原子操作（",[28,3772,3773],{},"Atomics",[24,3775,3776],{},"用于多个 Worker 或主线程之间共享内存（需跨域隔离上下文）。",[102,3778,3780],{"className":104,"code":3779,"language":106,"meta":107,"style":107},"\u002F\u002F 主线程\nconst sab = new SharedArrayBuffer(1024);\nconst int32 = new Int32Array(sab);\nworker.postMessage(sab);\n\n\u002F\u002F Worker 中\nAtomics.add(int32, 0, 1);\nAtomics.notify(int32, 0, 1);\n",[28,3781,3782,3787,3810,3829,3841,3845,3850,3873],{"__ignoreMap":107},[111,3783,3784],{"class":113,"line":114},[111,3785,3786],{"class":168},"\u002F\u002F 主线程\n",[111,3788,3789,3791,3794,3796,3798,3801,3803,3806,3808],{"class":113,"line":152},[111,3790,452],{"class":337},[111,3792,3793],{"class":455}," sab",[111,3795,460],{"class":459},[111,3797,463],{"class":459},[111,3799,3800],{"class":125}," SharedArrayBuffer",[111,3802,128],{"class":117},[111,3804,3805],{"class":495},"1024",[111,3807,193],{"class":117},[111,3809,196],{"class":121},[111,3811,3812,3814,3817,3819,3821,3824,3827],{"class":113,"line":172},[111,3813,452],{"class":337},[111,3815,3816],{"class":455}," int32",[111,3818,460],{"class":459},[111,3820,463],{"class":459},[111,3822,3823],{"class":125}," Int32Array",[111,3825,3826],{"class":117},"(sab)",[111,3828,196],{"class":121},[111,3830,3831,3833,3835,3837,3839],{"class":113,"line":187},[111,3832,3567],{"class":117},[111,3834,122],{"class":121},[111,3836,3514],{"class":125},[111,3838,3826],{"class":117},[111,3840,196],{"class":121},[111,3842,3843],{"class":113,"line":199},[111,3844,203],{"emptyLinePlaceholder":202},[111,3846,3847],{"class":113,"line":206},[111,3848,3849],{"class":168},"\u002F\u002F Worker 中\n",[111,3851,3852,3854,3856,3858,3861,3863,3865,3867,3869,3871],{"class":113,"line":212},[111,3853,3773],{"class":117},[111,3855,122],{"class":121},[111,3857,2111],{"class":125},[111,3859,3860],{"class":117},"(int32",[111,3862,141],{"class":121},[111,3864,1693],{"class":495},[111,3866,141],{"class":121},[111,3868,1987],{"class":495},[111,3870,193],{"class":117},[111,3872,196],{"class":121},[111,3874,3875,3877,3879,3882,3884,3886,3888,3890,3892,3894],{"class":113,"line":582},[111,3876,3773],{"class":117},[111,3878,122],{"class":121},[111,3880,3881],{"class":125},"notify",[111,3883,3860],{"class":117},[111,3885,141],{"class":121},[111,3887,1693],{"class":495},[111,3889,141],{"class":121},[111,3891,1987],{"class":495},[111,3893,193],{"class":117},[111,3895,196],{"class":121},[39,3897,3899],{"id":3898},"七剪贴板-api","七、剪贴板 API",[24,3901,3902,3905],{},[58,3903,3904],{},"异步读写剪贴板","（需用户授权）：",[102,3907,3909],{"className":104,"code":3908,"language":106,"meta":107,"style":107},"\u002F\u002F 写入文本\nawait navigator.clipboard.writeText(\"Hello World\");\n\u002F\u002F 读取文本\nconst text = await navigator.clipboard.readText();\n\u002F\u002F 写入图片（ClipboardItem）\nconst imgBlob = await fetch(\"image.png\").then(r => r.blob());\nawait navigator.clipboard.write([\n    new ClipboardItem({ [imgBlob.type]: imgBlob }),\n]);\n",[28,3910,3911,3916,3947,3952,3978,3983,4031,4049,4084],{"__ignoreMap":107},[111,3912,3913],{"class":113,"line":114},[111,3914,3915],{"class":168},"\u002F\u002F 写入文本\n",[111,3917,3918,3921,3924,3926,3929,3931,3934,3936,3938,3941,3943,3945],{"class":113,"line":152},[111,3919,3920],{"class":345},"await",[111,3922,3923],{"class":117}," navigator",[111,3925,122],{"class":121},[111,3927,3928],{"class":117},"clipboard",[111,3930,122],{"class":121},[111,3932,3933],{"class":125},"writeText",[111,3935,128],{"class":117},[111,3937,132],{"class":131},[111,3939,3940],{"class":135},"Hello World",[111,3942,132],{"class":131},[111,3944,193],{"class":117},[111,3946,196],{"class":121},[111,3948,3949],{"class":113,"line":172},[111,3950,3951],{"class":168},"\u002F\u002F 读取文本\n",[111,3953,3954,3956,3959,3961,3963,3965,3967,3969,3971,3974,3976],{"class":113,"line":187},[111,3955,452],{"class":337},[111,3957,3958],{"class":455}," text",[111,3960,460],{"class":459},[111,3962,2770],{"class":345},[111,3964,3923],{"class":117},[111,3966,122],{"class":121},[111,3968,3928],{"class":117},[111,3970,122],{"class":121},[111,3972,3973],{"class":125},"readText",[111,3975,801],{"class":117},[111,3977,196],{"class":121},[111,3979,3980],{"class":113,"line":199},[111,3981,3982],{"class":168},"\u002F\u002F 写入图片（ClipboardItem）\n",[111,3984,3985,3987,3990,3992,3994,3996,3998,4000,4003,4005,4007,4009,4011,4013,4016,4018,4021,4023,4026,4029],{"class":113,"line":206},[111,3986,452],{"class":337},[111,3988,3989],{"class":455}," imgBlob",[111,3991,460],{"class":459},[111,3993,2770],{"class":345},[111,3995,2773],{"class":125},[111,3997,128],{"class":117},[111,3999,132],{"class":131},[111,4001,4002],{"class":135},"image.png",[111,4004,132],{"class":131},[111,4006,193],{"class":117},[111,4008,122],{"class":121},[111,4010,2276],{"class":125},[111,4012,128],{"class":117},[111,4014,4015],{"class":333},"r",[111,4017,338],{"class":337},[111,4019,4020],{"class":117}," r",[111,4022,122],{"class":121},[111,4024,4025],{"class":125},"blob",[111,4027,4028],{"class":117},"())",[111,4030,196],{"class":121},[111,4032,4033,4035,4037,4039,4041,4043,4046],{"class":113,"line":212},[111,4034,3920],{"class":345},[111,4036,3923],{"class":117},[111,4038,122],{"class":121},[111,4040,3928],{"class":117},[111,4042,122],{"class":121},[111,4044,4045],{"class":125},"write",[111,4047,4048],{"class":117},"([\n",[111,4050,4051,4054,4057,4059,4061,4064,4067,4069,4071,4073,4075,4078,4080,4082],{"class":113,"line":582},[111,4052,4053],{"class":459},"    new",[111,4055,4056],{"class":125}," ClipboardItem",[111,4058,128],{"class":117},[111,4060,2116],{"class":121},[111,4062,4063],{"class":155}," [",[111,4065,4066],{"class":117},"imgBlob",[111,4068,122],{"class":121},[111,4070,665],{"class":117},[111,4072,2060],{"class":155},[111,4074,159],{"class":121},[111,4076,4077],{"class":117}," imgBlob ",[111,4079,190],{"class":121},[111,4081,193],{"class":117},[111,4083,749],{"class":121},[111,4085,4086,4089],{"class":113,"line":739},[111,4087,4088],{"class":117},"])",[111,4090,196],{"class":121},[39,4092,4094],{"id":4093},"八全屏-api-与页面可见性","八、全屏 API 与页面可见性",[44,4096,4098],{"id":4097},"_1-全屏-api","1. 全屏 API",[102,4100,4102],{"className":104,"code":4101,"language":106,"meta":107,"style":107},"\u002F\u002F 进入全屏\ndocument.documentElement.requestFullscreen();\n\u002F\u002F 退出全屏\ndocument.exitFullscreen();\n\u002F\u002F 监听变化\ndocument.addEventListener(\"fullscreenchange\", () => {\n    console.log(document.fullscreenElement);\n});\n",[28,4103,4104,4109,4127,4132,4145,4150,4175,4196],{"__ignoreMap":107},[111,4105,4106],{"class":113,"line":114},[111,4107,4108],{"class":168},"\u002F\u002F 进入全屏\n",[111,4110,4111,4113,4115,4118,4120,4123,4125],{"class":113,"line":152},[111,4112,300],{"class":117},[111,4114,122],{"class":121},[111,4116,4117],{"class":117},"documentElement",[111,4119,122],{"class":121},[111,4121,4122],{"class":125},"requestFullscreen",[111,4124,801],{"class":117},[111,4126,196],{"class":121},[111,4128,4129],{"class":113,"line":172},[111,4130,4131],{"class":168},"\u002F\u002F 退出全屏\n",[111,4133,4134,4136,4138,4141,4143],{"class":113,"line":187},[111,4135,300],{"class":117},[111,4137,122],{"class":121},[111,4139,4140],{"class":125},"exitFullscreen",[111,4142,801],{"class":117},[111,4144,196],{"class":121},[111,4146,4147],{"class":113,"line":199},[111,4148,4149],{"class":168},"\u002F\u002F 监听变化\n",[111,4151,4152,4154,4156,4158,4160,4162,4165,4167,4169,4171,4173],{"class":113,"line":206},[111,4153,300],{"class":117},[111,4155,122],{"class":121},[111,4157,85],{"class":125},[111,4159,128],{"class":117},[111,4161,132],{"class":131},[111,4163,4164],{"class":135},"fullscreenchange",[111,4166,132],{"class":131},[111,4168,141],{"class":121},[111,4170,1182],{"class":121},[111,4172,338],{"class":337},[111,4174,149],{"class":121},[111,4176,4177,4179,4181,4183,4185,4187,4189,4192,4194],{"class":113,"line":212},[111,4178,557],{"class":117},[111,4180,122],{"class":121},[111,4182,387],{"class":125},[111,4184,128],{"class":155},[111,4186,300],{"class":117},[111,4188,122],{"class":121},[111,4190,4191],{"class":117},"fullscreenElement",[111,4193,193],{"class":155},[111,4195,196],{"class":121},[111,4197,4198,4200,4202],{"class":113,"line":582},[111,4199,190],{"class":121},[111,4201,193],{"class":117},[111,4203,196],{"class":121},[44,4205,4207],{"id":4206},"_2-页面可见性-api","2. 页面可见性 API",[102,4209,4211],{"className":104,"code":4210,"language":106,"meta":107,"style":107},"document.addEventListener(\"visibilitychange\", () => {\n    if (document.hidden) {\n        console.log(\"页面隐藏，暂停动画或轮询\");\n    } else {\n        console.log(\"页面可见，恢复\");\n    }\n});\n",[28,4212,4213,4238,4255,4276,4285,4306,4310],{"__ignoreMap":107},[111,4214,4215,4217,4219,4221,4223,4225,4228,4230,4232,4234,4236],{"class":113,"line":114},[111,4216,300],{"class":117},[111,4218,122],{"class":121},[111,4220,85],{"class":125},[111,4222,128],{"class":117},[111,4224,132],{"class":131},[111,4226,4227],{"class":135},"visibilitychange",[111,4229,132],{"class":131},[111,4231,141],{"class":121},[111,4233,1182],{"class":121},[111,4235,338],{"class":337},[111,4237,149],{"class":121},[111,4239,4240,4242,4244,4246,4248,4251,4253],{"class":113,"line":152},[111,4241,346],{"class":345},[111,4243,349],{"class":155},[111,4245,300],{"class":117},[111,4247,122],{"class":121},[111,4249,4250],{"class":117},"hidden",[111,4252,648],{"class":155},[111,4254,377],{"class":121},[111,4256,4257,4259,4261,4263,4265,4267,4270,4272,4274],{"class":113,"line":172},[111,4258,382],{"class":117},[111,4260,122],{"class":121},[111,4262,387],{"class":125},[111,4264,128],{"class":155},[111,4266,132],{"class":131},[111,4268,4269],{"class":135},"页面隐藏，暂停动画或轮询",[111,4271,132],{"class":131},[111,4273,193],{"class":155},[111,4275,196],{"class":121},[111,4277,4278,4280,4283],{"class":113,"line":187},[111,4279,2346],{"class":121},[111,4281,4282],{"class":345}," else",[111,4284,149],{"class":121},[111,4286,4287,4289,4291,4293,4295,4297,4300,4302,4304],{"class":113,"line":199},[111,4288,382],{"class":117},[111,4290,122],{"class":121},[111,4292,387],{"class":125},[111,4294,128],{"class":155},[111,4296,132],{"class":131},[111,4298,4299],{"class":135},"页面可见，恢复",[111,4301,132],{"class":131},[111,4303,193],{"class":155},[111,4305,196],{"class":121},[111,4307,4308],{"class":113,"line":206},[111,4309,418],{"class":121},[111,4311,4312,4314,4316],{"class":113,"line":212},[111,4313,190],{"class":121},[111,4315,193],{"class":117},[111,4317,196],{"class":121},[39,4319,4320],{"id":4320},"总结",[4322,4323,4324,4337],"table",{},[4325,4326,4327],"thead",{},[4328,4329,4330,4334],"tr",{},[4331,4332,4333],"th",{},"类别",[4331,4335,4336],{},"核心 API \u002F 概念",[4338,4339,4340,4351,4361,4371,4381,4391,4401,4411],"tbody",{},[4328,4341,4342,4348],{},[4343,4344,4345],"td",{},[58,4346,4347],{},"DOM 事件",[4343,4349,4350],{},"事件流（捕获\u002F冒泡）、委托、CustomEvent、MutationObserver、IntersectionObserver、ResizeObserver",[4328,4352,4353,4358],{},[4343,4354,4355],{},[58,4356,4357],{},"BOM",[4343,4359,4360],{},"history (SPA)、navigator、screen、location 精细操作",[4328,4362,4363,4368],{},[4343,4364,4365],{},[58,4366,4367],{},"图形",[4343,4369,4370],{},"Canvas 2D、WebGL (Three.js 等)",[4328,4372,4373,4378],{},[4343,4374,4375],{},[58,4376,4377],{},"存储",[4343,4379,4380],{},"localStorage\u002FsessionStorage、IndexedDB、Cookies (SameSite\u002FSecure\u002FHttpOnly)",[4328,4382,4383,4388],{},[4343,4384,4385],{},[58,4386,4387],{},"网络请求",[4343,4389,4390],{},"fetch (拦截、中止、流)、XHR (进度监听)、WebSocket、SSE",[4328,4392,4393,4398],{},[4343,4394,4395],{},[58,4396,4397],{},"多线程",[4343,4399,4400],{},"Web Worker、Shared Worker、Service Worker、SharedArrayBuffer + Atomics",[4328,4402,4403,4408],{},[4343,4404,4405],{},[58,4406,4407],{},"剪贴板",[4343,4409,4410],{},"navigator.clipboard (readText\u002FwriteText)",[4328,4412,4413,4418],{},[4343,4414,4415],{},[58,4416,4417],{},"其他",[4343,4419,4420],{},"全屏 API、页面可见性 API",[24,4422,4423],{},"生产项目须关注 API 兼容性（查 MDN 兼容性表）与 HTTPS 等安全要求（如 Service Worker）。",[39,4425,4426],{"id":4426},"参考文献",[24,4428,4429],{},"以下链接在编写时均可正常访问：",[4322,4431,4432,4442],{},[4325,4433,4434],{},[4328,4435,4436,4439],{},[4331,4437,4438],{},"资料",[4331,4440,4441],{},"说明",[4338,4443,4444,4457,4469,4480,4492,4504],{},[4328,4445,4446,4454],{},[4343,4447,4448],{},[33,4449,4453],{"href":4450,"rel":4451},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FAPI\u002FDocument_Object_Model",[4452],"nofollow","MDN：Document Object Model",[4343,4455,4456],{},"DOM",[4328,4458,4459,4466],{},[4343,4460,4461],{},[33,4462,4465],{"href":4463,"rel":4464},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FAPI\u002FEvent",[4452],"MDN：事件",[4343,4467,4468],{},"事件对象",[4328,4470,4471,4478],{},[4343,4472,4473],{},[33,4474,4477],{"href":4475,"rel":4476},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FAPI\u002FWindow\u002Ffetch",[4452],"MDN：fetch",[4343,4479,4387],{},[4328,4481,4482,4489],{},[4343,4483,4484],{},[33,4485,4488],{"href":4486,"rel":4487},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FAPI\u002FWeb_Workers_API",[4452],"MDN：Web Workers",[4343,4490,4491],{},"Worker",[4328,4493,4494,4501],{},[4343,4495,4496],{},[33,4497,4500],{"href":4498,"rel":4499},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FAPI\u002FIntersection_Observer_API",[4452],"MDN：Intersection Observer",[4343,4502,4503],{},"交叉观察器",[4328,4505,4506,4513],{},[4343,4507,4508],{},[33,4509,4512],{"href":4510,"rel":4511},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FAPI\u002FStorage",[4452],"MDN：Storage",[4343,4514,4515],{},"localStorage 等",[4517,4518,4519],"style",{},"html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZUrc, html code.shiki .sZUrc{--shiki-light:#E53935;--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":107,"searchDepth":152,"depth":152,"links":4521},[4522,4536,4546,4550,4557,4563,4569,4570,4574,4575],{"id":41,"depth":152,"text":42,"children":4523},[4524,4525,4527,4528,4530,4532,4534],{"id":46,"depth":172,"text":47},{"id":89,"depth":172,"text":4526},"2. addEventListener 的 useCapture 与 once",{"id":261,"depth":172,"text":262},{"id":429,"depth":172,"text":4529},"4. 自定义事件（CustomEvent）",{"id":591,"depth":172,"text":4531},"5. MutationObserver – 监听 DOM 变化",{"id":806,"depth":172,"text":4533},"6. IntersectionObserver – 懒加载、无限滚动",{"id":992,"depth":172,"text":4535},"7. ResizeObserver – 监听元素尺寸变化",{"id":1121,"depth":152,"text":1122,"children":4537},[4538,4540,4542,4544],{"id":1125,"depth":172,"text":4539},"1. history 对象 – SPA 路由核心",{"id":1231,"depth":172,"text":4541},"2. navigator – 浏览器与设备信息",{"id":1279,"depth":172,"text":4543},"3. screen – 屏幕信息",{"id":1307,"depth":172,"text":4545},"4. location – URL 精细操作",{"id":1529,"depth":152,"text":1530,"children":4547},[4548,4549],{"id":1533,"depth":172,"text":1534},{"id":1746,"depth":172,"text":1747},{"id":1791,"depth":152,"text":1792,"children":4551},[4552,4554,4556],{"id":1795,"depth":172,"text":4553},"1. localStorage \u002F sessionStorage",{"id":1944,"depth":172,"text":4555},"2. IndexedDB – 大型结构化数据存储",{"id":2166,"depth":172,"text":2167},{"id":2237,"depth":152,"text":2238,"children":4558},[4559,4560,4561,4562],{"id":2241,"depth":172,"text":2242},{"id":2911,"depth":172,"text":2912},{"id":3089,"depth":172,"text":3090},{"id":3338,"depth":172,"text":3339},{"id":3444,"depth":152,"text":3445,"children":4564},[4565,4566,4567],{"id":3448,"depth":172,"text":3449},{"id":3618,"depth":172,"text":3619},{"id":3766,"depth":172,"text":4568},"3. SharedArrayBuffer 与原子操作（Atomics）",{"id":3898,"depth":152,"text":3899},{"id":4093,"depth":152,"text":4094,"children":4571},[4572,4573],{"id":4097,"depth":172,"text":4098},{"id":4206,"depth":172,"text":4207},{"id":4320,"depth":152,"text":4320},{"id":4426,"depth":152,"text":4426},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fweb\u002FJs\u002Fdom-bom","knowledge\u002Fknowledge\u002Fbooklet\u002Fweb\u002FJs\u002Fdom-bom.md","md",{"items":4581},[4582,4586,4590,4594,4598,4602],{"path":4583,"title":4584,"description":4585,"category":10,"score":206},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Ferror","错误处理与调试","结构化错误类型、try\u002Fcatch 与全局未捕获处理是健壮应用的基础。",{"path":4587,"title":4588,"description":4589,"category":10,"score":206},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fperformance","性能优化","防抖\u002F节流、渲染与内存、资源预加载及引擎行为是前端性能的主要抓手。相关 CSS 见 视觉效果、Head 资源提示。",{"path":4591,"title":4592,"description":4593,"category":10,"score":206},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fcommon","模块化与工程化","ESM、CommonJS 与打包工具（Tree Shaking、代码分割）是前端工程化的基础。入门见 JavaScript 基础 · 模块。",{"path":4595,"title":4596,"description":4597,"category":10,"score":206},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fscope","执行模型与作用域","执行上下文与词法作用域决定变量在何处可访问、闭包如何形成，以及 var \u002F let \u002F const 的差异。语言概览见 JavaScript 基础。",{"path":4599,"title":4600,"description":4601,"category":10,"score":206},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fmap-set","数据结构与集合增强","Map \u002F Set、WeakMap \u002F WeakSet、数组高阶方法、TypedArray 与 Symbol 等扩展了内置数据结构能力。见 语言基础。",{"path":4603,"title":4604,"description":4605,"category":10,"score":206},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fbasics","JavaScript 基础","JavaScript（ECMAScript）是 Web 页面与 Node.js 等运行时的脚本语言：在浏览器中操作 DOM、发起网络请求；在服务端处理 I\u002FO。语法与 HTML、CSS 配合构成前端技术栈。",{"series":4607,"title":106,"items":4608,"index":187,"prev":4650,"next":4651},"booklet\u002Fweb\u002Fjs",[4609,4613,4615,4617,4621,4622,4624,4628,4632,4634,4636,4640,4644,4648],{"path":4610,"title":4611,"date":4612,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fadvanced","函数进阶","2022-10-24",{"path":4603,"title":4604,"date":4614,"pinned":15},"2023-11-24",{"path":4591,"title":4592,"date":4616,"pinned":15},"2025-06-21",{"path":4618,"title":4619,"date":4620,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdesign","设计模式","2021-10-05",{"path":7,"title":8,"date":14,"pinned":15},{"path":4583,"title":4584,"date":4623,"pinned":15},"2026-06-25",{"path":4625,"title":4626,"date":4627,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fevent-loop","异步编程与事件循环","2020-03-23",{"path":4629,"title":4630,"date":4631,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fexec","正则表达式","2022-05-21",{"path":4599,"title":4600,"date":4633,"pinned":15},"2024-07-10",{"path":4587,"title":4588,"date":4635,"pinned":15},"2025-07-04",{"path":4637,"title":4638,"date":4639,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fprototype","原型与面向对象","2020-04-13",{"path":4641,"title":4642,"date":4643,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fproxy","代理与反射","2022-10-23",{"path":4645,"title":4646,"date":4647,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fsafe","安全","2023-06-26",{"path":4595,"title":4596,"date":4649,"pinned":15},"2025-01-29",{"path":4618,"title":4619,"date":4620,"pinned":15},{"path":4583,"title":4584,"date":4623,"pinned":15}]