DOM中所有背景图像列表

14

如何使用JavaScript在给定的页面上找到所有的背景图片?

理想的结果是获得一个包含所有URL的数组。


8
jQuery 爱好者,请注意标签“no-framework”。 - user241244
主要问题在于图像和类可以在CSS类内定义。这些图像将被单独下载。但是,您可以创建一个HttpHandler来处理所有图像。为此,您需要使用.NET框架。 - azamsharp
这个问题的答案(第二段)是我找到的最快、最短的解决方案:https://dev59.com/J2445IYBdhLWcg3wRoLH#4952411 - Philipp
8个回答

12

//alert(getallBgimages())

function getallBgimages(){
 var url, B= [], A= document.getElementsByTagName('*');
 A= B.slice.call(A, 0, A.length);
 while(A.length){
  url= document.deepCss(A.shift(),'background-image');
  if(url) url=/url\(['"]?([^")]+)/.exec(url) || [];
  url= url[1];
  if(url && B.indexOf(url)== -1) B[B.length]= url;
 }
 return B;
}

document.deepCss= function(who, css){
 if(!who || !who.style) return '';
 var sty= css.replace(/\-([a-z])/g, function(a, b){
  return b.toUpperCase();
 });
 if(who.currentStyle){
  return who.style[sty] || who.currentStyle[sty] || '';
 }
 var dv= document.defaultView || window;
 return who.style[sty] || 
 dv.getComputedStyle(who,"").getPropertyValue(css) || '';
}

Array.prototype.indexOf= Array.prototype.indexOf || 
 function(what, index){
 index= index || 0;
 var L= this.length;
 while(index< L){
  if(this[index]=== what) return index;
  ++index;
 }
 return -1;
}

第6行应该是[^")']而不是[^")],这样可以匹配以单引号结尾的URL。 - cheng

6
不使用jQuery,您可以进行以下操作:
var elementNames = ["div", "body", "td"] // Put all the tags you want bg images for here
var allBackgroundURLs = new Array();
elementNames.forEach( function(tagName) {
     var tags = document.getElementsByTagName(tagName);
     var numTags = tags.length;
     for (var i = 0; i < numTags; i++) {
         tag = tags[i];
         if (tag.style.background.match("url")) {
             var bg = tag.style.background;
             allBackgroundURLs.push(bg.substr(bg.indexOf("url") + 4, bg.lastIndexOf(")") - (bg.indexOf("url") + 4) ) );
         }
     }
});

1
在 Chrome 中,我实际上是在 tag.style.backgroundImage 中找到它的,但其他方面都运行得很好。 - lapo

2
一种方法是查看所有文档对象并获取其样式。然后在"url("字符串上测试style.background属性,如果匹配,则获取在"url("和")"之间的路径,并将其放入数组中。这是JS算法。尝试自己做。如果遇到问题,请使用代码解决。

但是如果样式是在 .css 文件中定义的话,可能就不起作用了。 - azamsharp
1
它会的。只要试一下。无论它们在哪里声明。 - Artsiom Anisimau

1

以下是一种在页面样式中检查背景URL的方法(不需要jQuery):

window.npup = (function (doc) {
  var sheets = doc.styleSheets;
  var hash = {}, sheet, rules, rule, url, match;
  // loop the stylesheets
  for (var sheetIdx=0, sheetsLen=sheets.length; sheetIdx<sheetsLen; ++sheetIdx) {
    sheet = sheets[sheetIdx];
    // ie or w3c stylee rules property?
    rules = sheet.rules ? sheet.rules : sheet.cssRules;
    // loop the rules
    for (var ruleIdx=0, rulesLen=rules.length; ruleIdx<rulesLen; ++ruleIdx) {
      rule = rules[ruleIdx];
      if (rule.selectorText && rule.style.cssText) {
        // check if there's a style setting we're interested in..
        if (rule.style.cssText.match(/background/)) {
          // ..and if it has an url in it, put it in the hash
          match = /url\(([^)]*)\)/.exec(rule.style.cssText);
          if (match) {hash[match[1]] = true;}
        }
      }
    }
  }
  // return an array of unique urls
  var urls = [];
  for (url in hash) {urls.push(url);}
  // export a getter for what we found
  return {
    getBackgroundUrls: function () { return urls;}
  };
})(document); // submit reference to the document of interest

在页面上使用此代码,您可以使用npup.getBackgroundUrls();获取URL数组。 我在代码中添加了一些(多余的?)注释,解释了它的工作原理。 它不会抓取内联样式,但我认为这对您来说不是问题? 外部样式表和页面上的<style>标签中的样式被收集。

如果您想保留计数或保留与实际规则相关的关联,则可以轻松修改该例程。


1
这对我非常有效。特别适用于预加载附加到尚未在DOM中的元素上的图像。感谢您的发布! - donut
1
更新了这段代码以获得更好的跨浏览器支持,并且只有在首次调用时才会触发:https://gist.github.com/1293825 需要注意的重要事项是,该方法可能无法处理不同域和端口上的样式表。 - donut
1
我进一步改进了这个函数的版本,以更好地处理IE 7和8。它们将CSS属性转换为大写字母,而此函数没有进行不区分大小写的搜索。更新后的版本位于相同的URL:https://gist.github.com/1293825 - donut
使用styleSheets有一些棘手,因为您需要手动检查媒体查询,并在从其他服务器加载CSS文件(例如Google地图样式)时处理CORS限制 - Philipp

1
获取具有内联背景样式的集合元素
document.querySelectorAll('[style*="background"]')

0

这是一个复杂的问题。原因是可以使用单独的CSS文件将background-image应用于元素。这样,解析DOM中的所有对象并检查它们的background-image是行不通的。

我能想到的一种方法是创建一个简单的HttpHandler,该处理程序将适用于所有类型的图像。当图像在CSS文件中被引用时,它们会作为单独的实体下载。这意味着HttpHandler将能够捕获图像的类型,然后对其执行。

也许,服务器端的解决方案是解决这个问题的最佳方法!


2
OP请求访问背景图像,而不是常规图像。 - user241244

0

[...new Set(Array.from(document.querySelectorAll('div')).map(x => window.getComputedStyle(x).getPropertyValue('background-image').split(/[^4],\s*/)).flat())].map(x=>x.replace(/^\s*url\(["']([^"']+)["']\)?\s*$/, '$1'))

  • New Set: 去重
  • QuerySelectorAll: 选择所有节点
  • window.getComputedStyle: 获取动态样式(外部CSS文件)
  • flat(): 将数组的嵌套展开
  • split(/[^4],\s*/): 如果有多个背景,以逗号分隔,但不要在base64上分隔...
  • replace: 移除url(...)

0
我需要这个函数,可惜它们都太重了。所以经过思考,这是我的解决方案,希望能有所帮助。
function getAllBgInHtml()
{
    return document.body.innerHTML.match(/background-image.+?\((.+?)\)/gi).map(function(e){ return ((e.match(/background-image.+?\((.+?)\)/i) || [])[1] || '').replace(/&quot;|"/g,'') });
}

在外部样式表中,不适用于背景图片。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接