【问题标题】:Is there an even shorter way of writing this script?有没有更短的方法来编写这个脚本?
【发布时间】:2019-06-28 11:00:36
【问题描述】:

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

我有一个表单,我正在编写基于正则表达式的验证。到目前为止,它完全符合我的要求。问题是我觉得它太多了。每个输入都需要不同的模式,并非全部都是必需的。

我试图想出一个 for 循环来处理这个问题,但它没有给我每个单独输入所需的控制。有没有办法只为某些输入编写 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");

【问题讨论】:

  • 改用循环?
  • 您在代码中使用没有任何 cmets 的正则表达式? (这是非常糟糕的做法)
  • @MrJ:var onlyText = /^[A-Za-zÀ-ÖØ-öø-ÿ]+$/; // text only 真的比 var onlyText = /^[A-Za-zÀ-ÖØ-öø-ÿ]+$/; 更好,信息量更大吗?
  • 欣赏它。同样,这只是一个小脚本,我正在快速尝试测试新的东西。我的最终版本通常被过度评论,但现在我仍然在搞乱一切。而且由于我独自工作,如果我知道我在看什么,那么在这个阶段对我来说,cmets 并不重要。

标签: javascript shorthand


【解决方案1】:

这个问题应该是CodeReview。

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

【讨论】:

    【解决方案2】:

    您可以分离重复代码并创建一个通用函数。例如在所有条件中重复添加样式,可以将其替换为通用函数和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;
    }
    

    【讨论】:

      【解决方案3】:

      我不知道是否有更短的方法,因为我没有使用 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...
      

      如果这仍然是很多硬编码,您可以编写一个数组或其他类型的可迭代对象(如字典或二维数组),如下所示:

      //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)

      一般来说,有很多方法可以解决这个问题,当出现非常相似的代码行时,每个程序员都应该看到正在发生的事情。通常的做法是获取一遍又一遍出现的代码 sn-p 并为其设计一个函数,但我想你已经知道这一点。

      另外,来自 java 背景,这里介绍的功能可能有问题或时间效率不高。

      【讨论】:

      • 谢谢。我想我的问题措辞不佳。但是由于我搞砸了 for 循环,我想知道的是一种更好的方法来编写一个函数来完成我在上面写的内容。解决了
      【解决方案4】:

      {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"; 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-17
        • 1970-01-01
        • 2013-08-18
        • 1970-01-01
        相关资源
        最近更新 更多