javascript - Can not define value for Object in addEventListener / Creating Object Array -
i want achive this:
- get elements have same class (
queryselectorall
) - use these elements
href
attr links. - use these links check these remote images' height , width.
- pack them object , push declared array.
but, can not values img.addeventlistener("load", function(){})
values in there, if check console.log(this.naturalwidth)
undefined
outside function.
right now, got 20 tabs opened on stackoverflow "js scope" doesn't make sense situation.
note: i'm trying make without jquery.
var pselemgroup = document.queryselectorall(pselemgroupname); for(var j = 0; j < pselemgroup.length; j++){ var obj = new object(); var href = pselemgroup[j].href; var img = new image(); img.src = pselemgroup[j].href; img.addeventlistener("load", function(){ obj = { src: href, w: this.naturalwidth, h: this.naturalheight }; console.log(obj); }); //pselemgroup[j].dataset.index = j; galleryelements.push(obj); }
also not actual question but: when try href
value, got error href
.
after hour learned queryselectorall
returns nodelist, not array. tried:
[].slice.call(document.queryselectorall(pselemgroupname));
and changed of code that:
pselemgroup[j]["href"]
but no luck.
thank you.
edit:
so works when use galleryelements.push(obj) inside load function but, ultimate goal create array contains objects.
like:
var items = [ { src: "foo", w: "bar", h: "baz" }, { src: "foo", w: "bar", h: "baz" }, ]
i can access objects items[0].src
. cant access galleryelements[]
array objects same way. got error says:
undefined.src
well part of problem lack of understanding how eventlistener works , when object filled or not.
eventlisteners run in async way, so, cannot assume object filled in callback filled outside of scope.
an easy way go around make use of promise
object.
you change code enough following
// loads image , resolves when ready, containing information wanted receive image function loadimagefromurlasync( url, text ) { return new promise( (resolve, reject) => { let image = new image(); image.src = url; image.addeventlistener('load', () => resolve({ title: text, width: image.naturalwidth, height: image.naturalheight } ) ); }); } function loadallimagesbyselectorasync( selector ) { return new promise( (resolve, reject) => { let elements = document.queryselectorall( selector ), loaders = [], gallery = []; (let element of elements) { // after image loaded result gets pushed in gallery loaders.push( loadimagefromurlasync( element.href, element.innertext ) .then( result => gallery.push(result) ) ); } // go resolve after images loaded promise.all( loaders ).then( () => { resolve( gallery ); }); }); } loadallimagesbyselectorasync('.image-link').then( gallery => { // writes content of gallery result div document.queryselector('#result').innerhtml = gallery .map( item => `${item.width}px + ${item.height}px ${item.title}` ) .join('<br />'); });
<a class="image-link" href="https://tse4.mm.bing.net/th?id=oip.x0sjkpqsiubt0asgiba-iwesdh&pid=15.1&p=0&w=232&h=175">image 1</a> <a class="image-link" href="https://tse2.mm.bing.net/th?id=oip.wfyof5hqmlo2j9p39ntbogesc7&pid=15.1&p=0&w=279&h=175">image 2</a> <a class="image-link" href="https://tse2.mm.bing.net/th?id=oip.sv38mmyjt0tbuzpjmm1mtwesdi&pid=15.1&p=0&w=255&h=171">image 3</a> <a class="image-link" href="https://tse1.mm.bing.net/th?id=oip.s2udayjt1fqnot921zfsqwdhes&pid=15.1&p=0&w=300&h=300">image 4</a> <a class="image-link" href="https://tse3.mm.bing.net/th?id=oip.cz12zxh0ukesf3y1_gareqdhes&pid=15.1&p=0&w=300&h=300">image 5</a> <div id="result"></div>
however if not want such extensive changes current code, can change this, in case have function callback called once images loaded
i tried comment changes in code, hope enough
function loadmygallery(pselemgroupname, callback) { // move variable declaration per function // top, var function scoped var pselemgroup = document.queryselectorall(pselemgroupname), j, img, galleryelements = []; (j = 0; j < pselemgroup.length; j++) { img = new image(); img.src = pselemgroup[j].href; img.addeventlistener("load", function( href ) { // push in load method galleryelements.push({ title: this.src, width: this.naturalwidth, height: this.naturalheight }); // call callback when loaded many images found in pselemgroup.length if (galleryelements.length === pselemgroup.length) { callback( galleryelements ); } // bind img context }.bind(img)); } if (pselemgroup.length === 0) { // no elements settimeout( callback, 0 ); } } // load gallery loadmygallery( '.image-link', ( gallery ) => { // writes content of gallery result div document.queryselector('#result').innerhtml = gallery .map( item => `${item.width}px + ${item.height}px ${item.title}` ) .join('<br />'); });
<a class="image-link" href="https://tse4.mm.bing.net/th?id=oip.x0sjkpqsiubt0asgiba-iwesdh&pid=15.1&p=0&w=232&h=175">image 1</a> <a class="image-link" href="https://tse2.mm.bing.net/th?id=oip.wfyof5hqmlo2j9p39ntbogesc7&pid=15.1&p=0&w=279&h=175">image 2</a> <a class="image-link" href="https://tse2.mm.bing.net/th?id=oip.sv38mmyjt0tbuzpjmm1mtwesdi&pid=15.1&p=0&w=255&h=171">image 3</a> <a class="image-link" href="https://tse1.mm.bing.net/th?id=oip.s2udayjt1fqnot921zfsqwdhes&pid=15.1&p=0&w=300&h=300">image 4</a> <a class="image-link" href="https://tse3.mm.bing.net/th?id=oip.cz12zxh0ukesf3y1_gareqdhes&pid=15.1&p=0&w=300&h=300">image 5</a> <div id="result"></div>
Comments
Post a Comment