Skip to content

Latest commit

 

History

History
538 lines (419 loc) · 20.1 KB

07.md

File metadata and controls

538 lines (419 loc) · 20.1 KB

六、事件

不限于单个ready()事件

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

注释:

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

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

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

| * 更蓝【focus】* 【负载】 | * Mormon* Mormon Church |

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

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

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

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

样本:sample65.html

<!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 事件,如 mouseentermouseleave 。使用这些快捷方式只需将事件名称替换为方法名称即可,例如**.click()mouseout()focus()**。

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

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

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

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

样本:sample66.html

<!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 标准对事件对象进行规范化。这意味着当事件对象被传递给函数处理程序时,您不必担心事件对象的 浏览器特定实现(例如互联网浏览器的window.event)。您可以使用事件对象的以下属性和方法,而不用担心浏览器的差异,因为 jQuery 将事件对象规范化了。

事件对象属性

  • 事件类型
  • 事件.目标
  • 事件.数据
  • 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

<!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

<!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

<!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.uniquemyclick.unique

格罗金事件代表团

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

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

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

样本:sample70.html

<!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()方法传递一个元素表达式来移除它。

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

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

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

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

样本:sample71.html

<!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()支持以下处理程序:clickdblclickmousedownmouseupmousemovemouseovermouseoutkeydownkeypresskeyup

live()只对选择器有效。

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

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

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

样本:sample72.html

<!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

<!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

<!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

<!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

<!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

<!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 规范化事件对象的pageYpageX属性来完成的。

样本:sample78.html

<!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

<!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>

```**