成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

QT WebKit鼠標引發事件處理

移動開發
QT WebKit鼠標引發事件處理是本文要介紹的內容,主要是來學習QT WebKit的事件處理的機制,以鼠標事件為案例,具體內容的詳解來看本文。

QT WebKit鼠標引發事件處理是本文要介紹的內容,主要是來學習QT WebKit事件處理的機制,以鼠標事件為案例,具體內容的詳解來看本文。先來貼個圖,來看:

QT WebKit鼠標引發事件處理

Figure 1. JavaScript onclick event

先看一段簡單的HTML文件。在瀏覽器里打開這個文件,將看到兩張照片。把鼠標移動到第一張照片,點擊鼠標左鍵,將自動彈出一個窗口,上書“World”。但是當鼠標移動到第二張照片,或者其它任何區域,點擊鼠標,卻沒有反應。關閉“World”窗口,自動彈出第二個窗口,上書“Hello”。

  1. <html> 
  2.   <script type="text/javascript"> 
  3.     function myfunction(v)  
  4.     {  
  5.       alert(v)  
  6.     }  
  7.   </script> 
  8.  
  9.   <body onclick="myfunction('Hello')"> 
  10.     <p> 
  11.     <img onclick="myfunction('World')" height="250" width="290" 
  12. src="http://www.dirjournal.com/info/wp-content/uploads/2009/02/antarctica_mountain_mirrored.jpg"> 
  13.     <p> 
  14.     <img height="206" width="275" 
  15. src="http://media-cdn.tripadvisor.com/media/photo-s/01/26/f4/eb/hua-shan-hua-mountain.jpg"> 
  16.   </body> 
  17. </html> 

這段HTML文件沒有什么特別之處,所有略知一點HTML的人,估計都會寫。但是耳熟能詳,未必等于深入了解。不妨反問自己幾個問題,

1、瀏覽器如何知道,是否鼠標的位置,在第一個照片的范圍內?

2、假如修改一下HTML文件,把第一張照片替換成另一張照片,前后兩張照片的尺寸不同。在瀏覽器里打開修改后的文件,我們會發現,能夠觸發彈出窗口事件的區域面積,隨著照片的改變而自動改變。瀏覽器內部,是通過什么樣的機制,自動識別事件觸發區域的?

3、Onclick 是HTML的元素屬性(Element attribute),還是JavaScript的事件偵聽器(EventListener)?換而言之,當用戶點擊鼠標以后,負責處理onclick事件的,是Webkit 還是JavaScript Engine?

4、Alert() 是HTML定義的方法,還是JavaScript提供的函數?誰負責生成那兩個彈出的窗口,是Webkit還是JavaScript Engine?

5、注意到有兩個onclick="myfunction(...)",當用戶在第一張照片里點擊鼠標的時候,為什么是先后彈出,而不是同時彈出?

6、除了PC上的瀏覽器以外,手機是否也可以完成同樣的事件及其響應?假如手機上沒有鼠標,但是有觸摸屏,如何把onclick定義成用手指點擊屏幕?

7、為什么需要深入了解這些問題? 除了滿足好奇心以外,還有沒有其它目的?

QT WebKit鼠標引發事件處理

Figure 2. Event callback stacks

當用戶點擊鼠標,在OS語匯里,這叫發生了一次中斷(interrupt)。系統內核(kernel) 如何偵聽以及處理interrupt,不妨參閱“Programming Embedded Systems” 一書,Chapter 8. Interrupts。這里不展開介紹,有兩個原因,1. 這些內容很龐雜,而且與本文主題不太相關。2. 從Webkit角度看,它不必關心interrupt 以及interrupt handling 的具體實現,因為Webkit建筑在GUI Toolkit之上,而GUI Toolkit已經把底層的interrupt handling,嚴密地封裝起來。Webkit只需要調用GUI Toolkit 的相關APIs,就可以截獲鼠標的點擊和移動,鍵盤的輸入等等諸多事件。所以,本文著重討論Figure 2 中,位于頂部的Webkit和JavaScript兩層。

不同的操作系統,有相應的GUI Toolkit。GUI Toolkit提供一系列APIs,方便應用程序去管理各色窗口和控件,以及鼠標和鍵盤等等UI事件的截獲和響應。

1、微軟的Windows操作系統之上的GUI Toolkit,是MFC(Microsoft Fundation Classes)。

2、Linux操作系統GNOME環境的GUI Toolkit,是GTK+.

3、Linux KDE環境的,是QT。

4、Java的GUI Toolkit有兩個,一個是Sun Microsystem的Java Swing,另一個是IBM Eclipse的SWT。
 
