资源信息汲取,中文輸入法與KeyDown

By admin in 4858美高梅 on 2019年4月7日

早年 HTML 的 input 輸入框,無法即時反映使用者的輸入內容。
onkeyup、onkeydown 事件,無法即時、精確地取得使用者的輸入資料;而
onchange、onblur 事件,要等到失去焦點時,或按下 Enter 時,才會被觸發。

結合 HTML5 標準事件
oninput 和 IE 專屬事件 onpropertychange 事件來監聽輸入框值變化。

资源信息汲取,中文輸入法與KeyDown。近来專案中援引了Telerik
ASP.NET擴充元件AutoComplete輸入欄位,測試時發現偶爾會不聽始喚,輸入文字時無法觸發資料查詢,在Javascript
Source Code裡反覆追蹤測試,燃燒了可觀的寶貴春青,終於理出頭緒:
問題在国语輸入法!

簡介

正文將以實際範例介紹怎么着以 JDOM 搭配 TagSoup ,將 HTML 解析為 DOM
文件物件模型,並使用 X帕特h 汲取資訊,大概將文件輸出為 XHTML 格式。

現在 HTML5 新增的 input 事件,可達成「立时、精準地觸發」,類似 AJAX
功效。唯一的缺點,是不增加援助 IE 瀏覽器,但帮忙别的各瀏覽器。

 

過去模糊地知道中文輸入在瀏覽器的鍵盤事件行為上稍稍与众分裂,但從未深究,這回算是比較清楚商量之中的差別。其實最明顯的差異是:
切到中文輸入法後,輸入文字將不會觸發KeyPress事件,只會有KeyDown,而且傳回的e.keyCode會1律是22玖。

資訊汲取

Internet 上蘊藏著豐富的內容,供人們分享訊息、傳承知識。但是在 Semantic
Web
普及在此之前,除非資料來源網站主動提供資料存取 API,否則,要擷取既有
Internet 上的資訊,還是只可以從解析 HTML 著手。

一般来说 html 程式碼,可測試出,input 事件可達成「立时、精準地觸發」;舊有的
change 事件,則须要失去焦點時,或按下 Enter 時,才會被觸發。

  oninput
是 HTML5 的標準事件,對於檢測 textarea,
input:text, input:password 和 input:search
這幾個成分通過用戶界面發生的內容變化格外有用,在內容修改後登时被觸發,不像
onchange
事件需求失去焦點才觸發。oninput 事件在主流瀏覽器的分外情況如下:

寫了1段程式來做實驗:

雜亂無章的 HTML (Malformed and faulty HTML)

可是眾所週知,纵然存在著如 XHTML
標準規範,網路上還是充斥著各種不合乎標準的 HTML
網頁。這個現象,甚至還有個專用名詞,叫做 Tag
soup。

而業界1致主张、制訂中的 HTML5
,面對這樣的現況,並非選擇像 XHTML
2.0
1樣,以放棄向後相容的秘籍,以霸气的招数加以抵制。而是,相反地,對這樣的現況加以兼容。由此,能够預見,要想解析
HTML,程式設計師必然無法逃避與 tag soup 的纏鬥。

回過頭來想,XHTML 的設計思維,是以有益程式化處理為主要考虑衡量;而 HTML5則以最大相容性為出發,要协作現實中的實際使用要求。有沒有辦法能夠兩者兼得,既能够便宜人們撰寫網頁,又有啥不可讓程式方便解析呢?

答案其實就在头里。瀏覽器,這個當年 Internet 標準大戰的顶梁柱,雖然對於 tag
soup 的留存,也有一点都不小的貢獻,不过,從另①方面來看,瀏覽器其實也是 tag
soup
的解藥:瀏覽器能夠將網路上充斥的各式各樣不合標準的內容,呈現給使用者觀看,其實是瀏覽器的設計者,竭盡所能,猜測網頁設計者大概的意圖,設法將雜亂不合規格的
HTML 文件,轉換成瀏覽器能夠解讀的格式。

在 RIA4858美高梅 , 盛行、Javascript
大行其道的今日,client side 的程式設計師,能够很简单地透過
Javascript,利用 jQuery 等 famework 很便利地存取瀏覽器解析完畢的 DOM
文件物件模型,取得须求的資訊。

 

而是 server side 呢?除了嵌入
Mozilla
或 Webkit 瀏覽器大旨之外,有沒有更簡單的不贰诀窍吗?

