天天看點

IE事件模型--向上冒泡

<SCRIPT>

function checkCancel()

{

window.event.cancelBubble = true;

document.write(123)

alert('abc')

}

function showSrc()

{

alert(123)

}

</SCRIPT>

</HEAD>

<BODY οnclick="showSrc()">

<input type="button" οnclick="checkCancel()" value="測試IE的向上冒泡">

 </BODY> 

IE事件模型--向上冒泡, 從觸發源到document樹對象模型dom依次觸發的過程

在dom2标準模型中可以控制向下捕捉事件的過程從document到觸發源.(IE中不支援)

 事件捕捉(capturing)的過程分三階段,第一階段就是向下捕捉, 第二目标節點,第三是事件傳播-向上(bubbling)

所有事件都受捕捉階段的控制,但向上傳播觸發的過程也有一些自已的規則

iE中停止傳播的方法是window.event.cancelBubble = true;

在fireFox中, dom2級中是stopPropagation()

=====================

注冊多個處理程式

dom 2中addEventListener()及removeEventListener()三個參數,true為僅用于捕捉事件,觸發是不bubbling,為false為正常事件,将觸發。。

ie中attachEvent及detachEvent方法

=====================================

以下為asp.net中的伺服器組合控件中的bubbling, override OnBubbleEven重寫的冒泡,為true是則允許捕捉到裡面的子控件。從傳播的角度而言,應該說是裡面的子控件可以冒泡為外面的事件。(不點不通, 暈, 為個麼不叫捕捉不更好了解嗎,難道隻是為了不引入一個新概念)

 using System;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

namespace CustomControls

{

 public class EventBubbler : Control, INamingContainer

 {

  private int number = 100;

  private Label label;

  private TextBox box1;

  private TextBox box2;

  public event EventHandler Click;

  public event EventHandler Reset;

  public event EventHandler Submit;

  public string Label

  {

   get

   {

    EnsureChildControls();

    return label.Text;

   }

   set

   {

    EnsureChildControls();

    label.Text = value;

   }

  }

  public int Number

  {

   get

   {

    return number;

   }

   set

   {

    number = value;

   }

  }

  public string Text1

  {

   get

   {

    EnsureChildControls();

    return box1.Text;

   }

   set

   {

    EnsureChildControls();

    box1.Text = value;

   }

  }

  public string Text2

  {

   get

   {

    EnsureChildControls();

    return box2.Text;

   }

   set

   {

    EnsureChildControls();

    box2.Text = value;

   }

  }

  protected override void CreateChildControls()

  {

   Controls.Add(new LiteralControl("<h3>Enter a number : "));

   box1 = new TextBox();

   box1.Text = "0";

   Controls.Add(box1);

   Controls.Add(new LiteralControl("</h3>"));

   Controls.Add(new LiteralControl("<h3>Enter another number : "));

   box2 = new TextBox();

   box2.Text = "0";

   Controls.Add(box2);

   Controls.Add(new LiteralControl("</h3>"));

   Button button1 = new Button();

   button1.Text = "Click";

   button1.CommandName = "Click";

   Controls.Add(button1);

   Button button2 = new Button();

   button2.Text = "Reset";

   button2.CommandName = "Reset";

   Controls.Add(button2);

   Button button3 = new Button();

   button3.Text = "Submit";

   button3.CommandName = "Submit";

   Controls.Add(button3);

   Controls.Add(new LiteralControl("<br><br>"));

   label = new Label();

   label.Height = 50;

   label.Width = 500;

   label.Text = "Click a button.";

   Controls.Add(label);

  }

  protected override bool OnBubbleEvent(object source, EventArgs e)

  {  

   bool handled = false;

   if (e is CommandEventArgs)

   {

    CommandEventArgs ce = (CommandEventArgs)e;

    if (ce.CommandName == "Click")

    {

     OnClick(ce);

     handled = true;  

    } 

    else if (ce.CommandName == "Reset")

    {

     OnReset(ce);

     handled = true;  

    }

    else if (ce.CommandName == "Submit")

    {

     OnSubmit(ce);

     handled = true;  

    }

   }

   return handled;           

  }

  protected virtual void OnClick (EventArgs e)

  {

   if (Click != null)

   {

    Click(this,e);

   }

  }

  protected virtual void OnReset (EventArgs e)

  {

   if (Reset != null)

   {

    Reset(this,e);

   }

  }

  protected virtual void OnSubmit (EventArgs e)

  {

   if (Submit != null)

   {

    Submit(this,e);

   }

  } 

 }

}

==================

<%@ Register TagPrefix="Custom" Namespace="CustomControls" Assembly = "CNTO_WebControls" %>

<HTML>

<META http-equiv="Content-Type" content="text/html; charset=utf-8">

<script language="C#" runat="server">

private void ClickHandler(Object sender,EventArgs e)

{

MyControl.Label = "You clicked the <b> Click </b> button";

}

private void ResetHandler(Object sender,EventArgs e)

{

MyControl.Text1 = "0";

MyControl.Text2 = "0";

}

