减少一系列 JavaScript 函数表达式中的代码冗余



我有一长串的javascript函数,这些函数是通过html中的函数名称上的"onClick"调用的。

    Corporate number <input type="text" autofocus id="corp_text">
    <button onclick="getCorpNum(this.form)">SAVE</button><br><br>
    LLC number <input type="text" autofocus id="LLC_text">
    <button onclick="getLLCNum(this.form)">SAVE</button><br><br>
    Type of nonprofit <input type="text" autofocus id="NP_text">
    <button onclick="getNonProfit(this.form)">SAVE</button><br><br>
    Other description <input type="text" autofocus id="OD_text">
    <button onclick="getDesc(this.form)">SAVE</button><br><br>

在javascript中,函数在形式上非常相似:

    /**
     * Get corporation number text field data.
     */
     var getCorpNum = function() {
         var Corp_number = [];
         Corp_number=document.getElementById("corp_text").value;
         if (Corp_number.length > 0) createJSONobj("Corp", Corp_number);
     }
    /**
     * Get LLC number text field data.
     */
    var getLLCNum = function() {
       var LLC_number = [];
       LLC_number = document.getElementById("LLC_text").value;
       if (LLC_number.length > 0) createJSONobj("LLC", LLC_number);
    }
    /**
     * Get type of non-profit text field.
     */
    var getNonProfit=function() {
        var NP_number = [];
        NP_number = document.getElementById("NP_text").value;
        if (NP_number.length > 0) createJSONobj("NP", NP_number);
    }
   /**
    * Get other description text
    */
    var getDesc=function() {
        var getDesc=[];
        getDesc = document.getElementById("OD_text").value;
        if (getDesc.length > 0) createJSONobj("Other_desc", getDesc);
    }

问题是我还有其他类似的函数,它们都具有相同的形式,我想减少代码量。可以捕获代码形式的通用内容。这对我来说很困难,因为 onClicks 需要每个函数对象的名称。

你可以只传递不同的部分。

Corporate number <input type="text" autofocus id="corp_text">
<button onclick="getThing('corp_text', 'Corp')">SAVE</button><br><br>

然后在更通用的函数中使用这些变量:

var getThing = function(id, name) {
     var values=document.getElementById(id).value;
     if (values.length > 0) createJSONobj(name, values);
}

但。。。也许比"getThing"更具描述性的东西:)

这个怎么样?

首先,让每个按钮调用一个函数,并将其作为字符串参数的形式类型传递

Corporate number <input type="text" autofocus id="corp_text">
<button onclick="getDetail('corp')">SAVE</button><br><br>

然后,有一个灵活的功能,可以获得您需要的详细信息:

 var getDetail = function(type) {
  var getElem = document.getElementById(type + '_text').value;
  if ((getElem).length > 0) {
    createJSONobj(type, getElem);
  }
 }

以下是我处理这个问题的方法 - 您可以通过将函数调用的不同部分存储在外部来重构函数。请注意,我不知道createJSONobj在您的代码中做了什么,所以我创建了一个虚拟实现,以便您可以看到控制台输出。

另一个值得注意的变化是在 HTML 标记中不使用 onxxx 属性。看看不显眼的JavaScript,你就会明白为什么。

function createJSONobj(k, v) {
  console.log('Dummy function ' + k + ', ' + v);
};
var jsonNameMap = {
  'corp_text': {
    k: 'Corp'
  },
  'LLC_text': {
    k: 'LLC'
  },
  'NP_text': {
    k: 'NP'
  },
  'OD_text': {
    k: 'Other_desc'
  }
};
document.getElementById('myForm').addEventListener('click', function(e) {
  if (e.target.nodeName === 'BUTTON') {
    var field = e.target.previousSibling.nodeType !== 3 ?
      e.target.previousSibling :
      e.target.previousSibling.previousSibling;
    if (field.value.length > 0) {
      createJSONobj(jsonNameMap[field.id].k, field.value);
    }
  }
});
<form id="myForm">
  Corporate number
  <input type="text" autofocus id="corp_text">
  <button>SAVE</button>
  <br>
  <br>LLC number
  <input type="text" id="LLC_text">
  <button>SAVE</button>
  <br>
  <br>Type of nonprofit
  <input type="text" id="NP_text">
  <button>SAVE</button>
  <br>
  <br>Other description
  <input type="text" id="OD_text">
  <button>SAVE</button>
  <br>
  <br>
</form>

另一件需要注意的事情:考虑只有一个保存按钮。我不确定您的用例是什么,但"每个字段的按钮"方法肯定有点忙。

只是添加到已经很明显的其他答案...您还可以选择使用 data- 属性来保存您希望传递给调用函数的值,并将其与约定相结合,例如<button>将始终在<input>之后/之前,当您单击按钮时,您可以使用 JavaScript 导航回其以前的同级(即<input>)并从中提取所需的值。

请参阅示例代码段...打开您的 JavaScript 控制台以查看实际输出。 该代码段还演示了如何将保存合并到一个"全部保存"按钮。

function createJSONobj(key, value) {
  var o = {};
  o[key] = value;
  var json = JSON.stringify(o);
  console.log(json);
}
function saveValue(el) {
  var input = el.previousElementSibling;  //get the input element next to the button
  saveJson(input);
}
function saveJson(input) {
  var key = input.dataset.jsonKey;        //get that input's data-json-key value
  var value = input.value;                //get the input's value
  
  if (value.length > 0) {
    createJSONobj(key, value);
  } else {
    console.log('Nothing to create.');
  }
}
function saveAll(frm) {
  //console.log(frm);
  
  var inputs = document.querySelectorAll('input', frm);  //get me all the inputs from the form
  //console.log(inputs);
  
  for(var i = 0, il = inputs.length; i < il; i++) {    
    var currentEl = inputs[i];
    saveJson(currentEl);
  }
  
}
<form id="theForm">
    
    Corporate number <input type="text" autofocus id="corp_text" data-json-key="Corp">  
    <button type="button" onclick="saveValue(this)">SAVE</button><br><br>
    LLC number <input type="text" id="LLC_text" data-json-key="LLC">
    <button type="button" onclick="saveValue(this)">SAVE</button><br><br>
    Type of nonprofit <input type="text" id="NP_text" data-json-key="NP">
    <button type="button" onclick="saveValue(this)">SAVE</button><br><br>
    Other description <input type="text" id="OD_text" data-json-key="Other_desc">
    <button type="button" onclick="saveValue(this)">SAVE</button><br><br>
    
    <!--better yet, instead of all those buttons -->
    <hr>
    <button type="button" onclick="saveAll(this.form)">SAVE ALL</button>
      
</form>
                                   

至于我自己的喜好,我宁愿使用像敲除这样的绑定库库或像 angular 这样的框架来做这类事情。 它们允许更好地分离 UI 内容与应用程序逻辑之间的关注点。

最新更新