# 六、事件

## 不限于单个`ready()`事件

重要的是要记住，您可以根据自己的意愿声明任意多的自定义`ready()`事件。您不限于将单个`.ready()`事件附加到文档。 **``ready()``** 事件按照其包含的顺序执行。

注释:

传递 jQuery 函数，一个函数——例如**`jQuery(funciton(){//code here})`**——是 **`jQuery(document).ready()`** 的捷径。

## 使用`bind()`和`unbind()`附加/移除事件

使用`bind()`方法，例如`jQuery('a').bind('click',function(){})`，您可以将以下任何标准处理程序添加到适当的 DOM 元素中:

| *   [更蓝](http://docs.jquery.com/Events/blur)[【focus】](http://docs.jquery.com/Events/focus)*   【负载】 | *   [Mormon](http://docs.jquery.com/Events/mousemove)*   Mormon Church |

显然，基于 DOM 标准，只有特定的处理程序与特定的元素一致。

除了这个标准处理程序列表之外，您还可以利用`bind()`来附加 jQuery 自定义处理程序，例如`mouseenter`和`mouseleave`，以及您可能创建的任何自定义处理程序。

要移除标准处理程序或自定义处理程序，我们只需将需要移除的处理程序名称或自定义处理程序名称传递给`unbind()`方法，例如`jQuery('a').unbind('click')`。如果没有参数被传递到`unbind()`**，它将移除附加到元素的所有处理程序。**

 **刚刚讨论的这些概念在下面的代码示例中进行了表达。

样本:sample65.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <input type="text" value="click
me" />
    <br />
    <br />
    <button>remove events</button>
    <div id="log" name="log"></div>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
      // Bind events 
      $('input').bind('click', function () { alert('You
clicked me!'); });
      $('input').bind('focus', function () {
          // alert and focus
events are a recipe for an endless list of dialogs
          // we will log instead
          $('#log').html('You
focused this input!');
      });
      // Unbind events 
      $('button').click(function () {
          // Using shortcut
binding via click()     
          $('input').unbind('click');
          $('input').unbind('focus');
          // Or, unbind all
events     // $('button').unbind(); 
      });
  })(jQuery); </script>
</body>
</html>

```

注意事项:

jQuery 为所有标准 DOM 事件提供了几种 **`bind()`** 方法的快捷方式，不包括自定义 jQuery 事件，如 **`mouseenter`** 和 **`mouseleave`** 。使用这些快捷方式只需将事件名称替换为方法名称即可，例如**`.click()`****`mouseout()`****`focus()`**。

您可以使用 jQuery 为单个 DOM 元素附加无限的处理程序。

jQuery 提供了 **`one()`** 事件处理方法，方便地将一个事件绑定到 DOM 元素，DOM 元素将被执行一次，然后移除。 **`one()`** 法只是 **`bind()`** 和 **`unbind()`** 的一种包装。

## 通过短事件方法以编程方式调用特定的处理程序

用于将事件处理程序绑定到 DOM 元素的快捷语法(例如`.click()`、**、 ``mouseout()`、`、**、**、、**和`focus()`)也可用于以编程方式调用处理程序。要做到这一点，只需使用快捷方式事件方法，而无需向其传递函数。理论上，这意味着我们可以将一个处理程序绑定到一个 DOM 元素，然后立即调用该处理程序。下面，我通过`click()`事件来演示这一点。

样本:sample66.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <a>Say Hi</a>
    <!--clicking this
element will alert "hi" -->
    <a>Say Hi</a>
    <!--clicking this element
will alert "hi" -->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
      // Bind a click
handler to all <a> and immediately invoke their handlers. 
      $('a').click(function () { alert('hi') }).click();
      // Page will alert
twice. On page load, a click 
      // is triggered for
each <a> in the wrapper set.  
  })(jQuery); </script>
</body>
</html>

```

注释:

也可以使用事件 **`trigger()`** 方法调用特定的处理程序，例如 **`jQuery('a').click(function(){ alert('hi') }).trigger('click')`** 。这也适用于命名空间和自定义事件。

## jQuery 将事件对象规范化

[jQuery 根据 W3C 标准对事件对象](http://docs.jquery.com/Events/jQuery.Event)进行规范化。这意味着当事件对象被传递给函数处理程序时，您不必担心事件对象的 [浏览器特定实现(例如互联网浏览器的`window.event`)。您可以使用事件对象的以下属性和方法，而不用担心浏览器的差异，因为 jQuery 将事件对象规范化了。](http://www.quirksmode.org/js/events_access.html)

### 事件对象属性

*   事件类型
*   事件.目标
*   事件.数据
*   event.relatedTarget
*   事件. currentTarget
*   event.pageX
*   事件. pageY
*   事件.结果
*   event.timeStamp

### 事件对象方法

*   event.preventDefault（）
*   event.isDefaultPrevented()
*   event.stopPropagation()
*   event.isPropagationStopped()
*   event.stopImmediatePropagation()
*   event . isimmediatepropagationstop()

要访问规范化的 jQuery 事件对象，只需传递匿名函数，传递给一个 jQuery 事件方法，一个名为“event”的参数(或者您想调用它的任何东西)。然后，在匿名回调函数内部，使用参数访问事件对象。下面是这个概念的编码示例。

样本:sample67.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
      $(window).load(function (event) {
alert(event.type); }); // Alerts "load".  
  })(jQuery); </script>
</body>
</html>

```

## 格罗金事件命名空间

通常我们会在 DOM 中有一个对象，它需要将几个函数绑定到一个事件处理程序。例如，让我们采用调整大小处理程序。使用 jQuery，我们可以向`window.resize`处理程序添加任意多的函数。但是，当我们只需要删除其中一个功能，而不是全部功能时，会发生什么呢？如果我们使用`$(window).unbind('resize')` **，**附加到`window.resize`处理器的所有功能都将被移除。通过命名一个处理程序(例如`resize.unique`)，我们可以给一个特定的函数分配一个唯一的钩子来移除。

样本:sample68.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
      $(window).bind('resize', function ()
      { alert('I
have no namespace'); });

      $(window).bind('resize.unique', function () { alert('I
have a unique namespace'); });

      // Removes only the
resize.unique function from event handler 
      $(window).unbind('resize.unique')
  })(jQuery); </script>
</body>
</html>

```

在上面的代码中，我们向 resize 处理程序添加了两个函数。添加的第二个(文档顺序)调整大小事件使用事件名称间距，然后使用`unbind()`立即移除该事件。我这样做是为了说明附加的第一个功能没有被移除。Namespacing 事件使我们能够在单个 DOM 元素上标记和移除分配给同一处理程序的唯一函数。

除了解除绑定与单个 DOM 元素和处理程序相关联的特定函数之外，我们还可以使用事件名称空间来专门调用(使用`trigger()`)附加到 DOM 元素的特定处理程序和函数。在下面的代码中，两个点击事件被添加到`<a>`中，然后使用名称间距，只调用一个。

样本:sample69.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <a>click</a>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
      $('a').bind('click',
       function () { alert('You
clicked me') });
      $('a').bind('click.unique',
          function () { alert('You
Trigger click.unique') });  // Invoke the function passed to click.unique 
      $('a').trigger('click.unique');
  })(jQuery); </script>
</body>
</html>

```

注意事项:

使用的名称空间的深度或数量没有限制，例如**`resize.layout.headerFooterContent`** 。

名称空间是一种保护、调用、移除插件可能需要的任何独占处理程序的好方法。

命名空间既适用于标准事件，也适用于自定义事件，例如 **`click.unique`** 或 **`myclick.unique`** 。

## 格罗金事件代表团

事件委托依赖于事件传播(也称为冒泡)。当您单击位于`<ul>`内部的`<li>`内部的`<a>`时，单击事件会在从`<a>`到`<li>`到`<ul>`的 DOM 中冒泡，以此类推，直到每个具有分配给事件处理程序的功能的祖先元素触发。

这意味着，如果我们将一个点击事件附加到一个`<ul>`上，然后点击一个封装在`<ul>`内部的`<a>`，最终由于冒泡，附加到`<ul>`上的点击处理程序将被调用。当它被调用时，我们可以使用事件对象(`event.target`)来识别 DOM 中哪个元素实际上导致了事件冒泡开始。同样，这将为我们提供对开始冒泡的元素的引用。

通过这样做，我们可以仅使用一个事件处理程序/声明，将一个事件处理程序添加到大量 DOM 元素中。这是极其有用的；例如，一个有 500 行的表，其中每一行都需要一个 click 事件，可以利用事件委托。请检查下面的代码以获得澄清。

样本:sample70.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <ul>
        <li><a href="#">remove</a></li>
        <li><a href="#">remove</a></li>
        <li><a href="#">remove</a></li>
        <li><a href="#">remove</a></li>
        <li><a href="#">remove</a></li>
        <li><a href="#">remove</a></li>
    </ul>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
      $('ul').click(function (event) { //
Attach click handler to <ul> and pass event object.     
          // event.target is the
<a>.     

$(event.target).parent().remove(); // Remove <li> using
parent()     
          return false; //
Cancel default browser behavior, stop propagation. 
      });
  })(jQuery); </script>
</body>
</html>

```

现在，如果你真的点击了列表中的一个项目符号，而不是链接本身，你猜怎么着？你最终会移除`<ul>`。为什么呢？因为所有的点击都是泡沫。所以当你点击子弹时，`event.target`是`<li>` **，**不是`<a>`。既然是这样，`parent()`法将抓取`<ul>`并将其移除。我们可以更新我们的代码，这样我们只在从`<a>`中点击`<li>`时通过向`parent()`方法传递一个元素表达式来移除它。

```js
$(event.target).parent('li').remove();

```

这里重要的一点是，当可点击区域包含多个封装元素时，您必须仔细管理正在点击的内容，因为您永远不知道用户可能点击的确切位置。因此，您必须检查以确保点击发生在您预期的元素中。

## 将事件处理程序应用于 DOM 元素，而不管使用`live()`进行的 DOM 更新

使用方便的`live()`事件方法，您可以将处理程序绑定到当前网页中的 DOM 元素和那些尚未添加的元素。`live()`方法使用事件委托来确保新添加/创建的 DOM 元素将始终响应事件处理程序，而不管 DOM 操作或对 DOM 的动态更改。使用`live()`本质上是手动设置事件委托的快捷方式。例如，使用`live()`我们可以创建一个按钮，无限期地创建另一个按钮。

样本:sample71.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <button>Add another
button</button>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
      $('button').live('click', function ()
      { $(this).after("<button>Add
another button</button>"); });
  })(jQuery); </script>
</body>
</html>

```

检查完代码后，应该很明显，我们正在使用`live()`将事件委托应用于父元素(代码示例中的`<body>` 元素)，以便添加到 DOM 中的任何按钮元素总是响应点击处理程序。

要删除实时事件，我们只需使用`die()`方法—例如`$('button').die()`。

要带走的概念是`live()`方法可以用来将事件附加到使用 AJAX 移除和添加的 DOM 元素上。这样，您就不必在初始页面加载后将事件重新绑定到引入 DOM 的新元素。

注释:

`live()`支持以下处理程序:`click`、`dblclick`、`mousedown`、`mouseup`、`mousemove`、`mouseover`、`mouseout`、`keydown`、`keypress`、`keyup`。

`live()`只对选择器有效。

**`live()`** 默认情况下会通过使用`return false`内的功能发送到`live()`的方法停止传播。

## 给多个事件处理程序添加一个函数

可以将事件`bind()`方法传递给几个事件处理程序。这使得将一次编写的同一个函数附加到多个处理程序成为可能。在下面的代码示例中，我们将一个匿名回调函数附加到文档上的 click、keypress 和 resize 事件处理程序。

样本:sample72.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
      // Responds to
multiple events. 
      $(document).bind('click
keypress resize', function (event) { alert('A
click, keypress, or resize event occurred on the document.'); });
  })(jQuery); </script>
</body>
</html>

```

## 用`preventDefault()`取消默认浏览器行为

当单击链接或提交表单时，浏览器将调用与这些事件相关联的默认功能。例如，单击`<a>`链接，网络浏览器将尝试在当前浏览器窗口中加载`<a> href`属性的值。要停止浏览器执行此类功能，可以使用 jQuery 规范化事件对象的`preventDefault()`方法。

样本:sample73.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <a href="http://www.jquery.com">jQuery</a>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
      // Stops browser from
navigating. 
      $('a').click(function (event) {
event.preventDefault(); });
  })(jQuery); </script>
</body>
</html>

```

## 取消事件传播用`stopPropagation()`

事件在 DOM 中传播(也称为冒泡)。当为任何给定元素触发事件处理程序时，被调用的事件处理程序也会为所有祖先元素调用。这种默认行为有助于像事件委托这样的解决方案。要禁止这种默认冒泡，可以使用 jQuery 规范化事件方法 **`stopPropagation()`** 。

样本:sample74.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <div><span>stop</span></div>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
      $('div').click(function (event) {
          // Attach click
handler to <div>.     
          alert('You
clicked the outer div');
      });

      $('span').click(function (event) {
          // Attach click
handler to <span>.     
          alert('You
clicked a span inside of a div element');
          // Stop click on
<span> from propagating to <div>.
          // If you comment out
the line below, 
          //the click event
attached to the div will also be invoked.
          event.stopPropagation();
      });
  })(jQuery); </script>
</body>
</html>

```

在上面的代码示例中，附加到`<div>`元素的事件处理程序不会被触发。

## 通过`return false`取消默认行为和事件传播

返回 false(例如`return false`)相当于同时使用`preventDefault()`和`stopPropagation()`。

样本:sample75.html

```js
<!DOCTYPE html>
<html lang="en">
<body><span><a href="javascript:alert('You
clicked me!')" class="link">click me</a></span>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function($){     $('span').click(function(){ 
      // Add click event to
<span>.         
      window.location='http://www.jquery.com';     });      
      $('a').click(function(){ 
          // Ignore clicks on
<a>.         
          return false;
      });
  })(jQuery); </script>
</body>
</html>

```

如果您注释掉上面代码中的`return false`语句，`alert()`将被调用，因为默认情况下浏览器将执行`href`的值。此外，由于事件冒泡，页面将导航到 jQuery.com。

## 创建自定义事件并通过`trigger()`触发

使用 jQuery，您可以使用`bind()`方法制造自己的自定义事件。这是通过为`bind()`方法提供自定义事件的唯一名称来实现的。

现在，因为这些事件是自定义的，浏览器不知道，调用自定义事件的唯一方法是使用 jQuery `trigger()`方法以编程方式触发它们。查看下面的代码，了解使用`trigger()`调用的自定义事件的示例。

样本:sample76.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <div>jQuery</div>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
$('div').bind('myCustomEvent', function () {
      // Bind a custom event
to <div>.     
      window.location = 'http://www.jquery.com';
  });
      $('div').click(function () {
          // Click the
<div> to invoke the custom event.     
          $(this).trigger('myCustomEvent');
      })
  })(jQuery); </script>
</body>
</html>

```

## 克隆事件以及 DOM 元素

默认情况下，使用`clone()`方法克隆 DOM 结构不会额外克隆附加到正被克隆的 DOM 元素的事件。为了克隆元素和附加到元素上的事件，您必须向`clone()`方法传递一个布尔值`true`。

样本:sample77.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <button>Add another
button</button>
    <a href="#" class="clone">Add another link</a>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
$('button').click(function () {
var $this = $(this);
      $this.clone(true).insertAfter(this);
      // Clone element and
its events.     
      $this.text('button').unbind('click'); //
Change text, remove event. 
  });
      $('.clone').click(function () {
          var $this = $(this);
          $this.clone().insertAfter(this); //
Clone element, but not its events.     
          $this.text('link').unbind('click'); //
Change text, remove event.
      });
  })(jQuery); </script>
</body>
</html>

```

## 在视口中获取鼠标的 X 和 Y 坐标

通过将`mousemove`事件附加到整个页面(文档)，当鼠标指针在画布上的视口内移动时，您可以检索鼠标指针的 X 和 Y 坐标。这是通过检索 jQuery 规范化事件对象的`pageY`和`pageX`属性来完成的。

样本:sample78.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function ($) {
$(document).mousemove(function (e) {
      // e.pageX - gives you
the X position.     
      // e.pageY - gives you
the Y position.     
      $('body').html('e.pageX
= '
+ e.pageX + ', e.pageY = ' + e.pageY);
  });
  })(jQuery); </script>
</body>
</html>

```

## 获取鼠标相对于另一元素的 X 和 Y 坐标

通常需要获取鼠标指针相对于视口或整个文档之外的元素的 X 和 Y 坐标。这通常通过工具提示来完成，其中工具提示相对于鼠标悬停的位置显示。这可以通过从视口的 X 和 Y 鼠标坐标中减去相对元素的偏移来轻松实现。

样本:sample79.html

```js
<!DOCTYPE html>
<html lang="en">
<body>
    <!-- Move mouse over
div to get position relative to the div -->
    <div style="margin: 200px; height: 100px; width: 100px; background: #ccc; padding: 20px">
        relative to this </div>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>  (function($){  $('div').mousemove(function(e){     
      //relative to this div
element instead of document.     
      var relativeX =
e.pageX - this.offsetLeft;
      var relativeY =
e.pageY - this.offsetTop;
      $(this).html('releativeX
= '
+ relativeX + ', releativeY = ' + relativeY);
  });
  })(jQuery); </script>
</body>
</html>

```**