為了簡化 HTML 網頁的資訊汲取作業,若能像瀏覽器將 HTML 轉換成 DOM
1樣,將 HTML 網頁(不論是不是吻合標準格式),轉換成標準的 well-formed XML
文件,或是 XHTML。那麼,不就足以采用諸如 XPath 、 XPointer
等標準,利用現成的 API 或工具,隨意存取資訊了嗎?

4858美高梅 14858美高梅 2

  4858美高梅 3

4858美高梅 4

HTML 解析器 (HTML Parser)

毋庸置疑,老早就有人想到這樣做了。以下是幾個熱門的 HTML 解析器:

  • Cyberneko HTML Parser
  • HTML Parser
  • JTidy
  • TagSoup

里头,TagSoup 是架構在 XML 解析器 SAX2
標準
XMLReader
介面之上,所以具有卓绝的可攜性,能够與
JAXP、JDOM、XOM、dom4j
等主流工具搭配使用。

 1 <!DOCTYPE html>
 2 <html >
 3 <head>    
 4     <script>
 5         function myFunc1(input) {
 6             document.getElementById("output1").value = input;
 7         }
 8         
 9         function myFunc2(input) {
10             document.getElementById("output2").value = input;
11         }
12     </script>
13 </head>
14 <body>
15     <input id="input1" type="text" oninput="myFunc1(this.value)" />
16     <br />
17     <input id="input2" type="text" onchange="myFunc2(this.value)" />
18     <p></p>
19     <output id="output1"></output>
20     <br />
21     <output id="output2"></output>
22 </body>
23 </html>

  從下边表格能够看到,oninput 事件在
IE九 以下版本不帮忙,供给选取 IE 特有的 onpropertychange
事件代表,這個事件在用戶界面改變可能采取腳本直接改动內容兩種情況下都會觸發,有以下幾種情況:

4858美高梅 5

使用 JDOM + TagSoup 解析 HTML

接下來,作者將介紹怎么着以 JDOM 搭配 TagSoup ,將 HTML 解析為 DOM
文件物件模型,並使用 XPath 汲取資訊,可能將文件輸出為 XHTML
格式。(日後自身再找機會介紹 Groovy 內建的
XmlSlurper
搭配 TagSoup 的用法。)

oninput、onchange 比較

  • 修改了 input:checkbox 或许 input:radio 成分的選擇中狀態, checked
    屬性發生變化。
  • 修改了 input:text 可能 textarea 成分的值,value 屬性發生變化。
  • 修改了 select 元素的選中項,selectedIndex 屬性發生變化。
 
準備工作

先是,請下載並安裝 JDOM:

下載
jdom-1.1.1.zip,解開後,將
jdom.jar (JDOM 的實作) 及 jaxen.jar (XPath 的實作),加到 CLASSPATH
下;或是放到 JDK 安裝目錄的 jre\lib\ext 目錄下;或是放到 Groovy
安裝目錄的 lib 目錄下即可。

接著,請下載及安裝 TagSoup:

下載
tagsoup-1.2.jar,就像上一步驟,將檔案间接加到
CLASSPATH 下即可。

進一步聯想,若寫的是: 購物商場、網路書城,若要讓 input 或 textarea
輸入框,能夠「马上、精準地觸發」,只要使用 HTML5 的 input
事件,則不必本人寫程式去参预 AJAX 功效,就能輸鬆地達成需要。

  在監聽到 onpropertychange 事件后,能够选用event 的 propertyName 屬性來獲取發生變化的屬性名稱。

jQuery – 普通话輸入法與KeyDown/KeyPress事件

不久前專案中引用了Telerik
ASP.NET擴充元件AutoComplete輸入欄位,測試時發現偶爾會不聽始喚,輸入文字時無法觸發資料查詢,在Javascript
Source Code裡反覆追蹤測試,燃燒了可觀的寶貴春青,終於理出頭緒:
問題在中文言輸入法!

過去模糊地知道汉语輸入在瀏覽器的鍵盤事件行為上有点与众区别,但從未深究,這回算是比較清楚商讨之中的差別。其實最明顯的差異是:
切到汉语輸入法後,輸入文字將不會觸發KeyPress事件,只會有KeyDown,而且傳回的e.keyCode會一律是22九。

寫了1段程式來做實驗:

排版顯示純文字複製文字

本人利用倉頡輸入法(New ChangJie 20十),以IE9測試,操作過程及結果如下:

  1. 切換到新倉頡輸入法,點txtTest取得焦點準備輸入文字
  2. 按【一】(M鍵),出現KeyDown: 229
  3. 按Enter鍵確定選字,此時出現Input!
  4. 按數字1,出現KeyDown:
    229跟Input!
  5. 动用滑鼠將輸入法切回英文(不用按鍵切換制止觸發多餘事件)
  6. 按數字2,出現KeyDown: 50、KeyPress: 50以及Input!

