使用鼠标事件调用函数而不将其附加到HTML元素?

时间:2014-03-04 04:57:16

标签: javascript html

我正在参加一个Web开发课程。今天老师给了我们一段代码,提出了一些我无法通过自己的搜索得到满意解决的问题。有问题的代码基本上是这样的:

<script>
function selectmouse(e){
...
...
}

document.onmousedown = selectmouse;
</script>

我的第一个问题,这是一种调用函数的合法方式吗?这是完成的事情吗?我当然熟悉从HTML元素调用函数的典型方法,例如

<body onmousedown="selectmouse(event)">

代码应该是调用函数并将它传递给onmousedown的事件对象。在玩了一段时间后,我找到了一些不寻常的东西。

首先,如果我在函数调用后放置括号,就像我习惯做的那样(即selectmouse();),那么函数在加载页面后立即解析,变量的值为'undefined'。这对我来说很直观,因为我假设浏览器将其视为变量赋值,因此在解析代码时调用函数,因为它通常会分配变量。

然而,当我删除'()'并将其保留为上面编码时,对我来说奇怪的部分发生了。在这种情况下,它似乎像她想要的那样运作。当在主体的任何部分按下鼠标时它会调用该函数,并将事件对象作为函数的变量发送。但我无法弄清楚为什么。我在网上找不到类似的东西,我以前从未见过这样的东西。这是一种合法的做法吗?或者这个错误的代码是否由于某种原因而发生,并且可能在将来引起问题?它为什么有效?

4 个答案:

答案 0 :(得分:1)

document.onmousedown = selectmouse;  //note: never do this except in old browsers
  

然而,当我删除'()'并将其保留为上面编码时,对我来说奇怪的部分发生了。在这种情况下,它似乎像她想要的那样起作用。

这并不奇怪。您正在将函数的引用传递给浏览器,而不是执行它。

例如,您有此功能:

function callback(){
    alert("clicked!");
}

document.body.onclick = callback;

您将引用传递给onclick,浏览器将知道触发事件时要调用的函数。但如果你这样做:

document.body.onclick = callback();

这将被评估为:

document.body.onclick = alert("clicked!");
//Note that this is simplified explanation to visualize what is happening.
//The returned value of alert() is not assigned to onclick.
//To be exact the returned value of callback() is the one that is being assigned.
//Similar to:
//  ...onclick = (function(){ alert("clicked!"); })();

然后您将看到一个警报,浏览器将继续执行其余代码:

document.body.onclick = undefined;

<body onmousedown="selectmouse(event)">     <!-- Don't do this too -->

括号是必要的,因为此代码不会立即执行。它仅在触发事件时执行。


无论如何,您不应使用.onmousedownonmousdown="..."附加事件。有一种更好的方法:

element.addEventListener("mousedown", callback, false);

原因:如果您使用onmousedown属性,则只能附加一个mousedown事件。在大多数情况下,您需要附加更多而不是一个。

同时附加事件内联可能导致安全问题(cross-site scripting),而且在开发Chrome应用/扩展程序时确实是why Google decided to prohibit all developers from using them

答案 1 :(得分:0)

这是合法的代码,并且正在按预期工作。

您熟悉的方式只是我们在网络发展过程中尝试的一种方法,但目前我们应该更好地使用您展示的第二种方式,尽管它的更改会让您更好地理解它使用事件绑定。

当你这样做时

function selectmouse(e){
...
...
}

javascript将创建一个名为selectmouse的变量,并将该函数保存在该变量中。所以selectmousefunction类型的变量,函数体为其值。

另一方面,

document可以与class或具体为object的实例相关联。每个document和每个HTML元素或DOM node都可以包含变量,以存储要在onmousedown等用户事件上调用的函数。

所以在做的时候

document.onmousedown = selectmouse;

我们说的是

  

当mousedown发生在文档中时,该函数名为selectmouse   应该叫做

如果你这样做

document.onmousedown = selectmouse();

意味着

  

立即运行函数selectmouse并获取结果,分配   结果为DOM节点文档的onmousedown事件。

如果你问为什么这会从表格中删除

<body onmousedown="selectmouse(event)">

要以简单的方式回答,HTML是超文本标记语言,其唯一目的是表示格式化数据,网络内容的快速演变使其与此behaviourspresentation代码混乱像内联css。因此,为了使用HTML创建行为和表示,从而做到更好的设计,我们就这样做了。

请花点时间看看你如何能够bind一个事件的功能,这是当前做同样事情的权衡。

有关详细说明,请查看ppk博客的活动部分here

答案 2 :(得分:-1)

我认为这是正确的,因为函数在脚本中被调用就好像它是一个对象一样,对我来说这不是最好的方法,我会喜欢这个(用jquery):

$(document).mousedown(function (event) {
  // here the content of the function
 });

答案 3 :(得分:-2)

<body onmousedown="selectmouse(event)">

在此示例中,浏览器评估表达式 selectmouse(event)的结果,并将其分配给正文的onmousedown属性,事件未定义且selectmouse不会不返回任何内容,因此结果未定义。

如果它在脚本标记

中,则等效于以下内容
<script>
    function selectmouse(e) {
    }

    document.body.onmousedown = selectmouse(event);
</script>

<body onmousedown="selectmouse">

当你删除()时,你正在为onmousedown属性分配一个函数。现在,只要mousedown事件被引发并且它冒泡到正文,浏览器就会触发你的回调方法,将当前事件作为你声明为“e”的参数传递。如果另一个元素也声明了一个onmousedown事件处理程序,但是它取消了该事件(通过调用event.cancelBubble = true),则主体的onmousedown处理程序将被调用。

<script>
    function selectmouse(e) {
    }

    document.body.onmousedown = selectmouse;
</script>