1

я даже не знаю как отредактировать вопрос, что бы разъяснить вам. если бы я не написал бы вопрос а просто искал бы, я бы не понял из предпологаемого дуюликата ничего, потому что не обратил бы на него внимание... для мне тот вариант ответа не является ответом.....

var wrapperPlayList = document.getElementById('wrapperPlayList'),
        p = document.createElement('p'),
        mus = music[0];


        var music = [
    '../binary/sounds/music/Strangersbynight.mp3',
    '../binary/sounds/music/029 E-Type - Russian lullaby.mp3',
    '../binary/sounds/music/035 Technotronic - This beat is Technotronic.mp3',
    '../binary/sounds/music/037 Radiorama - Desire.mp3',
    '../binary/sounds/music/039 Silent circle - Touch in the night.mp3'
    ];

    for (var i = 0; i < music.length; i++) {
        var playList = p.cloneNode(true);

        playList.innerHTML = music[i];

        playList.className = 'playList';

        wrapperPlayList.appendChild(playList);

        playList.addEventListener('click', function () {
        /*
        как мне тут при клике получиь индекс --- playList 
        */  
        })

    }
Air
  • 14,505
  • Уважаемые пользователи. Если вы получили ответ на свой вопрос, просьба не забывать помечать его как ответ! Это важно! – Stanislav Hmelevsky Aug 18 '17 at 04:05
  • По секрету он на сайте уже более года –  Aug 18 '17 at 20:40
  • Дубликат?)))) Ну если бы я столько понимал, я бы не задавал вопросов.... Ну раз вы так считайте, объясните? – Air Sep 11 '17 at 12:01
  • Ну раз вы так считайте, объясните? - ты в цикле создаешь функции, которые вызываются не сразу, то есть не в момент создания, и хочешь использовать счетчик внутри этих функций. Все то же самое, что и в вопросе дубликате – Grundy Sep 11 '17 at 12:16
  • Grundy, я JS изучаю, пару тройку месяцев... щас я код пишу на уровне интуиции... Если бы ты не ответил как ответил, я бы не решил свою проблему... вспомни себя, когда ты начал писать код... что все понимание пришло разом.... это я к тому, что если кто то "сырой" будут искать впрос подобный моему, то ему будет легче найти ответ в моем вопросе – Air Sep 11 '17 at 12:28
  • @Air, на самом деле не легче, потому что ты завуалировал основной вопрос: получение счетчика цикла в асинхронной функции, своей формулировкой – Grundy Sep 11 '17 at 17:47
  • с вами не соскучишься)))) я уже понял о чем речь... – Air Sep 11 '17 at 18:09

3 Answers3

3

Вам нужно создать замыкание, в котором хранить этот самый индекс, для этого addEventListener надо вынести в отдельную функцию в которою передавать индекс, в следствии чего индекс будет сохраняться в замыкании функции обработчика клика и вы сможете его использовать.

Вот краткий пример :

var music = [
  '../binary/sounds/music/Strangersbynight.mp3',
  '../binary/sounds/music/029 E-Type - Russian lullaby.mp3',
  '../binary/sounds/music/035 Technotronic - This beat is Technotronic.mp3',
  '../binary/sounds/music/037 Radiorama - Desire.mp3',
  '../binary/sounds/music/039 Silent circle - Touch in the night.mp3'
];

document.addEventListener('DOMContentLoaded', function() { for (var i = 0; i < music.length; i++) { addEventListenerToBtn(i, document.getElementById('btn' + i)) } });

function addEventListenerToBtn(index, btn) { btn.addEventListener('click', function() { console.log(music[index]); }); };

<button id="btn0">btn0</button>
<button id="btn1">btn1</button>
<button id="btn2">btn2</button>
<button id="btn3">btn3</button>
<button id="btn4">btn4</button>

Вот пример с вашими тегами p:

var music = [
  '../binary/sounds/music/Strangersbynight.mp3',
  '../binary/sounds/music/029 E-Type - Russian lullaby.mp3',
  '../binary/sounds/music/035 Technotronic - This beat is Technotronic.mp3',
  '../binary/sounds/music/037 Radiorama - Desire.mp3',
  '../binary/sounds/music/039 Silent circle - Touch in the night.mp3'
];

var wrapperPlayList = document.getElementById('wrapperPlayList'), p = document.createElement('p'), mus = music[0];

for (var i = 0; i < music.length; i++) { var playList = p.cloneNode(true); playList.innerHTML = music[i]; playList.className = 'playList';

wrapperPlayList.appendChild(playList);

addEventListenerToP(i, playList); }

function addEventListenerToP(index, _p) { _p.addEventListener('click', function() { console.log(music[index]); }); };

<div id="wrapperPlayList">
</div>
  • @Air не думал что так сложно будет переделать пример :) Дополнил ответ – Rostyslav Kuzmovych Aug 17 '17 at 06:10
  • если вам всетаки нужно при клике на p получить тот индекс массива, на котором на этот p был повешан ивентхендлер, то функция массива вам не поможет , а надо сменить подход, самый елегантный вариант это замыкания – Rostyslav Kuzmovych Aug 17 '17 at 06:20
  • @Air ну честно говоря ето костыль, да и не работает в том виде в котором вы написали, но почему бы и нет :) – Rostyslav Kuzmovych Aug 18 '17 at 18:31