FireFox肆測試的結果與IE玖相同。若將IE9切成IE7相容方式,結果不太一样,看來並不增派Input事件

  1. 切換到新倉頡輸入法,點txtTest取得焦點準備輸入文字
  2. 按【一】(M鍵),出現KeyDown: 229
  3. 按空白鍵選字,再出現KeyDown:
    22九
  4. 按數字1,出現KeyDown: 229
  5. 利用滑鼠將輸入法切回英文(不用按鍵切換幸免觸發多餘事件)
  6. 按數字2,出現KeyDown: 50、KeyPress: 50

Chrome10的測試結果為:

  1. 切換到新倉頡輸入法,點txtTest取得焦點準備輸入文字
  2. 按【一】(M鍵),出現KeyDown:
    229跟Input!
  3. 按空白鍵選字,出現KeyDown:
    22玖跟Input!
  4. 按數字1,出現KeyDown:
    229跟Input!
  5. 运用滑鼠將輸入法切回英文(不用按鍵切換幸免觸發多餘事件)
  6. 按數字2,出現KeyDown: 50、KeyPress: 50以及Input!

胡亂做個結論:

  • style=”color: #ff8040;”>輸入欄位啟用粤语輸入法時,將不會觸發KeyPress事件,而KeyDown事件中的
    KeyCode則固定傳回22玖。IE九, Firefox 四,
    Chrome支援按鍵Input事件,在IE9/Firefox四上可輔助判別普通话輸入的細節,但IE柒不援助,Chrome的行為不一样。*

綜合以上觀察,要本人搞出跨瀏覽器能够精準在使用者輸入每個字(不管有輸入法、不管中国和英国文)時觸發的轩然大波,看來是很艱鉅的任務。所幸網路上善心神人很多,找到一個不錯的解法,
Cross browser input event for
jQuery,
這個Plugin重新包裝了input事件,所以笔者們只需寫成:

$(“#txtText”).bind(“input”, function()
{
    this.value; //可取得近日的文字內容
});

就能在历次輸入粤语字或英文字時觸發input事件,雖然無法精確通晓每一回的按鍵內容,但已可滿足精通中文輸入形式下每一回文字變動的必要。[2011-04-26補充]要精確抓取每壹個按鍵的keyCode,可考慮使用KeyUp事件(但連選字時的上下鍵,送字的Space都饱含在內),感謝drem補充!

為網路開發者社会群众体育按一個讚!

使用 SAXBuilder 建立 DOM 文件

首先,建立 JDOM 的 SAXBuilder,SAXBuilder 能够在 constructor
钦定解析器的類別名稱,小编們只要傳入 TagSoup
的解析器類別全名:org.ccil.cowan.tagsoup.Parser,即可使用 TagSoup
進行解析:

def builder =newSAXBuilder("org.ccil.cowan.tagsoup.Parser")

制造好 SAXBuilder,就足以準備呼叫 build() 方法進行 HTML 解析,並建立 DOM
物件。

雖然 SAXBuilder 提供了多個分裂參數的 build() 方法,当中也有以
String systemId 為參數,可以一直傳入 uri
的本子,但是實際解析時,該方法卻是以系統預設編碼進行解析,而不會自動依據
HTML 文件钦点的編碼格式自動解析。在台灣,這表示將以 BIG五編碼解析文件,如若對象文件並非以 BIG伍 編碼(這裡將以
http://news.google.com.tw/
為例,該網頁是以 UTF-捌 編碼。別誤會,這裡使用 谷歌(Google) News
首頁,並不代表該網站不符合 HTML 規範,而是因為 谷歌的服務具有卓绝的反應速度與穩定性,相信它能夠承受得起小编們這些程式設計師的胡亂測試,…這應該算是對
谷歌 的讲究吧!),解析結果將是一批亂碼。因而,小编們必須使用
build(org.xml.sax.InputSource in)
這個版本,建立好 InputSouce 之後,設定正確的編碼情势,再傳入 SAXBuilder
的 build() 方法進行解析:

defis=newInputSource("http://news.google.com.tw/")is.setEncoding(“UTF-8”)def doc = builder.build(is)

