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/
如果这能解决您的问题,我会删除我的其他答案。
正如您在下面看到的,我正在尝试编写一个程序,它将采用图像的平均颜色,然后将其显示为 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/
如果这能解决您的问题,我会删除我的其他答案。