如何让一个按钮适用于所有输入

Ano*_*irl 1 html javascript button

我正在尝试使用按钮将所有输入翻译为其各自的翻译语言输出

当我单击“翻译”按钮时,它可以工作,但不适用于相应的语言,输出语言会发生变化。

选择中的每种输出语言都应固定,对于西班牙语输出,第二个选择应固定为西班牙语,对于荷兰语输出,第二个选择应固定为荷兰语,依此类推。(每次都懒得选择)

每个选项的第二个选择是输出语言,应在 HTML<option>标记中为每个选项进行固定

因此,当单击“翻译”时,它应该翻译所有相应的输入。

const countries = {
  "ar-SA": "Arabic",
  "bn-IN": "Bengali",
  "da-DK": "Danish",
  "de-DE": "German",
  "el-GR": "Greek",
  "en-GB": "English",
  "es-ES": "Spanish",
  "fa-IR": "Persian",
  "fi-FI": "Finnish",
  "fr-FR": "French",
  "gu-IN": "Gujarati",
  "hi-IN": "Hindi",
  "hu-HU": "Hungarian",
  "id-ID": "Indonesian",
  "it-IT": "Italian",
  "ja-JP": "Japanese",
  "kn-IN": "Kannada",
  "ko-KR": "Korean",
  "ku-TR": "Kurdish",
  "la-VA": "Latin",
  "my-MM": "Burmese",
  "ne-NP": "Nepali",
  "nl-NL": "Dutch",
  "ur-PK": "Pakistani",
  "pa-IN": "Panjabi",
  "pl-PL": "Polish",
  "pt-PT": "Portuguese",
  "ro-RO": "Romanian",
  "ru-RU": "Russian",
  "sq-AL": "Albanian",
  "sr-RS": "Serbian",
  "sv-SE": "Swedish",
  "ta-LK": "Tamil",
  "te-IN": "Telugu",
  "th-TH": "Thai",
  "tr-TR": "Turkish",
  "uk-UA": "Ukrainian",
  "vi-VN": "Vietnamese"
};
const fromText = document.querySelectorAll(".from-text", ".from-text2"),
  toText = document.querySelectorAll(".to-text", ".to-text2"),
  selectTag = document.querySelectorAll("select");

(translateBtn = document.getElementById("btn4all")),
  selectTag.forEach((tag, id) => {
    for (let country_code in countries) {
      let selected =
        id == 0
          ? country_code == "en-GB"
            ? "selected"
            : ""
          : country_code == "es-ES"
          ? "selected"
          : "";
      let option = `<option ${selected} value="${country_code}">${countries[country_code]}</option>`;
      tag.insertAdjacentHTML("beforeend", option);
    }
  });

fromText.forEach((el, index) => {
  if(!el.value){
    toText[index].value = "";
  }
});
function translate(fromEl, toEl, language){
    let text = fromEl.value.trim();
    let translateFrom = "en-GB"; //I've hard-coded this as there's only 1 select tag per row? Something to consider
    let translateTo = language.value;
    
    if(!text){
        return;
    }

    toEl.setAttribute("placeholder", "Translating...");
    let apiUrl = `https://api.mymemory.translated.net/get?q=${text}&langpair=${translateFrom}|${translateTo}`;

    fetch(apiUrl)
        .then((res) => res.json())
        .then((data) => {
            toText.value = data.responseData.translatedText;
            data.matches.forEach((data) => {
                if (data.id === 0) {
                    toEl.value = data.translation;
                }
            });
            toEl.setAttribute("placeholder", "Translation");
        });
}

translateBtn.addEventListener("click", () => {
    //this button is the first button on the page so we'll hard-code the first elements for now
    translate(fromText[0], toText[0], selectTag[0]);
});

document.getElementById("btn4all").addEventListener("click", () => {
    //here I am assuming that there are matching numbers of from, to, and language dropdowns - worth considering

    for(let i = 0; i < fromText.length; i++){
        translate(fromText[i], toText[i], selectTag[i]);
    }
});
Run Code Online (Sandbox Code Playgroud)
.radioact {
  display: inline-flex;
}
.input-group {
  display: flex;
  align-content: stretch;
  width: 75.666667%;
  margin-left: 17%;
  margin-bottom: 15px;
}

