如何编写易于调试/维护的JavaScript事件处理程序

如何编写易于调试/维护的JavaScript事件处理程序,javascript,jquery,Javascript,Jquery,事件处理程序的编写主要有两种方式: <input type="button" onclick="clickFunction()" /> 必须有人在后期调试/维护此代码。在第一种情况下,我们可以执行“检查元素”并快速找到执行的内容。在第二种情况下,我们必须找到正确的文档加载器代码,以找到分配给它的位置 推荐的方法是什么?推荐的方法是编写事件处理程序(第二个选项)。关于这背后的原因,请参阅中的“2.不要编写内联Javascript” 此外,如果您正在寻找编写更容易调试的代码,请考虑命名

事件处理程序的编写主要有两种方式:

<input type="button" onclick="clickFunction()" />
必须有人在后期调试/维护此代码。在第一种情况下,我们可以执行“检查元素”并快速找到执行的内容。在第二种情况下,我们必须找到正确的文档加载器代码,以找到分配给它的位置


推荐的方法是什么?

推荐的方法是编写事件处理程序(第二个选项)。关于这背后的原因,请参阅中的“2.不要编写内联Javascript”

此外,如果您正在寻找编写更容易调试的代码,请考虑命名回调。这样,它们将以函数名而不是“未定义”显示在js错误中


第二种方法是首选方法。这有几个原因:

首先,它将表示与逻辑分离。您不想让您的演示文稿(HTML)与您的逻辑混淆,因为事情变得难以维护。我喜欢JavaScript的一个区域专门用于“绑定”,这样我就可以很容易地看到我的JavaScript逻辑钩住HTML的地方。但重要的是不要让它进入HTML本身

其次,它可以防止代码重复。内联方法通常会产生如下代码:

[ <a href="javascript:void(0)" onclick="closeWindow()">X</a> ]
...
<button onclick="closeWindow()">Close Window</button>
<button onclick="one();">One</button>
<button onclick="one();two();">Two</button>
<button onclick="two();">Three</button>
[]
...
关窗
问题在于,最终会有许多不同的元素引用单个函数或方法。如果该函数或方法以任何方式发生更改,则需要查找所有引用。这违反了基本的反代码重复措施。这样做要好得多

[ <a href="javascript:void(0)" class="closeWin">X</a> ]
...
<button class="closeWin">Close Window</button>
...
<script type="text/javascript">
    $(function() {
        $(".closeWin").on("click", closeWindow);
    });
</script>
[]
...
关窗
...
$(函数(){
美元(“.closeWin”)。点击(“点击”,关闭窗口);
});
第三,它允许对某些用户操作使用一个阻塞点,您可以在其中添加一个断点以进行调试。当然,您可以在调用的任何函数中执行此操作,但是有一个专用的绑定区域似乎可以加快速度

第四,它允许多个绑定。例如,您可能有三个按钮,前两个执行一个操作,后两个执行另一个操作(因此第二个按钮执行两个操作)。您可以开始在onclick中抛出多行JavaScript,如下所示:

[ <a href="javascript:void(0)" onclick="closeWindow()">X</a> ]
...
<button onclick="closeWindow()">Close Window</button>
<button onclick="one();">One</button>
<button onclick="one();two();">Two</button>
<button onclick="two();">Three</button>
1
两个
三
这看起来很难看。您还可以使用一些笨拙的中间方法,如:

<button onclick="one();">One</button>
<button onclick="oneAndTwo();">Two</button>
<button onclick="two();">Three</button>
1
两个
三
这也是超级丑陋,将成为一个维护噩梦。或者,您可以执行一些简单的绑定:

<button class="actionOne">One</button>
<button class="actionOne actionTwo">Two</button>
<button class="actionTwo">Three</button>
...
<script type="text/javascript">
    $(function() {
        $(".actionOne").on("click", one);
        $(".actionTwo").on("click", two);
    });
</script>
1
两个
三
...
$(函数(){
美元(“.actionOne”)。点击(“点击”,一);
美元(“.actionTwo”)。点击(点击),点击两次;
});
更干净,更容易维护

现在,关于如何确定附加了哪些事件处理程序,我没有一个完美的答案,但我有一个非常好的答案:获取Google Chrome(这可能在Safari中也适用)。当您在Google Chrome中检查一个元素时,它会给您一个附加到该元素的事件处理程序列表


如果您按照我的建议在JavaScript中设置一个“绑定”部分,那么很容易缩小绑定到什么的范围。但使用Chrome更快捷、更简单。欢迎您以您认为最好的方式编写代码。尽管人们普遍认为远程绑定比内联绑定更受欢迎。除此之外,如何处理这些问题还取决于您自己的经验和编程风格。

除了上述所有出色的答案之外,我还发现了一个名为VisualEvent的工具,它为事件处理程序提供了很多可见性


如果它做了一些不同的事情,并且有一个单独的回调,那么它应该有一个不同的id。为什么要在一个做了不同事情的按钮上使用相同的id?@Kostia在表单上使用类似于
btnSubmit
的东西并不少见。这可能发生在许多页面上@在这种情况下,您需要将脚本划分为单独的文件。您可以在一个脚本中使用多个页面可以使用的通用功能,并且每个页面特定的脚本都位于各自的文件中,仅包含在相关页面上。您可以在调试器堆栈中看到它们的名称trace@Shmiddty我不同意。仅仅因为它的普遍性并不意味着它的最佳实践;虽然我知道有些特殊情况,但如果DOM中永远不会同时存在两个按钮,那么它们就没有理由需要单独的ID。最好将每个页面的功能分离为单独的脚本,从而完全消除任何命名冲突。