• JQuery基础教程:事件(下)


     事件传播

        为了说明不可单击的页面元素处理单击事件的能力,例如样式转换器中包含按钮的div元素或者兄弟元素h3,我们来实现一个鼠标指针进入元素和离开元素时的效果,首先需要添加一种翻转状态,表明能与鼠标进行某种交互,然后我们.hover()方法给h3元素添加这个样式,伪代码如下:

    <style>
    .hover { 
    cursor: pointer; 
    background-color: #afa; 
    }
    </style
    <script>
    $(document).ready(function() { 
    $('#switcher h3').hover(function() { 
    $(this).addClass('hover'); 
    }, function() { 
    $(this).removeClass('hover'); 
    }); 
    });
    </sctipt>
    
    <body>
    ...
    </body>
    代码

          注:.hover()方法接受两个函数参数。第一个函数会在鼠标指针进入被选择的元素时执行,而第二个函数会在鼠标指针离开该元素时触发

    • 事件的旅程

         当页面上发生一个事件时,每个层次上的DOM元素都有机会处理这个事件。以下面的页面模型为例:

     1 <div class="foo"> 
     2 <span class="bar"> 
     3 <a href="http://www.example.com/"> 
     4 The quick brown fox jumps over the lazy dog. 
     5 </a> 
     6 </span> 
     7 <p> 
     8 How razorback-jumping frogs can level six piqued gymnasts! 
     9 </p> 
    10 </div>

    允许多个元素响应单击事件的一种策略叫做事件捕获。在事件捕获的过程中,事件首先会交给最外层的元素,接着再交给更具体的元素。在这个例子中,意味着单击事件首先会传递给<div>,然后是<span>,最后是<a>。另一种相反的策略叫做事件冒泡。即当事件发生时,会首先发送给最具体的元素,在这个元素获得响应机会之后,事件会向上冒泡到更一般的元素。在我们的例子中,<a>会首先处理事件,然后按照顺序依次是<span>和<div>

    • 事件冒泡的副作用

         假设在我们的例子中,为<div>添加了一个mouseout事件处理程序。当用户的鼠标指针退出这个<div>时,会按照预期运行mouseout处理程序。因为这个过程发生在顶层元素上,所以其他元素不会取得这个事件。但是,当指针从<a>元素上离开时,<a>元素也会取得一个mouseout事件。然后,这个事件会向上冒泡到<span>和<div>,从而触发上述的事件处理程序。这种冒泡序列很可能不是我们所希望的

     通过事件对象改变事件的旅程

           假设我们希望增大触发样式转换器折叠或扩展的可单击区域。一种方案就是将事件处理程序从标签移至包含它的<div>元素

    $(document).ready(function() { 
    $('#switcher').click(function() { 
    $('#switcher button').toggleClass('hidden'); 
    }); 
    });
    JS

    完整代码如下:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
        <style type="text/css">
            body.large {
                font-size: 1.5em;
            }
    
            body.narrow {
                width: 250px;
            }
    
            .selected {
                font-weight: bold;
            }
    
    
            .hover {
                cursor: pointer;
                background-color: #afa;
            }
    
            .hidden {
             display:none;
            }
    
        </style>
        <script src="Scripts/jquery-1.8.2.js"></script>
        <script src="Scripts/jquery-1.8.2.min.js"></script>
        <script>
    
          
    
            $(document).ready(function () {
                $('#switcher-default').addClass('selected');
                $('#switcher button').on('click', function () {
                        var bodyClass = this.id.split('-')[1];
                        var bodyClass = this.id.split('-')[1];
                        $('body').removeClass().addClass(bodyClass);
                        $('#switcher button').removeClass('selected');
                        $(this).addClass('selected');                    
                        //eventobj.stopPropagation(); //阻止事件冒泡       
                    //return false;  //也可以阻止事件冒泡,也可以阻止默认事件
                });
            });
    
          
            $(document).ready(function () {
                $('#switcher h3').hover(function () {
                    $(this).addClass('hover');
                }, function () {
                    $(this).removeClass('hover');
                });
            });
    
            $(document).ready(function () {
                $('#switcher').click(function () {
                    $('#switcher button').toggleClass('hidden');
                });
            });
    
        </script>
    </head>
    <body>
        <div id="switcher" class="switcher">
            <h3>样式转换器</h3>
            <button id="switcher-default">
                默认视图
            </button>
            <button id="switcher-narrow">
                窄列视图
            </button>
            <button id="switcher-large">
                大字视图
            </button>
        </div>
        <h2>Shakespeare's Plays</h2>
    
        <table>
            <tr>
                <td>As You Like It</td>
                <td>Comedy</td>
                <td></td>
            </tr>
            <tr>
                <td>All's Well that Ends Well</td>
                <td>Comedy</td>
                <td>1601</td>
            </tr>
            <tr>
                <td>Hamlet</td>
                <td>Tragedy</td>
                <td>1604</td>
            </tr>
            <tr>
                <td>Macbeth</td>
                <td>Tragedy</td>
                <td>1606</td>
            </tr>
            <tr>
                <td>Romeo and Juliet</td>
                <td>Tragedy</td>
                <td>1595</td>
            </tr>
            <tr>
                <td>Henry IV, Part I</td>
                <td>History</td>
                <td>1596</td>
            </tr>
            <tr>
                <td>Henry V</td>
                <td>History</td>
                <td>1599</td>
            </tr>
        </table>
        <h2>Shakespeare's Sonnets</h2>
        <table>
            <tr>
                <td>The Fair Youth</td>
                <td>1–126</td>
            </tr>
            <tr>
                <td>The Dark Lady</td>
                <td>127–152</td>
            </tr>
            <tr>
                <td>The Rival Poet</td>
                <td>78–86</td>
            </tr>
        </table>
    </body>
    </html>
    完整代码

      这种改变会使样式转换器的整个区域都可以通过单击切换其可见性。但时也造成了一个问题,即单击按钮会在修改内容区的样式之后折叠样式转换器。导致这个问题的原因就是事件冒泡,即事件首先被按钮处理,然后又沿着DOM树向上传递,直至到达<div id="switcher">激活事件处理程序并隐藏按钮。要解决这个问题,必须访问事件对象

            注:事件对象是一种DOM结构,它会在元素获得处理事件的机会时传递给被调用的事件处理程序。这个对象中包含着与事件有关的信息(例如事件发生时的鼠标指针位置),也提供了可以用来影响事件在DOM中传递进程的一些方法

    • 事件目标         

             变量event保存着事件对象。而event.target属性保存着发生事件的目标元素。通过.target,可以确定DOM中首先接收到事件的元素(即实际被单击的元素)。而且,我们知道this引用的是处理事件的DOM元素,修改上面的代码可以得到如下代码

    $(document).ready(function() { 
    $('#switcher').click(function(event) { 
    if (event.target == this) { 
    $('#switcher button').toggleClass('hidden'); 
    } 
    }); 
    });
    代码 

             

        此时的代码确保了被单击的元素是<div id="switcher">,而不是其他后代元素。现在,单击按钮不会再折叠样式转换器,而单击转换器背景区则会触发折叠操作。但是,单击标签(<h3>)同样什么也不会发生,因为它也是一个后代元素

    • 停止事件传播

         删除刚才的event.target==this,我们来给按钮的事件处理添加一个事件对象并调用event.stopPropagation()方法,这样可以阻止按钮的事件冒泡行为,这样一来,单击按钮的事件会被按钮处理,而且只会被按钮处理。单击样式转换器的其他地方则可以折叠和扩展整个区域,代码如下:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
        <style type="text/css">
            body.large {
                font-size: 1.5em;
            }
    
            body.narrow {
                width: 250px;
            }
    
            .selected {
                font-weight: bold;
            }
    
    
            .hover {
                cursor: pointer;
                background-color: #afa;
            }
    
            .hidden {
             display:none;
            }
    
        </style>
        <script src="Scripts/jquery-1.8.2.js"></script>
        <script src="Scripts/jquery-1.8.2.min.js"></script>
        <script>
    
          
    
            $(document).ready(function () {
                $('#switcher-default').addClass('selected');
                $('#switcher button').on('click', function (event) {
                        var bodyClass = this.id.split('-')[1];
                        var bodyClass = this.id.split('-')[1];
                        $('body').removeClass().addClass(bodyClass);
                        $('#switcher button').removeClass('selected');
                        $(this).addClass('selected');                    
                        event.stopPropagation(); //阻止事件冒泡       
                    //return false;  //也可以阻止事件冒泡,也可以阻止默认事件
                });
            });
    
          
            $(document).ready(function () {
                $('#switcher h3').hover(function () {
                    $(this).addClass('hover');
                }, function () {
                    $(this).removeClass('hover');
                });
            });
    
            $(document).ready(function () {
                $('#switcher').click(function (event) {                
                    $('#switcher button').toggleClass('hidden');
                });
            });
    
        </script>
    </head>
    <body>
        <div id="switcher" class="switcher">
            <h3>样式转换器</h3>
            <button id="switcher-default">
                默认视图
            </button>
            <button id="switcher-narrow">
                窄列视图
            </button>
            <button id="switcher-large">
                大字视图
            </button>
        </div>
        <h2>Shakespeare's Plays</h2>
    
        <table>
            <tr>
                <td>As You Like It</td>
                <td>Comedy</td>
                <td></td>
            </tr>
            <tr>
                <td>All's Well that Ends Well</td>
                <td>Comedy</td>
                <td>1601</td>
            </tr>
            <tr>
                <td>Hamlet</td>
                <td>Tragedy</td>
                <td>1604</td>
            </tr>
            <tr>
                <td>Macbeth</td>
                <td>Tragedy</td>
                <td>1606</td>
            </tr>
            <tr>
                <td>Romeo and Juliet</td>
                <td>Tragedy</td>
                <td>1595</td>
            </tr>
            <tr>
                <td>Henry IV, Part I</td>
                <td>History</td>
                <td>1596</td>
            </tr>
            <tr>
                <td>Henry V</td>
                <td>History</td>
                <td>1599</td>
            </tr>
        </table>
        <h2>Shakespeare's Sonnets</h2>
        <table>
            <tr>
                <td>The Fair Youth</td>
                <td>1–126</td>
            </tr>
            <tr>
                <td>The Dark Lady</td>
                <td>127–152</td>
            </tr>
            <tr>
                <td>The Rival Poet</td>
                <td>78–86</td>
            </tr>
        </table>
    </body>
    </html>
    代码
    • 阻止事件默认行为

         对于一个锚元素(<a>),当用户单击时浏览器会加载一个新页面,这种行为与事件处理程序不是同一个概念,它是单击锚元素的默认操作。即便在事件对象上调用.stopPropagation()方法也不能禁止这种默认操作,因为默认操作不是在正常的事件传播流中发生的。在这种情况下,.preventDefault()方法则可以阻止事件的默认行为。另外,如果想要同时停止事件传播和默认操作,可以在事件处理程序中返回false,代码如下:

     $(document).ready(function () {
                $('#switcher-default').addClass('selected');
                $('#switcher button').on('click', function (event) {
                        var bodyClass = this.id.split('-')[1];
                        var bodyClass = this.id.split('-')[1];
                        $('body').removeClass().addClass(bodyClass);
                        $('#switcher button').removeClass('selected');
                        $(this).addClass('selected');                    
                    //event.stopPropagation(); //阻止事件冒泡      
                        //event.preventDefault(); //阻止默认事件和事件冒泡
                        return false;  //也可以阻止事件冒泡,也可以阻止默认事件
                });
            });
    代码

     事件委托

        事件冒泡也有好处,通过事件冒泡我们可以用很少的代码为元素注册重复的事件,例如,一个table里有很多td,如果为每个td都注册一个hover事件,不仅需要遍历table的子节点,而且严重降低了性能,通过事件委托可以这样写

    $("table").delegate("td", "hover", function(){
    $(this).toggleClass("hover"); });
      将每个单元格的hover事件委托给了table元素,每当单元格td触发hover事件是就会执行元素table绑定的函数fn
  • 相关阅读:
    C# 根据主窗体的位置弹窗信息窗体一直保持在主窗体中间
    c# winForm父子窗口 通过委托进行信息传递
    使用devexpress插件 消除运行时弹窗
    C# 获取当前时间戳
    WinForm实现Loading等待界面
    转载 C#设置控件 Enabled 为 false 时背景色不改变
    DEV gridView中加入加载条显示进度,必须为圆角型
    winfrom 圆角化
    列表元素的反转、排序——python
    使用for循环和while循环打印九九乘法表——python
  • 原文地址:https://www.cnblogs.com/SamFlynn/p/4444822.html
Copyright © 2020-2023  润新知