2

Для определения индекса элемента у массива есть парные функции .indexOf/.lastIndexOf, отличающиеся направлением поиска, с начала массива или с конца.

А также функция .findIndex, позволяющая искать индекс элемента, удовлетворяющего переданному условию.


Небольшие уточнения по задаче:

  1. this внутри обработчика будет указывать на текущий playList
  2. playList.innerHTML - строка из массива music
  3. поиск индекса в массиве music

Исходя из этого, предоставленный код можно переписать следующим образом:

var wrapperPlayList = document.getElementById('wrapperPlayList'),
    p = document.createElement('p'),
    mus = music[0];


var music = [
    '../binary/sounds/music/Strangersbynight.mp3',
    '../binary/sounds/music/029 E-Type - Russian lullaby.mp3',
    '../binary/sounds/music/035 Technotronic - This beat is Technotronic.mp3',
    '../binary/sounds/music/037 Radiorama - Desire.mp3',
    '../binary/sounds/music/039 Silent circle - Touch in the night.mp3'
];

for (var i = 0; i < music.length; i++) {
    var playList = p.cloneNode(true);

    playList.innerHTML = music[i];

    playList.className = 'playList';

    wrapperPlayList.appendChild(playList);

    playList.addEventListener('click', function () {
        /*
        получить индекс можно так
        */  
        var playListIndex = music.indexOf(this.innerHTML);
        /* или так*/
        var playListIndex = music.lastIndexOf(this.innerHTML);
        /* или так*/
        var playListIndex = music.findIndex(el=>el === this.innerHTML);
    })

}

Но на самом деле все это не нужно.

Достаточно использовать let вместо var и в качестве индекса можно использовать переменную i напрямую в обработчике:

var wrapperPlayList = document.getElementById('wrapperPlayList'),
p = document.createElement('p'),
mus = music[0];


var music = [
    '../binary/sounds/music/Strangersbynight.mp3',
    '../binary/sounds/music/029 E-Type - Russian lullaby.mp3',
    '../binary/sounds/music/035 Technotronic - This beat is Technotronic.mp3',
    '../binary/sounds/music/037 Radiorama - Desire.mp3',
    '../binary/sounds/music/039 Silent circle - Touch in the night.mp3'
];

for (let i = 0; i < music.length; i++) {
    var playList = p.cloneNode(true);

    playList.innerHTML = music[i];

    playList.className = 'playList';

    wrapperPlayList.appendChild(playList);

    playList.addEventListener('click', function () {
    /*
      i - и есть нужный индекс.
    */  
    })

}
Grundy
  • 81,538
  • тоесть получаеться что с помощью let создастся что-то типа замыкания на уровни итерации цикла ? – Rostyslav Kuzmovych Aug 18 '17 at 18:46
  • @Air, не видел этого вопроса. – Grundy Aug 18 '17 at 18:54
  • 3
    @RostyslavKuzmovych, замыкание есть в любом случае, здесь скорее важно как объявлены переменные которые замыкаются. В отличие от var, переменные объявленные с помощью let или const объявляются на уровне блока {...}, а не всей функции, таким образом, на каждой итерации цикла будет новая переменная i, которая и будет замкнута, а не одна переменная i на всю функцию, значение которой во время обработчика будет тем же, что и после окончания цикла. – Grundy Aug 18 '17 at 18:57
  • @Grundy спасибо за розьяснения, я бы недодумался до такого ) – Rostyslav Kuzmovych Aug 18 '17 at 19:01
  • @RostyslavKuzmovych, ссылки на документацию есть в ответе, там более подробно написано – Grundy Aug 18 '17 at 19:01
1

Как вариант можно ещё вот так. С авто генерацией элементов:

var music = [
  '../binary/sounds/music/Strangersbynight.mp3',
  '../binary/sounds/music/029 E-Type - Russian lullaby.mp3',
  '../binary/sounds/music/035 Technotronic - This beat is Technotronic.mp3',
  '../binary/sounds/music/037 Radiorama - Desire.mp3',
  '../binary/sounds/music/039 Silent circle - Touch in the night.mp3'
];

function addEventListenerToBtn(index, btn) { btn.addEventListener('click', function() { alert("Download: " + this.innerHTML + "\n\r" + "His id: " + this.getAttribute("data-id")); }); };

function splitName(str) { if (typeof str != "undefined") {
return str.split("/"); } }

function createBtn(tracks) { if (tracks.length > 0 && tracks) { for (let i = 0; i < tracks.length; i++) {

  let p = document.createElement('p'),
      track_name = splitName(tracks[i]);

  p.id = "track-" + i;
  p.className += "playList";
  p.setAttribute("data-id", i);
  p.innerHTML = track_name[track_name.length-1];    
  document.body.appendChild(p);
  addEventListenerToBtn(i, document.getElementById("track-" + i));  
}

} }

createBtn(music);

  • @Air исправил кнопки на параграф. – Stanislav Hmelevsky Aug 17 '17 at 06:16
  • @Air в таком случае если ни один из нынешних ответов не удовлетворяет вашим требованиям, напишите ответ сами, и отметте его как решение. :) – Stanislav Hmelevsky Aug 18 '17 at 18:51