Why, if the data is in the userData array, load through the contact, and then create a list of ul, from this data, and if you try to iterate over the elements with the .igrost class

that are in the muz block, will it not find anything?

http://plnkr.co/edit/5hH9iEYjQ29oB6XUDYlo?p=preview

I tried to lighten the code, made it without contact, and now it finds the elements, but with the contact it does not, why?

https://jsfiddle.net/049x0eeL/

<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="style.css"> <script src="http://vk.com/js/api/openapi.js"></script> </head> <body> <div class="container"> <h1 id="headerInfo"></h1> <span class="igrost">play</span> <ul class='muz' id='muz'> </ul> <div class="progress"> <div class="progress-bar progress-bar-danger" data-role="progressbar" style="width: 0%"></div> </div> </div> <script src="script.js"></script> </body> </html> function foo() { VK.init({ apiId: 5580872 }); VK.Auth.login(function(response){ if(response.session){ VK.api('audio.get', {}, response => { if(response.error){ alert(response.error.error_msg); } else{ let userData = response.response; for(var i = 0; i < userData.length; i++){ var ul = document.querySelector('.muz'); var li = document.createElement('li'); li.innerHTML = '<span class="igrost">'+'play '+'</span>' + userData[i].artist + ' - ' + userData[i].title ul.appendChild(li) } } }); } else{ alert('Не удалось авторизироваться') } }, 8); } foo() var igrost = muz.querySelectorAll('.igrost') console.log(igrost) 

///////////////////////////////////////

 <ul class='muz' id='muz'> </ul> let userData = ['sdfs', 'ggggggg', 'uuuu']; for(var i = 0; i < userData.length; i++){ var ul = document.querySelector('.muz'); var li = document.createElement('li'); li.innerHTML = '<span class="igrost">' +' play ' +'</span>' + '<span>' +userData[i] +'</span>' ul.appendChild(li) } var igrost = muz.querySelectorAll('.igrost') console.log(igrost) for(var m = 0; m < igrost.length; m++){ igrost[m].addEventListener('click', function(e) { console.log(e.target) }) } 

Reported as a duplicate at Grundy. javascript Jan 20 '17 at 5:57 pm

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

    1 answer 1

    The thing is that the VK.Auth.login() and VK.api() methods are asynchronous. So that you understand what asynchronous methods are, I will try to explain to you using the VC example.

    Imagine that VC began to lag terribly. Requests to the API are carried out for a long time, but you need to call some API method:

     VK.api('users.get', {}, response => { alert(response.response[0].first_name + ' ' + response.response[0].last_name); }); alert('Привет!'); 

    If the VK.api() method were synchronous (in fact, it is asynchronous, but just imagine that it is synchronous), then the following instructions in the script (namely, alert('Привет!') ) Would be executed only after would execute an API request. And in our example, VKontakte lags, so our script would just freeze and wait for a successful API request. But ultimately, after a noticeable delay, we would first get our first name and then Привет! .

    That is why heavy, resource-intensive and long methods usually make asynchronous so that they do not block the work of the script. When the interpreter encounters an asynchronous method, it does not wait until it is executed, but immediately proceeds to the next instructions. In the example above, VK.api() is, of course, an asynchronous method. What do you think, in what order will the alerts be executed? In this: Привет! first Привет! and then your first name with last name.

    Now about your code. I will slightly simplify the example for better readability. You create DOM elements inside an asynchronous method:

     VK.api('audio.get', {}, response => { let userData = response.response; for (let i = 0; i < userData.length; i++){ let ul = document.querySelector('.muz'); let li = document.createElement('li'); li.innerHTML = '<span class="igrost">' + 'play ' + '</span>' + userData[i].artist + ' - ' + userData[i].title; ul.appendChild(li); } }); let igrost = document.querySelectorAll('.muz .igrost'); console.log(igrost); 

    And then, in the last lines of my example, you are trying to get the elements created. But for the let igrost = document.querySelectorAll('.muz .igrost') these elements do not exist yet! That's because it was called before the .igrost elements were created when accessing the API.

    Everything that is created inside asynchronous methods should be processed only there - in the same asynchronous methods. That is, the example above should be rewritten as:

     VK.api('audio.get', {}, response => { let userData = response.response; for (let i = 0; i < userData.length; i++){ let ul = document.querySelector('.muz'); let li = document.createElement('li'); li.innerHTML = '<span class="igrost">' + 'play ' + '</span>' + userData[i].artist + ' - ' + userData[i].title; ul.appendChild(li); } let igrost = document.querySelectorAll('.muz .igrost'); console.log(igrost); }); 

    Yes, it will create a strong nesting code. But here you will be helped only by such a thing as Promises, which I suggest you study on your own: