ブラウザのイベント分析

JavaScriptを、ブラウザのイベントとの関係

JavaScriptプログラムは、非同期イベント駆動型プログラミング(イベント駆動型プログラミング)モデルを使用してウィキペディアそれは次のとおりです。

イベント駆動型プログラミング(イベント駆動型プログラミング)コンピュータ・プログラミングモデルです。このモデルの実行プロセスは、他のプログラムのメッセージによって、ユーザまたは(例えば、マウスボタン、キーボードボタン操作など)を操作することによって決定されます。バッチプログラミング(バッチプログラミング)と比較すると、プログラムの実行の流れは、プログラマによって決定されます。主要なプログラミングのカリキュラムでのプログラミングの大部分は1つの方法です。しかし、この設計のイベント駆動型のプログラミングモデルは、対話型プログラム(インタラクティブ・プログラム)の場合のうちに生まれています

要するに、ユーザからの入力を受け、ブラウザによって提供されたイベントモデルAPIとユーザーとの対話により、WebフロントエンドJavaScriptプログラミングの内部。

ユーザの行動は不明ですので。あなたが唯一のコードの後ろに終了し、ユーザの操作を実行するために待つことができないので、このシーンは、モデルが解決することはできません伝統的な同期のプログラミングです。そのため、JavaScriptで非同期イベントの使用は、それは言うことです:JSイベントは非同期で実行されています

イベント駆動型プログラミングモデルの基本的な原則は基本的に達成イベントループ(イベントループ)、このセクションのカバーのブラウザイベントモデル、コールバックの原理を使用します。

JavaScriptのDOM、BOMモデル、同じ非同期そこのsetTimeoutは、XMLHTTPRequestを、このようなAPI JavaScript言語そのものではありません。

結合事象の方法

イベントバインディング3つの方法があります。

インライン結合

直接設定することで、DOM要素のon + eventTypeバインディングイベントハンドラを。例えば:

<a href="#none" onclick="alert('clicked')">点击我</a>

このアプローチは、2つの欠点があります。

  1. イベントハンドラとHTMLの構造混合一緒に、MVXが仕様を満たしていません。コンテンツ、プレゼンテーションや行動が分離されるためには、我々はこのようなアプローチを避ける必要があります。
  2. 書き込みコードは深刻な予期せぬ結果につながる、発生する可能性が名前の競合を、グローバルな範囲で決定します。

DOM要素に直接イベントコールバック関数をオーバーライドします

+のeventTypeにDOM要素のプロパティのAPIを使用して、上記

var el = getElementById('button');  //button是一个<button>元素
el.onclick = function(){ alert('button clicked.') };
el.onclick = function(){ alert('Button Clicked.') };
//实际之弹出'Button Clicked.',函数发生了覆盖

また、このメソッドは、欠点があります:関数は前の関数を上書きします結合した後。例えば、我々はwindow.onloadイベントを登録し、ライブラリ内の既存のイベント機能を無効にすることができます。もちろん、これは解決策を持っていることができます。

function addEvent(element, EventName, fun) {   //EventName = 'on' + eventType
    var oldFun = element[EventName];
    if (typeof oldFun !== 'function') {
        element[EventName] = fun;
    } else {
        element[EventName] = function() {
            oldFun();
            fun();
        };
    }
}

addEvent(window, "onload", function() { alert('onload 1') });
addEvent(window, "onload", function() { alert('onload 2') });

JavaScriptのDOM仕上げロードがで実行することができるので、もちろん、通常の状況下ではDOMの準備は、それを使用するには

標準的な結合方法

結合の2つの標準的な方法がありますが、addEventListenerをして​​attachEvent前者はIE8のブラウザがサポートするには、以下のAPIである標準的なブラウザのサポートのAPI、次のとおりです。

//例如给一个button注册click事件
var el = getElementById('button');  //button是一个<button>元素
if(el.addEventLister){
    el.addEventListener("click", function(e){
        alert("button clicked.");
    },false);
}
if(el.attachEvent){
    el.attachEvent("onclick", function(e){
        alert("button clicked.");
    });
}

