關閉Android/iPhone瀏覽器自動識別數字為電話號碼

關閉Android/iPhone瀏覽器自動識別數字為電話號碼

在半年前寫過了一篇<去掉Opera Mobile自動將數字轉成電話號碼>,讓我在開發Mobile Web Application時,

針對行動瀏覽器自動識別的問題,解決了大部分的需求,讓我可以按照需求在需要的文字或功能上,加上處理

呼叫電話或是傳送Mail的任務。

 

不過在解決了Opera Mobile的問題之後,接下來自己又遇到現在最紅的:iPhone與Android內鍵的瀏覽器。

它們二個瀏覽器採用相似的底層(WebKit),也是目前支援HTML5、JavaScript、Css最為標準且豐富的,

但它們一樣會把某些字串,例如:00-00-01111識別為電話號碼,那將會造成在操作網頁時,使用者不小心的誤觸,

雖然誤觸的結果,可能就是自動撥號,但其實這樣的字串在撥號時,電信業者會自動把它擋下來,所以對使用者而

言,只是會一直出現奇怪的訊息。但這樣的情形卻是我們開發人員覺得最麻煩的地方。

 

至於這樣的問題在Android、iPhone的內鍵瀏覽器要怎麼來克服呢?

〉舉個與<去掉Opera Mobile自動將數字轉成電話號碼>相同的範例,並且以簽核單號為例:

006 005

從上面二張圖可以看到,明明是一個簽核單號,按下去時卻變成要撥打電話的模式,這是非常不方便的,因此,

往下將介紹如何解決這樣的問題:

〉嘗試方法(1) - 失敗

採用在<去掉Opera Mobile自動將數字轉成電話號碼>使用的方法,試著找出是否如同Opera Mobile自動加上的<a>標籤:

   1: $(function(){
   2:     $("a").each(function(){
   3:     alert("序號HTML:" + $(this).text()+"\n\rHref屬性:"+$(this).attr("href")); 
   4:     });
   5: });

測試的結果是沒有用的,因為iPhone/Android並不是直接採用將識別出來的數字字串加上<a>標籤

 

〉使用iPhone/Android瀏覽器(WebKit)支援的TouchEvent

針對iPhone/Android瀏覽器針對Touch  Event的處理,主要分成四個類型:

‧Touch Event Type

(a) touchstart

     相似於mouseDown的事件,它是整個touch event的第一個啟動項目;

(b) touchmove

    相似於mouseMove的事件,它touch start觸發後,手指未離開直接移動於畫面上時所觸發的項目;

(c) touchend

    相似於mouseUp的事件,代表手指離開了畫面,所代表觸發事件結束的項目;

(d) touchcancel

    當系統發出取消追蹤touch event的任務,所觸發的事件;

 

在Touch Event裡,針對每一個擷取到的Touch Object都具有一些基本的屬性可以使用,如下:

‧Touch Event Attributes

(a) changedTouches

    由Touch Event所擷取到此次Event所觸摸到的對象集合,其代表所有的按鍵可能改變了這一活動;

    包含了所有相關Touch Events資訊;(此屬性接到是所有的touch event資訊)

(b) targetTouches

    由Touch Event所擷取到此次Event所觸摸到的對象集合,其代表所以涉及與此相關的目標;

    包含了觸發目標的所有相關Touch資訊;(此屬性接到的觸發目標的touch event資訊)

(c) touches

    由Touch Event所擷取到此次Event所觸摸到的對象集合,其代表所有涉及與此相關的事件,

    包含了在touch start與touch move的相關touch資訊;(代表可以捉到這二個事件時間點所觸發的物件)

三個屬性其實使用起來,我覺得真正比較與我們相關的是touches屬性,因為真正要操作的是touch object

因此,在此篇文章中,要擷取的內容是在用戶觸發click(touchstart)時所發出的事件資訊,只需使用touches屬性即可。

更多介紹有關三個Event Attributes的內容,可以參考此篇內容:<Handling Multi-Touch Events>。

 

由上述可以得知,要實際操作touch object前還需要了解一下touch object有那些屬性有辦法讓我們識別我們要操作的對象,

對應到HTML內容時,究竟是何種HTML標籤。以下將介紹touch object的基本屬性:

‧Touch Object Attributes:

(a) clientX:觸摸對象相對於Window的Viewport中的X座標位置;

