javascript - 通过选择按钮更改自键入文本无法正常工作
问题描述
https://jsfiddle.net/AlexThunders/k8s79zL5/18/
当我单击选择中的选项时,我正在尝试将自输入文本从英语更改为俄语:
let engType = [
'Never give up. ',
'You can win. '
]
let rusType = [
'Никогда не сдавайся. ',
'Ты можешь победить. '
]
页面已加载,此功能逐渐键入字母:
function typeCharacters(phrases) {
if(phrases[count] !== undefined && phrases[count] !== null && phrases[count] !== "") {
let allLength = phrases[count].length
setInterval(() => {
if(phrases[count] !== undefined && typePar !== null) {
character = phrases[count].slice(ind,ind+1)
txt = document.createTextNode(character)
typePar.appendChild(txt)
ind++
let typeLength = typePar.textContent.length
if(typeLength === allLength) {
count++
ind = 0
if(phrases[count] !== undefined) {
allLength += phrases[count].length
}
}
}
},100)
}
}
typeCharacters(engType)
有用。但是,当我只是触摸选择按钮而不选择语言时,我会在同一段落中得到一种或两种语言中混合字母的废话段落:
function searchLang(choosenLang) {
//if choosen language coincides with one in Object:
if(languages[choosenLang]) {
allDataElements.forEach(element => {
//every property of choosen object/language
for(let x in languages[choosenLang]) {
//compare with element's data attribute
if(element.getAttribute('data') === x) {
//the same attribute changes iinerText in accordance with object
element.innerText = languages[choosenLang][x]
if(languages[choosenLang].changePhrases !== undefined) {
languages[choosenLang].changePhrases(choosenLang)
}
}
}
})
}
}
select.addEventListener('click', () => {
allLangOptions.forEach(option => {
if(option.selected === true) {
let lang = option.value
searchLang(lang)
}
})
})
结果:
Никeгда не сд.вайся. Тыuможешь по едить. OR
Никогда нe up. айс
但是,对于其他 html 元素,选择按钮可以正常工作:仅当我选择选项而不是单击选择本身时。
我在对象中使用 changePhrases 函数来更改键入段落的语言:
let languages = {
en: {
mPheadLIabout: 'About',
mPheadLIprojects: 'Projects',
mPheadLIcontacts: 'Contacts',
changePhrases: function() {
if(typePar !== null) {
typePar.textContent = "";
count = 0
ind = 0
typeCharacters(engType)
}
}
},
ru: {
mPheadLIabout: 'О сайте',
mPheadLIprojects: 'Проекты',
mPheadLIcontacts: 'Контакты',
changePhrases: function() {
if(typePar !== null) {
typePar.textContent = "";
count = 0
ind = 0
typeCharacters(rusType)
}
}
}
}
在第一段清除自身,并从第一个字符开始输入,如上所示。
我尝试使用变量重置来停止调用输入英文字符,但没有成功。
此外,我使用 setTimeout 应用了不同的变体,并承诺在段落被清除后才运行函数 typeCharacters(rusType)。仍然无法正常工作,并且控制台中没有错误。
和我用英语得到的结果相同。
看起来当我单击选择按钮(不是选项)时,它再次触发输入文本的功能,而不是等到我使用选项。当我单击选项时,它会同时触发多次。
这是整个代码和奇怪的结果:
解决方案
不应将事件处理程序绑定到事件,而应仅在用户更改元素click
的选定选项时触发回调。select
所以事件类型应该是change
:
select.addEventListener('change', () => {
allLangOptions.forEach((option) => {
if (option.selected === true) {
let lang = option.value;
searchLang(lang);
}
});
});
这样,您还可以使用键盘更改选项。尽管键盘用户可以更改语言选项,因为这不是鼠标点击,但您的click
事件不会触发,您内部的回调addEventListener
也不会运行。确保始终挂钩到元素的change
事件。select
另一个问题是您永远不会取消间隔。当您选择一种语言时,它只会启动另一个计时器,这只会搞砸一切。看起来效果会加快,随着不同字符的混合,文本会变得乱七八糟,等等。
为避免这种情况,您需要保存从返回的间隔 IDwindow.setInterval()
并在运行时将其取消typeCharacters()
:
// ...
let reset = false;
// create a variable in an outer scope
let activeInterval = null;
function typeCharacters(phrases) {
// clear running interval
clearInterval(activeInterval);
if (reset) return;
if(phrases[count] !== undefined
&& phrases[count] !== null
&& phrases[count] !== "") {
let allLength = phrases[count].length
// save the interval ID
activeInterval = setInterval(() => {
if(phrases[count] !== undefined && typePar !== null) {
// ... rest of your code
推荐阅读
- javascript - javascript 设计模式 Revealing Module Pattern 它是如何工作的?
- apache-spark - DSE SearchAnalytics with Scala error
- android - Android mediacodec:是否可以同时使用 mediacodec 和 muxer 对音频和视频进行编码?
- neo4j - 或两者之间的操作和操作
- ios - Firestore iOS queryWhereField 和 queryOrderedByField 不返回特定数据
- php - 如何检索 Kaltura 中超过 10k 标记的所有媒体条目?
- java - 插入模型 android studio 时出错
- git - 如何根据 master 上的新更改继续我的更改
- c# - DataGrid 在其 ItemSource 更新时不创建行,有时重复条目
- merge - 如何确定merge()后是否需要git_commit_create()?