const utterances = ['utt01', 'utt02', 'utt03']
const analysis = ['try+ing', 'climb+ing', 'swimm+ing']
const translation = ['trying', 'climbing', 'swimming']
let utteranceIndex = 0;
loadUtterance(utterances[utteranceIndex]);
function loadUtterance(utterance) {
audio.src = `audio/${utterance}.mp3`;
subtitle.innerText = utterance;
translation.innerText = translation;
}
This is meant to be an exercise for studying a foreign text. I want to
I have added the "analysis" array to help visualize what I am trying to do. Eventually I'd like to display the translation (and the analysis) only after an eventListener (the student's request with a click).
Problem: the translation items do not load with this script. I am a long retired linguist looking for some guidance. Thank you.
A feasible approach could be build around a generator which was created by a generator function and does yield an utterance item compound which gets created from the next/current index of all three initially provided arrays ...
function *createUtteranceItemGenerator(
utteranceArray,
analysisArray,
translationArray,
filesArray,
) {
let name, idx = -1;
// as long as an `utteranceArray` item exists ...
while (name = utteranceArray[++idx]) {
// ... create and yield an utterance item compound.
yield {
name,
analysis: analysisArray[idx],
translation: translationArray[idx],
url: filesArray[idx]
};
}
}
function renderNextUtteranceItem(item, elmNodes) {
const { name, analysis, translation, url } = item;
const { audio, label, caption } = elmNodes;
console.log({ item });
audio && (audio.src = url);
// audio && (audio.src = `audio/${ name }.mp3`);
label && (label.textContent = analysis);
caption && (caption.textContent = translation);
}
function handleNextUtteranceItem(generator, elmNodes) {
const item = generator.next();
if (item.done === false) {
renderNextUtteranceItem(item.value, elmNodes);
}
}
function init(config) {
const elmFigure = document.querySelector('figure');
const elmButton = elmFigure?.querySelector('button');
if (elmButton) {
const { utterances, analysis, translation, files } = config;
const generator =
createUtteranceItemGenerator(utterances, analysis, translation, files);
elmButton
.addEventListener(
'click',
(/* evt */) => handleNextUtteranceItem(generator, {
audio: elmFigure.querySelector('audio'),
label: elmFigure.querySelector('label'),
caption: elmFigure.querySelector('figcaption'),
}),
);
}
}
const files = [
'https://freesound.org/data/previews/46/46989_514283-lq.mp3',
'https://freesound.org/data/previews/46/46990_514283-lq.mp3',
'https://freesound.org/data/previews/46/46991_514283-lq.mp3'
];
const utterances = ['utt01', 'utt02', 'utt03'];
const analysis = ['try+ing', 'climb+ing', 'swimm+ing'];
const translation = ['trying', 'climbing', 'swimming'];
init({ utterances, analysis, translation, files });
* { margin: 0; padding: 0; }
figure button { display: block; margin-bottom: 5px; }
figure label { display: block; }
.as-console-wrapper {
left: auto!important;
width: 51%;
min-height: 100%!important;
}
<figure class="utterance">
<button>Next Utterance</button>
<label></label>
<figcaption></figcaption>
<audio src="" controls autoplay></audio>
</figure>
I have managed to make it work as follows (see above for the const):
function loadUtterance(utterance){
audio.src = audio/${utterance}.mp3;
var x = utteranceIndex;
document.getElementById("subtitle").innerText = subtitle[x];
}
Thank you for the comments which gave me more ideas.
Based on your description, there might be different reasons:
if you intend to display the whole array of translation/analysis, the problem is translation.innerText is actually operating the array you declared above instead of the html element, so if your html element that you want to show translation in's id is "translation", simply change your function to below should fix your problem:
function loadUtterance(utterance) {
audio.src = `audio/${utterance}.mp3`;
subtitle.innerText = utterance;
document.getElementById("translation").innerText = translation;
}
Or if you want to display only the translation/analysis with the same utteranceIndex, then the function in your code seems in lack of couple input parameters (translation, analysis), Try the code below:
const utterances = ['utt01', 'utt02', 'utt03']
const analysis = ['try+ing', 'climb+ing', 'swimm+ing']
const translation = ['trying', 'climbing', 'swimming']
let utteranceIndex = 0;
loadUtterance(utterances[utteranceIndex], translation[utteranceIndex], analysis[utteranceIndex]);
function loadUtterance(selectedUtterance, selectedTranslation, selectedAnalysis) {
audio.src = `audio/${selectedUtterance}.mp3`;
subtitle.innerText = selectedUtterance;
document.getElementById("translation").innerText = selectedTranslation;
// analysis.innerText = selectedAnalysis;
}