それに注意してください。

  1. 最初のパラメータは、接頭辞なしのイベントaddEventListerの種類、およびattachEventプレフィックスに追加する必要があります。
  2. addEventListerイベントコールバックイベントターゲット要素自体にこのポイントの機能が、このattachEventウィンドウにイベントコールバック関数を指します。
  3. 真addEventLister 3番目の引数は、キャプチャ段階、偽のバブリング段階(:偽デフォルト値)でイベントことを示しています。attachEventはバブリング段階で動作することができます。

クロムは、以下のコードを実行します。

<a href="javascript:alert(1)" onclick="alert(2)" id="link">click me</a>
<script>
    var link = document.getElementById('link');
    link.onclick = function() { alert(3); };  //覆盖了行内的onclick定义
    link.addEventListener('click', function() { alert(4); },false);
    link.addEventListener('click', function() { alert(5); },false);
</script>

クリックイジェクト順序は次のとおりです。3 - > 4 - > 5 - > 1

ここで、コードカバーのライン4は列内で定義されたonclickのコメントは、入力順である場合、この行は:2 - > 4 - > 5 - > 1、カバーのaddEventListener間で生じません。

リフトイベントバインディング

最初の2つの方法は、上述したイベントのみヌルに対応するイベント機能セットを持ち上げる必要が結合するため、それができるようになります。

var el = document.getElementById('button');
el.onclick = null;

上述した第3の方法は、removeListenを使用するための()メソッドは、対応するdetachEventを使用して、IE8であってもよいです()。(注)上記の登録方法、それらが対応すること、混合することができません。

//这是一段错误代码,不能实现事件移除

//建立一个事件
var el = document.getElementById('button');  //button是一个<button>元素
if(el.addEventLister){
    el.addEventListener("click", function(e){
        alert("button clicked.");
    },false);
}
if(el.attachEvent){
    el.attachEvent("onclick", function(e){
        alert("button clicked.");
    });
}

//试图移除这个事件
if(el.removeEventLister){
    el.addEventListener("click", function(e){
        alert("button clicked.");
    },false);
}
if(el.detachEvent){
    el.datachEvent("onclick", function(e){
        alert("button clicked.");
    });
}

//移除失败

ときに上記のエラー関数イベントこの定義をそれ、メモリ内の同じアドレスまったく同じに見えますが、していないが。その結果、コンピュータは正常に持ち上げないだろう、当然、解除して同じ機能への結合を考慮しています。読み込みする必要があります。

//建立一个事件
var el = document.getElementById('button');  //button是一个<button>元素
var handler = function(e){alert("button clicked.");};
if(el.addEventLister){
    el.addEventListener("click", handler,false);
}
if(el.attachEvent){
    el.attachEvent("onclick", handler);
}

//试图移除这个事件
if(el.removeEventLister){
    el.addEventListener("click", handler, false);
}
if(el.detachEvent){
    el.datachEvent("onclick", handler);
}

//移除成功

キャプチャとイベントバブリング

彼は、addEventListenerを関数の第三引数は、キャプチャとバブリングを表明する前に、これは重要なポイントであると述べました!

私は自分の定義は説明します。

バブル :イベントが要素の上にトリガされ、それは内側からイベントのこの要素の親をオントリガーになります、ウィンドウ要素まで。

キャプチャ:すべての要素は、もはや子供でなくなるまでイベントが要素でトリガされ、すべての子要素は、層によって各イベントのこの要素の層と内側層の上にトリガします。

以下に示すように(注:Baiduの検索からの画像)

イベントの間に関数のパラメータへのバックには、例えば、我々は次のようにバブリングし、デフォルトのイベントを防ぐことができますプロパティとメソッド、多くのイベントを含むイベントオブジェクトを、次のとおりです。

//该例子只写了handler函数
function handler(event) {
    event = event || window.event;
    //阻止冒泡
    if (event.stopPropagation) {
        event.stopPropagation();      //标准方法
    } else {
        event.cancelBubble = true;    // IE8
    }
    //组织默认事件
    if (event.perventDefault) {
        event.perventDefault();      //标准方法
    } else {
        event.returnValue = false;    // IE8
    }
}

