亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

由點擊頁面其它地方隱藏div所想到的jQuery的delegate

2019-11-20 22:21:09
字體:
來源:轉載
供稿:網友

先從最簡單的開始,假如頁面有一個id為test的div,我們要實現點擊頁面其它地方隱藏該div:

復制代碼 代碼如下:

<div id="test" style="margin:100px;background-color:#3e3;width:100px;height:100px;">

        </div>

對于這個問題一般有兩種思路,這兩種思路都會利用事件冒泡這一原理,想要詳細了解Javascript事件機制可以看看JavaScript與HTML交互――事件,這不是本文重點,所以這里只是簡單介紹一下事件冒泡,

事件冒泡

IE的事件冒泡:事件開始時由最具體的元素接收,然后逐級向上傳播到較為不具體的元素

Netscape的事件捕獲:不太具體的節點更早接收事件,而最具體的元素最后接收事件,和事件冒泡相反

DOM事件流:DOM2級事件規定事件流包括三個階段,事件捕獲階段,處于目標階段,事件冒泡階段,首先發生的是事件捕獲,為截取事件提供機會,然后是實際目標接收事件,最后是冒泡句階段。

Opera、Firefox、Chrome、Safari都支持DOM事件流,IE不支持事件流,只支持事件冒泡

如有以下html,點擊div區域,按照不同的模型事件元素的click事件觸發順序如下所示:

復制代碼 代碼如下:

<!DOCTYPE html >
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <title>Test Page</title>
</head>
<body>
    <div>
        Click Here</div>
</body>
</html>




在觸發DOM上的某個事件的時候會產生一個事件對象event,這個對象包含著所有與事件有關的信息,包括產生事件的元素、事件類型等相關信息。所有瀏覽都支持event對象,但支持方式不同。事件對象有一個方法(W3C:stopPropagation)/屬性(IE:cancelBulle=true)可以阻止事件繼續冒泡或捕獲。我們如果想在事件冒泡到某元素時阻止冒泡可以寫一個這樣的兼容瀏覽器方法:

復制代碼 代碼如下:

function stopPropagation(e) {//把事件對象傳入
            if (e.stopPropagation) //支持W3C標準
                e.stopPropagation();
            else //IE8及以下瀏覽器
                e.cancelBubble = true;
        }

因為所有的瀏覽器都支持事件冒泡,瀏覽器兼容性考慮,我們一般綁定事件的的時候都會利用事件冒泡而不是事件捕獲。了解了這個之后我們可以看看下面兩種思路了。

思路一
第一種思路分兩步

第一步:對document的click事件綁定事件處理程序,使其隱藏該div

第二步:對div的click事件綁定事件處理程序,阻止事件冒泡,防止其冒泡到document,而調用document的onclick方法隱藏了該div。

復制代碼 代碼如下:

<script type="text/javascript">
            function stopPropagation(e) {
                if (e.stopPropagation)
                    e.stopPropagation();
                else
                    e.cancelBubble = true;
            }

            $(document).bind('click',function(){
                $('#test').css('display','none');
            });

            $('#test').bind('click',function(e){
                stopPropagation(e);
            });
        </script>

這樣當點擊頁面非div區域的時候,直接或層層冒泡會調用document的onclick方法,隱藏該div,而點擊div或其子元素的時候,事件總會冒泡的div本身,這時候會阻止事件繼續冒泡,不會調用doument的onclick方法致使div被隱藏,從而完成了我們的需求。

思路二

我們之前提到,在觸發DOM上的某個事件的時候會產生一個事件對象event,這個對象包含著所有與事件有關的信息,包括產生事件的元素、事件類型等相關信息,思路一中div的click事件處理程序傳入的參數就是這個event對象。訪問IE中的event對象有幾種不同的方式,取決于指定事件處理程序的方法。直接為DOM元素添加事件處理程序時,event對象作為window對象的一個屬性存在。

event對象包含了一個重要屬性:target(W3C)/srcElement(IE),這個屬性標識了觸發事件的原始元素,思路二就是要利用這個屬性。我們可以直接對document的click事件綁定事件處理程序,在事件處理程序中判讀事件源是否為id==test的div元素或其子元素,如果是則方法return不做操作,如果不是則隱藏該div。

復制代碼 代碼如下:

<script type="text/javascript">
            $(document).bind('click',function(e){
                var e = e || window.event; //瀏覽器兼容性
                var elem = e.target || e.srcElement;
                while (elem) { //循環判斷至跟節點,防止點擊的是div子元素
                    if (elem.id && elem.id=='test') {
                        return;
                    }
                    elem = elem.parentNode;
                }

                $('#test').css('display','none'); //點擊的不是div或其子元素
            });
        </script>

這樣當點擊頁面任何地方的時候都會層層冒泡至document的click事件,事件處理程序會判斷事件源是否為id==test的div或其子元素,如果是方法return,否則隱藏該div,也能夠實現我們的需求。

注意點及優劣

這兩種思路都依賴于事件冒泡,所以我們在處理其它相關元素的click事件的時候一定要注意這點,避免其他相關元素的click事件處理程序中包含阻止事件冒泡代碼而影響了該功能。

