缩短JavaScript代码预告片



我有五个输入字段。当您删除内容时,首先,第一个输入字段填充了输入字段 2,然后输入字段 5 为空。同样,如果删除第一个输入字段中的内容,则第二个输入字段中的内容将进入第一个输入字段,现在输入字段 4 和 5 为空。我需要五个输入字段消失,只留下一个空输入字段。然后,如果第三个和第四个元素为空,则 forth 应该消失,依此类推,直到只剩下第一个输入字段。因此,我使用硬编码值解决此问题:

if ((document.getElementsByClassName('requestRightsTitle4')[0].value == '')
&& (document.getElementsByClassName('requestRightsEmail4')[0].value == ''))
{
displayInputField('none', 5);
}
if (
(document.getElementsByClassName('requestRightsTitle3')[0].value == '')
&& (document.getElementsByClassName('requestRightsEmail3')[0].value == '')
&& (document.getElementsByClassName('requestRightsTitle4')[0].value == '')
&& (document.getElementsByClassName('requestRightsEmail4')[0].value == '')
)
{
displayInputField('none', 4);
}
if (
(document.getElementsByClassName('requestRightsTitle2')[0].value == '')
&& (document.getElementsByClassName('requestRightsEmail2')[0].value == '')
&& (document.getElementsByClassName('requestRightsTitle3')[0].value == '')
&& (document.getElementsByClassName('requestRightsEmail3')[0].value == '')
&& (document.getElementsByClassName('requestRightsTitle4')[0].value == '')
&& (document.getElementsByClassName('requestRightsEmail4')[0].value == '')
)
{
displayInputField('none', 3);
}

现在我想像一个真正的程序员一样缩短这段代码,但我没有时间(把我送到另一个项目(或技能来这样做。但我真的很想了解这怎么可能,比如:

for (let i = 0; i < 5; i++) {
if (document.getElementsByClassName('requestRightsTitle' + i)[0].value == ''
&& document.getElementsByClassName('requestRightsEmail' + i)[0].value == '')
displayInputField('none', (i+1));
}   

您可以在所有输入字段上设置侦听器。如果字段被清空,请将所有剩余值向左移动,并确定需要显示哪些字段(即具有值的所有字段和第一个空字段(。

这是一个完整的独立代码段:

const action = (inputs) => {
const listener = () => {
const values = inputs.map(input => input.value).filter(v => v);
inputs.forEach((input, i) => {
input.value = values[i] || '';
input.style.display = values[i] || !i || values[i - 1] ? '' : 'none';
});
};
inputs.forEach((input, i) => input.addEventListener('input', listener));
};
action([...document.querySelectorAll('input')]);
<input value="One">
<input value="Two">
<input value="Three">
<input value="Four">
<input value="Five">

当您只想选择第一个元素时,最好使用querySelector。我会用每个元素的值创建一个对象,然后检查对象值:

const valsAreEmpty = ...vals => vals.every(val => val === '');
const vals = [
'requestRightsEmail2',
'requestRightsEmail3',
'requestRightsEmail4',
'requestRightsTitle2',
'requestRightsTitle3',
'requestRightsTitle4',
].map(classStr => document.querySelector('.' + classStr).value);
if (valsAreEmpty(
vals.requestRightsTitle4,
vals.requestRightsEmail4
)) {
displayInputField('none', 5);
}
if (valsAreEmpty(
vals.requestRightsTitle3,
vals.requestRightsEmail3,
vals.requestRightsTitle4,
vals.requestRightsEmail4
)) {
displayInputField('none', 4);
}
// etc

如果有更多的Email#Title#元素,则可以使用循环来创建val

一些评论:

  • 看起来您正在使用HTML类来识别页面中的单个元素

您可以更通用地使用 HTML 类:

<input class="requestRightsTitle" />
<input class="requestRightsEmail" />
<input class="requestRightsTitle" />
<input class="requestRightsEmail" />
<input class="requestRightsTitle" />
<input class="requestRightsEmail" />
<input class="requestRightsTitle" />
<input class="requestRightsEmail" />

在javascript方面:document.getElementsByClassName('requestRightsEmail')会给你一个有用的数组:

let emailInputs = document.getElementsByClassName('requestRightsEmail');
emailInputs[0].value = ...
emailInputs[1].value = ...
emailInputs[2].value = ...
...
// note : this array will be 0-indexed.
//   emailInputs[0] will match your 'requestRightsEmail1'

这可能也会在 css 方面帮助你。

  • 然后,您可以更轻松地构建和扫描值数组

例如:

let titles = document.getElementsByClassName('requestRightsTitle')
.map( e => e.value )
let emails = document.getElementsByClassName('requestRightsEmail')
.map( e => e.value )
// as said above : '3' matches 'requestRights4'
if (titles[3] == '' && emails[3] == '') {
displayInputField('none', 5);
}
if (  titles[2] == '' && emails[2] == ''
&& titles[3] == '' && emails[3] == '') {
displayInputField('none', 4);
}
  • 然后,您可以更轻松地将其放入循环中

  • 最后一点,关于您的示例的作用以及如何重写它:

如果requestRightsEmail3为空,您已经知道包含requestRightsEmail3的所有测试都将返回false

所以查看循环的另一种方法是:如果
i不为空,则在此处停止,否则,显示这些额外的字段:

for (let i = 3; i >= 1; i--) {   // <- decreasing loop
// if one field contains something, stop here :
if (emails[i] != '' || titles[i] != '') {
break;
}
// otherwise : call your displayInputFields
displayInputField('none', i);
}

最新更新