Javascript 如何干燥我的jQuery代码并使其更具可读性/可维护性?

Javascript 如何干燥我的jQuery代码并使其更具可读性/可维护性?,javascript,jquery,Javascript,Jquery,我开始做很多jQuery编程。我发现我的代码变得有点难以维护,而且不那么可读。我的javascript包含在web应用程序的每个页面上,即使它只在一个页面上使用。这样做的好处是在加载页面之前缓存javascript,但我担心会意外地创建具有相同名称的函数(由我团队中的其他程序员创建) 我是javascript新手,因此可能缺少一些基础知识。我可以将哪些技术应用于以下代码以及将来的其他代码,以使jQuery代码更易于维护和阅读 <script type="text/javascript"&g

我开始做很多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>

$(文档).ready(函数(){
$(“#注册信息.复制按钮”)。单击(复制字段);
});
函数copyField(e){
e、 预防默认值();
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=$('').hide().insertAfter($按钮);
var$undoLink=$('').hide().insertAfter($button);
var字段=$button.attr('id');
$undoLink。单击(函数(e){
e、 预防默认值();
undoCopyField($tr,originalText);
});
$button.hide();
$loadingIcon.show();
$.ajax({
url:“/registrations/将字段复制到联系人”,
数据:{
id:“”,
字段:字段,
数据:新文本
},
成功:功能(数据){
if(data.success){
$loadingIcon.hide();
$tr.find('.contact data').html(newText);
$tr.find('td.form\u field\u label')。removeClass('mismatched');
$tr.effect('highlight',1000,function(){
$undoLink.fadeIn();
});
}否则{
显示错误消息(data.error);
$loadingIcon.hide();
$button.show();
}
},
错误:函数(){
displayErrorMessage(“未知原因”);
$loadingIcon.hide();
$button.show();
}
});
}
函数undoCopyField($tr,originalText){
var$button=$tr.find('.copy button');
var$loadingIcon=$tr.find('.loadingIcon');
var$undoLink=$tr.find('.undo-link');
var字段=$button.attr('id');
$undoLink.hide();
$loadingIcon.show();
$.ajax({
url:“/registrations/将字段复制到联系人”,
数据:{
id:“”,
字段:字段,
资料来源:原文
},
成功:功能(数据){
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();
});
}否则{
显示错误消息(data.error);
$loadingIcon.hide();
$undoLink.show();
}
},
错误:函数(){
displayErrorMessage(“未知原因”);
$loadingIcon.hide();
$undoLink.show();
}
});
}
函数displayErrorMessage(消息){
警报('抱歉,尝试保存更改时出错:'+消息);
}
更新:此代码示例的许多部分包含几乎相同的代码块。特别是AJAX调用。除了调用完成后发生的操作外,这两个块基本上是相同的。我真的很想找出一种方法来干燥这些部分。

两个小贴士:

  • 为代码使用名称空间以避免名称冲突。Javascript中当然没有真正的名称空间,但是可以使用对象来伪造它们
`

  • 将javascript代码放在一个或多个单独的文件(每个名称空间一个)中,并使用第三方库将它们合并到一个文件中,缩小它们并进行适当的缓存。它节省了大量带宽,比跨不同页面分发各种javascript函数更干净
我在这里看到的唯一真正的可读性问题是,通过在每个变量后使用逗号,可以声明变量,而无需每次使用
var

var $tr = $(this).closest('tr'),
    originalText = jQuery.trim($tr.find('.contact-data').text()),
    newText = jQuery.trim($tr.find('.registration-data').text());
我总是发现这比一系列变量更容易阅读。看起来,它就像一个代码块,从
var
开始,在缩进返回时结束


除此之外,一切看起来都不错。

让jQuery代码更干净、更易于维护的一种方法是将其分解为可重用的jQuery插件。这允许您将相关功能封装在单个文件中。每个插件实际上都是一个名称空间,因此可以避免函数名冲突。您还可以将参数传递给插件,以便在逐页或逐案的基础上自定义行为

有一个编写插件的很好的指南和模板作为开始

使用类似jsunit的东西测试代码

使用命名良好的小方法创建命名良好的小类。该类的名称将描述其职责。方法的名称也将描述它的职责

重构以消除重复

限制全局范围的使用

阅读干净的代码:敏捷软件工艺手册[平装本]
Robert C.Martin(编辑)

您可以使用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=函数(){
变量a=参数,o=null,i,j,d;
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;
        }
    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);
options.url = "http://www.google.com";
$.ajax(options);
options.data.id = "newID";
$('#registration-information input.copy-button')
$('#registration-information input.copy-button, #registration-information a.copy-button')
$('.copy-button')