這兩種方式都很容易理解,貌似思路一更優秀一些,看起來它的處理更簡單一些,不用去層層判斷事件源,直接把click事件綁定在該div上。在這個例子中確實如此,但是有些復雜的頁面就不盡然了,假如我們有一個頁面,上面有數十個div都需要點擊頁面其它地方隱藏這類問題

復制代碼 代碼如下:

<div class="dialogs">
        <div class="dialog">
            <div id="1">1</div>
            <div id="2">2</div>
        </div>
        <div class="dialog">
            <div id="1">1</div>
            <div id="2">2</div>
        </div>
        <div class="dialog">
            <div id="1">1</div>
            <div id="2">2</div>
        </div>
        ...
    </div>

我們用思路一寫出的代碼可能是這樣:

復制代碼 代碼如下:

<script type="text/javascript">
            function stopPropagation(e) {
                if (e.stopPropagation)
                    e.stopPropagation();
                else
                    e.cancelBubble = true;
            }

            $(document).bind('click',function(){
                $('.dialog').css('display','none');
            });

            $('.dialog').bind('click',function(e){
                stopPropagation(e);
            });

        </script>

看起來簡單依舊的樣子,但是我們仔細想想就會發現問題,我們在每個dialog上都綁定了類似的方法,維護如此多的click事件處理程序對內存來說絕對是可開銷,導致我們頁面運行緩慢。而且如果我們可以動態使用ajax創建新dialog問題又來了,新創建的dialog不能實現隱藏功能!因為綁定函數已經執行完了,不會再為新的dialog綁定click事件處理程序,我們只能自己來做此事。也就是說思路一無法把處理程序附加到可能還未存在于DOM中的DOM元素之上。因為它是直接把處理程序綁定到各個元素上,它不能把處理程序綁定到還未存在于頁面中的元素之上。

這時候就是思路二展示身手的時候了,我們看看思路二在這種時候代碼的書寫

復制代碼 代碼如下:

<script type="text/javascript">
            $(document).bind('click',function(e){
                var e = e || window.event;
                var elem = e.target || e.srcElement;
                while (elem) {
                    if (elem.className && elem.className.indexOf('dialog')>-1) {
                        return;
                    }
                    elem = elem.parentNode;
                }

                $('#test').css('display','none');
            });
        </script>

改動也相當的小,我們來看看是不是能解決上邊的兩個問題了,首先無論多少個dialog我們只是綁定了一個click事件處理程序,對性能影響不大,添加一個新的dialog思路二的代碼還好不好使呢,依舊好使,這樣我們就能發現在復雜頁面的情況下實際上思路二是一種更優秀的解決方案。

這些都明白了,我們就能說說本文的第二個主角jQuery的delegate方法了。

delegate
首先看看jQuery官方對delegate的語法及描述

.delegate( selector, eventType, handler(eventObject) )

Description: Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.

delegate() 方法為指定的元素(屬于被選元素的子元素)添加一個或多個事件處理程序,并規定當這些事件發生時運行的函數。

使用 delegate() 方法的事件處理程序適用于當前或未來的元素(比如由腳本創建的新元素)。

復制代碼 代碼如下:

$( "table" ).delegate( "td", "click", function() {
      $( this ).toggleClass( "chosen" );
    });

    通過上面語句我們就可以為所有table的td綁定click事件處理程序。

delegate方法設計意圖在于把處理程序附加到單個元素上或是一小組元素之上,監聽后代元素上的事件而不是循環遍歷并把同一個函數逐個附加到DOM中的多個個元素上。把處理程序附加到一個(或是一小組)祖先元素上而不是直接把處理程序附加到頁面中的所有元素上,從而帶來性能上的優化。

jQuery版隱藏dialog

通過上面知識我們可以發現jQuery的delegate方法可以方便實現我們隱藏div的需求

復制代碼 代碼如下:

<script type="text/javascript">
            $('.dialogs').delegate('.dialog','click',function(){
                $(this).css('display','none');
            });
        </script>

 使用jQuery我們發現比我們思路二在性能上又有了小幅提升,因為我們不需要冒泡至document處理了,只需要在dialog的父元素就可以處理完成了,可以不至于把很多類似功能都綁定到document上,需要注意的一點就是jQuery已經貼心的幫我們把this處理為事件源,處理起來更是如魚得水了。

