Javascript onclick="&引用;vs事件处理程序

Javascript onclick="&引用;vs事件处理程序,javascript,event-handling,inline-code,Javascript,Event Handling,Inline Code,如果我想执行一个函数,我更喜欢内联js: <p id="element" onclick="doSomething();">Click me</p> 为什么推荐使用js事件监听器?对于CSS和内联样式,您也可以这样说。不必费力地浏览css文件就可以很容易地找到当前使用的类/id或父/子元素 将一个点击绑定为10个不同的项目是否真的更好?还是只针对一个类的一个事件处理程序?即使您不需要10个点击处理程序,也最好将代码设置为可维护性,并在以后进行升级。基本上,这与整体有关,

如果我想执行一个函数,我更喜欢内联js:

<p id="element" onclick="doSomething();">Click me</p>

为什么推荐使用js事件监听器?

对于CSS和内联样式,您也可以这样说。不必费力地浏览css文件就可以很容易地找到当前使用的类/id或父/子元素


将一个点击绑定为10个不同的项目是否真的更好?还是只针对一个类的一个事件处理程序?即使您不需要10个点击处理程序,也最好将代码设置为可维护性,并在以后进行升级。

基本上,这与整体有关,我相信,将所有内容分开。因此,将HTML/CSS/JS分开。它使你的HTML更加整洁,而且,我认为,不用它也更容易导航

然后,当/如果您需要进行较大更改时,您有足够的空间将内联JS转换为外部文件,或者如果您希望将相同的函数应用于多个按钮,那么代码就更少了。代码越少越好


如果您正确地保存了JS文件,并对其进行了完整的文档记录,那么由外部人员对其进行导航就成了eaiser

我不知道使用内联处理程序与稍后附加处理程序的优点。根据我的经验,当我必须处理动态元素时,我更喜欢使用inline方法,例如,如果我想为每个图像添加一个处理程序,并且图像的数量会根据其他数据(例如db中的图像)而变化。在本例中,使用inline允许我向每个图像添加一个处理程序,否则我必须重新计算javascript文件中要附加到每个图像的图像数和处理程序数


当然,当您可以使用jQuery这样的库,轻松地获取内联元素列表时,这些库是没有用的

有很多原因可以避免使用内联JavaScript,其中最重要的可能是代码的可维护性

一个简单的例子(我使用jQuery只是为了演示)


不管其他人怎么想,我认为在标记中内联侦听器是有补偿价值的。具体来说,它为您修改DOM节点提供了更多的自由。如果通过JavaScript添加侦听器,则在替换任何父节点的innerHTML时,侦听器将丢失。如果在标记中内联侦听器,则可以克隆节点,对其进行修改,然后用刚刚克隆和修改的节点替换原始节点


也许最好在一个特定的用例中描述它。我希望在不触发多次回流的情况下对文档的多个部分进行更改。因此,在这种情况下,我可以克隆节点,对其进行任何更改(自其分离后无回流),然后用修改的节点替换上一个节点(触发一个回流)。对于内联监听器,这可以防止任何监听器在替换过程中丢失。

反对内联事件处理程序的一个大参数,这里的其他答案解决的参数是

然而,IMO实际上还有一个更大的问题:内联事件处理程序的评估方式有点难以捉摸

您可能知道,*属性上的
内容将用作事件处理程序函数的主体。但是这个函数有什么特点呢

令人惊讶的是,一些祖先元素的属性和元素本身的属性都在内联事件处理程序的范围内


点击我
也点击我!

我看到一些人说,需要将有关表示和业务逻辑的关注点分离开来

OP在他的例子中确实显示了这种分离!内联事件处理程序中没有逻辑,只有将在“单击”事件上执行的函数引用/调用。。。逻辑本身可以在其他地方单独维护

由于逻辑流的可发现性,我个人更喜欢这种方法。如果我以前从未见过申请。。。我要开始代码遍历的第一个地方是在DOM中,在那里可以清楚地看到哪些事件处理程序正在运行,哪些函数正在为处理程序提供逻辑。如果使用“JQuery.On”事件处理方法,只需浏览html,您将不知道哪些处理程序实际连接起来并提供功能


只提供函数指针的内联事件处理程序只是将事件连接起来,而不是将逻辑泄漏到表示中。

除了编码标准透视图之外

使用属性:

单击我

如果再次添加相同的属性(请参见下文),则将考虑最新的属性

单击我

使用事件处理程序:

document.getElementById('element').onclick=doSomething

假设您添加了以下行

document.getElementById('element').onclick=doSomethingMore

这两个处理程序都被调用。

内联时,关注点分离和可组合性丢失。也就是说,您将显示与行为混合在一起,如果您想更改行为(例如添加到行为中),则需要在多个位置进行更改。也称为unobtrusive JS。另一个问题是
,它很容易被window.onload覆盖,因此请将事件处理程序放在一个位置。我目前正在处理一个小的单页应用程序,我的JavaScript文件已超过700行。如果我必须在HTML代码中搜索我的所有事件处理程序绑定,我可能会不知所措
:)
请参阅一个更实际的原因,即永远不要使用内联事件处理程序属性:您永远不知道哪些对象属性将被放入您的范围中,从而可能隐藏全局变量并使您的代码中断
document.getElementById('element').onclick = doSomething;
<p class="element" onclick="doSomething();">Click me</p>
<p class="element" onclick="doSomething();">Click me</p>
<p class="element" onclick="doSomething();">Click me</p>
<p class="element" onclick="doSomething();">Click me</p>
<p class="element" onclick="doSomething();">Click me</p>
<p class="element" onclick="doSomething();">Click me</p>
<p class="element">Click me</p>
<p class="element">Click me</p>
<p class="element">Click me</p>
<p class="element">Click me</p>
<p class="element">Click me</p>
<p class="element">Click me</p>

$('.element').bind('click', doSomethingElse);
Project = {
    // All the variables/constants/objects that need to be globally accessible inside the Project object.

    init : function(){
        // Main entry point...
        this.MainMenu.init();

        // Rest of the code which should execute the moment Project is initiated.
    }
}

Project.MainMenu = {
    // All the variables/constants/objects that need to be accessible only to MainMenu.

    init : function(){ // Is run immediatelly by Project.init()
        // Event handlers relevant to the main menu are bound here

        // Rest of the initialization code
    }
}

Project.SlideShow = {
    // All the variables/constants/objects that need to be accessible only to SlideShow.

    init : function(){ // Is run only on pages that really require it.
        // Event handlers for the slideshow.
    }
}