我正在尝试制作一个基本页面,如果您单击字母,它将播放发音的声音文件。
我正在使用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>
答案 0 :(得分:0)
您将需要执行以下操作:
删除第20-23行和第43-46行的内部循环。这些行由于各种原因而令人不寒而栗,最重要的是:您对所有循环(包括这些嵌套循环)使用相同的变量(i
),代码正在中断。对内部循环变量使用i
以外的其他值。
使用const
或IIFE处理您在第52行遇到的变量提升问题。
const audio = document.createElement("audio");
$(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。演示中会评论详细信息。
<!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('Åå');
AZaz.push('Ææ');
AZaz.push('Øø');
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>