モバイル端末web開発---Touchイベント詳細

23736 ワード

一、pcエンドイベントの回顧
HTMLイベント、DOM 0イベント、DOM 2イベント
イベント・オブジェクト.
上記の概念が不明な場合は、まず理解してください.
二、移動端イベントの概要
2.1 pcエンドイベントのモバイルエンドでの問題
モバイルデバイスの主な特徴は、マウスを搭載せず、キーボードも入力が必要な場所でのみ仮想キーボードをアクティブにすることです.従って、従来のpcエンドイベントは、モバイルエンドで使用すると、以前ほど爽やかではありませんが、一部は使用できます.
  • clickイベントの300 ms遅延問題.2007年に初代iPhoneがリリースされ、その年代はすべてのページが大画面のpc端向けに設計されていたため、iPhoneのSafariブラウザはユーザーがページを閲覧する際にページ全体を閲覧できるようにviewportを960 px(前の記事参照)に設定したのが良いのですが、ページ全体をズームしたため、内容が非常に小さくなり、視力6.0のものは必ずしもはっきり見えるとは限らない.だからSafariブラウザは当時かなりクールに見えた機能を持っていました:ダブルクリックしてスケールします.ページをダブルクリックすると、ブラウザは現在のページを元のサイズにスマートにスケールします.ダブルクリックズームの原理は、clickが1回通過すると300 ms後にclickが1回あるかどうかを検出し、あればページをズームすることです.そうでなければclickイベントです.だから、click操作を実行したいときは、「カートン」を感じます.クリックしてから100 ms後に反応しなければ、基本的にカートンの感じがします.
  • dblickイベントが無効になったダブルクリックスケールの存在により、pc側のdblickイベントも無効になった.

  • 2.2モバイル端末web新規touchイベント
    タッチスクリーン装置の普及に伴い、w 3 cはモバイル端末webにtouchイベントを追加した.
    最も基本的なtouchイベントには、4つのイベントが含まれます.
  • touchstart画面で指を押すと
  • がトリガーされる.
  • touchmove画面上で指を移動すると
  • がトリガーされる.
  • touchendスクリーン上で指を持ち上げると
  • がトリガーされる.
  • touchcancelは、電話アクセスやポップアップ情報などのより高いレベルのイベントが発生すると、現在のtouch操作がキャンセルされ、touchcancelがトリガーされます.一般的にtouchcancelではゲームやアーカイブなどの操作を一時停止します.

  • 三、関連知識の詳細
    移動端に関連するinterfaceは主に3つあります.
  • TouchEventは、タッチ状態が変化するとトリガーされるevent
  • を示す.
  • Touchは、ユーザとタッチパネル装置との接触時における個別のインタラクションポイント(a single point of contact)
  • を示す.
  • TouchListは、touchesのセットを表す.マルチタッチが発生したときに使います.

  • 3.1、TouchEvent詳細
    タッチに関する状態の変化を区別するために、様々なタイプのタッチイベントが存在する.現在のイベントがどのタイプに属するかは、タッチイベントのTouchEvent.type属性をチェックすることによって決定することができる.
    注意:多くの場合、タッチイベントとマウスイベントが同時にトリガーされます(タッチデバイスに最適化されていないコードがタッチデバイス上で正常に動作することを目的とします).タッチイベントを使用すると、event.preventDefault()を呼び出してマウスイベントがトリガーされるのを阻止できます.
    var i = 1;
    var box = document.querySelector("div");
    var ps = document.querySelectorAll("p");
    box.addEventListener("touchstart", function (e){
       ps[0].innerHTML = e.type + i++;
    })
    box.addEventListener("touchmove", function (e){
       ps[1].innerHTML = e.type + i++;
    })
    box.addEventListener("touchend", function (e){
       ps[2].innerHTML = e.type + i++;
    })

    3.1.1 touchstart
    ユーザの指がタッチスクリーンに触れたときにトリガーされる.イベントオブジェクトのtargetは、touchが発生した位置の要素です.
    <div>
        <p>p>
    div>
    <script>
        var i = 1;
        var box = document.querySelector("div");
        var p = document.querySelector("p");
        box.addEventListener("touchstart", function (e){
            p.innerHTML = e.target.tagName + ", " + i++;    //  P
        })
    
    script>

    3.1.2 touchmove
    ユーザがタッチスクリーン上でコンタクト(指)を移動すると、このイベントがトリガーされる.必ずtouchstartイベントをトリガーし、touchmoveイベントをトリガーする可能性があります.touchmoveイベントのtargetは、最初にトリガされたtouchstarttargetと一致する.touchmoveイベントは、マウスのmousemoveイベントと同様に複数回繰り返し呼び出されるため、イベント処理時に時間がかかりすぎる操作はできません.異なるデバイスでは、同じ距離を移動するtouchmoveイベントのトリガ周波数は異なる.
    指が元のtarget元素から移動しても、touchmoveは常にトリガーされ、targetは元のtarget元素であることに注意してください.
    <div>
        <p>p>
    div>
    <script>
        var i = 1;
        var box = document.querySelector("div");
        var p = document.querySelector("p");
        box.addEventListener("touchmove", function (e){
            p.innerHTML = e.target.tagName + ", " + i++;
        })
    script>

    3.1.3 touchend
    ユーザの指が持ち上げられると、touchendイベントがトリガーされる.ユーザの指がタッチスクリーンデバイスのエッジからタッチスクリーンデバイスから移動すると、touchendイベントもトリガーされます.touchendイベントのtargetも、要素が移動されたとしても、touchstarttargetと一致する.
    3.1.4 touchcancel
    コンタクトが何らかの理由で中断されたときにトリガーされます.いくつかの可能性のある理由は次のとおりです(具体的な理由は、デバイスやブラウザによって異なります).
  • は、イベントによってタッチがキャンセルされた.例えば、タッチプロセスは、モードのポップアップボックスによって中断される.
  • コンタクトは、ドキュメントウィンドウを離れ、ブラウザのインタフェース要素、プラグイン、または他の外部コンテンツ領域に入る.
  • ユーザが生成する接点の個数がデバイスがサポートする個数を超えると、TouchListのうち最も早いTouchオブジェクトが
  • からキャンセルされる.touchcancelイベントは、通常、フィールドデータを保存するために使用される.例えば、ゲームをしていて、touchcancelイベントが発生した場合は、ゲームの現在の状態に関するデータを保存する必要があります.
    3.2 TouchList詳細
    タッチスクリーン上のすべての接点のリストを表すTouchList.
    例えば、1人のユーザが3本の指でスクリーン(またはタッチパネル)に接触すると、それに関連するTouchListは1本の指に対してTouchのオブジェクトを生成し、合計3つとなる.
    TouchListには1つの属性と2つの方法があります
  • 読取り専用プロパティ:lengthは、このTouchListTouchペアの数を返します.(いくつかの指がスクリーンに触れた)
  • メソッド:identifiedTouch()戻り値は、TouchListのうち1番目のTouchオブジェクトであり、すでに古いとマークされており、一部のブラウザでは使用可能であるが、使用を推奨しない.
  • メソッド:item(index)は、TouchListで指定されたインデックスのTouchオブジェクトを返します.
  • TouchListオブジェクトを取得するには、TouchEventの3つのプロパティをTouchListに取得します.
  • changedTouches:(読み取り専用)このTouchListオブジェクトは、このタッチイベントに対応する変化したTouchオブジェクトをリストしている.
  • touchstartイベントについて、このTouchListオブジェクトは、今回のイベントで新たに追加されたコンタクトをリストする.
  • touchmove , , 。
  • touchendについては、タッチプレーンに接触する指に対応するタッチプレーンから離れた接点
  • がリストする.
  • targetTouches:(読み取り専用)このTouchListには、touchstartがこの要素で発生し、touch surfaceからまだ離れていないtouch point(指)がリストされています.touchesの厳密なサブセットです.
  • touches`:(読み取り専用)このTouchListは、イベントトリガ時:touch suface上のすべてのtouch pointをリストします.

  • touches.length>=targetTouches.length
  • 次のコードを見てください:
  • <div>
        <p style="font-size: 50px; color: #ffffff;">p>
    div>
    <script>
        var box = document.querySelector("div");
        var p = document.querySelector("p");
        box.addEventListener("touchend", function (e){
            p.innerHTML = e.changedTouches.length;  //  Touch     
            for(var i = 0; i < e.changedTouches.length; i++){
                //      Touch  
                console.log(e.changedTouches.item(i));
            }
        })
    
    script>
  • 次のコード
  • を見てください.
    <div>div>
    <p>p>
    <script>
        var div = document.querySelector("div");
        var p = document.querySelector("p");
        div.addEventListener("touchstart", function (e){
            var msg = "touches.length: " + e.touches.length +
                    "
    targetTouches.length: "
    + e.targetTouches.length + "
    changedTouches.length: "
    + e.changedTouches.length; p.innerHTML = msg; })
    script>

    操作:
  • 1指をdivに1本置く
  • まず1本の指を他の場所に置いて、それから1本の指をdivの上に
  • 置いてください.
  • まず1本の指を他の場所に置いてから、2本の指をdivの上に
  • 徐々に置いた.
    3.3 Touch詳細
    ユーザとタッチデバイスとの接触時の個別のインタラクションポイント(a single point of contact)を示す.
    このインタラクティブポイントは通常指やタッチペンです.
    タッチデバイスは、通常、タッチスクリーンまたはタッチパネルである.
    jsオブジェクトは、Touchオブジェクトを記述するために複数の属性を提供する.
    これらのプロパティは、次の2つの大部分に分かれています.
  • 基本属性(Basic properties)
  • タッチ領域関連属性(Touch area)Touch areaは現在も試験段階にある.私たちはまずあまり議論しない.

  • 基本プロパティ:
    これらのアトリビュートはすべて読み取り専用です
  • identifier:Touchの各オブジェクトを表すユニークなidentifier.このidentifierがあれば、このTouchのオブジェクトを常に追跡できることを保証します.
    <div>
       <p style="font-size: 50px; color: #ffffff;">p>
    div>
    <script>
       var box = document.querySelector("div");
       var p = document.querySelector("p");
       box.addEventListener("touchend", function (e){
           var touchList = e.changedTouches;
           for (var i = 0; i < touchList.length; i++){
               console.log(touchList.item(i).identifier);  
           }
       })
    
    script>
  • screenX:タッチポイントの画面左端に対するx座標.
  • scre enY:画面の上端に対するタッチポイントのy座標.
  • clientX:ブラウザのviewportの左端に対するタッチポイントのx座標.左側のスクロール距離は含まれません.
  • clientY:ブラウザのviewportの上端に対するタッチポイントのy座標.上のスクロール距離は含まれません.
  • pageX:documentの左端に対するタッチポイントのx座標.clientXとは異なり、左に転がる距離も含まれています.もしあれば.
  • pageY:documentの左端に対するタッチポイントのy座標.clientYとは異なり、上を転がす距離も含まれています.もしあれば.
  • target:指がタッチデバイス上に最初に置かれたトリガポイントの位置を常に示すelement.元素が除去されてもdocumentが除去されても、彼が示したelement
  • に変わらない.
    var box = document.querySelector("div");
    var p = document.querySelector("p");
    box.ontouchstart = function (e){
        var touchList = e.changedTouches;
        for (var i = 0; i < touchList.length; i++){
            var touch = touchList[i];
            var msg = `id : ${touch.identifier} 
    screenX : ${touch.screenX}
    screenY : ${touch.screenY}
    clientX : ${touch.clientX}
    clientY : ${touch.clientY}
    pageX : ${touch.pageX}
    pageY : ${touch.pageY}
    target: ${touch.target.nodeName}
    `; p.innerHTML = msg; } }

    左右スクロールなし:
    左右スクロール:pageXclientXより明らかに大きい
    四、パッケージング移動端イベント
    前述は最も基本的なイベントであり,直接使用するのは比較的面倒であるため,いくつかの一般的なイベントをカプセル化する必要がある.
    たとえば、クリックイベント、ダブルクリックイベント、スライド方向など
    (function (window){  //  window,         
        function myQuery(selector){  //             。
            //             _init  ,   
            return myQuery.prototype._init(selector);
        }
        myQuery.prototype = {
            /*     ,    query     */
            _init: function (selector){
                if (typeof selector == "string"){
                    //                 。
                    this.ele = window.document.querySelector(selector);
                    //           。
                    return this;
                }
            },
            /*    :
             *     click 300ms   ,         
             *     :
             *             
             *                     ,    500ms      。
             *
             *          500ms,      
             * */
            tap: function (handler){
                this.ele.addEventListener("touchstart", touchFn);
                this.ele.addEventListener("touchend", touchFn);
    
                var startTime,
                    endTime;
    
                function touchFn(e){
                    e.preventDefault()
                    switch (e.type){
                        case "touchstart":
                            startTime = new Date().getTime();
                            break;
                        case "touchend":
                            endTime = new Date().getTime();
                            if (endTime - startTime < 500){
                                handler.call(this, e);
                            }
                            break;
                    }
                }
            },
            /**
             *   
             * @param handler
             */
            longTag: function (handler){
                this.ele.addEventListener("touchstart", touchFn);
                this.ele.addEventListener("touchmove", touchFn);
                this.ele.addEventListener("touchend", touchFn);
                var timerId;
    
                function touchFn(e){
                    switch (e.type){
                        case "touchstart" :  //500ms    
                            timerId = setTimeout(function (){
                                handler.call(this, e);
                            }, 500)
                            break;
                        case "touchmove" :
                            //             
                            clearTimeout(timerId)
                            break;
                        case "touchend" :
                            //   500ms       ,      
                            clearTimeout(timerId);
                            break;
                    }
                }
            },
            /**
             *     。
                         ,         deltaX         
             *
             */
            slideLeft: function (handler){
                this.ele.addEventListener("touchstart", touchFn);
                this.ele.addEventListener("touchend", touchFn);
                var startX, startY, endX, endY;
    
                function touchFn(e){
                    e.preventDefault();
                    var firstTouch = e.changedTouches[0];
                    switch (e.type){
                        case "touchstart":
                            startX = firstTouch.pageX;
                            startY = firstTouch.pageY;
                            break;
                        case "touchend":
                            endX = firstTouch.pageX;
                            endY = firstTouch.pageY;
    //x      y     ,  x       25   ,        
                            if (Math.abs(endX - startX) >= Math.abs(endY - startY) && startX - endX >= 25){
                                handler.call(this, e);
                            }
                            break;
                    }
                }
            },
            /**
             *     。
             *
             */
            rightLeft: function (e){
                //TODO:
            }
        }
        window.$ = window.myQuery = myQuery;
    })(window);

    次の操作を行います.
    $("div").tap(function (e){
        console.log("    ")
    })
    $("div").longTag(function (){
        console.log("    ");
    })
    
    $("div").slideLeft(function (e){
        console.log(this);
        this.innerHTML = "     ....."
    })

    参考資料:mdn関連ドキュメント