直接获取所有的img图片
// 获取网页中所有的img标签的图片
// 返回一个包含图片的src,宽度和高度的对象数组
function getImgs (doc) {
return Array.from(doc.getElementsByTagName('img')) // 转换 NodeList 到数组
.map(img => ({
src: img.currentSrc, // 使用img.src来获取图片的原始src
width: img.naturalWidth,
height: img.naturalHeight
}))
}
console.log(getImgs(document));
使用document.images获取图片
// 与上一个函数类似,但使用document.images来获取所有的img标签
function getImgs (doc) {
return Array.from(doc.images)
.map(img => ({
src: img.currentSrc,
width: img.naturalWidth,
height: img.naturalHeight
}))
}
console.log(getImgs(document));
获取背景图片
/**
* 获取文档中所有DOM元素的background-image属性值。
* @param {Document} doc - 需要查询的文档对象,通常是document。
* @returns {string[]} - 背景图片URL的数组。
*/
function getBgImgs(doc) {
// 定义一个正则表达式来匹配CSS中的background-image属性值。
// 该正则可以捕获格式为url("path/to/image")中的路径字符串。
const srcChecker = /url\(\s*?['"]?\s*?(\S+?)\s*?["']?\s*?\)/i;
// 返回从文档中查询到的所有DOM元素的结果。
return Array.from(
Array.from(doc.querySelectorAll('*')) // 查询文档中的所有DOM元素。
.reduce((collection, node) => { // 使用reduce方法,将所有背景图片的URL聚合到一个Set中,以消除重复项。
// 使用window.getComputedStyle方法获取节点的所有计算后的CSS样式。
let prop = window.getComputedStyle(node, null)
.getPropertyValue('background-image'); // 从样式中获取background-image属性值。
let match = srcChecker.exec(prop); // 使用正则表达式匹配background-image的属性值。
if (match) {
collection.add(match[1]); // 如果匹配成功,将图片URL添加到集合中。
}
return collection; // 返回集合,供下一次迭代使用。
}, new Set()) // 初始化一个新的Set对象,用于收集背景图片的URL。
);
}
// 在控制台中打印当前文档中的所有背景图片URL。
console.log(getBgImgs(document));
加载并获取背景图片的尺寸信息
// 背景图片本身不带有尺寸信息
// 这个函数将加载每一张图片并返回其尺寸
function loadImg(src, timeout = 500) {
// 创建一个新的Promise来处理图片加载事件
var imgPromise = new Promise((resolve, reject) => {
let img = new Image() // 创建一个新的Image对象
// 图片加载成功后,调用resolve方法,并返回图片的src和其自然尺寸
img.onload = () => {
resolve({
src: src,
width: img.naturalWidth,
height: img.naturalHeight
})
}
// 如果图片加载失败,调用reject方法
img.onerror = reject
// 设置图片的来源
img.src = src
})
// 设置一个定时器,如果超过给定的超时时间(默认500毫秒)则触发reject
var timer = new Promise((resolve, reject) => {
setTimeout(reject, timeout)
})
// 使用Promise.race返回先发生的事件,要么是图片加载完成,要么是超时
return Promise.race([imgPromise, timer])
}
// 该函数接受一个图片URL列表,并尝试加载每一张图片
// 它将返回一个新的数组,包含成功加载的图片的信息
function loadImgAll(imgList, timeout = 500) {
return new Promise((resolve, reject) => {
// 使用Promise.all尝试并行加载所有图片
// 使用map将每个图片URL转化为一个加载图片的Promise
// 使用.catch处理每一个Promise,以确保即使某些图片加载失败,也不会使整个Promise.all失败
Promise.all(
imgList
.map(src => loadImg(src, timeout))
.map(p => p.catch(e => false))
).then(results => {
// 过滤结果,移除任何加载失败的图片(它们会被标记为false)
resolve(results.filter(r => r))
})
})
}
// 调用loadImgAll函数,传入一个通过getBgImgs函数获取的背景图片列表
console.log(loadImgAll(getBgImgs(document)));
在iframe中获取图片
// 递归搜索所有的iframe,并获取其中的 img>标签的图片
function searchIframes (doc) {
var imgList = []
doc.querySelectorAll('iframe')
.forEach(iframe => {
try {
iframeDoc = iframe.contentDocument || iframe.contentWindow.document
imgList = imgList.concat(getImgs(iframeDoc))
imgList = imgList.concat(searchIframes(iframeDoc))
} catch (e) {
// 忽略因跨域引发的错误
}
})
return imgList
}
console.log(searchIframes(document));
整合所有方法获取所有图片
/**
* 获取网页上的所有图片,并返回一个包含图片的src、宽度和高度的对象数组
* @param {Document} doc - 网页的Document对象
* @return {Promise Array>} - 返回图片的信息数组
*/
function getImgAll(doc) {
// 主函数返回一个Promise,用于处理图片加载
return new Promise((resolve, reject) => {
loadImgAll(Array.from(searchDOM(doc)))
.then(resolve, reject)
})
/**
* 从指定的DOM中搜索所有图片的src
* @param {Document} doc - DOM文档对象
* @return {Set string>} - 返回一个包含所有图片src的Set对象
*/
function searchDOM(doc) {
const srcChecker = /url\(\s*?['"]?\s*?(\S+?)\s*?["']?\s*?\)/i; // 正则用于匹配CSS背景图片的url
// 查询所有元素,并将它们的src或background-image收集到一个Set中
return Array.from(doc.querySelectorAll('*'))
.reduce((collection, node) => {
// 获取元素的计算样式
let prop = window.getComputedStyle(node, null)
.getPropertyValue('background-image');
// 使用正则检查是否有背景图片
let match = srcChecker.exec(prop);
if (match) {
collection.add(match[1]); // 如果有,添加到集合中
}
// 如果元素是 img>标签,添加其src到集合
if (/^img$/i.test(node.tagName)) {
collection.add(node.src);
}
// 如果元素是 frame>标签,尝试从它的contentDocument或contentWindow.document中获取图片
else if (/^frame$/i.test(node.tagName)) {
try {
searchDOM(node.contentDocument || node.contentWindow.document)
.forEach(img => {
if (img) {
collection.add(img);
}
});
} catch (e) {}
}
return collection;
}, new Set());
}
/**
* 加载单个图片并返回其信息
* @param {string} src - 图片的src
* @param {number} [timeout=500] - 超时时间,默认为500毫秒
* @return {Promise Object>} - 返回一个Promise,包含图片的信息或错误
*/
function loadImg(src, timeout = 500) {
// 创建一个新的Promise来处理图片加载
var imgPromise = new Promise((resolve, reject) => {
let img = new Image();
img.onload = () => {
// 当图片加载完成时,返回图片的信息
resolve({
src: src,
width: img.naturalWidth,
height: img.naturalHeight
});
}
img.onerror = reject; // 加载错误时拒绝Promise
img.src = src;
});
// 创建一个定时器,如果在指定的超时时间内图片未完成加载,则拒绝Promise
var timer = new Promise((resolve, reject) => {
setTimeout(reject, timeout);
});
// 返回两个Promise中最先完成的一个
return Promise.race([imgPromise, timer]);
}
/**
* 加载所有图片并返回它们的信息
* @param {Array string>} imgList - 图片src的数组
* @param {number} [timeout=500] - 超时时间,默认为500毫秒
* @return {Promise Array>} - 返回一个Promise,包含所有图片的信息或错误
*/
function loadImgAll(imgList, timeout = 500) {
return new Promise((resolve, reject) => {
// 使用Promise.all来处理所有图片的加载
Promise.all(
imgList
.map(src => loadImg(src, timeout)) // 对每个图片src执行loadImg
.map(p => p.catch(e => false)) // 对于任何拒绝的Promise,返回false
).then(results => resolve(results.filter(r => r))); // 过滤掉所有的false值,只保留图片信息
});
}
}
console.log(getImgAll(document)); // 在控制台打印出从当前文档中获取的所有图片信息