利用事件冒泡和阻止事件冒泡的例子
生活随笔
收集整理的這篇文章主要介紹了
利用事件冒泡和阻止事件冒泡的例子
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
利用事件冒泡機制
頁面中的評分界面,大家一定都很熟悉,現在假如我開了一家飯店,我需要一個在我們的網頁上能讓顧客對我的飯店進行打分。首先,我們需要兩張星星的圖片,一張是灰的的星星,一張是黃色的星星,我們分別命名為star.gif和star2.gif。如下圖所示:
接下來,我們開始編寫打分程序的代碼:
<!--相關的html結構-->?<h1>費墨的飯店</h1>
?<p>hygiene</p>
?<p class="J_rate">
? <img src="star.gif" title="很爛" />
? <img src="star.gif" title="一般" />
? <img src="star.gif" title="還好" />
? <img src="star.gif" title="較好" />
? <img src="star.gif" title="很好" />
?</p>
?<p>price</p>
?<p class="J_rate">
? <img src="star.gif" title="很爛" />
? <img src="star.gif" title="一般" />
? <img src="star.gif" title="還好" />
? <img src="star.gif" title="較好" />
? <img src="star.gif" title="很好" />
?</p>
?<p>flavour</p>
?<p class="J_rate">
? <img src="star.gif" title="很爛" />
? <img src="star.gif" title="一般" />
? <img src="star.gif" title="還好" />
? <img src="star.gif" title="較好" />
? <img src="star.gif" title="很好" />
?</p>
?<script type="text/javascript">
? //DOM,event ?package
? var GLOBAL={};
? GLOBAL.namespace=function(str){
? ? var arr=str.split("."),o=GLOBAL;
? ? for(var i=(arr[0]=="GROBAL") ? 1:0; i<arr .length;i++){
? ? ? ? //相當于GLOBAL{arr[i]:{}}
? ? ? o[arr[i]]=o[arr[i]] || {};
? ? ? o=o[arr[i]];
? ? }
? }
? GLOBAL.namespace("Dom");
? GLOBAL.Dom.getElementsByClassName=function(str,root,tag){
? ? //是否存在root,并且是否已經與DOM節點掛鉤。不存在則賦于document.body
? ? if(root){
? ? ? root=typeof root=="string" ? document.getElementById("root"):root;
? ? }
? ? else{
? ? ? root=document.body;
? ? }
? ? //是否存在tag,不存在則為通配符
? ? tag=tag||"*";
? ? //在root里取得tag的數組,arr數組備用儲存結果
? ? var els=root.getElementsByTagName(tag),arr=[];
? ? //遍歷取得的每個標簽
? ? for(var i=0,n=els.length;i<n;i++){
? ? ? //遍歷標簽的每個class
? ? ? for(var j=0,k=els[i].className.split(" "),l=k.length;j<l;j++){
? ? ? ? ? //查找匹配項,并跳出遍歷className的循環
? ? ? ? if(k[j]==str){
? ? ? ? ? arr.push(els[i]);
? ? ? ? ? break;
? ? ? ? }
? ? ? }
? ? }
? ? return arr;
? }
? GLOBAL.namespace("Event");
? GLOBAL.Event.on=function(node,eventType,handler,scope){
? ? //確保node與DOM節點掛鉤
? ? node=typeof node=="string" ? document.getElementById(node) : node;
? ? scope=scope || node;
? ? //如果是IE
? ? if(document.all){
? ? ? node.attachEvent("on"+eventType,function(){handler.apply(scope,arguments)});
? ? }
? ? else{
? ? ? node.addEventListener(eventType,function(){handler.apply(scope,arguments)},false);
? ? }
? }
? function Rate(rateRoot){
? ? var root=typeof rateRoot=="string" ? document.getElementById(rateRoot) : rateRoot;
? ? var items=root.getElementsByTagName("img");
? ? var imgs=["star.gif","star2.gif"];
? ? var rateFlag;
? ? for(var i=0,n=items.length;i<n;i++){
? ? ? //記錄DOM索引
? ? ? items[i].index=i;
? ? ? //鼠標滑過效果
? ? ? GLOBAL.Event.on(items[i],"mouseover",function(){
? ? ? ? //點擊過后,直接跳出,不執行該函數
? ? ? ? if(rateFlag) return;
? ? ? ? //遍歷每個星星,如果在點擊索引位置之前的變黃色,之后的為灰色
? ? ? ? for(var j=0;j<n;j++){
? ? ? ? ? if(j<=this.index){
? ? ? ? ? ? items[j].src=imgs[1];
? ? ? ? ? }
? ? ? ? ? else{
? ? ? ? ? ? items[j].src=imgs[0];
? ? ? ? ? }
? ? ? ? }
? ? ? });
? ? ? //鼠標滑出,但未點擊,所有星星變成灰色
? ? ? GLOBAL.Event.on(items[i],"mouseout",function(){
? ? ? ? if(rateFlag) return;
? ? ? ? for(var j=0;j<n;j++){
? ? ? ? ? items[j].src=imgs[0];
? ? ? ? }
? ? ? });
? ? ? //鼠標點擊,顯示打分
? ? ? GLOBAL.Event.on(items[i],"click",function(){
? ? ? ? if(rateFlag) return;
? ? ? ? rateFLag=true;
? ? ? ? alert("您打了"+(this.index+1)+"分");
? ? ? });
? ? }
? }
? //實例化rate
? var rateNodes=GLOBAL.Dom.getElementsByClassName("J_rate");
? for(var i=0,n=rateNodes.length;i<n;i++){
? ? new Rate(rateNodes[i]);
? }
?</script>
在上述代碼中,對每個星星監聽了mouseover、mouseout和click事件。其效果等同于:
<p class="J_rate">? <img src="star.gif" title="很爛" onmouseover="..." onmouseout="..." onclick="..." />
? <img src="star.gif" title="一般" onmouseover="..." onmouseout="..." onclick="..." />
? <img src="star.gif" title="還好" onmouseover="..." onmouseout="..." onclick="..." />
? <img src="star.gif" title="較好" onmouseover="..." onmouseout="..." onclick="..." />
? <img src="star.gif" title="很好" onmouseover="..." onmouseout="..." onclick="..." />
?</p>
之前我們提到過事件冒泡,利用事件冒泡我們可以進一步優化代碼。代碼如下:
function Rate(rateRoot){? ? var root=typeof rateRoot=="string" ? document.getElementById(rateRoot) : rateRoot;
? ? var items=root.getElementsByTagName("img");
? ? var imgs=["star.gif","star2.gif"];
? ? var rateFlag;
? ? for(var i=0,n=items.length;i<n ;i++){
? ? ? //記錄DOM索引
? ? ? items[i].index=i;
? ? }
? ? //鼠標滑過效果
? ? GLOBAL.Event.on(root,"mouseover",function(e){
? ? ? //點擊過后,直接跳出,不執行該函數
? ? ? if(rateFlag) return;
? ? ? var target=e.target || e.srcElement;
? ? ? if(target.tagName.toLowerCase() !="img") return;
? ? ? //遍歷每個星星,如果在點擊索引位置之前的變黃色,之后的為灰色
? ? ? for(var i=0,n=items.length;i<n;i++){
? ? ? ? if(i<=target.index){
? ? ? ? ? items[i].src=imgs[1];
? ? ? ? }
? ? ? ? else{
? ? ? ? ? items[i].src=imgs[0];
? ? ? ? }
? ? ? }
? ? });
? ? //鼠標滑出,但未點擊,所有星星變成灰色
? ? GLOBAL.Event.on(root,"mouseout",function(e){
? ? ? if(rateFlag) return;
? ? ? var target=e.target || e.secElement;
? ? ? for(var i=0,n=items.length;i<n;i++){
? ? ? ? items[i].src=imgs[0];
? ? ? }
? ? });
? ? //鼠標點擊,顯示打分
? ? GLOBAL.Event.on(root,"click",function(e){
? ? ? if(rateFlag) return;
? ? ? rateFLag=true;
? ? ? var target=e.target || e.srcElement;
? ? ? alert("您打了"+(target.index+1)+"分");
? ? });
? }
? //實例化rate
? var rateNodes=GLOBAL.Dom.getElementsByClassName("J_rate");
? for(var i=0,n=rateNodes.length;i<n;i++){
? ? new Rate(rateNodes[i]);
? }
?</script>
冒泡的思路是在祖先節點上監聽事件,結合event.target/event.srcElement來實現最終效果,其效果等同于如下代碼:
<p class="J_rate" onmouseover="..." onmouseout="..." onclick="...">? <img src="star.gif" title="很爛" />
? <img src="star.gif" title="一般" />
? <img src="star.gif" title="還好" />
? <img src="star.gif" title="較好" />
? <img src="star.gif" title="很好" />
?</p>
利用事件冒泡機制可以讓事件掛鉤更干凈,有效減小內存的開銷。
?
阻止事件冒泡
???????? JS事件流中有一種事件被稱為“冒泡事件”,當一個元素被觸發一個事件時,該目標元素上的事件會優先被執行,然后向外傳播到每個祖先元素,恰如水里的一個泡泡似的,從產生就一直往上冒,到達水平面時,它才消失。在這個過程中,如果你只希望觸發目標元素上的事件,而不想它傳播到祖先元素上去,那么你需要在“泡泡”離開對象之前刺破它。下面,就以一個簡單的Demo來演示下JS如何阻止事件冒泡:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>js阻止事件冒泡的DEMO</title> <script type="text/javascript">//阻止冒泡的方法function stopPP(e){var evt = e || window.event;//IE用cancelBubble=true來阻止而FF下需要用stopPropagation方法evt.stopPropagation ? evt.stopPropagation() : (evt.cancelBubble=true);} </script> </head> <body> <div style="margin: 150px 400px;width: 700px; height: 550px; background-color: #878788;" οnclick="alert('最外層div上的onclick事件');"> <h2>最外層div上的onclick事件</h2> <div style="margin: 100px; width: 500px; height: 300px; background-color: #545444;" οnclick="stopPP(arguments[0]);alert('中間層div上的onclick事件');"> <h3>中間層div上的onclick事件</h3> <div style="margin: 60px 100px; height: 100px; width: 300px; background-color: red;" οnclick="stopPP(arguments[0]);alert('最內層div上的onclick事件');"> <h4>最內層div上的onclick事件”</h4> </div> </div> </div></body> </html> |
轉載于:https://www.cnblogs.com/fumj/archive/2012/10/19/2730527.html
總結
以上是生活随笔為你收集整理的利用事件冒泡和阻止事件冒泡的例子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IIS中架设二级域名网站
- 下一篇: [转载] 晓说——第31期:无比强大的美