delegate與bind
通過上面我們說一堆我們可以在權衡使用bind還是delegate上有一定依據了,如果就單獨綁定一個元素的事件處理程序,用bind還是很合適的,但是如果處理很多類似元素的事件處理程序的時候不妨考慮一下delegate,看看是否對提高性能有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产视频综合在线| 欧美成人一区在线| 欧美日韩中文在线观看| 性欧美在线看片a免费观看| 欧美成人午夜免费视在线看片| 91视频国产精品| 欧美不卡视频一区发布| 91国偷自产一区二区三区的观看方式| 欧美激情第99页| 日韩精品在线观看一区二区| 亚洲全黄一级网站| 欧美激情高清视频| 亚洲aa中文字幕| 亚洲最大激情中文字幕| 成人h片在线播放免费网站| 国产精品一区二区电影| 韩国视频理论视频久久| 欧美亚洲国产精品| 91精品国产91久久久久久不卡| 国产精品视频区1| 国产精品丝袜高跟| 亚洲丝袜av一区| 日韩在线欧美在线国产在线| 成人www视频在线观看| 久久久精品影院| 午夜精品蜜臀一区二区三区免费| 国产欧美一区二区三区久久人妖| 国产精品一区专区欧美日韩| 亚洲国产精品久久久久久| 色噜噜狠狠狠综合曰曰曰| 成人美女av在线直播| 亚洲男人的天堂在线| 日韩中文字幕免费视频| 午夜精品国产精品大乳美女| 国产精品h片在线播放| 国产精品久久久久9999| 欧美精品久久久久久久| 精品亚洲aⅴ在线观看| 国内揄拍国内精品少妇国语| 亚洲人免费视频| 久久五月天综合| 久久久久久九九九| 成人xvideos免费视频| 91青草视频久久| 青青a在线精品免费观看| 日韩电影在线观看永久视频免费网站| 日日狠狠久久偷偷四色综合免费| 亚洲人成网站在线播| 欧美一级电影免费在线观看| 日产日韩在线亚洲欧美| 欧美极品少妇xxxxⅹ裸体艺术| 福利视频一区二区| 国产精品美女www| 亚洲欧美另类人妖| 国产精品久久久久久亚洲调教| 亚洲欧美日韩精品久久奇米色影视| 久久激情视频久久| 亚洲精品成人久久久| 久久综合伊人77777尤物| 午夜精品一区二区三区av| 精品亚洲精品福利线在观看| 一区二区三区国产视频| 精品国产老师黑色丝袜高跟鞋| 欧美最猛性xxxxx免费| 精品国产999| 精品久久久在线观看| 久久久亚洲精品视频| 国产精品稀缺呦系列在线| 91精品国产一区| 亚洲美女视频网站| 精品国产一区二区在线| 国产精品成人av在线| 日韩成人久久久| 欧美极品少妇xxxxx| 成人久久一区二区| 久久天天躁狠狠躁老女人| 欧美精品一区二区三区国产精品| 亚洲精品永久免费| 中文字幕国产精品| 日韩精品极品视频| 久久成人综合视频| 一本色道久久综合亚洲精品小说| 不卡毛片在线看| 亚洲va欧美va国产综合剧情| 欧美亚洲另类在线| 久久国产精品视频| 丝袜亚洲欧美日韩综合| 黄色成人av网| 亚洲欧美日韩在线一区| 欧美亚洲激情在线| 日韩欧美一区二区三区久久| 欧美性猛交xxxx乱大交| 欧美日韩国产成人高清视频| 日韩福利在线播放| 久久精品视频免费播放| 国产精品一区二区久久| 亚洲人成亚洲人成在线观看| 在线观看欧美成人| 欧美丝袜第一区| 富二代精品短视频| 国产精品jizz在线观看麻豆| 亚州国产精品久久久| 日韩精品视频三区| 成人福利在线视频| 精品国产鲁一鲁一区二区张丽| 最新69国产成人精品视频免费| 欧美视频二区36p| 成人免费网站在线观看| 国产精品国产三级国产aⅴ浪潮| 日韩精品在线免费播放| 5278欧美一区二区三区| 国语自产精品视频在免费| 成人精品一区二区三区电影黑人| 大胆欧美人体视频| 中文字幕视频在线免费欧美日韩综合在线看| 成人情趣片在线观看免费| 国产精品一区二区在线| 日韩在线视频免费观看高清中文| 91精品视频在线| 久久综合九色九九| 精品国内亚洲在观看18黄| 亚洲日本aⅴ片在线观看香蕉| 久久久这里只有精品视频| 国产精品视频xxxx| 夜夜嗨av一区二区三区免费区| 亚洲精品720p| 国产成人福利夜色影视| 精品久久久久久久久久久久| 伊是香蕉大人久久| 国产精品美女久久久免费| 亚洲男人天堂2024| 97**国产露脸精品国产| 欧美日韩成人在线观看| 91嫩草在线视频| 日韩av在线免费播放| 欧美成人精品激情在线观看| 青青青国产精品一区二区| 亚洲美女性视频| 久久国产色av| 在线观看亚洲视频| 国产精品扒开腿爽爽爽视频| 粉嫩av一区二区三区免费野| 在线播放国产精品| 国产精品扒开腿做爽爽爽视频| 亚洲一区二区三区乱码aⅴ| 久久精品视频在线观看| 亚洲成**性毛茸茸| 日韩最新免费不卡| 亚洲精品中文字幕女同| 国产精品久久97| 久久影院资源网| 91福利视频在线观看| 欧美大片免费看| 中文字幕精品一区二区精品| 2019日本中文字幕| 中文字幕在线亚洲| 热99久久精品| 日韩av在线免播放器| xvideos成人免费中文版| 亚洲激情视频网| 亚洲free嫩bbb| 成人av电影天堂| 欧美老少做受xxxx高潮| 尤物yw午夜国产精品视频明星|