第二に、通常の登録されたイベントだけでバブリング停止することはできません、既定のイベントを防ぐことができます

element = document.getElemenById("submit");
element.onclick = function(e){
    /*...*/
    return false;    //通过返回false,阻止冒泡
}

イベントオブジェクト

イベント関数は、1つの引数は、すべてのキーの組み合わせなど、イベントがマウス座標の多様性と画面のシリーズがありますものを含め、ボタンが含まれますどのような時、キーボードのクリックなどのイベントに関する情報を含むイベントオブジェクトでありタイプ、あるいはドラッグをクリックして、上のようにします。もちろん、それはまた、そのような要素がクリックされたものと、内部情報DOMの多くが含まれ、事務の現在の状態のどの要素にドラッグ、というように。

強調する必要性についてここでは互換性のイベント:

document.addEventListener('click', function(event) {
    event = event || window.event;   //该对象是注册在window上的
    console.log(event);   //可以输出事件对象看一看, 属性很多很多
    var target = event.target || event.srcElement;  //前者是标准事件目标,后者是IE的事件目标
},false);

:マウスイベントの座標についての質問、あなたは別のブログ見ることができる要素の距離属性とマウスイベントを

イベントトリガー

ユーザーのアクションに加えて、我々はまた、イベントをトリガする書き込みコードにイニシアチブを取ることができ、例としてELE要素にイベントをクリックします。

ele.click();   //触发ele元素上的单击事件

イベント代理店

時には、我々はいくつかのDOM要素は、ユーザの要素として結合事象、動的に追加に存在しない、またはDOMノードのレンダリングが完了した後、いくつかのAjaxリクエスト与える必要があります。イベントの一般的な結合ロジックは、レンダリングの前に実行されますが、それは成功することはできませんので、時間結合要素を見つけることができません。

この問題を解決するために、我々は通常、イベント代理店/手数料(イベント委任)を使用します。そして、一般的にイベントの委任を使用することを言えば、私たちは例を見て、単一の結合事象よりもはるかに高いパフォーマンスだろう。

  • 低効率の多くの内容は、要素の動的な追加をサポートしていない伝統的なイベントの登録方法、
<ul id="list">
    <li>item-1</li>
    <li>item-2</li>
    <li>item-3</li>
    <li>item-4</li>
    <li>item-5</li>
</ul>
<script>
    var lists = document.getElementsByTagName('li');
    for(var i = 0; i < lists.length; ++i){
        lists[i].onclick = (function(i){
                return function(){
                  console.log("item-" + (i + 1));
                };
            })(i);
    }
    //添加节点
    var list = document.getElementById('list');
    var newNode = document.createElement('li');
    newNode.innerHTML = "item-6";
    list.appendChild(newNode);
</script>
  • イベントデリゲートの登録方法、一回だけが登録されているどのくらいの内容に関係なくは、動的な要素のサポートを追加します。
<ul id="list">
    <li>item-1</li>
    <li>item-2</li>
    <li>item-3</li>
    <li>item-4</li>
    <li>item-5</li>
</ul>
<script>
    var list = document.getElementById('list');
    var handler = function(e){
      e = e || window.event;
      var target = e.target || e.srcElement;
      if(target.nodeName && target.nodeName === "LI"){
        console.log(target.innerHTML);
      }
    };

    if(list.addEventListener){
      list.addEventListener("click", handler);
    } else {
      list.attachEvent("onclick", handler);
    }

    //添加节点
    var list = document.getElementById('list');
    var newNode = document.createElement('li');
    newNode.innerHTML = "item-6";
    list.appendChild(newNode);
</script>

イベントパッケージ

明らかに、プロセスのブラウザの互換性あまりにも面倒なので、ここに置かjsのイベント登録相関関数は、仕上げとしてそれをパッケージ化します。

