Последовательные вызовы Ajax в Javascript For Loop - Плейлист
Пожалуйста помоги!! Когда я ищу это, я вижу много смешанных результатов, ни один из которых не применим здесь. Моя цель состоит в том, чтобы превратить произвольно и динамически заполненный список песен в список воспроизведения, чтобы каждая песня воспроизводилась одна за другой, а iframe для youtube или soundcloud последовательно включался.
У меня есть простой список песен, который заполняется из API YouTube и Soundcloud, который выводится в неупорядоченный список. Поскольку каждая песня в списке загружается в браузер, ее якорный тег получает идентификатор.
//List Item
echo "<a id=\"" . $i . "\" href=\"javascript:void(0)\" onclick=\"play_clicked('youtube',".$i.",".$song_count.")\">
<li class = \"song\">";
Первая песня в списке получает идентификатор 0, вторая, 1 и так далее. Идентификатор мультимедиа каждой песни также "помещается" в массив javascript по одному при загрузке, так что идентификатор тега привязки песни соответствует ключу в массиве, в котором хранится идентификатор композиции песни.
echo
'<script type="text/javascript">
track_id_array.push("'.$vid_id.'");
</script>';
Я создал функцию javascript, которая вызывается при нажатии на песню:
function play_clicked(api_type,clicked_key,song_count)
Функция получает параметры для типа API - soundcloud или youtube, идентификатор привязки или ключ массива, в котором хранится нажатый идентификатор мультимедиа, а затем количество песен в списке. Существует цикл for для перебора массива идентификаторов медиа:
for (var i=clicked_key; i<=song_count; i++){
Итак, я начинаю цикл с любого идентификатора песни, по которой щелкнули, и цель состоит в том, чтобы продолжать перебирать песни, которые следуют после песни, по которой щелкают. Сначала я проверяю, существует ли идентификатор массива в массиве:
if(window.track_id_array[i])
Если он существует, он должен содержать идентификатор носителя - например, идентификатор youtube - 6_8ZZtL6qmM. Затем я проверяю, является ли это песней soundcloud или youtube, и, в зависимости от этого, я отправляю медиа-идентификатор с помощью ajax в php-скрипт, который будет вставлять этот идентификатор в виджет встраивания iframe html5 для soundcloud или youtube, что-то вроде этого:
$vid_id = $_GET[id];
//Youtube player embed
echo '<iframe width="498" height="280" src="http://www.youtube.com/embed/'.$vid_id. '?autoplay=1" frameborder="0" allowfullscreen></iframe>
';
а затем я возвращаю этот HTML-файл в div на моей главной странице, и песня будет воспроизводиться в соответствующем виджете. То, как я себе представлял, выполняя мою цель списка воспроизведения, - это начать с идентификатора / ключа нажатой песни в цикле, извлечь идентификатор медиа для этого ключа из массива, проверить тип API, сделать правильный вызов ajax, установить тайм-аут для длины песни, а затем продолжите цикл до следующей клавиши в массиве после того, как песня была закончена, чтобы он начал процесс заново со следующей песней в списке или идентификатором в массиве.
Javascript на самом деле не моя сильная сторона, и я ненавижу, что для этого мне нужно использовать код на стороне клиента. Мой вопрос: возможен ли метод, который я здесь описал, или я поступаю неправильно? Я хочу, чтобы вызовы ajax выполнялись только один за другим в цикле, чтобы они не происходили одновременно. Вот вся моя функция, и я получаю странные результаты. Он проигрывает последнюю песню в списке и пропускает все остальные. Любое объяснение может быть, почему? Опять же, я действительно не очень хорош в javascript, и помощь НАМНОГО ценится!!
//play clicked track and those following
function play_clicked(api_type,clicked_key,song_count){
function showPlayTrack() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var outLink = xhr.responseText;
}
else {
var outLink = "There was a problem with the request" + xhr.status;
}
}
var vis = parent.document.getElementById("play_content");
vis.innerHTML = outLink;
setTimeout(300000);
}
for (var i=clicked_key;i<=song_count;i++){
if(window.track_id_array[i]){
if(api_type == "scloud"){
var soundcloud_id = window.track_id_array[i];
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else {
if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
}
}
}
if (xhr) {
xhr.onreadystatechange = showPlayTrack;
xhr.open("GET", "getsoundcloud.php?streamurl="+soundcloud_id, true);
}
else {
alert("Sorry, but I could't create an XMLHttpRequest");
}
}else if (api_type == "youtube"){
var vid_id = window.track_id_array[i];
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else {
if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
}
}
}
if (xhr) {
xhr.onreadystatechange = showPlayTrack;
xhr.open("GET", "getyoutube.php?streamurl="+vid_id, true);
xhr.send(null);
}
else {
alert("Sorry, but I could't create an XMLHttpRequest");
}
}
}
}
}
1 ответ
Итак, я решил проблему с помощью рекурсивных вызовов функций. При нажатии я вызываю функцию воспроизведения, которая считывает идентификатор медиа, проверяет тип API, увеличивает ключ и вызывает ajax, чтобы получить iframe. Функция успеха для ajax затем возвращает iframe в соответствующий div, ждет длину песни и затем снова вызывает функцию начального воспроизведения с увеличенной клавишей в качестве параметра. Есть еще некоторые мелочи, которые нужно решить, например, добавление или вычитание времени, если пользователь ищет в медиа, но по большей части это отличное решение для плейлистов!