Swing對native的依賴較小,它依靠Java 2D來繪制窗口以及控件,而Java 2D對于native的依賴基本上只限于用native library畫點畫線著色。 SWT對native的依賴較大,很多人把SWT理解為Java通過JNI,對MFC,GTK+和QT進行的封裝。這種理解雖然不是百分之百準確,但是大體上也沒錯。

有了GUI Toolkit,應用程序處理鼠標和鍵盤等等UI事件的方式,就簡化了許多,只需要做兩件事情。1. 把事件來源(event source),與事件處理邏輯(event listener) 綁定。2. 實現事件處理邏輯的細節。

Figure 3 顯示的是Webkit如何綁定event source和event listener。Figure 4 顯示的是Webkit如何調用JavaScript Engine,解析并執行事件處理邏輯。首先看看event source,注意到在HTML文件里有這么一句,

  1. <img onclick="myfunction('World')" height="250" width="290"  src=".../antarctica_mountain_mirrored.jpg"> 

這句話里“<img>”標識告訴Webkit,需要在瀏覽器頁面里擺放一張照片,“src”屬性明確了照片的來源,“height, width”明確了照片的尺寸。“onclick”屬性提醒Webkit,當用戶把鼠標移動到照片顯示的區域,并點擊鼠標時(onclick),需要有所響應。響應的方式定義在“onclick”屬性的值里面,也就是“myfunction('World')”。

當Webkit解析這個HTML文件時,它依據這個HTML文件生成一棵DOM Tree,和一棵Render Tree。對應于這一句<img>語句,在DOM Tree里有一個HTMLElement節點,相應地,在Render Tree里有一個RenderImage節點。在layout() 過程結束后,根據<img>語句中規定的height和width,確定了RenderImage的大小和位置。由于 Render Tree的RenderImage節點,與DOM Tree的HTMLElement節點一一對應,所以HTMLElement節點所處的位置和大小也相應確定。

因為onclick事件與這個HTMLElement節點相關聯,所以這個HTMLElement節點的位置和大小確定了以后,點擊事件的觸發區域也就自動確定。假如修改了HTML 文件,替換了照片,經過layout() 過程以后,新照片對應的HTMLElement節點,它的位置和大小也自動相應變化,所以,點擊事件的觸發區域也就相應地自動變化。

在onclick屬性的值里,定義了如何處理這個事件的邏輯。有兩種處理事件的方式,1. 直接調用HTML DOM method,2. 間接調用外設的Script。onclick="alert('Hello')",是第一種方式。alert()是W3C制訂的標準的 HTML DOM methods之一。除此以外,也有稍微復雜一點的methods,譬如可以把這一句改成,<img onclick="document.write('Hello')">。本文的例子,onclick="myfunction('world')",是第二種方式,間接調用外設的Script。

外設的script有多種,最常見的是JavaScript,另外,微軟的VBScript和Adobe的ActionScript,在一些瀏覽器里也能用。即便是JavaScript,也有多種版本,各個版本之間,語法上存在一些差別。為了消弭這些差別,降低JavaScript使用者,以及 JavaScript Engine開發者的負擔,ECMA(歐洲電腦產聯)試圖制訂一套標準的JavaScript規范,稱為ECMAScript。

各個瀏覽器使用的JavaScript Engine不同。

1、微軟的IE瀏覽器,使用的JavaScript Engine是JScript Engine,渲染機是Trident。

2、Firefox瀏覽器,使用的JavaScript Engine是TraceMonkey,TraceMonkey的前身是SpiderMonkey,渲染機是Gecko。TraceMonkey JavaScript Engine借用了Adobe的Tamarin的部分代碼,尤其是Just-In-Time即時編譯機的代碼。而Tamarin也被用在Adobe Flash的Action Engine中。

3、Opera瀏覽器,使用的JavaScript Engine是Futhark,它的前身是Linear_b,渲染機是Presto。

4、Apple的Safari瀏覽器,使用的JavaScript Engine是SquirrelFish,渲染機是Webkit。

5、Google的Chrome瀏覽器,使用的JavaScript Engine是V8,渲染機也是Webkit。

6、Linux的KDE和GNOME環境中可以使用Konqueror瀏覽器,這個瀏覽器使用的JavaScript Engine是JavaScriptCore,前身是KJS,渲染機也是Webkit。

同樣是Webkit渲染機,可以調用不同的JavaScript Engine。之所以能做到這一點,是因為Webkit的架構設計,在設置JavaScript Engine的時候,利用代理器,采取了松散的調用方式

QT WebKit鼠標引發事件處理

Figure 3. The listener binding of Webkit

