我有一长串的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 内容与应用程序逻辑之间的关注点。