最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript利用Bookmarklet給網(wǎng)頁臨時掛載一個圖片調(diào)試面板

 更新時間:2026年04月26日 13:43:23   作者:前端不開發(fā)  
在前端開發(fā)中,我們經(jīng)常需要分析頁面中的資源情況,比如頁面實際加載了哪些圖片,不同分辨率資源的分布等等,這些事情當(dāng)然可以通過 DevTools 完成,但在某些場景下效率并不高,所以本文介紹了JavaScript利用Bookmarklet給網(wǎng)頁臨時掛載一個圖片調(diào)試面板

在前端開發(fā)中,我們經(jīng)常需要分析頁面中的資源情況,比如:

  • 頁面實際加載了哪些圖片
  • 不同分辨率資源的分布
  • 是否存在重復(fù)圖片請求
  • UI 還原時如何快速定位原始素材

這些事情當(dāng)然可以通過 DevTools 完成,但在某些場景下效率并不高。例如批量瀏覽圖片、篩選大圖、快速預(yù)覽等操作,都需要在多個面板之間來回切換。

于是可以換一個思路:

不擴展 DevTools,而是用一段 Bookmarklet,在任意網(wǎng)頁上臨時掛載一個“圖片調(diào)試面板”。

這篇文章的重點不在工具本身,而在于這種實現(xiàn)方式背后的前端技術(shù)思路。

一、為什么是 Bookmarklet

Bookmarklet 的本質(zhì),是一段運行在當(dāng)前頁面上下文中的 JavaScript。

javascript:(()=>{ /* your code */ })()

它有幾個非常關(guān)鍵的特性:

  • 直接運行在頁面環(huán)境中,可以訪問 DOM
  • 不需要構(gòu)建或發(fā)布瀏覽器插件
  • 無需侵入頁面代碼
  • 可以在任意網(wǎng)站使用

這使它非常適合做“臨時調(diào)試能力注入”。

可以把它理解為:

一種輕量級的“運行時工具擴展機制”

二、核心問題:如何獲取真實圖片資源

最直接的方式是:

[...document.images]

但這只是第一步,真正需要解決的是兩個問題:

1. 圖片是否已經(jīng)加載完成

i.naturalWidth

只有當(dāng)圖片完成加載后,naturalWidthnaturalHeight 才是有效的。

2. 如何獲取真實資源地址

i.currentSrc || i.src

這里的關(guān)鍵是 currentSrc。

在響應(yīng)式圖片場景中:

<img src="small.jpg" srcset="large.jpg 2x">

瀏覽器實際使用的資源并不一定是 src,而是 currentSrc。

如果忽略這一點,拿到的數(shù)據(jù)很可能是不準(zhǔn)確的。

三、數(shù)據(jù)建模:不僅僅是收集

收集圖片之后,需要對數(shù)據(jù)做一層結(jié)構(gòu)化處理:

{
  s: src,
  w: width,
  h: height,
  m: max(width, height)
}

這里的關(guān)鍵字段是:

  • w / h:用于展示尺寸信息
  • m:用于排序和篩選

為什么使用最大邊?

因為在實際使用中:

  • 橫圖和豎圖不好直接比較
  • 最大邊可以作為統(tǒng)一尺度
  • 更適合做“是否為大圖”的判斷

四、去重策略:Map 比 Set 更合適

const map = new Map()
imgs.forEach(i => !map.has(i.s) && map.set(i.s, i))

這里選擇 Map 而不是 Set 的原因是:

  • 去重依據(jù)是 URL
  • 但我們需要保留完整對象
  • Map 可以同時解決“唯一性 + 數(shù)據(jù)存儲”

這是一個很典型的前端數(shù)據(jù)處理模式。

五、篩選與排序:面向使用場景設(shè)計

base.filter(i => !v || i.m >= v)

篩選邏輯圍繞一個實際需求:

快速找到大圖資源

配合排序:

first ? b.m - a.m : a.m - b.m

首屏優(yōu)先展示大圖,可以顯著提升信息獲取效率。

這其實是一個“數(shù)據(jù)展示策略”的問題,而不僅僅是代碼實現(xiàn)。

六、為什么在新窗口中渲染 UI

const w = open()
w.document.write(...)

這是整個實現(xiàn)中一個很關(guān)鍵的設(shè)計點。

如果直接在當(dāng)前頁面插入 UI,會遇到幾個問題:

  • 樣式?jīng)_突(CSS 污染)
  • z-index 競爭
  • 可能被頁面腳本影響

而新窗口的優(yōu)勢是:

  • 完全隔離運行環(huán)境
  • 樣式可控
  • 生命周期獨立

可以理解為:

用瀏覽器原生能力實現(xiàn)了一種“輕量沙箱”

七、實現(xiàn)代碼

完整實現(xiàn)如下(Bookmarklet 版本):

javascript:(()=>{const imgs=[...document.images].filter(i=>i.naturalWidth).map(i=>({s:i.currentSrc||i.src,w:i.naturalWidth,h:i.naturalHeight,m:Math.max(i.naturalWidth,i.naturalHeight)}));const map=new Map();imgs.forEach(i=>!map.has(i.s)&&map.set(i.s,i));const base=[...map.values()];const sizes=[...new Set(base.map(i=>i.m))].sort((a,b)=>b-a);const w=open();w.document.write(`<!doctype html><meta charset=utf-8><title>頁面圖片資源(${base.length})</title><style>*{box-sizing:border-box}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;background:#0f1115;color:#e6e6e6}header{position:sticky;top:0;z-index:10;background:#161a20;padding:12px 16px;font-size:14px;display:flex;gap:12px;align-items:center;box-shadow:0 6px 20px rgba(0,0,0,.4)}select{margin-left:auto;background:#0f1115;color:#e6e6e6;border:1px solid #333;border-radius:6px;padding:4px 8px;font-size:12px}.grid{padding:16px;display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:16px}.card{background:#161a20;border-radius:12px;overflow:hidden;position:relative;transition:transform .18s ease-out,opacity .18s ease-out}.card.enter{transform:scale(.96);opacity:0}.card img{width:100%;height:180px;object-fit:contain;background:#0b0d11;cursor:zoom-in}.badge{position:absolute;top:8px;right:8px;font-size:11px;padding:2px 6px;border-radius:6px;background:rgba(0,0,0,.65)}.tools{position:absolute;bottom:8px;right:8px;display:flex;gap:6px}.tools button{background:rgba(0,0,0,.7);color:#fff;border:none;padding:5px 7px;font-size:12px;border-radius:6px;cursor:pointer}.toast{position:fixed;top:14px;left:50%;transform:translateX(-50%);background:#222;padding:8px 14px;border-radius:20px;font-size:12px;opacity:0;transition:.2s;z-index:20}.toast.show{opacity:1}.preview{position:fixed;inset:0;background:rgba(0,0,0,.9);display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:.2s;z-index:30}.preview.show{opacity:1;pointer-events:auto}.preview img{max-width:90%;max-height:90%}</style><header>頁面圖片資源(${base.length})<select id=f><option value=0>全部</option></select></header><div class=toast id=t></div><div class=grid id=g></div><div class=preview id=p><img></div>%60);const d=w.document,G=d.getElementById("g"),F=d.getElementById("f"),T=d.getElementById("t");sizes.forEach(s=>{const o=d.createElement("option");o.value=s;o.textContent="≥ "+s+"px";F.appendChild(o)});const toast=m=>{T.textContent=m;T.className="toast show";setTimeout(()=>T.className="toast",1200)};const draw=(v,first)=>{const arr=base.filter(i=>!v||i.m>=v).sort((a,b)=>first?b.m-a.m:a.m-b.m);G.innerHTML="";arr.forEach(i=>{const c=d.createElement("div");c.className="card enter";c.innerHTML='<span class="badge">'+i.w+' × '+i.h+'</span><img src="'+i.s+'"><div class="tools"><button data-copy="'+i.s+'">復(fù)制</button><button data-open="'+i.s+'">打開</button></div>';G.appendChild(c);setTimeout(()=>c.classList.remove("enter"),0)})};draw(0,true);F.onchange=e=>draw(+e.target.value,false);d.onclick=e=>{if(e.target.dataset.copy){const a=d.createElement("textarea");a.value=e.target.dataset.copy;d.body.appendChild(a);a.select();d.execCommand("copy");a.remove();toast("已復(fù)制")}if(e.target.dataset.open)w.open(e.target.dataset.open,"_blank","noopener");if(e.target.tagName==="IMG"){d.getElementById("p").classList.add("show");d.querySelector("#p img").src=e.target.src}if(e.target.id==="p")e.target.classList.remove("show")};d.onkeydown=e=>e.key==="Escape"&&d.getElementById("p").classList.remove("show");d.close()})();

八、可以延展的方向

這個思路可以進一步擴展為一類能力:

  • CSS 調(diào)試面板(查看覆蓋關(guān)系)
  • 字體分析工具
  • 網(wǎng)絡(luò)請求監(jiān)控(結(jié)合 fetch hook)
  • DOM 結(jié)構(gòu)可視化

也就是說:

Bookmarklet 不只是“小工具”,而是一種可以快速構(gòu)建調(diào)試能力的前端模式。

九、總結(jié)

這段代碼的價值不在于“提取圖片”,而在于它體現(xiàn)了幾個重要的前端思路:

  • 如何在運行時擴展頁面能力
  • 如何做輕量級的數(shù)據(jù)建模與處理
  • 如何在無框架環(huán)境下構(gòu)建完整交互
  • 如何利用瀏覽器原生能力實現(xiàn)隔離

如果換一個角度看,它更像是一個無需安裝的臨時 DevTools 擴展。

理解這一點,比代碼本身更重要。

以上就是JavaScript利用Bookmarklet給網(wǎng)頁臨時掛載一個圖片調(diào)試面板的詳細內(nèi)容,更多關(guān)于JavaScript Bookmarklet網(wǎng)頁掛載圖片調(diào)試面板的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JS實現(xiàn)拖拽進度條改變元素透明度

    JS實現(xiàn)拖拽進度條改變元素透明度

    這篇文章主要為大家詳細介紹了JS實現(xiàn)拖拽進度條改變元素透明度,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • JavaScript ES6 Class類實現(xiàn)原理詳解

    JavaScript ES6 Class類實現(xiàn)原理詳解

    這篇文章主要介紹了JavaScript ES6 Class類實現(xiàn)原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-05-05
  • 如何編寫一個d.ts文件的步驟詳解

    如何編寫一個d.ts文件的步驟詳解

    這篇文章主要給大家介紹了關(guān)于如何編寫一個d.ts文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用d.ts具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-04-04
  • JavaScript中如何跳出forEach循環(huán)代碼示例

    JavaScript中如何跳出forEach循環(huán)代碼示例

    循環(huán)遍歷一個元素是開發(fā)中最常見的需求之一,下面這篇文章主要給大家介紹了關(guān)于JavaScript中如何跳出forEach循環(huán)的相關(guān)資料,文章通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-06-06
  • Kotlin學(xué)習(xí)第一步 kotlin語法特性

    Kotlin學(xué)習(xí)第一步 kotlin語法特性

    Kotlin學(xué)習(xí)第一步,從kotlin語法特性開始學(xué)習(xí),包括變量定義、函數(shù)擴展、Parcelable序列化、編寫工具類等,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • javascript的offset、client、scroll使用方法詳解

    javascript的offset、client、scroll使用方法詳解

    javascript的offset、client、scroll在使用過程中非常頻繁,接下來將對此進行一一介紹,需要了解的朋友可以詳細參考下
    2012-12-12
  • JS禁用瀏覽器退格鍵實現(xiàn)思路及代碼

    JS禁用瀏覽器退格鍵實現(xiàn)思路及代碼

    關(guān)于瀏覽器退格鍵的禁用,可行的方法有很多,在本文將為大家詳細介紹下在js中時如何做到的,有需求的各位可以參考下
    2013-10-10
  • JavaScript操作Oracle數(shù)據(jù)庫示例

    JavaScript操作Oracle數(shù)據(jù)庫示例

    這篇文章主要介紹了JavaScript操作Oracle數(shù)據(jù)庫示例,本文使用ActiveXObject實現(xiàn)訪問Oracle數(shù)據(jù)庫,需要的朋友可以參考下
    2015-03-03
  • 折疊菜單及選擇器的運用

    折疊菜單及選擇器的運用

    本文主要介紹了折疊菜單及選擇器的運用。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • IE8 內(nèi)存泄露(內(nèi)存一直增長 )的原因及解決辦法

    IE8 內(nèi)存泄露(內(nèi)存一直增長 )的原因及解決辦法

    最近開發(fā)的時候?qū)撁媸褂昧硕〞r的局部更新,結(jié)果在ie6,7和Firefox下,一切正常,而在ie8下過上幾個小時就瀏覽器就崩潰了,顯示是內(nèi)存溢出,下面由腳本之家小編給大家介紹ie8下內(nèi)存一直增長內(nèi)存泄漏的原因及解決辦法,需要的朋友一起學(xué)習(xí)吧
    2016-04-04

最新評論

岳普湖县| 来安县| 辰溪县| 仙游县| 太湖县| 称多县| 新兴县| 张家界市| 怀化市| 武邑县| 特克斯县| 比如县| 磐安县| 全州县| 秦安县| 苏尼特右旗| 彭阳县| 新乐市| 泊头市| 清流县| 阿拉善右旗| 浪卡子县| 临漳县| 平罗县| 山阳县| 闽侯县| 南汇区| 乾安县| 大荔县| 宜兰县| 尖扎县| 泰和县| 手游| 泸州市| 渝中区| 老河口市| 东港市| 阿坝| 随州市| 阿拉善盟| 拜泉县|