//均采用冒泡事件模型
var myEventUtil={
    //添加事件函数
    addEvent: function(ele, event, func){
        var target = event.target || event.srcElement;
        if(ele.addEventListener){
            ele.addEventListener(event, func, false);
        } else if(ele.attachEvent) {
            ele.attachEvent('on' + event, func);   //func中this是window
        } else {
            ele['on' + event] = func;    //会发生覆盖
        }
    },
    //删除事件函数
    delEvent:function(ele, event, func) {
        if(ele.removeEventListener){
            ele.removeEventListener(event, func, false);
        } else if(ele.detachEvent) {
            ele.detachEvent('on' + event, func);
        } else {
            ele['on' + event] = null;
        }
    },
    //获取触发事件的源DOM元素
    getSrcElement: function(event){
        return event.target || event.srcElement;
    },
    //获取事件类型
    getType: function(event){
        return event.type;
    },
    //获取事件
    getEvent:function(event){
        return event || window.event;
    },
    //阻止事件冒泡
    stopPropagation: function(event) {
        if(event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBuble = false;
        }
    },
    //禁用默认行为
    preventDefault: function(event){
        if(event.preventDefault){
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    }
};

jQueryのイベント

jQueryのイベントは、バブリング段階で作業している、とバブリング段階でできる唯一の仕事:という注意

登録リフティングイベント

  • この方法の一つ:
//不会发生覆盖,但不利于解除,不能动态操作事件
<button id="button">here</button>
$("#button").click(function(){   //注册一个click事件,当然可以用其他事件名的函数注册其他事件
  console.log("clicked");
});
  • 方法2:
//不会发生覆盖,利于解除,不能动态操作事件
<button id="button">here</button>
//注册一个事件
$("#button").bind("click", function() {    //注册一个click事件,当然可以用其他事件名的函数注册其他事件
  console.log("clicked");
});
//当然还可以这样写,给事件指定命名空间
$(document).bind('click.handler1', function() { console.log(1);})
$(document).bind('click.handler2', function() { console.log(2);})

//解除一个事件
$("#button").unbind(".handler1");    //解除元素上所以handler1命名空间中的事件
$("#button").unbind('click.handler2');   // 解除元素上的click.handler2事件
$("#button").unbind('click');            // 解除元素上所有点击事件
$("#button").unbind()                    // 解除元素上所有事件

//bind()方法还介受3个参数形式,这里就不赘述了,感兴趣可以自己看看相关资料。
  • 方法3:
//不会发生覆盖,但不利于解除,能动态操作事件,依赖于事件冒泡

//注册事件
$(document).delegate(".item", "click", function(){console.log(this.innerHTML);});   //第一个是选择器, 第二个是事件类型, 第三个是事件函数

//移除事件
$(document).undelegate(".item", "click", handler);  //移除元素上指定事件
$(document).undelegate(".item", "click");  //移除元素上所有click事件
$(document).undelegate(".item");  //移除元素上所有事件
  • 方法4:
//不会发生覆盖,但不利于解除,能动态操作事件,不依赖于事件冒泡

//注册事件
#(".item").live("click", function(){console.log(this.innerHTML);})  //第一参数是事件类型, 第二参数是事件函数

//移除事件
$(".item").die("click", handler);  //移除元素上指定click事件
$(".item").die("click");  //移除元素上所有click事件
  • 二つの簡略化された方法:
//hover方法
$("#button").hover(function(){
        //鼠标移入时的动作,不冒泡
    }, function(){
        //鼠标移出时的动作,不冒泡
});

//toggle方法
$("#button").toggle(function(){
        //第一次点击时的动作
    }, function(){
        //第二次点击时的动作
}, .../*可以放多个函数,依次循环响应*/);

イベントトリガー

//不能触发addEventListener和attachEvent
//主动触发一个事件
$("#button").trigger("click");   //触发所有click事件
$("#button").trigger("click.handler1");   //触发所有click.handler1事件
$("#button").trigger(".handler1");   //触发所有handler1命名空间的事件
$("#button").trigger("click!");   //触发所有没有命名空间的click事件
$("#button").trigger(event);   //在该元素上触发和事件event一样的事件
$("#button").trigger({type:"click", sync: true});   //触发click事件,同步

おすすめ

転載: www.cnblogs.com/jlfw/p/11842645.html