.btn3 {
  cursor: pointer;
  background: #05203e;
  color: white;
  width: 150px;
  padding: 20px 30px;
  border-radius: 4px;
}
.transs {
  list-style: none;
  margin-bottom: 0px;
  width: 15%;
  margin-right: 35px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="input-group">

  <input type="text" value="" class="to-text form-control" name="name_eslang" placeholder="Spanish Word">

  <input spellcheck="false" value="Translate word" id="translatename" class="from-text" placeholder="Type to Translate">

  <ul class="transs">
    <li class="row from"><select></select>
    </li>
    <li class="row to"><select></select>
    </li>
  </ul>

</div>

<div class="input-group">

  <input type="text" value="" class="to-text form-control" name="name_eslang" placeholder="Dutch Word">

  <input spellcheck="false" value="Translate word" id="translatename" class="from-text" placeholder="Type to Translate">

  <ul class="transs">
    <li class="row from"><select></select>
    </li>

    <li class="row to">
      <select>
      </select>
    </li>
  </ul>
</div>

<div class="input-group">

  <input type="text" value="" class="to-text form-control" name="name_eslang" placeholder="Hindi Word">

  <input spellcheck="false" value="Translate word" id="translatename" class="from-text" placeholder="Type to Translate">

  <ul class="transs">
    <li class="row from"><select></select>
    </li>
    <li class="row to">
      <select>
      </select>
    </li>
  </ul>
</div>

<div class="input-group">

  <input type="text" value="" class="to-text form-control" name="name_eslang" placeholder="Portuguese Word">

  <input spellcheck="false" value="Translate word" id="translatename" class="from-text" placeholder="Type to Translate">

  <ul class="transs">
    <li class="row from"><select></select>
    </li>
    <li class="row to">
      <select>
      </select>
    </li>
  </ul>
</div>
<br>
<span id="btn4all" class="btn3">Translate</span>
Run Code Online (Sandbox Code Playgroud)

Luk*_*uke 5

首先,我建议更改fromText = document.querySelector(fromText = document.querySelectorAll(,它现在返回所有匹配元素的数组 -toText也执行相同的操作。

我建议将代码分成translateBtn.addEventListener它自己的函数

function translate(fromEl, toEl, languageFrom, languageTo){
    let text = fromEl.value.trim();
    let translateFrom = languageFrom.value
    let translateTo = languageTo.value;
    
    if(!text){
        return;
    }

    if(languageFrom == languageTo){
        alert("Languages must be different!");
        return;
    }

    toEl.setAttribute("placeholder", "Translating...");
    let apiUrl = `https://api.mymemory.translated.net/get?q=${text}&langpair=${translateFrom}|${translateTo}`;

    fetch(apiUrl)
        .then((res) => res.json())
        .then((data) => {
            toText.value = data.responseData.translatedText;
            data.matches.forEach((data) => {
                if (data.id === 0) {
                    toEl.value = data.translation;
                }
            });
            toEl.setAttribute("placeholder", "Translation");
        });
}
Run Code Online (Sandbox Code Playgroud)

然后我们可以重用它,无论是添加额外的翻译按钮还是我们的“翻译全部”按钮。单击按钮来调用它会变成这样:

translateBtn.addEventListener("click", () => {
    //this button is the first button on the page so we'll hard-code the first elements for now
    translate(fromText[0], toText[0], selectTag[0], selectTag[1]);
});
Run Code Online (Sandbox Code Playgroud)

或者,添加更多按钮会给我们这样的代码:

document.querySelectorAll(".btn3").forEach((el, index) => {
    el.addEventListener("click", () => {
        translate(fromText[i], toText[i], selectTag[i * 2], selectTag[(i * 2) + 1]);
    });
});
Run Code Online (Sandbox Code Playgroud)

无论如何,现在我们已经将translate函数分开了,我们可以启动神奇的“全部翻译”功能 - 它实际上看起来与我们的具有许多翻译按钮的代码非常相似!

document.getElementById("btn4all").addEventListener("click", () => {
    //here I am assuming that there are matching numbers of from, to, and language dropdowns - worth considering

    for(let i = 0; i < fromText.length; i++){
        translate(fromText[i], toText[i], selectTag[i * 2], selectTag[(i * 2) + 1]);
    }
});
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,可能值得检查您的 ID 和类 -.btn3并且#btn4all它们不是最具描述性的名称!请考虑使用.btn-translate(或.btn.translate) 和#translateAll(或#translateAll.btn))


正如评论中提到的,fromText现在变成了一个数组 - 所以你的事件监听器需要看起来不同。尝试这样的事情:

//an exact replacement - only listening for the first element
fromText[0].addEventListener("keyup", () => {
  if (!fromText[0].value) {
    toText[0].value = "";
  }
});

//OR - listening for all
fromText.forEach((el, index) => {
  if(!el.value){
    toText[index].value = "";
  }
});
Run Code Online (Sandbox Code Playgroud)

  • 看来我误读了您的代码并错过了隐藏的选择,我已经做出了更改来解决这个问题。你明白这段代码在做什么吗,因为这些都是细微的调整?另外 - 我无法保存 codepen,因为它与您的帐户绑定,因此您必须在那里自己进行这些更改 (2认同)