事件-PC 與 mobile phone

事件

  • 注意點: 事件方法都是沒有駝峯的
  • ==移動端和 PC 端各自有特有的事件==
  • css 的 pointerevents: none; 能使對應選擇器選到的 dom 不響應不攔截事件 css 的 pointerevents: none; 能使對應選擇器選到的 dom 不響應不攔截事件

移入, 移出, 移動 (移動端沒有移入移出事件)

  • .onmouseover .onmouseenter
  • .onmouseout .onmouseleave
  • .onmousemove
  • 淦!竟然沒駝峯
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>13-JavaScript-移入移出事件</title><style>*{margin: 0;padding: 0;
        }div{width: 300px;height: 300px;background: red;
        }</style></head><body><div></div><script>let oDiv = document.querySelector("div");// 1.移入事件// oDiv.onmouseover = function () {//     console.log("移入事件");// }// 注意點: 對於初學者來講, 爲了不未知的一些BUG, 建議使用onmouseenteroDiv.onmouseenter = function () {console.log("移入事件");
    }// 2.移出事件// oDiv.onmouseout = function () {//     console.log("移出事件");// }// 注意點: 對於初學者來講, 爲了不未知的一些BUG, 建議使用onmouseleaveoDiv.onmouseleave = function () {console.log("移出事件");
    }3.移動事件
    oDiv.onmousemove = function () {console.log("移動事件");
    }</script></body></html>複製代碼

表單焦點事件

  • .onfocus
  • .onblur
  • .onchange (只在失焦後才能拿到修改後的數據)
  • .oninput (實時獲取到修改後的數據)
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>17-JavaScript-焦點事件</title></head><body><input type="text"><script>let oInput = document.querySelector("input");// 1.監聽input獲取焦點oInput.onfocus = function () {console.log("獲取到了焦點");
    }// 2.監聽input失去焦點oInput.onblur = function () {console.log("失去了焦點");
    }// 3.監聽input內容改變// 注意點: onchange事件只有表單失去焦點的時候, 才能拿到修改以後的數據oInput.onchange = function () {console.log(this.value);
    }// oninput事件能夠時時獲取到用戶修改以後的數據, 只要用戶修改了數據就會調用(執行)// 注意點: oninput事件只有在IE9以上的瀏覽器才能使用// 在IE9如下, 若是想時時的獲取到用戶修改以後的數據, 能夠經過onpropertychange事件來實現oInput.oninput = function () {console.log(this.value);
    }</script></body></html>複製代碼

添加事件的三種方式

  1. element.onxxx
  2. element.attachEvent (上古, 瞭解便可)
  3. element.addEventListener (現代,可選事件冒泡 or 捕獲)

方法一:onxxx

注意點:css

  1. 因爲是給屬性賦值, 因此後賦值的會覆蓋先賦值
  2. 缺點很明顯: 不能經過一個事件觸發多個方法, 不利於維持方法的細粒度
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>onclick</title></head><body><button id="btn">我是按鈕</button><script>// 這點擊事件只會輸出 777, 原理就是給對象屬性重賦值會對原有的值進行覆蓋var oBtn = document.getElementById("btn");

    oBtn.onclick = function () {
        alert("666");
    }
    oBtn.onclick = function () {
        alert("777");
    }</script></body></html>複製代碼

方法二:attachEvent

注意點:html

  1. 事件名稱必須加上on
  2. 後添加的不會覆蓋先添加的
  3. 只支持低版本的瀏覽器
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>attachEvent</title></head><body><button id="btn">我是按鈕</button><script>// 既輸出 666 也輸出 777,但現代瀏覽器已經摒棄了這個方法var oBtn = document.getElementById("btn");

    oBtn.attachEvent("onclick", function () {
        alert("666");
    });
    oBtn.attachEvent("onclick", function () {
        alert("777");
    });</script></body></html>複製代碼

方法三:addEventListen

注意點:瀏覽器

  1. 事件名稱不須要添加 on
  2. 後添加的不會覆蓋先添加的
  3. 只支持現代瀏覽器(其實徹底足夠了)
  4. 這是三個裏惟一可自定義事件是冒泡行爲仍是捕獲行爲的方法
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>addEventListener</title></head><body><button id="btn">我是按鈕</button><script>// 既輸出 666 也輸出 777,現代瀏覽器通用這個方法var oBtn = document.getElementById("btn");

    oBtn.addEventListener("click", function () {
        alert("666");
    });
    oBtn.addEventListener("click", function () {
        alert("777");
    });</script></body></html>複製代碼

強行兼容

看似考慮周全,實則沒有必要dom

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>加個判斷</title></head><body><button id="btn">我是按鈕</button><script>var oBtn = document.getElementById("btn");function addEvent(ele, name, fn) {if(ele.attachEvent){
            ele.attachEvent("on"+name, fn);
        }else{
            ele.addEventListener(name, fn);
        }
    }</script></body></html>複製代碼

事件對象

  • 事件對象就是一個系統自動建立的一個對象
  • 當註冊的事件被觸發的時候, 系統就會自動建立事件對象
  • 事件對象的屬性海了去了

注意點:ide

  1. 在高級版本的瀏覽器中, 會自動將事件對象傳遞給回到函數
  2. 在低級版本的瀏覽器中, 不會自動將事件對象傳遞給回調函數, 須要經過 window.event 來獲取事件對象

關於阻止默認行爲:函數

  1. event.preventDefault(); 只支持現代瀏覽器
  2. event.returnValue = false; 只支持上古瀏覽器(瞭解便可, 這年頭誰還用 IE8 啊)
  3. return false; 通吃
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>事件對象</title></head><body><button id="btn">我是按鈕</button><a href="http://www.baidu.com">百度首頁</a><script>
   var oBtn = document.getElementById("btn");
   oBtn.onclick = function (event) {       // 兼容性的寫法   event = event || window.event;       // alert("666");   console.log(event);       console.log(typeof event);
   }   let oA = document.querySelector("a");
    oA.onclick = function (event) {// 兼容性的寫法event = event || window.event;

        alert("666");// 阻止默認行爲return false; // 企業開發推薦// event.preventDefault(); // 高級瀏覽器// event.returnValue = false; // IE9如下瀏覽器}</script></body></html>複製代碼

事件執行的三個階段

三個階段

  1. 捕獲階段(從外向內的傳遞事件)
  2. 當前目標階段
  3. 冒泡的階段(從內向外的傳遞事件)

注意點:this

  • 三個階段只有兩個會被同時執行
  • 要麼捕獲和當前, 要麼當前和冒泡

爲何要麼只能是捕獲和當前, 要麼只能是當前和冒泡?scala

這是JS處理事件的歷史問題orm

早期各大瀏覽器廠商爲爭奪定義權, 以及對事件的理解不一樣, 產生了捕獲和冒泡兩種流向htm

後續W3C爲了兼容, 將兩種方式都歸入標準

冒泡仍是捕獲

如何設置事件究竟是捕獲仍是冒泡?

經過addEventListener方法, 這個方法接收三個參數

  • 第一個參數: 事件的名稱
  • 第二個參數: 回調函數
  • 第三個參數: ==false 冒泡== / ==true 捕獲==

注意點:

  • onXxx的屬性, 不接收任何參數, 因此默認就是冒泡
  • attachEvent方法, 只能接收兩個參數, 因此默認就是冒泡
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>41-JavaScript-事件執行的三個階段</title><style>*{margin: 0;padding: 0;
        }.father{width: 300px;height: 300px;background: red;
        }.son{width: 150px;height: 150px;background: blue;
        }</style></head><body><div class="father"><div class="son"></div></div><script>let oFDiv = document.querySelector(".father");let oSDiv = document.querySelector(".son");
    oFDiv.addEventListener("click", function () {console.log("father");
    }, false);
    oSDiv.addEventListener("click", function () {console.log("son");
    }, false);</script></body></html><!--
默認就是 false,也就是冒泡
設置爲 true 的元素及其子元素鏈條都變爲捕獲,且僅影響自身及其子代,不影響其父元素
-->複製代碼

關於冒泡的細節

IE6.0: div -> body -> html -> document

其餘瀏覽器: div -> body -> html -> document -> window

注意: 不是全部的事件都能冒泡,有些事件不冒泡,如 blur、 focus、 load、 unload 等

阻止事件冒泡 (強行兼容)

首先要明確:阻止的前提是有事件,阻止事件冒泡的操做是寫在實踐方法的回調函數裏的

  1. event.cancelBubble = true; (上古)
  2. event.stopProgagation(); (現代,知道這個纔要緊)
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>43-JavaScript-阻止事件冒泡</title><style>*{margin: 0;padding: 0;
        }.father{width: 300px;height: 300px;background: red;
        }.son{width: 150px;height: 150px;background: blue;
        }</style></head><body><div class="father" id="father"><div class="son" id="son"></div></div><script>// 1.拿到須要操做的元素var oFDiv = document.getElementById("father");var oSDiv = document.getElementById("son");    // 2.註冊事件監聽oFDiv.onclick = function () {console.log("father");
    }
    oSDiv.onclick = function (event) {
        event = event || window.event;// event.stopPropagation(); // 高級瀏覽器// event.cancelBubble = true; // 低級瀏覽器if(event.cancelBubble){
            event.cancelBubble = true;
        }else{
            event.stopPropagation();
        }console.log("son");
    }</script></body></html>複製代碼

不一樣移入移出事件辨析

區別在因而否觸發冒泡(或捕獲)

  1. onmouseover 和 onmouseenter 的區別
  • onmouseover 移入到子元素,父元素的移入事件也會被觸發
  • onmouseenter 移入到子元素,父元素的移入事件不會被觸發
onmouseout 和 onmouseleave 的區別
  • onmouseout 移出到子元素,父元素的移入事件也會被觸發
  • onmouseleave 移出到子元素,父元素的移入事件不會被觸發
簡單來講, enter 和 leave 比較乾淨不拖泥帶水
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>44-JavaScript-移入移出事件區別</title><style>*{margin: 0;padding: 0;
        }.father{width: 300px;height: 300px;background: red;
        }.son{width: 150px;height: 150px;background: blue;
        }</style></head><body><div class="father"><div class="son"></div></div><script>let oFDiv = document.querySelector(".father");let oSDiv = document.querySelector(".son");/*
    oFDiv.onmouseover = function () {
        console.log("father");
    }
    oSDiv.onmouseover = function () {
        console.log("son");
    }
     *//*
    oFDiv.onmouseenter = function () {
        console.log("father");
    }
    oSDiv.onmouseenter = function () {
        console.log("son");
    }
     */oFDiv.onmouseleave = function () {console.log("father");
    }
    oSDiv.onmouseleave = function () {console.log("son");
    }</script></body></html>複製代碼

經過事件獲取元素位置

  • offsetX/offsetY: 事件觸發點相對於當前元素自身以左上爲原點的位置
  • clientX/clientY: 事件觸發相對於瀏覽器可視區域的位置(上古瀏覽器不支持)
  • 注意點:
    • 顯示器區域不包括滾動出去的部分(這個開發中用的少)
  • screenX/screenY: 事件觸發相對於屏幕的位置
  • 整個網頁包括滾動出去的部分 pageX/pageY: 事件觸發相對於整個網頁的位置(在頁面不滾動時拿到的值和 clientX/clientY 是同樣的)

細節們

  • 調用事件方法時 return false 能夠禁用默認事件, 或者用 event.preventDefault() 也行

  • 若是想獲取 query 到的 input 標籤對象中輸入的內容, 只能經過其 value 屬性

    html 能夠給標籤設置自定義標籤屬性, 能夠給 JS 用,

    甚至能夠經過 JS 給指定 DOM 添加自定義屬性標籤

  • 在 JS 中若是 HTML 標籤的屬性名稱和取值名稱同樣的時候, JS 會返回 true/false 但若是是經過代碼給 input 設置的數據, 那麼不會觸發 oninput 事件

  • 對上古瀏覽器的兼容只需瞭解便可

移動端事件

移動端特有事件對象

  1. Touch事件對象
  • 移動端的touch事件也是一個事件, 因此被觸發的時候系統也會自動傳遞一個事件對象給咱們
移動端touch事件對象中比較重要的三個子對象
  1. touches: 當前屏幕上全部手指的列表
  2. targetTouches: 保存了當前元素上全部的手指裏列表 (這個用的多)
  3. changedTouches: 當前屏幕上剛剛接觸的手指或者離開的手指

移動端點透問題

  1. 移動端點透問題
  • 當一個元素放覆蓋了另外一個元素, 覆蓋的元素監聽 ==touch== 事件,而下面的元素監聽 ==click== 事件
  • 而且touch事件觸發後覆蓋的元素就消失了, 那麼就會出現點透問題
移動端點透問題出現的緣由
  1. 當手指觸摸到屏幕的時候,系統生成兩個事件,一個是touch 一個是click
  2. touch 事件先執行,執行完後從文檔上消失
  3. click 事件有 100~300ms 延遲, 因此後執行. (理由不對嗷, 我加了 content="scalable=no" 也還能點透)
  4. 但 click 事件執行的時候觸發的元素已經消失了, 對應的位置如今是下面的元素, 因此就觸發了下面元素的 click    事件
移動端點透問題解決方案 在touch事件中添加event.preverDefault(); 阻止事件擴散
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>10-移動端點透問題</title><style>
			* {				margin: 0;				padding: 0;
			}			div {				text-align: center;				font-size: 40px;
			}			.click {				width: 300px;				height: 300px;				background: red;				position: absolute;				left: 50%;				transform: translateX(-50%);				top: 100px;
			}			.tap {				width: 200px;				height: 200px;				background: blue;				position: absolute;				left: 50%;				transform: translateX(-50%);				top: 150px;
			}		</style></head><body><div class="click">click</div><div class="tap">tap</div><!-- 兩元素在同級, 但展示時兩個塊塊有重疊 --><script>let oClick = document.querySelector(".click");			let oTap = document.querySelector(".tap");

			oTap.ontouchstart = function (event) {				this.style.display = "none";
				event.preventDefault(); //  阻止事件擴散
			};
			oClick.onclick = function () {				console.log("click");
			};		</script></body></html>複製代碼
相關文章
相關標籤/搜索