我开始做很多jQuery编程。我发现我的代码变得有点难以维护并且不是那么可读。我的javascript被包含在我们的Web应用程序的每个页面上,即使它只在一个页面上使用。这有利于在加载页面之前缓存javascript,但我担心意外创建具有相同名称的函数(由我团队中的其他程序员创建)。
我是javascript的新手,所以可能会有一些我缺少的基础知识。我可以将哪些技术应用于以下代码,以及将来的其他代码,以使我的jQuery代码更易于维护和读取?
<script type="text/javascript">
$(document).ready(function(){
$('#registration-information .copy-button').click(copyField);
});
function copyField(e) {
e.preventDefault();
var $tr = $(this).closest('tr');
var originalText = jQuery.trim($tr.find('.contact-data').text());
var newText = jQuery.trim($tr.find('.registration-data').text());
var $button = $tr.find('.copy-button');
var $loadingIcon = $('<span class="loading-icon"></span>').hide().insertAfter($button);
var $undoLink = $('<a class="undo-link" href="#">Undo</a>').hide().insertAfter($button);
var field = $button.attr('id');
$undoLink.click(function(e){
e.preventDefault();
undoCopyField($tr, originalText);
});
$button.hide();
$loadingIcon.show();
$.ajax({
url: '/registrations/copy-field-to-contact',
data: {
id: '<?php echo $registration->ID ?>',
field: field,
data: newText
},
success: function(data){
if (data.success) {
$loadingIcon.hide();
$tr.find('.contact-data').html(newText);
$tr.find('td.form_field_label').removeClass('mismatched');
$tr.effect('highlight', 1000, function(){
$undoLink.fadeIn();
});
} else {
displayErrorMessage(data.error);
$loadingIcon.hide();
$button.show();
}
},
error: function(){
displayErrorMessage('Unknown reason');
$loadingIcon.hide();
$button.show();
}
});
}
function undoCopyField($tr, originalText) {
var $button = $tr.find('.copy-button');
var $loadingIcon = $tr.find('.loading-icon');
var $undoLink = $tr.find('.undo-link');
var field = $button.attr('id');
$undoLink.hide();
$loadingIcon.show();
$.ajax({
url: '/registrations/copy-field-to-contact',
data: {
id: '<?php echo $registration->ID ?>',
field: field,
data: originalText
},
success: function(data){
if (data.success) {
$undoLink.remove();
$loadingIcon.hide();
$tr.find('.contact-data').html(originalText);
$tr.find('td.form_field_label').addClass('mismatched');
$tr.effect('highlight', 1000, function(){
$tr.find('.copy-button').fadeIn();
});
} else {
displayErrorMessage(data.error);
$loadingIcon.hide();
$undoLink.show();
}
},
error: function(){
displayErrorMessage('Unknown reason');
$loadingIcon.hide();
$undoLink.show();
}
});
}
function displayErrorMessage(message) {
alert('Sorry, there was an error while trying to save your changes: ' + message);
}
</script>
更新:此代码示例的许多部分都包含几乎完全相同的代码块。特别是AJAX调用。除了呼叫完成后发生的操作外,这两个块基本相同。我真的想找出一种方法来干掉这些部分。
答案 0 :(得分:3)
两个提示:
`
var MyCode=MyCode||{
copyField:function (e){
},
someOtherFunction:function(){
}
};
$(document).ready(function(){
MyCode.copyField(...);
});
答案 1 :(得分:2)
使jQuery代码更清晰,更易于维护的一种方法是将其分解为可重用的jQuery插件。这允许您将相关功能封装在单个文件中。每个插件实际上都是命名空间,因此您将避免函数名称冲突。您还可以将参数传递给插件,以逐页或逐个案例地自定义页面上的行为。
有一个非常好的指南和模板用于编写插件here
答案 2 :(得分:0)
我在这里看到的唯一真正的可读性问题是,您可以在每次变量后使用逗号每次都不使用var
来声明变量:
var $tr = $(this).closest('tr'),
originalText = jQuery.trim($tr.find('.contact-data').text()),
newText = jQuery.trim($tr.find('.registration-data').text());
我总是发现这更容易阅读,然后只是一系列变量。从表面上看,它看起来像是以var
开头的代码块,并在缩进返回时结束。
除此之外,一切看起来都不错。
答案 3 :(得分:0)
首先......
使用像jsunit这样的东西来测试代码。
使用名称很小的方法创建小型的命名类。该类的名称将描述它的职责。该方法的名称也将描述它的职责。
重构以删除重复。
限制使用全球范围。
阅读清洁代码:敏捷软件工艺手册[平装] Robert C. Martin(编辑)
答案 4 :(得分:0)
您可以使用YUI名称空间模型, 创建顶级对象(命名空间) 让var STW = {}; 使用此命名空间函数来创建其他类或命名空间
STW.namespace = function () {
var a = arguments, o = null, i, j, d;
for (i = 0; i < a.length; i = i + 1) {
d = ("" + a[i]).split(".");
o = STW;
for (j = (d[0] == "STW") ? 1 : 0; j < d.length; j = j + 1) {
o[d[j]] = o[d[j]] || {};
o = o[d[j]];
}
}
return o;
}
让我们举一些例子 在你的第一个文件中 使用STW.namespace(“STW.namespace1”); STW.Namespace1.class1 =函数(){
//你的代码 } 在其他文件中 STW.namespace( “STW.namespace1.namespace2”); STW.namespace1.namespace2.class2 =函数(){
//你的代码 }
答案 5 :(得分:0)
$ .ajax parens中的东西只是一个单一的参数,就像任何基于c的函数一样。
{}是JS对象的文字表示。因此,如果两个案例在{}之间具有相同的内容,则可以执行此操作:
options = {
url: '/registrations/copy-field-to-contact',
data: {
id: '<?php echo $registration->ID ?>',
field: field,
data: newText
},
success: function(data){
if (data.success) {
$loadingIcon.hide();
$tr.find('.contact-data').html(newText);
$tr.find('td.form_field_label').removeClass('mismatched');
$tr.effect('highlight', 1000, function(){
$undoLink.fadeIn();
});
} else {
displayErrorMessage(data.error);
$loadingIcon.hide();
$button.show();
}
},
error: function(){
displayErrorMessage('Unknown reason');
$loadingIcon.hide();
$button.show();
}
}
然后两者:
$.ajax(options);
现在,如果您的下一次ajax呼叫的选项存在差异:
示例#1 - 只需将网址更改为Google
options.url = "http://www.google.com";
$.ajax(options);
示例#2 - 更改数据属性(另一个对象)的id属性
options.data.id = "newID";
对JQuery的选择器语法提出警告。直接通过ID抓取是理想的选择。在旧版本的IE(没有本机getByClassName方法,因此有更多的解释器级循环)中,仅仅按类抓取可能会非常慢。编写选择器的理想方法会缩小到最接近的父ID,如果可以显式,则将标记名称添加到后续类选择器中以进一步缩小范围(getElementsByTagName是本机和快速的)。
因此,如果我们可以依赖.copy-button作为输入标记:
$('#registration-information input.copy-button')
或者我们可以依赖它作为输入或锚标记
$('#registration-information input.copy-button, #registration-information a.copy-button')
如果在#registration-information中有大量的HTML元素,那么在IE 6中可能会有相当快的选择,也许可能是7。我尝试将ID提供给所有可能保持这种状态的独特容器,这样我就可以使用ID来获得更高效的JQuery选择器。
但无论你做什么,都要避免这些:
$('.copy-button')
如果有足够的可用内容,那么即使是在一个较大的HTML文档上也可能会阻塞IE 6。如果您计划多次使用选择器的结果,请将其保存到var。它非常简洁,很容易忘记在某些情况下这些操作可能是资源密集型操作。