【記】input type為checkbox或radio時的click默認事件


  在input中,如果type為checkbox或radio時,瀏覽器會將該input渲染成為系統的單選或多選組件,如果這時,我們在這個input上綁定click事件,那就要小心謹慎使用e.preventDefault()這個方法(jQuery中整合了這個方法使得它能夠兼容去掉瀏覽器中的默認事件)。之所以要說謹慎使用,就是,如果你在這個事件的響應程序中判斷該checkbox是否選中時,得到的結果和真正的選中狀態會有所不同。下面先從一個簡單的示例說明這個現象。(為了簡單起見,我使用了jquery,他能節省選擇器部分的代碼,但不影響本文需要說明的問題)。代碼段如下:

<script type="text/javascript">
window.onload=function(){ $('#chk').on('click',function(e){ e.preventDefault(); alert($(this).attr('checked')); }); } </script> </head> <body> <input type="checkbox" id="chk" /> </body>

  示例很簡單,就是在一個checkbox上綁定一個click事件,這個click事件是判斷當前的checkbox是否選上了。通過在瀏覽器上實際運行,結果是,在鼠標點擊checkbox的時候,彈出checked。但是關掉alert之后,頁面上的checkbox是未選中的狀態。我們將這個form提交到后台也是取不到值的。既然沒選上,那我們在alert的后面加上這句:$(this).attr('checked',true);讓它選上,刷新下,再點擊,你會發現,在我們關閉alert之后,頁面上的checkbox仍然是未選中的。問題就在這,我們通過程序選中了checkbox,為什么在響應函數執行完之后,checkbox還是未選中的狀態呢?

  為解釋這個問題,我們需要修改上面的代碼:

window.onload=function(){
    $('#chk').on('click',function(e){
        e.preventDefault();
        $(this).attr('checked',true);
        alert($(this).attr('checked'));
    });
}

上面的代碼我們先將設置check為true的語句放到alert前面,運行下看看,當我們點擊checkbox時:

  可以看到,在執行完$(this).attr('checked',true);后到alert時,checkbox的狀態是選中的,而且彈出的狀態也是checked,也就是說,這個時候,checkbox是選中的。但是為什么我們在點擊確定之后,checkbox又變回了未選中了呢?在相應事件結束之后,一定還有什么東西讓它改回去了?其實,這是checkbox的默認click事件的做的。也許大家會問,我不是通過e.preventDefault()把默認事件去掉了嗎?為什么還有默認事件?難道e.preventDefault()沒有生效?

  在這里需要說明下:一般的默認事件,會在我們綁定的響應事件之后執行(這樣說不准確,默認事件和自己綁定的響應事件是在一起執行的,只不過,它的真正的作用一般會在所有事件內容做完之后才會體現出來,因此,在這就簡單理解成在綁定的事件之后執行吧)。有了這個說明,我們再來說下這個現象。這不是瀏覽器的bug,也不是沒有禁掉默認事件。由於checkbox是系統的組件,因此它的實現機理比較復雜,在這里不討論,這個問題的主要原因是:checkbox的click事件的默認事件是將修改的選中狀態生效。解釋一下,如果在鼠標點擊之前,checkbox的狀態是選中,那么在點擊checkbox時,它會將當前的狀態取反即取消選中,然后執行響應事件,最后默認事件將這個狀態生效。

  上面的這個代碼中,由於去掉了默認事件,因此,在執行響應事件時,checkbox確實選中了,alert出來的也是選中的,但是在事件結束時,由於沒有沒有默認事件,那么這個checkbox就回到了點擊之前的狀態。我們如果將input寫成:<input type="checkbox" id="chk" checked />,即在點擊之前就選中它,那么點擊之后,checkbox就是選中的狀態了。當然,這個選中狀態不是因為$(this).attr('checked',true);造成的,而是沒有默認事件,它又重置回之前的狀態了。這里我們將代碼改成$(this).attr('checked',false);在執行完之后,仍然會是選中狀態的。

  這個問題充分體現出了默認事件的重要性,我們之前去掉過很多默認事件,但是大部分的默認事件如我們想象的那樣,去掉之后,基本功能就不存在了。但是checkbox的click默認事件不是讓它沒有反應,而是將修改后的狀態生效(注意:僅僅是click事件,mousedown和mouseup事件是沒有這個特點的)。因此,在我們不知道這個問題之前,如果禁掉了它的click事件,就會出現一些問題了。當然,這知識針對checkbox和radio而言。w3c的文檔也證實了這一點,它的文檔上有明確的說明:

Note: During the handling of a click event on an input element with a type attribute that has the value "radio" or "checkbox", some implementations may change the value of this property before the event is being dispatched in the document. If the default action of the event is canceled, the value of the property may be changed back to its original value. This means that the value of this property during the handling of click events is implementation dependent.

原文地址:http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-6043025


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM