首頁 > web前端 > js教程 > 主體

js之dom事件的進階補充

小云云
發布: 2017-12-08 16:51:42
原創
1630 人瀏覽過

前面我們分享過原生js 操作dom的方法,本文我們接著js之dom事件的進階補充,希望能幫助大家。

事件覆寫的問題
清楚原理
使用事件來源.事件類型的新增事件方式會產生覆寫問題。我們透過一個函數去避免這個問題。

function addEvent(tag,fn){
    var oldClick=tag.onclick    if(typeof oldClick=="function"){
        tag.onclick=function(){
            oldClick();
            fn();
    }
    }else{
        tag.onclick=fn;
    }
}
登入後複製
登入後複製

新增事件(必須掌握)
自帶的新增事件新方式:
好處,可以避免事件覆寫問題
事件來源.addEventListener(“click ”,function(){});   ie9以上瀏覽器支援
注意:類型名稱不加on

事件來源.attachEvent(“onclick”,function(){})  ie低版支援
注意,類型名稱加on

移除事件的方式
addEventListener 的新增方式使用removeEventListener進行移除
注意第二個參數的寫法

js之dom事件的進階補充

事件來源.detachEvent(“onclick”,fn)用於取消使用attachEvent新增的事件

js之dom事件的進階補充

原始的取消方式

box.onclick=function(){}
box.onclick=null;
登入後複製
登入後複製

addEventListener相容封裝。

var Event = {//添加事件。oElement:元素,sEvent:事件类型,fnHandler:绑定的函数
    addHandler: function (oElement, sEvent, fnHandler) {
        oElement.addEventListener ? oElement.addEventListener(sEvent, fnHandler, false) : oElement.attachEvent("on" + sEvent, fnHandler)    
    },//删除事件。
    removeHandler: function (oElement, sEvent, fnHandler) {
        oElement.removeEventListener ? oElement.removeEventListener(sEvent, fnHandler, false) : oElement.detachEvent("on" + sEvent, fnHandler)
    }
}
使用列子:
<input type="button" value="毫无用处的按钮"> <input type="button" value="绑定click"> <input type="button" value="解除绑定">

window.onload = function (){
    var aBtn = document.getElementsByTagName("input");    //为第一个按钮添加绑定事件
    aBtn[1].onclick = function ()
    {
        Event.addHandler(aBtn[0], "click", fnHandler);    
        aBtn[0].value = "我可以点击了"
    }    //解除第一个按钮的绑定事件
    aBtn[2].onclick = function ()
    {
        Event.removeHandler(aBtn[0], "click", fnHandler);
        aBtn[0].value = "毫无用处的按钮"    
    }    //事件处理函数
    function fnHandler ()
    {
        alert("事件绑定成功!")    
    }
}
登入後複製
登入後複製

事件冒泡和事件捕獲
必須掌握冒泡和捕獲的執行順序
事件冒泡是事件傳遞的一種方式
傳遞方式為:由最特定的元素觸發到最不特定的元素 子向父
首先觸發當前元素的事件,觸發完畢向上傳播,如果父級也含有這個事件,觸發,再向上,如果沒有直接繼續向上尋找。
透過addEventListener新增的事件,第三個參數為false表示事件冒泡。預設為false

box1.addEventListener("click",function(){alert(1)},false)
登入後複製
登入後複製

事件捕獲是事件傳遞的一種方式
事件捕獲的執行方式,是由外向內(跟冒泡相反)。
透過addEventListener新增的事件,第三個參數為true表示事件捕獲。

box1.addEventListener("click",function(){alert(1)},true)
登入後複製
登入後複製

事件物件(必須掌握)
取得方式:
1、當事件觸發時,我們可以透過在事件處理程序中接收事件物件。
這種獲取形式在ie低版本不支援。

document.onmousemove=function(e){
    var e=e||window.event;//兼容ie}
登入後複製
登入後複製

2、在ie低版本中使用window.event作為事件對象,作用和e相同

事件對象的屬性(必須掌握)
事件物件.type 表示事件的類型,注意是不加on的

事件物件.clientX和事件物件.clientY可以取得事件觸發時滑鼠針對瀏覽器視覺區域的橫座標和縱座標。

事件物件.pageX與事件物件.pageY可以取得事件觸發時滑鼠針對頁面左頂點的橫座標和縱座標。 有相容性問題,ie低版本不支持,需要封裝函數取得。
pageX與pageY的封裝

function getPage(e){var e=e||window.event;var src=scroll()//这个函数是在dom高级里面讲到对scrollLeft和scrollTop的封装;
    return {
     PageX:scroll.scrollleft+e.clientX,
      PageY:scroll.scrolltop+e.clienttop,
    }
}
登入後複製
登入後複製

onmousemove 滑鼠移動時觸發
onmousedown 滑鼠點下時觸發
onmouseup    滑鼠抬起時觸發
#事件處理程序的執行環境
ele.onxxx = function(event) { }  
程式this指向是dom元素本身
obj.addEventListener(type, fn, false);  
#程式this指向是dom元素本身
obj.attachEvent('on' + type, fn);  
程式this指向window

封装兼容性的addEvent(elem, type, handle);方法function addEvent(elem, type, handle) {    if(elem.addEventListener) {
        elem.addEventListener(type, handle, false);
    }else if(elem.attachEvent) {
         elem[&#39;temp&#39;] = function() {
            handle.call(elem);
        }
        elem.attachEvent(&#39;on&#39; + type, elem[&#39;temp&#39;]);
    }else{
        elem[&#39;on&#39; + type] = handle;
    }
}
登入後複製
登入後複製
封装的兼容方法function removeEvent(elem, type, handle) {
    if(elem.removeEventListener) {
        elem.removeEventListener(type, handle, false);
    }else if(elem.detachEvent) {
        elem.detachEvent(&#39;on&#39; + type, handle);
    }else{
        elem[&#39;on&#39; + type] = null;
    }
}
登入後複製
登入後複製

事件冒泡和事件捕獲有什麼好處和弊端。

(1)冒泡型事件:事件依照從最特定的事件目標到最不特定的事件目標(document物件)的順序觸發。
 IE 5.5: p -> body -> document
 IE 6.0: p -> body -> html -> document
Mozilla 1.0: p -> body -> html -> document -> window
(2)捕獲型事件(event capturing):事件從最不精確的物件(document 物件)開始觸發,然後到最精確(也可以在視窗層級擷取事件,不過必須由開發人員特別指定)。
(3)DOM事件流:同時支援兩種事件模型:捕獲型事件和冒泡型事件,但是,捕獲型事件先發生。兩種事件流會觸及DOM中的所有對象,從document物件開始,也在document物件結束。
 DOM事件模型最獨特的性質是,文字節點也觸發事件(在IE中不會)。
事件冒泡典型的例子
冒泡的思路是在祖先節點上監聽事件,結合event.target/event.srcElement來實現最終效果,其效果等同於如下程式碼:

<p class="J_rate" onmouseover="..." onmouseout="..." onclick="...">
  <img  src="star.gif" title="很烂" / alt="js之dom事件的進階補充" >
  <img  src="star.gif" title="一般" / alt="js之dom事件的進階補充" >
  <img  src="star.gif" title="还好" / alt="js之dom事件的進階補充" >
  <img  src="star.gif" title="较好" / alt="js之dom事件的進階補充" >
  <img  src="star.gif" title="很好" / alt="js之dom事件的進階補充" >
 </p>
 // 五心好评的例子,不用给img添加,直接给父元素加
登入後複製
登入後複製

停止事件冒泡

#
event.stopPropagation(); // 阻止事件冒泡return false;既能阻止默认事件又能 阻止事件冒泡
登入後複製
登入後複製

当用户名为空时,单击“提交”按钮,会出现提示,并且表单不能提交。只有在用户名里输入内容后,才能提交表单。可见,preventDefault()方法能阻止表单的提交行为。
如果想同时对事件对象停止冒泡和默认行为,可以在事件处理函数中返同false。这是对在事件对象上同时调用stopPrapagation()方法和preventDefault()方法的一种简写方式。
在表单的例子中,可以把 event.preventDefault(); 改写为: return false;
也可以把事件冒泡例子中的 event.stopPropaqation(); 改写为: return false;

事件覆盖的问题
清楚原理
使用事件源.事件类型的添加事件方式会产生覆盖问题。我们通过一个函数去避免这个问题。

function addEvent(tag,fn){
    var oldClick=tag.onclick    if(typeof oldClick=="function"){
        tag.onclick=function(){
            oldClick();
            fn();
    }
    }else{
        tag.onclick=fn;
    }
}
登入後複製
登入後複製

添加事件(必须掌握)
自带的添加事件新方式:
好处,可以避免事件覆盖问题
事件源.addEventListener(“click”,function(){}); ie9以上浏览器支持
注意:类型名不加 on

事件源.attachEvent(“onclick”,function(){}) ie低版本支持
注意,类型名加on

移除事件的方式
addEventListener 的添加方式使用removeEventListener进行移除
注意第二个参数的写法

js之dom事件的進階補充

事件源.detachEvent(“onclick”,fn)用于取消使用attachEvent添加的事件

js之dom事件的進階補充

原始的取消方式

box.onclick=function(){}
box.onclick=null;
登入後複製
登入後複製

addEventListener兼容封装。

var Event = {//添加事件。oElement:元素,sEvent:事件类型,fnHandler:绑定的函数
    addHandler: function (oElement, sEvent, fnHandler) {
        oElement.addEventListener ? oElement.addEventListener(sEvent, fnHandler, false) : oElement.attachEvent("on" + sEvent, fnHandler)    
    },//删除事件。
    removeHandler: function (oElement, sEvent, fnHandler) {
        oElement.removeEventListener ? oElement.removeEventListener(sEvent, fnHandler, false) : oElement.detachEvent("on" + sEvent, fnHandler)
    }
}
使用列子:
<input type="button" value="毫无用处的按钮"> <input type="button" value="绑定click"> <input type="button" value="解除绑定">

window.onload = function (){
    var aBtn = document.getElementsByTagName("input");    //为第一个按钮添加绑定事件
    aBtn[1].onclick = function ()
    {
        Event.addHandler(aBtn[0], "click", fnHandler);    
        aBtn[0].value = "我可以点击了"
    }    //解除第一个按钮的绑定事件
    aBtn[2].onclick = function ()
    {
        Event.removeHandler(aBtn[0], "click", fnHandler);
        aBtn[0].value = "毫无用处的按钮"    
    }    //事件处理函数
    function fnHandler ()
    {
        alert("事件绑定成功!")    
    }
}
登入後複製
登入後複製

事件冒泡和事件捕获
必须掌握冒泡和捕获的执行顺序
事件冒泡是事件传递的一种方式
传递方式为:由最特定的元素触发到最不特定的元素 子向父
首先触发当前元素的事件,触发完毕向上传播,如果父级也含有这个事件,触发,再向上,如果没有直接继续向上寻找。
通过addEventListener添加的事件,第三个参数为false表示事件冒泡。默认为false

box1.addEventListener("click",function(){alert(1)},false)
登入後複製
登入後複製

事件捕获是事件传递的一种方式
事件捕获的执行方式,是由外向内(跟冒泡相反)。
通过addEventListener添加的事件,第三个参数为true表示事件捕获。

box1.addEventListener("click",function(){alert(1)},true)
登入後複製
登入後複製

事件对象(必须掌握)
获取方式:
1、当事件触发时,我们可以通过在事件处理程序中接收事件对象。
这种获取形式在ie低版本不支持。

document.onmousemove=function(e){
    var e=e||window.event;//兼容ie}
登入後複製
登入後複製

2、在ie低版本中使用window.event作为事件对象,作用和e相同

事件对象的属性(必须掌握)
事件对象.type 表示事件的类型,注意是不加on的

事件对象.clientX和事件对象.clientY可以获取事件触发时鼠标针对浏览器可视区域的横坐标和纵坐标。

事件对象.pageX和事件对象.pageY可以获取事件触发时鼠标针对页面左顶点的横坐标和纵坐标。 有兼容性问题,ie低版本不支持,需要封装函数获取。
pageX和pageY的封装

function getPage(e){var e=e||window.event;var src=scroll()//这个函数是在dom高级里面讲到对scrollLeft和scrollTop的封装;
    return {
     PageX:scroll.scrollleft+e.clientX,
      PageY:scroll.scrolltop+e.clienttop,
    }
}
登入後複製
登入後複製

onmousemove 鼠标移动时触发
onmousedown 鼠标点下时触发
onmouseup 鼠标抬起时触发
事件处理程序的运行环境
ele.onxxx = function(event) { }
程序this指向是dom元素本身
obj.addEventListener(type, fn, false);
程序this指向是dom元素本身
obj.attachEvent(‘on’ + type, fn);
程序this指向window

封装兼容性的addEvent(elem, type, handle);方法function addEvent(elem, type, handle) {    if(elem.addEventListener) {
        elem.addEventListener(type, handle, false);
    }else if(elem.attachEvent) {
         elem[&#39;temp&#39;] = function() {
            handle.call(elem);
        }
        elem.attachEvent(&#39;on&#39; + type, elem[&#39;temp&#39;]);
    }else{
        elem[&#39;on&#39; + type] = handle;
    }
}
登入後複製
登入後複製
封装的兼容方法function removeEvent(elem, type, handle) {
    if(elem.removeEventListener) {
        elem.removeEventListener(type, handle, false);
    }else if(elem.detachEvent) {
        elem.detachEvent(&#39;on&#39; + type, handle);
    }else{
        elem[&#39;on&#39; + type] = null;
    }
}
登入後複製
登入後複製

事件冒泡和事件捕获有什么好处和弊端。

(1)冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。
IE 5.5: p -> body -> document
IE 6.0: p -> body -> html -> document
Mozilla 1.0: p -> body -> html -> document -> window
(2)捕获型事件(event capturing):事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)。
(3)DOM事件流:同时支持两种事件模型:捕获型事件和冒泡型事件,但是,捕获型事件先发生。两种事件流会触及DOM中的所有对象,从document对象开始,也在document对象结束。
DOM事件模型最独特的性质是,文本节点也触发事件(在IE中不会)。
事件冒泡典型的例子
冒泡的思路是在祖先节点上监听事件,结合event.target/event.srcElement来实现最终效果,其效果等同于如下代码:

<p class="J_rate" onmouseover="..." onmouseout="..." onclick="...">
  <img  src="star.gif" title="很烂" / alt="js之dom事件的進階補充" >
  <img  src="star.gif" title="一般" / alt="js之dom事件的進階補充" >
  <img  src="star.gif" title="还好" / alt="js之dom事件的進階補充" >
  <img  src="star.gif" title="较好" / alt="js之dom事件的進階補充" >
  <img  src="star.gif" title="很好" / alt="js之dom事件的進階補充" >
 </p>
 // 五心好评的例子,不用给img添加,直接给父元素加
登入後複製
登入後複製

停止事件冒泡

event.stopPropagation(); // 阻止事件冒泡return false;既能阻止默认事件又能 阻止事件冒泡
登入後複製
登入後複製

当用户名为空时,单击“提交”按钮,会出现提示,并且表单不能提交。只有在用户名里输入内容后,才能提交表单。可见,preventDefault()方法能阻止表单的提交行为。
如果想同时对事件对象停止冒泡和默认行为,可以在事件处理函数中返同false。这是对在事件对象上同时调用stopPrapagation()方法和preventDefault()方法的一种简写方式。
在表单的例子中,可以把 event.preventDefault(); 改写为: return false;
也可以把事件冒泡例子中的 event.stopPropaqation(); 改写为: return false;

相关推荐:

jquery之dom学习

原生js 操作dom

jQuery操作DOM的方法

以上是js之dom事件的進階補充的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!