Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将所有图像的宽度相加_Javascript_Reactjs - Fatal编程技术网

Javascript 将所有图像的宽度相加

Javascript 将所有图像的宽度相加,javascript,reactjs,Javascript,Reactjs,我试图得到所有图像宽度的总和 我试图得到数组中的值,这样我就可以计算它们的和,但仍然不起作用,但这应该是非常简单的事情。实际上,我想要的只是图像宽度值的和 componentDidMount() { let images = document.querySelectorAll('#draggable img'); let widths = []; images.forEach(each => { each.addEventListener("load

我试图得到所有图像宽度的总和

我试图得到数组中的值,这样我就可以计算它们的和,但仍然不起作用,但这应该是非常简单的事情。实际上,我想要的只是图像宽度值的和

componentDidMount() {
    let images = document.querySelectorAll('#draggable img');
    let widths = [];
    images.forEach(each => {
        each.addEventListener("load", () => {
            widths.push(each.width)
        });
    });
    console.log(widths); // this is logging the array!
    const total = widths.reduce(function(a, b){ return a + b; }); 
    console.log("total is : " + total ); // this is crashing!
}

当reduce发生时,您无法确保图像已加载,因为事件与您的函数是异步的。你需要一个机制来确保它们都被添加了。类似于计算图像数量,直到宽度中的项目数量与图像数量相同

function whenTotalWidthReady(cb) {
  let images = document.querySelectorAll('#draggable img');
  if (images.length==0) cb(0);
  let widths = [];
  images.forEach(each => {
    let img = new Image();
    img.onload = function() {
      widths.push(img.width);
      if (widths.length==images.length) {
        cb(widths.reduce(function(a, b){ return a + b; }););
      }
    }
    img.src = each.src;
  });
}
我不知道创建中间图像对象是否是必需的,但我知道这就是工作方式。我也不认为你的降价有问题。据我所知,初始值是可选的。但您仍然可以按照建议通过0

现在这个版本的工作方式是,因为它是异步的,所以您将回调函数作为参数传递。一旦图像准备好,这个函数将以总宽度调用

function componentDidMount() {
  whenTotalWidthReady(function(totalWidth) {
    console.log("The total width of images is: " + totalWidth);
  });
}
您的widths数组可能为空,您正在使用load事件填充它,并且在没有initialValue的情况下对其调用reduce。 这将导致错误

你可以这样做:

widths.reduce((acc, width) => (acc + width), 0);
更新1,基于您的代码笔和您的评论。。加载事件侦听器没有真正整理。IE<9存在兼容性问题,它支持attachEvent而不是addEventListener。我建议使用带有递归函数的计时器

sumWidths = () => {
  const images = document.querySelectorAll('#draggable img');
  let sum = 0;

  images.forEach(({ width }) => {
    if(!width){ // not width or width 0 means the image has not been fully loaded.
      setTimeout(this.sumWidths, 500) // delay half second to allow image to load and try again;
      return;
    } else {
      sum = sum + width;
    }
  });

  // This function can be created on parent component
  // or use state management library or what ever befit your needs.
  saveImageWidths(sum); // Create this function

  // Or save `sum` to the state of this component!!!!
  this.setState(state => ({ ...state, widthsSum: sum }));
}

componentDidMount() {
  this.sumWidths();
}
更新2。使用加载事件列表器 在你的叉子上吃点东西

像这样使用reduce:

让images=Array.fromdocument.queryselector调用'draggable img'; reduce在DOM节点集合上不可用。首先将其设置为数组

更新:

使用代码笔:记录所需答案:

const images=Array.fromdocument.queryselectoral'imagesContainer img'; const sumOfWidths=images.reducea,b=>a+b.width,0; console.log{sumOfWidths};//=>600 这假设图像已经加载

下面是一个等待他们加载承诺的解决方案,它在你的代码笔中起作用:这不是一个使用承诺的好例子——只是一个简单化的例子。。。考虑添加拒绝处理程序,例如

函数totalImagesWidth{ const images=Array.fromdocument.queryselectoral'imagesContainer img'; const loadHandler=img=>newpromiseresolve=>{ img.addEventListenerload,=>解析{}; }; Promise.allimages.maploadHandler.thenresults; 功能结果{ const sumOfWidths=images.reducea,b=>a+b.width,0; const results=document.createElementp; results.innerHTML=` 图像:${Images} 图像总数:${images.length} 总和:${sumOfWidths}`; document.body.appendChildresults; 控制台。长度的对数; } } 总图像宽度
您试图获取一个变量的值,该变量应该在将来更新。让它更新一个预期的次数,也就是图片的总数,然后当它更新了,找到总数

我没有运行我的代码,但正在查看类似

constructor() {
    this.widths = [];
}

componentDidMount() {
    let images = document.querySelectorAll('#draggable img');

    images.forEach(each => {
        each.addEventListener('load', () => {
            widths.push(each.width);

            if (widths.length === images.length) {
                this.reportWidth(widths.reduce(function (a, b) { return a + b; }, 0));
            }
        });
    });
}

reportWidth (width) {
    console.log(`Width is finally found to be ${width}`);
}

尝试将初始值作为第二个参数传递给reduce函数,尽管它是可选的const total=widths.reducefunctiona,b{return a+b;},0;它对我同步运行推送而不是在加载侦听器中运行推送效果很好,因为我没有实际加载图像。如果您在侦听器之外成功地记录了值,那么使用reduce似乎是正确的。如果你的浏览器出现了一些奇怪的问题,也许你可以将reduce替换为更老的东西,比如let total=0;对于宽度的宽度{total+=width}或使用Morlo的建议。我想你也可以加入一个parseInt作为衡量标准…Morlo的解决方案解决了这个问题,没有加载事件侦听器,而是添加了一个超时循环,这里可以看到:但唯一的缺点是,如果图像加载速度更快,并且我们可以选择将超时时间缩短,那么我们将在预先确定的超时时间下工作,我觉得使用加载事件侦听器提供的实际超时时间会更好。如果我们可以使用事件侦听器来解决这个问题,我认为它会更好。没有超时不工作:@cat你能在代码笔里试试吗?是的,我就是这么想的,但是我怎么能写这样的设置超时呢?没有设置超时我错了。我已经编辑了我的答案。但想法是一样的。在减少之前需要等待数据可用。但我如何才能做到这一点?componentDidmount不接受参数:抱歉,我不熟悉react。我以为这是你创造的。但这是一样的。只需更改我提供给您的函数的名称,然后从componentDidMount内部调用它这是记录阵列!表示宽度值在数组中可用。加载事件是必需的,因为所查询的标记并不表示图像本身
已加载。在这种情况下,宽度未知。这是崩溃类型错误:images.reduce不是一个函数Carousel.componentDidMount src/components/Carousel/index.jsx:32 29 | componentDidMount{30 | 31 | const images=document.queryselectoral'draggable img'| |【】>32 | const total=images.reduceac,image=>{^33 | iImage.width{34 | acc=acc+image.width;35 |}@米格,你说得很对。我已经编辑了我的答案。我不知道为什么我不能让它工作,我创建了一个代码笔让你看,你可以分叉它并进行更改。它在那里工作有点不同,没有获得相同的行为,根本没有将项目添加到数组中。长话短说,我只想计算所有ima的全宽总的来说,你能把一个解决方案放在代码笔里吗?这没有任何作用,而且崩溃了,它出了问题。当我测试它时,它工作得很好@Alex-一定是你的代码。我创建了一个代码笔让你看,你可以把它叉出来并进行更改。codepen.io/alexlais/pen/zYOBoRm你能在那里测试吗?@JackBashford OP的图片是a,不是数组,这就是他正确的原因。他的图像上不存在reduce。您可能直接创建了一个数组。OP应该使用array.fromimages来获取。reduce.Whoops-fixed@Alex,请参阅我的更新答案。感谢Dwmorin指出这一点。我们正在尝试在创建的变量上运行reduce,而不是dom节点本身,请检查我的更新的代码笔如果您在这里登录控制台,您可以看到3个宽度的数组,但我似乎无法使用它来计算总宽度。您可以使用代码笔进行更改。@Alex-在您的代码笔中不起作用的是,您的代码在results.innerHTML部分中运行的时间远远早于您的回调有机会设置值之前当设置reportWidth时,您需要执行results.innerHTML,即当reportWidth最终准备就绪或在我的答案中添加承诺时将其作为函数调用。哦,好的,我明白了,非常感谢您的答案,您现在在这里工作,谢谢!所以我尝试将其作为变量,但仍然没有升级Eded.如果你在这里登录,你能神奇地查看我更新的代码笔吗:你可以看到有3个宽度的数组,但我似乎无法使用它来计算总宽度。你可以叉代码笔并进行更改。谢谢大家,你计算循环的想法是它工作的原因,很好,它在这里工作,我将使用它这是一个项目,这是一个旋转木马行为,滑动图像旋转木马只为图像的总宽度,感谢你让它发生!酷!记得向上投票,并标记为选定的答案。
const res = [...images].reduce((a, { width = 0 }) => a + width, 0);
constructor() {
    this.widths = [];
}

componentDidMount() {
    let images = document.querySelectorAll('#draggable img');

    images.forEach(each => {
        each.addEventListener('load', () => {
            widths.push(each.width);

            if (widths.length === images.length) {
                this.reportWidth(widths.reduce(function (a, b) { return a + b; }, 0));
            }
        });
    });
}

reportWidth (width) {
    console.log(`Width is finally found to be ${width}`);
}