這樣子,就拿走了 DOM 物件。不過,這裡需注意的是,SAXBuilder 的 build()
方法,建立的 DOM 物件,是
org.jdom.Document
,若要求轉換為
org.w3c.dom.Document
(譬如想要進一步使用 Java 標準 API 對該 DOM
文件進行處理時),則必須别的利用
org.jdom.output.DOMOutputter
進行轉換:

org.w3c.dom.Document w3cdoc =newDOMOutputter().build( doc )

同樣地,假诺要將 JDOM 的 Document 輸出成 XML/XHTML ,則使用
org.jdom.output.XMLOutputter
進行轉換:

String xhtml =new org.jdom.output.XMLOutputter().outputString( doc )

或是直接輸出成檔案:

new org.jdom.output.XMLOutputter().output( doc,newFileWriter("output.html"))

如下 html 程式碼:

  集合 oninput & onpropertychange 監聽輸入框內容變化的示范代碼如下:

动用 XPath 汲取資訊

收获 DOM 物件後,就足以应用 X帕特h 汲取資訊。XPath
的中央語法相當簡單,可是內容也相當多,這裡就略過 X帕特h
的語法介紹,詳細語法介紹請讀者自行搜尋 XPath 教學。

這裡將示範怎样取出 谷歌(Google) News 主頁上的兼具新聞標題。查看
http://news.google.com.tw/
,能够看到每則新聞標題是以如下的格式呈現,譬如︰

曾雅妮的魔幻數字與粉紅色

簡單起見,假設要選取全部 class 含有 titletext 內容的 HTML 標籤,則 XPath
如下:

//*[contains(@class,’titletext’)]

決定了 XPath 路徑,就足以用來取得新聞標題,並列印出來了:

def xpath =XPath.newInstance("//*[contains(@class,'titletext')]")def result = xpath.selectNodes( doc )
result.each { println it.text }

总体的程式列表如下:

gnews.groovy
import org.jdom.*import org.jdom.input.*import org.jdom.xpath.*import org.jdom.output.*import org.xml.sax.*def builder =newSAXBuilder("org.ccil.cowan.tagsoup.Parser")def xpath =XPath.newInstance("//*[contains(@class,'titletext')]")defis=newInputSource("http://news.google.com.tw/")is.setEncoding("UTF-8")def doc = builder.build(is)def result = xpath.selectNodes( doc )
result.each { println it.text }

要執行上边的 groovy 程式,請在命令列下,執行:

groovy gnews

即會在螢幕上輸出最新 谷歌 News 上边的新聞標題。

正是這樣!是或不是很簡單?

 

歡迎大家的回饋與心得分享。 

 1 <!DOCTYPE html>
 2 <html >
 3 <head>
 4     <title>oninput</title>
 5     <script>
 6         function myFunc1(input) {
 7             document.getElementById("output1").value = 
 8                 input * 230;
 9         }
10     </script>
11 </head>
12 <body>
13     書名:快快樂樂學HTML5, <br />
14     價格:230, 購買數量:
15     <input id="input1" type="number" step="1" value="0" oninput="myFunc1(this.value)" />
16     <br /><br />
17     結帳金額:
18     <output id="output1"></output>
19 </body>
20 </html>
<head>
    <script type="text/javascript">
    // Firefox, Google Chrome, Opera, Safari, Internet Explorer from version 9
        function OnInput (event) {
            alert ("The new content: " + event.target.value);
        }
    // Internet Explorer
        function OnPropChanged (event) {
            if (event.propertyName.toLowerCase () == "value") {
                alert ("The new content: " + event.srcElement.value);
            }
        } 
    </script>
</head>
<body>
    Please modify the contents of the text field.
    <input type="text" oninput="OnInput (event)" onpropertychange="OnPropChanged (event)" value="Text field" />
</body>

 

  使用 jQuery 庫的話,只供给同時綁定
oninput 和 onpropertychange 兩個事件就能够了,示例代碼如下:

4858美高梅 6
圖 1 執行結果

$('textarea').bind('input propertychange', function() {
    $('.msg').html($(this).val().length + ' characters');
});

HTML5 的 input 事件,首要的缺點,是不帮忙微軟的 IE 瀏覽器,但扶助Chrome、Firefox、Opera、Safari、微軟的 Edge。

 

故而在網頁裡,引用此事件,對手機、平板上的操作,並不造成影響。


參考書籍:

[1] HTML五 完美風暴(第一版), ch五, 小编:呂高旭

相關作品:

[1] HTML 事件性质

[2] HTML五 input 事件检查测试输入框变化

[3] HTML伍 标准事件 oninput 达成输入检查评定


 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有