有没有更短的编写此脚本的方法?

时间:2019-02-04 16:44:08

标签: javascript shorthand

我一直在学习如何使用控制台和Firefox的ScratchPad。

我有一种形式,可以根据正则表达式进行验证。到目前为止,它确实可以实现我想要的功能。问题是我感觉太多了。每个输入都需要一个不同的模式,并不是全部都需要。

我试图提出一个for循环来处理此问题,但这并没有给我提供每个单独输入所需的控件。有没有一种方法可以只为某些输入编写循环?还是我必须为每个正则表达式写一个for循环

如果我所拥有的是执行此操作的正确方法,那么至少有一种较短的书写方法吗?

在这一点上,请记住我只是在编写所有正则表达式时对其进行测试,因此红色笔画为绿色笔画。这不是一个验证问题。我只想知道一种较短的语法,而不是一一写完每一行,,因为我要解释大约16个输入。

// grabs the form
var myForm = document.forms["main-contact"]

// regular expressions
var onlyText = /^[A-Za-zÀ-ÖØ-öø-ÿ]+$/;
var textNumbers = /^[A-Za-zÀ-ÖØ-öø-ÿ0-9\s]+$/;
var onlyEmail = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/;

// Testing value matches the regular expression
myForm[0].value.match(onlyText) && myForm[0].value.length >= 2 ? myForm[0].setAttribute("style","outline: unset") : myForm[0].setAttribute("style","outline: 2px solid crimson");
myForm[1].value.match(onlyText) && myForm[1].value.length >= 2 ? myForm[1].setAttribute("style","outline: unset") : myForm[1].setAttribute("style","outline: 2px solid crimson");
myForm[2].value.match(onlyEmail) && myForm[2].value.length >= 2 ? myForm[2].setAttribute("style","outline: unset") : myForm[2].setAttribute("style","outline: 2px solid crimson");
myForm[3].value.match(textNumbers) && myForm[3].value.length >= 2 ? myForm[3].setAttribute("style","outline: unset") : myForm[3].setAttribute("style","outline: 2px solid crimson");

4 个答案:

答案 0 :(得分:0)

这个问题可能应该在CodeReview上。

  • myForm是一个集合,它可能应该是复数。
  • 最后4行非常相似,可以在函数中进行重构,接受形式和正则表达式作为参数。
  • 您可以将三元运算符替换为if
  • 您可以定义CSS类(correctincorrect),而不用修改样式。
  • 您可以zip myForms和一组正则表达式([onlyText, onlyText, onlyEmail, textNumbers])来获取每种形式的正则表达式,并将它们发送给新函数。

答案 1 :(得分:0)

您可以隔离重复的代码并创建一个通用功能。例如,在所有情况下都重复添加样式,可以用通用函数和css类代替内联样式

var myForm = document.forms["main-contact"]

// regular expressions
var onlyText = /^[A-Za-zÀ-ÖØ-öø-ÿ]+$/;
var textNumbers = /^[A-Za-zÀ-ÖØ-öø-ÿ0-9\s]+$/;
var onlyEmail = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/;


for (var x = 0; x < 4; x++) {
  let elem = myForm[x];
  let elemValue = myForm[x].value;
  if (x === 2) {
    testCond(elemValue, 'onlyEmail') ? setOutline(elem) : setOutline(elem,
    'outlineCrimson');
  } else if (x === 3) {
    testCond(elemValue, 'textNumbers') ? setOutline(elem) : setOutline(elem, 'outlineCrimson');
  } else {
    testCond(elemValue, 'onlyText') ? setOutline(elem) : setOutline(elem, 'outlineCrimson');
  }
}
// function to test the regex and check the length of value
function testCond(b, a) {
  return elemValue.match(a) && 2 <= elemValue.length ? !0 : !1;
};

// function to set the class, by default it will be setOutline
function setOutline(elem, defClass = 'setOutline') {
  elem.classList.add(defClass)
}
.setOutline {
  outline: unset
}

.outlineCrimson {
  outline: 2px solid crimson;
}

答案 2 :(得分:0)

我不知道是否有更短的方法,因为我没有使用ScratchPad的经验,但是由于您一次又一次地对同一步骤进行硬编码,因此可以(如果myForm对象在范围内)布尔函数(也可以设置值),如下所示:

function matchReg(field, num){
    if (myForm[num].value.match(field) && myForm[num].value.length >= 2){
        //attribute setting can also be done out of function, with boolean value
        myForm[num].setAttribute("style","outline: unset");
        return true;
    } else {
        myForm[num].setAttribute("style","outline: 2px solid crimson");
        return false;
    }
}

并这样称呼它:

matchReg(onlyText, 0);
matchReg(onlyText, 1);
//etc...

如果仍然要进行大量的硬编码,则可以编写一个数组或某种其他可迭代对象(例如字典或2d数组),如下所示:

//js 2d array
var toIterate = [
         [onlyText, 0],
         [onlyText, 1],
         [onlyEmail,2],
         //etc....
]
//js dictionary object
var toIterate = {
        0: onlyText,
        1: onlyText,
        2: onlyEmail,
        //etc....
}

并对其进行迭代:

//for the dict:
Object.keys(toIterate).forEach(key => {
    matchReg(toIterate[key],key); 
});
//for the array-object:
for (var i = 0; i < toIterate.length; i++) {
   matchReg(toIterate[i][0],toIterate[i][1])
}

(见https://stackoverflow.com/a/41550077

一般来说,有很多方法可以解决此问题,并且当出现非常相似的代码行时,每个程序员都应该看到即将发生的事情。通常的做法是反复读取不断出现的代码片段并为其设计功能,但是我想您已经知道这一点。

同样,出于Java的背景,此处介绍的功能可能有错误或不节省时间。

答案 3 :(得分:0)

可以使用

{2,}代替+来匹配2个或更多,并且可以使用.style.outline来设置轮廓:

var onlyText = /^[A-Za-zÀ-ÖØ-öø-ÿ]{2,}$/;
var textNumbers = /^[A-Za-zÀ-ÖØ-öø-ÿ0-9\s]{2,}$/;
var onlyEmail = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/;
var myForm = document.forms["main-contact"]

function setOutline(i, r) { 
  myForm[i].style.outline = r.test(myForm[i].value) ? "unset" : "2px solid crimson"; 
}

setOutline(0, onlyText);
setOutline(1, onlyText);
setOutline(2, onlyEmail);
setOutline(3, textNumbers);

带循环和带有正则表达式的数组的替代方法:

var onlyText = /^[A-Za-zÀ-ÖØ-öø-ÿ]{2,}$/;
var textNumbers = /^[A-Za-zÀ-ÖØ-öø-ÿ0-9\s]{2,}$/;
var onlyEmail = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/;
var myForm = document.forms["main-contact"]
var patterns = [onlyText, onlyText, onlyEmail, textNumbers];

for (var i = 0; i < 4; ++i) {
  myForm[i].style.outline = patterns[i].test(myForm[i].value) ? "unset" : "2px solid crimson"; 
}