private void SubmitHandler(Object sender,EventArgs e)

{

if ( Int32.Parse(MyControl.Text1) + Int32.Parse(MyControl.Text2) == MyControl.Number)

MyControl.Label = "<h2> You won a million dollars!!!! </h2>";

else

MyControl.Label = "Sorry, try again. The numbers you entered don't add up to" +

" the hidden number.";

}

</script>

<body>

<h1>

The Mystery Sum Game

</h1>

<br>

<form runat="server" ID="Form1">

<Custom:EventBubbler id="MyControl" OnClick="ClickHandler" OnReset="ResetHandler" OnSubmit="SubmitHandler"

Number="10" runat="server" />

</form>

</body>

</HTML>

========================

A 事件流(event flow )

事件模型分為兩種:冒泡型事件、捕獲型事件。

冒泡型(dubbed bubbling )事件:指事件按照從最精确的對象到最不精确的對象的順序逐一觸發。

捕獲型(event capturing )事件:它與冒泡型事件相反,指事件按照從最不精确的對象到最精确的對象的順序逐一觸發。

捕獲型事件也被稱作自頂向下(DOM層次)的事件模型。

由于IE 浏覽器不支援捕獲型事件,是以并沒有被廣泛應用。

B 事件監聽

i > 通用監聽方法

示例一:

代碼如下:

<p οnclick="alert('點選了');">Click Me</p>

示例二:

代碼如下:

<html>

<head>

<title> demo </title>

<meta name="Author" content="xugang" />

<script type="text/javascript">

// 在onload 事件中添加所有标簽的事件

window.onload = function(){

// 找到對象

var o_p = document.getElementById("myp");

// 添加對象的onclick 事件

o_p.onclick = function(){

alert("我被點選了");

}

}

</script>

</head>

<body>

<p id="myp">Click Me</p>

</body>

</html>

此代碼實作了結構與行為的分離。

給浏覽器添加監聽方法,分為兩種:IE 中的監聽方法、标準DOM 的監聽方法。

ii > IE 中的監聽方法

在IE 浏覽器中,每個元素都有兩個方法來處理事件的監聽。分别是:attachEvent( ) 和 detachEvent( ) 。

附加事件方法:[object].attachEvent(“事件名”,方法名);

分離事件方法:[object].detachEvent(“事件名”,方法名);

如:o_p.detachEvent("onclick",click_A);

示例:

代碼如下:

<html>

<head>

<title> demo </title>

<meta name="Author" content="xugang" />

<script type="text/javascript">

<!--

function click_A(){

alert("click_A");

//删除監聽函數

o_p.detachEvent("onclick",click_B);

}

function click_B(){

alert("click_B, 我隻調用一次。");

}

var o_p;

window.onload = function(){

o_p = document.getElementById("myP");

// 添加監聽函數 click_A

o_p.attachEvent("onclick",click_A);

// 添加監聽函數 click_B

o_p.attachEvent("onclick",click_B);

}

//-->

</script>

</head>

<body>

<p id="myP">Click Me</p>

</body>

</html>

注意:

● 使用這種方式可以為同一進制素添加多個監聽函數;

● 在IE 浏覽器中,函數的執行順序與函數的添加順序相反;

● 在IE 浏覽器中,雖然函數有先後執行順序,但都會同時調用;

iii > 标準DOM 的監聽方法

在使用标準DOM 的浏覽器中,每個元素也有兩個方法來處理事件的監聽。分别是:addEventListener( ) 和 removeEventListener( ) 。

添加事件監聽方法:[object].addEventListener(“事件名”,方法名,事件模型 );

移除事件監聽方法:[object].removeEventListener(“事件名”,方法名,事件模型 );

注意:

這裡的“事件名”不能帶 on ,如:click(如果是onclick 則錯誤!)

“事件模型”為boolean 類型,通常設定為 false ,即“冒泡型”事件。(如果是true 則為“捕獲型”事件)

示例:

代碼如下:

<html>

<head>

<title> demo </title>

<meta name="Author" content="xugang" />

<script type="text/javascript">

<!--

function click_A(){

alert("click_A");

//删除監聽函數

o_p.removeEventListener("click",click_B,false);

}

function click_B(){

alert("被click_A删除, 一次都不能調用。");

}

var o_p;

window.onload = function(){

o_p = document.getElementById("myP");

// 添加監聽函數 click_A

o_p.addEventListener("click",click_A,false);

// 添加監聽函數 click_B

o_p.addEventListener("click",click_B,false);

}

//-->

</script>

</head>

<body>

<p id="myP">Click Me</p>

</body>

</html>

在Firefox 下運作通過,在IE 下報錯。

注意:

● 使用這種方式同樣可以為同一進制素添加多個監聽函數;

● 在Firefox 浏覽器中,函數的執行順序與函數的添加順序一緻(Firefox 與IE 正好相反);

● 在Firefox 浏覽器中,這種方式添加的函數是執行外一個再執行另一個(逐個執行);

繼續閱讀