使用csv文件中的链接使用javascript播放音频

时间:2019-03-22 14:26:11

标签: javascript jquery html csv

我正在尝试制作一个基本页面,如果您单击字母,它将播放发音的声音文件。

我正在使用csv file,看起来像这样。 单击该按钮时,它会播放音频文件,但是无论我按哪个按钮,都只会播放第一个音频文件。

有人对此有解决方案吗?

这是当前的js。

$(function() {
  //Load the data
  d3.csv("alphabet-sound-files.csv").then(function(data) {
    // Write the data variable to the console ->
    console.log(data);
    console.log(data[0].audioFiles);

    //Process the data here
    var content = document.getElementById("contents-alphabet");
    for (i = 0; i < data.length; i++) {

      // create div with class "alphabet-sound"
      var div = document.createElement("div");
      div.className = "alphabet-sound";
      content.appendChild(div);

      //make a button with each tof the alphabet (letters)
      var button = document.createElement("button");
      button.className = "click-for-sound";
      var list = document.getElementsByClassName("click-for-sound");
      for (var i = 0; i < list.length; i++) {
        list[i].setAttribute("id", +i);
      }

      var letters = document.createTextNode(data[i]['alphabet']);

      //store audio sources

      //create links
      var a = document.createElement("a");
      a.href = data[i]['audioFiles'];

      div.appendChild(a); // put a inside the div
      //div.appendChild(audio);
      div.appendChild(button); // put button inside the div
      button.appendChild(letters); // put each letter in the button


      $(document).ready(function() {

        var audio = document.createElement("audio");
        audio.className = "pronunciation";
        var list = document.getElementsByClassName("pronunciation");
        for (var i = 0; i < list.length; i++) {
          list[i].setAttribute("id", +i);
        }
        audio.src = data[i]['audioFiles'];


        $(document).on('click', ".click-for-sound", function() {

          audio.play();

        });
      });


    }

  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

2 个答案:

答案 0 :(得分:0)

您将需要执行以下操作:

  1. 删除第20-23行和第43-46行的内部循环。这些行由于各种原因而令人不寒而栗,最重要的是:您对所有循环(包括这些嵌套循环)使用相同的变量(i),代码正在中断。对内部循环变量使用i以外的其他值。

  2. 使用constIIFE处理您在第52行遇到的变量提升问题。

const audio = document.createElement("audio");
  1. 第50行将不起作用,因为选择器错误(当您只想选择在第18行中创建的按钮时,它将选择所有按钮元素)。但是,您不需要重新选择button元素,因为您已经在第18行中对其进行了引用。
    $(button).on("click", function () { audio.play(); });

示例工作代码:

d3.csv("alphabet-sound-files.csv").then(function (data) {

var content = document.getElementById("contents-alphabet");
//Process the data here
for (var i = 0; i < data.length; i++) {
    // Create a local variable for the current audioFile, simplifies the code below a lot.
    var audioFile = data[i];

    // create div class "alphabet-sound" as before
    var div = document.createElement("div");
    div.className = "alphabet-sound";
    content.appendChild(div);

    //store audio sources

    // Create audio tag before button.
    const audio = document.createElement("audio");
    // Use of const avoids issues with hoisting 

    // all elements should have unique ids. Therefore, prefix audio elements with audio1, audio2, etc.
    audio.setAttribute("id", "audio" + i);
    audio.src = audioFile.audioFiles;

    // TODO Uncomment the below two lines if you need to put the audio tag on the DOM.
    // audio.hidden = true;
    // div.appendChild(audio);

    // create button as before
    var button = document.createElement("button");
    // Instead of creating an inner loop, use the same i from line 10
    button.setAttribute("id", "button"+i);

    // textContent eliminates the need for the separate textNode
    button.textContent = audioFile.alphabet;

    // click handler can go here.
    $(button).on("click", function () {

      audio.play();

    });

    div.appendChild(button); // Button added here works

    //create links
    var a = document.createElement("a");
    // link given text so you can see it.
    a.textContent = "Download";
    // dot notation property access is much cleaner
    a.href = audioFile.audioFiles;

    div.appendChild(a); // put a inside the div

    audio.className = "pronunciation";
}

});

答案 1 :(得分:0)

使用数组合并字符串并插值模板文字以构建每个url。然后为每个按钮分配一个data-*属性和相应的URL。演示中会评论详细信息。


Plunker

演示

<!DOCTYPE html>
<html>
<head>
<style>
  html,
  body {
    width: 100%;
    height: 100%;
    font: 900 16px/1 Verdana;
  }
  .playlist {
    list-style: none;
  }
  
  li {
    margin: 5px;
  }
  
  button {
    display: inline-block;
    width: 4rem;
    height: 2rem;
    line-height: 2rem;
    vertical-align: middle;
    border: 3px ridge navy;
    border-radius: 6px;
    cursor: pointer;
    text-align: center;
    padding: 2px 3px 6px;
    background: rgba(145, 201, 247, 0.2);
    color: navy;
    font: inherit;
    font-size: 1.5rem;
  }
  
  button:hover,
  button:active,
  button.active {
    color: #FFF;
    text-shadow: 3px 2px 3px rgba(0, 0, 0, 0.5);
    background: rgba(145, 201, 247, 0.9);
  }   
</style>
</head>
<body>
  <main>
    <ul class='playlist'></ul>
  </main>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
// Host
const base = `http://www.student.city.ac.uk/~aczd144/Audio-files/`;

// Generate an Array of letter pairs of an uppercase and lowercase
let AZaz = Array.from(Array(26).keys(), idx => String.fromCharCode(idx + 65) + String.fromCharCode(idx + 97));

// Generate an Array of file names
let file = Array.from(Array(26).keys(), idx => String.fromCharCode(idx + 97) + '.mp3');

// Add the non-standard letters to each Array
AZaz.push('&#197;&#229;');
AZaz.push('&#198;&#230;');
AZaz.push('&#216;&#248;');
file.push('aa.mp3');
file.push('ae.mp3');
file.push('Q%20(1).mp3');

// On each iteration add a <li> and <button> and interpolate the the data from both Arrays
for (let i = 0; i < AZaz.length; i++) {

  $('.playlist').append(`<li><button class="btn" type="button" data-key="${base+file[i]}">${AZaz[i]}</button></li>`);

}

// Create an Audio Object
const player = new Audio();

/*
Register the click event to .playlist 
e.target is the currently clicked button
Extract the data-key value and assign it to the Audio src attribute
Load the Audio
Call the playMedia function
*/
$('.playlist').on('click', '.btn', playAudio);

function playAudio(e) {
  $('.btn').removeClass('active');
  const tgt = $(e.target);
  const url = tgt.data('key');
  tgt.addClass('active');
  player.src = url;
  player.load();
  playMedia();
}

/*
Because Chrome is trying to stifle autoplay, the process of playing audio and 
video require a Promise
*/
async function playMedia() {
  try {
    await player.play();
  } catch (err) {}
}
</script>
</body>
</html>