(b) clientY:觸摸對象相對於Window的Viewport中的Y座標位置;

(c) identifier:觸摸對象的唯一識別值;

(d) pageX:觸摸對象於頁面的X座標位置;

(e) pageY:觸發對象於頁面的Y座標位置;

(f) screenX:觸摸對象於螢幕的X座標位置

(g) screenY:觸發對象於螢幕的Y座標位置

(h) target:代表觸發的對象;(*)

上述介紹七種屬性,其中以target為此篇文件要專注的處理項目,因為需要針對觸發的對應做識別來找到要防止自動出現撥打電話的事件。

 

[實作原理]

了解了Touch Event的類型與屬性之後,接下來就按照實作的原理來撰寫JavaScript,完成我們要防止的事件。其原理如下:

補捉touchstart事件,識別觸發的來源者,是否為指定的HTML標籤並且是onClick沒有指派任務者,取消原本要觸發的事件處理」。

 

‧實作程式代碼:

   1: //document.load時所觸發的事件
   2: $(function() {
   3:     //註冊document需補捉touchstart的事件,並指定touchHandler為處理者;
   4:     document.addEventListener("touchstart", touchHandler, true);
   5:  });
   6:  
   7: //Touch Event處理者
   8: function touchHandler(event) {
   9:    var node = event.touches[0].target;
  10:    //比對只要是TD元素,而且onclick沒有設定時,則不能允許觸發事件。
  11:    if (node.onclick == null && node.tagName == 'TD') event.preventDefault();
  12: }

‧實作結果:

007 這樣就可以阻擋數字字串自動變成撥號的功能嘍!

 

[2011/06/27.. ..Pou:補充新的解法]

   1: function touchHandler(event) {
   2:     var node = event.touches[0].target;
   3:     //比對只要是TD元素,而且onclick沒有設定時,則不能允許觸發事件。
   4:     if (node.onclick == null && node.tagName == 'TD') {
   5:         //判斷是否為數字組合的字串, false代表是由數字, true代表不是(201-2)
   6:         if (isNaN(node.innerText) == false) {
   7:             //全數字時,超過5碼就要擋下來,不然就會電話號碼
   8:             if (node.innerText.length > 5) {
   9:                 event.preventDefault();
  10:             }
  11:         } else {
  12:             //true時要多判斷是否存在數字與中線同時存在
  13:             if (hasMatch(node.innerText)) {
  14:                 event.preventDefault();
  15:             }
  16:         }
  17:     }
  18: }

這個解法可以擋掉可能全部都為數字的字串之外,也可以阻掉TD等其他的元件。另外,針對preventDefault()的使用,

要特別注意,因為如果當Scroll的事件觸發在指定的TD上時,可能會造成Scroll的功能失敗,因此,此方法也解決了這些

問題。由於Android與iPhone在對數字識別的指定的meta可以擋掉。但我還是喜歡使用JavaScript來做,因為可以確保

自己要阻擋的範圍與增加需要的事件處理。

======

看到這裡,也許你會有個疑問,為何我只阻擋了"TD"的HTML標籤,其實要阻擋的範圍可以非常廣的,因為我嘗試過,

如果在<div>、<span>、<b>…等集合類型的元素中,出現如同"2010-07-19-000000001"這種字串的話,一樣會出現撥號畫面,

因此,如果要增加防範的條件式,我建議先考慮幾個項目:

(a) 如果網頁要增加指定的撥號功能,採用的方式是使用javascript觸發?還是由Server觸發?或是使用<a>來指定?

(b) 阻擋條件的增加,HTML集合標籤都有可能出現數字字串,需要配合(a)的使用機制來調整阻擋條件的指定。

 

以上是自己在開發Mobile Web時遇到的一些問題解法,希望對大家有所幫助;當然,如果有更好的解法,

也希望不妨分享出來給大家一起學習。謝謝。

 

References:

iPhone Touch Events in JavaScript (必讀)

touchevent (必讀)

Handling Events (必讀)

Mac OS X Developer Library - Guild

JavaScript Touch and Gesture Events iPhone and Android (重要必讀,裡面有列出支援系統清單)

Processing.js's Touch Events

tagName (W3C DOM Core property)

Get Elements by tag name and return an array of elements

javascript之getAttribute()方法 应用续

JavaScript getAttribute method

 

Dotblogs Tags: ,