This is really a simple affair, I just wonder if there is a better way to do it:
let el = document.querySelectorAll('#comic img');
let loadPromise = new Promise(function(resolve, reject) {
let ticker = setInterval(() => {
if (el[0].complete) {
clearInterval(ticker);
resolve();
}
}, 100);
setTimeout(() => {
clearInterval(ticker);
reject('Timeout');
}, 5000)
});
loadPromise.then(() => {
console.log(el[0].naturalWidth);
let container = document.querySelectorAll('.main-wrapper > div > section > section.column.column-1.grid-left-4.grid-width-16');
container[0].style.width = (el[0].naturalWidth + 420) + 'px';
});
I must wait for the image to load, so I know its size so that I can adjust an element on the page.
But setInterval
(aka polling the element) seems so... medieval. Is there a nicer way in modern JS?
1 Answer 1
"Must wait for the image to load" ... "Is there a nicer way?"
Yes,
At first, instead of accessing the image by index el[0]
- extract the image at once and give the variable meaningful name:
let img = document.querySelectorAll('#comic img')[0];
Next, you need to embed "load"
event listener into Promise executor function to ensure the image has loaded:
let loadPromise = new Promise(function(resolve, reject) {
img.addEventListener('load', function() {
resolve();
});
setTimeout(() => {
if (!img.complete) reject('Timeout');
}, 5000)
});
loadPromise.then(() => {
console.log(img.naturalWidth);
let container = document.querySelectorAll('.main-wrapper > div > section > section.column.column-1.grid-left-4.grid-width-16');
container[0].style.width = (img.naturalWidth + 420) + 'px';
});
-
\$\begingroup\$ This answer is very poor -1.
Image.complete
property indicates the status of the loading process not the whether or not the image has actually loaded. As the image is queried from the page it may have already loaded in which case nether the load or timeouts will resolve the promise. \$\endgroup\$Blindman67– Blindman672019年11月19日 13:27:25 +00:00Commented Nov 19, 2019 at 13:27 -
\$\begingroup\$ @Blindman67, such a comment does not consider situations when
img
element was added to the document, but itssrc
attribute is set or changed/delayed in another event/function \$\endgroup\$RomanPerekhrest– RomanPerekhrest2019年11月19日 13:34:47 +00:00Commented Nov 19, 2019 at 13:34 -
\$\begingroup\$ Even if you set the
src
the image can fail to load and the load event will not fire while the timeout will not detect that there was an error ascomplete
will be true \$\endgroup\$Blindman67– Blindman672019年11月19日 13:39:52 +00:00Commented Nov 19, 2019 at 13:39 -
\$\begingroup\$ Ugh. Must have been really tired to not think of looking into events. The
.complete
attribute criticism is valid, though I'm not certain it is trivial to fix the promise. Arguably however it can be simplified further by not promisifying the callback, which conveniently also avoids the.complete
issue. \$\endgroup\$martixy– martixy2019年11月19日 14:38:29 +00:00Commented Nov 19, 2019 at 14:38