Javascript 在多个背景上显示的图像的平均颜色

Javascript average colour of img displayed on mulitple backgrounds

正如您在下面看到的,我正在尝试编写一个程序,它将采用图像的平均颜色,然后将其显示为 img 所在的父 class 的背景。

每个图像都存储在单独的 class 中:'sqr1'、'sqr2' e.t.c

问题是最后一个图像元素的平均颜色显示为所有父 class 标签的背景('sqr1'、'sqr2' e.t.c ).

有没有办法把这两者分开?

有没有更好的做法?

<html>

<head>
  <title>getting average color</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="js/color-thief.js"></script>
</head>

<body>
  <p id="bob">...</p>

  <div class="sqr1">
    <img src="memes/apple.jpg" width="400" height="400">
  </div>

  <p></p>

  <div class="sqr2">
    <img src="memes/pie.jpg" width="400" height="400">
  </div>

  <script type="text/javascript">
    var x;
    var allimgs = document.getElementsByTagName("img");
    var imglen = 2;

    let change = function(color,img){
      for (var i = 0; i < imglen; i++) {
          if (allimgs[i].src == img){
            allimgs[i].parentElement.style.backgroundColor = 'rgb('+color[0]+','+color[1]+','+color[2]+')';
          }
      }
    let colormix = function(){
      for(x = 0; x<imglen; x++){
        var colorThief = new ColorThief();
        colorThief.getColorFromUrl(allimgs[x].src, change,1);
        console.log();
      }
    }
    colormix();
  </script>
</body>

</html>

您的问题是 JavaScript 编程中的经典问题:您在循环中修改对象引用,并无意中将所有对象设置为引用相同的值。这个问题有很多解决方案;我的首选解决方案是将 for 循环的内部包装在一个立即调用的函数表达式 (iife) 中,以便为您的变量形成一个闭包范围:

let change = function(color,img){
  for (var i = 0; i < imglen; i++) {
      (function (index) {
        if (allimgs[index].src == img){
          allimgs[index].parentElement.style.backgroundColor = 'rgb('+color[0]+','+color[1]+','+color[2]+')';
        }
      })(i)
  }
}
let colormix = function(){
  for(x = 0; x<imglen; x++){
    (function (index) {
      var colorThief = new ColorThief();
      colorThief.getColorFromUrl(allimgs[index].src, change,1);
      console.log();
    })(x)
  }
}

我发现这个问题的这个解决方案是最方便的,但有些人更喜欢简单地将循环内部拉入函数并在循环中调用它们。结果是一样的。

有关这里发生的事情的更完整解释,请参阅此问题:JavaScript closure inside loops – simple practical example

为避免将来出现此类问题,请阅读 Javascript 作用域和闭包:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

啊,简单的逻辑错误。您正在遍历并设置所有图像的颜色,每次 。您需要删除 change 中的循环传递索引,否则它们将始终作为您的最终颜色。一种方法是将索引参数绑定到函数:

var x;
var allimgs = document.getElementsByTagName("img");
var imglen = allimgs.length;
let change = function(index, color, img){
   if (allimgs[index].src == img){
      allimgs[index].parentElement.style.backgroundColor = 'rgb('+color[0]+','+color[1]+','+color[2]+')';
   }
}
let colormix = function(){
  for(x = 0; x<imglen; x++){
    var colorThief = new ColorThief();
    colorThief.getColorFromUrl(allimgs[x].src, change.bind(null, x),1);
    console.log();
  }
}

我还切换了你的 imglen 以动态获取它的长度。
这是我用来证明它的 jsfiddle:https://jsfiddle.net/9L3ofjba/
如果这能解决您的问题,我会删除我的其他答案。