Figure 3 詳細描繪了Webkit 設置JavaScript Engine 的全過程。在Webkit 解析HTML文件,生成DOM Tree 和Render Tree 的過程中,當解析到 <img onclick="..." src="..."> 這一句的時候,生成DOM Tree中的 HTMLElement 節點,以及Render Tree 中 RenderImage 節點。如前文所述。在生成HTMLElement 節點的過程中,因為注意到有onclick屬性,Webkit決定需要給 HTMLElement 節點綁定一個 EventListener,參見Figure 3 中第7步。

Webkit 把所有EventListener 的創建工作,交給Document 統一處理,類似于 Design Patterns中,Singleton 的用法。也就是說,DOM Tree的根節點 Document,掌握著這個網頁涉及的所有EventListeners。 有趣的是,當Document 接獲請求后,不管針對的是哪一類事件,一律讓代理器 (kjsProxy) 生成一個JSLazyEventListener。之所以說這個實現方式有趣,是因為有幾個問題需要特別留意,

1、一個HTMLElement節點,如果有多個類似于onclick的事件屬性,那么就需要多個相應的EventListener object instances與之綁定。

2、每個節點的每個事件屬性,都對應一個獨立的EventListener object instance。不同節點不共享同一個 EventListener object instance。即便同一個節點中,不同的事件屬性,對應的也是不同的EventListener object instances。

這是一個值得批評的地方。不同節點不同事件對應彼此獨立的EventListener object instances,這種做法給不同節點之間的信息傳遞,造成了很大障礙。反過來設想一下,如果能夠有一種機制,讓同一個object instance,穿梭于多個HTMLElement Nodes之間,那么瀏覽器的表現能力將會大大增強,屆時,將會出現大量的前所未有的匪夷所思的應用。

3、DOM Tree的根節點,Document,統一規定了用什么工具,去解析事件屬性的值,以及執行這個屬性值所定義的事件處理邏輯。如前文所述,事件屬性的值,分成HTML DOM methods 和JavaScript 兩類。但是不管某個HTMLElement節點的某個事件屬性的值屬于哪一類,Document 一律讓 kjsProxy代理器,生成一個 EventListener。

看看這個代理器的名字就知道,kjsProxy生成的 EventListener,一定是依托JavaScriptCore Engine,也就是以前的KJS JavaScript Engine,來執行事件處理邏輯的。核實一下源代碼,這個猜想果然正確。

4、如果想把JavaScriptCore 替換成其它JavaScript Engine,例如Google 的V8,不能簡單地更改configuration file,而需要修改一部分源代碼。所幸的是,Webkit的架構設計相當清晰,所以需要改動部分不多,關鍵部位是把 Document.{h,cpp} 以及其它少數源代碼中,涉及kjsProxy 的部分,改成其它Proxy即可。

5、kjsProxy 生成的EventListener,是JSLazyEventListener。解釋一下JSLazyEventListener 命名的寓意,JS容易理解,意思是把事件處理邏輯,交給JavaScript engine 負責。所謂 lazy 指的是,除非用戶在照片顯示區域點擊了鼠標,否則,JavaScript Engine 不主動處理事件屬性的值所規定的事件處理邏輯。

與 lazy做法相對應的是JIT即時編譯,譬如有一些JavaScript Engine,在用戶尚沒有觸發任何事件以前,預先編譯了所有與該網頁相關的JavaScript,這樣,當用戶觸發了一個特定事件,需要調用某些 JavaScript functions時,運行速度就會加快。當然,預先編譯會有代價,可能會有一些JavaScript functions,雖然編譯過了,但是從來沒有被真正執行過。

QT WebKit鼠標引發事件處理

Figure 4. The event handling of Webkit

當解析完HTML文件,生成了完整的DOM Tree 和Render Tree 以后,Webkit就準備好去響應和處理用戶觸發的事件了。響應和處理事件的整個流程,如Figure 4所描述。整個流程分成兩個階段,

1、尋找 EventTargetNode。

當用戶觸發某個事件,例如點擊鼠標,根據鼠標所在位置,從Render Tree的根節點開始,一路搜索到鼠標所在位置對應的葉子節點。Render Tree根節點對應的是整個瀏覽器頁面,而葉子節點對應的區域面積最小。

從Render Tree根節點,到葉子節點,沿途每個Render Tree Node,都對應一個DOM Tree Node。這一串DOM Tree Nodes中,有些節點響應用戶觸發的事件,另一些不響應。例如在本文的例子中,<body> tag 對應的DOM Tree Node,和第一張照片的<img> tag 對應的DOM Tree Node,都對onclick事件有響應。

第一階段結束時,Webkit得到一個EventTargetNode,這個節點是一個DOM Tree Node,而且是對事件有響應的DOM Tree Node。如果存在多個DOM Tree Nodes對事件有響應,EventTargetNode是那個最靠近葉子的中間節點。

2、執行事件處理邏輯。

如果對于同一個事件,有多個響應節點,那么JavaScript Engine 依次處理這一串節點中,每一個節點定義的事件處理邏輯。事件處理邏輯,以字符串的形式定義在事件屬性的值中。在本文的例子中,HTML文件包含<img onclick="myfunction('World')">,和<body onclick="myfunction('Hello')">,這意味著,有兩個DOM Tree Nodes 對onclick事件有響應,它們的事件處理邏輯分別是myfunction('World') 和myfunction('Hello'),這兩個字符串。

當JavaScript Engine 獲得事件處理邏輯的字符串后,它把這個字符串,根據JavaScript的語法規則,解析為一棵樹狀結構,稱作Parse Tree。有了這棵Parse Tree,JavaScript Engine就可以理解這個字符串中,哪些是函數名,哪些是變量,哪些是變量值。理解清楚以后,JavaScript Engine 就可以執行事件處理邏輯了。本文例子的事件處理過程,如Figure 4中第16步,到第35步所示。

本文的例子中,“myfunction('World')" 這個字符串本身并沒有定義事件處理邏輯,而只是提供了一個JavaScript函數的函數名,以及函數的參數的值。當JavaScript Engine 得到這個字符串以后,解析,執行。執行的結果是得到函數實體的代碼。函數實體的代碼中,最重要的是alert(v) 這一句。JavaScript Engine 把這一句解析成Parse Tree,然后執行。

注意到本文例子中,對于同一個事件onclick,有兩個不同的DOM Tree Nodes 有響應。處理這兩個節點的先后順序要么由capture path,要么由bubbling path決定,如Figure 5所示。(Figure 5中對應的HTML文件,不是本文所引的例子)。在HTML文件中,可以規定event.bubbles屬性。如果沒有規定,那就按照bubbling的順序進行,所以本文的例子,是先執行<img>,彈出“World” 的窗口,關掉“World”窗口后,接著執行<body>,彈出“Hello” 的窗口。

QT WebKit鼠標引發事件處理

小結:QT WebKit鼠標引發事件處理的內容介紹完了,希望通過本文的學習能對你有所幫助!

責任編輯:zhaolei 來源: 網易博客
相關推薦

2011-09-01 15:22:16

Qt WebKitWebKit

2011-09-07 17:04:40

QT平臺模擬鼠標

2011-10-13 14:26:12

Qt WebKitWebKit

2011-06-14 11:48:38

Webkit QT

2011-07-01 14:20:59

Qt 事件

2011-07-01 14:14:34

Qt 事件

2011-08-29 10:22:48

QtWebkit 模塊HTML文檔

2011-09-09 17:24:39

Qt Webkit模塊

2009-09-02 18:34:28

C#鼠標事件

2011-08-29 10:01:27

QTWebkit插件

2011-07-04 14:38:43

QT Qevent

2011-07-04 14:50:49

QT Event 事件

2011-08-29 14:59:26

QtEvent事件

2011-08-29 14:10:03

QtWebkitFlash

2011-09-01 14:04:45

QT Webkit插件

2011-09-09 18:43:13

Qt Webkit瀏覽器

2011-08-29 14:27:33

QTWebkit瀏覽器

2011-08-29 14:19:48

QtWebkit瀏覽器

2013-09-09 16:46:38

Webkit內核

2011-08-29 14:40:58

QTWebkit
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 丝袜一区二区三区 | 色资源在线视频 | 亚洲一区二区在线播放 | 国产一级免费在线观看 | 欧美日韩91 | 毛片高清 | 成人av电影免费在线观看 | 伊人最新网址 | 日韩中文字幕一区 | 欧美一区二区三区高清视频 | 久久a久久 | 成人综合视频在线 | 国产激情视频在线观看 | 久久综合狠狠综合久久 | 亚洲精品日韩在线 | 精品欧美乱码久久久久久 | 一区二区精品在线 | 午夜视频一区二区 | 免费高清av | 日韩手机在线看片 | 7777久久| 久久一区二区三区四区 | 国产女人与拘做受免费视频 | 狠狠涩 | 天天干夜夜拍 | 国产激情在线看 | 精品一二 | 国产欧美日韩一区 | 国产激情一区二区三区 | 中文字幕视频三区 | 国产电影一区二区 | 欧美精品一二三区 | 999久久久久久久久6666 | 日韩免费电影 | 亚洲精品日韩一区二区电影 | 综合国产 | 国产精品无码专区在线观看 | 九九九久久国产免费 | 黄色欧美视频 | 可以在线看的黄色网址 | 黄视频国产|