亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript中mouseenter與mouseover的異同點有哪些

發布時間:2021-08-11 15:27:43 來源:億速云 閱讀:150 作者:小新 欄目:web開發

這篇文章主要介紹javascript中mouseenter與mouseover的異同點有哪些,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

mouseenter與mouseover的異同?

要說清楚mouseenter與mouseover有什么不同,也許可以從兩方面去講。

是否支持冒泡 事件的觸發時機

先來看一張圖,對這兩個事件有一個簡單直觀的感受。

javascript中mouseenter與mouseover的異同點有哪些 再看看官網對mouseenter的解釋

mouseenter | onmouseenter event

The event fires only if the mouse pointer is outside the boundaries of the object and the user moves the mouse pointer inside the boundaries of the object. If the mouse pointer is currently inside the boundaries of the object, for the event to fire, the user must move the mouse pointer outside the boundaries of the object and then back inside the boundaries of the object.

大概意思是說:當鼠標從元素的邊界之外移入元素的邊界之內時,事件被觸發。而當鼠標本身在元素邊界內時,要觸發該事件,必須先將鼠標移出元素邊界外,再次移入才能觸發。(英語比較渣:no_mouth:,湊合看哈)

Unlike the onmouseover event, the onmouseenter event does not bubble.

大概意思是:和mouseover不同的是,mouseenter不支持事件冒泡 (英語比較渣:no_mouth:,湊合看哈)

由于mouseenter不支持事件冒泡,導致在一個元素的子元素上進入或離開的時候會觸發其mouseover和mouseout事件,但是卻不會觸發mouseenter和mouseleave事件

我們用一張動圖來看看他們的區別(或者點擊該鏈接體驗)。

javascript中mouseenter與mouseover的異同點有哪些

我們給左右兩邊的ul分別添加了 mouseovermouseenter 事件,當鼠標進入左右兩邊的ul時, mouseovermouseenter 事件都觸發了,但是當移入各自的子元素li的時候,觸發了左邊ul上的mouseover事件,然而右邊ul的mouseenter事件沒有被觸發。

造成以上現象本質上是 mouseenter 事件不支持冒泡所致。

如何模擬mouseenter事件。

可見mouseover事件因其具有冒泡的性質,在子元素內移動的時候,頻繁被觸發,如果我們不希望如此,可以使用mouseenter事件代替之,但是早期只有ie瀏覽器支持該事件,雖然現在大多數高級瀏覽器都支持了mouseenter事件,但是難免會有些兼容問題,所以如果可以自己手動模擬,那就太好了。

關鍵因素: relatedTarget 要想手動模擬mouseenter事件,需要對mouseover事件觸發時的事件對象event屬性relatedTarget了解。

relatedTarget事件屬性返回與事件的目標節點相關的節點。 對于mouseover事件來說,該屬性是鼠標指針移到目標節點上時所離開的那個節點。 對于mouseout事件來說,該屬性是離開目標時,鼠標指針進入的節點。 對于其他類型的事件來說,這個屬性沒有用。

重新回顧一下文章最初的那張圖,根據上面的解釋,對于ul上添加的mouseover事件來說,relatedTarget只可能是

ul的父元素wrap(移入ul時,此時也是觸發mouseenter事件的時候, 其實不一定,后面會說明 ), 或者ul元素本身(在其子元素上移出時), 又或者是子元素本身(直接從子元素A移動到子元素B)。

javascript中mouseenter與mouseover的異同點有哪些

relatedTarget

根據上面的描述,我們可以對relatedTarget的值進行判斷:如果值不是目標元素,也不是目標元素的子元素,就說明鼠標已移入目標元素而不是在元素內部移動。

條件1: 不是目標元素 很好判斷 e.relatedTarget !== target(目標元素)

條件2:不是目標元素的子元素,這個應該怎么判斷呢?

ele.contains

這里需要介紹一個新的api node.contains(otherNode) , 表示傳入的節點是否為該節點的后代節點, 如果 otherNode 是 node 的后代節點或是 node 節點本身.則返回true , 否則返回 false

用法案例

<ul class="list">
 <li class="item">1</li>
 <li>2</li>
</ul>
<div class="test"></div>
let $list = document.querySelector('.list')
let $item = document.querySelector('.item')
let $test = document.querySelector('.test')

$list.contains($item) // true
$list.contains($test) // false
$list.contains($list) // true

那么利用contains這個api我們便可以很方便的驗證條件2,接下來我們封裝一個 contains(parent, node) 函數,專門用來判斷 node 是不是 parent 的子節點

let contains = function (parent, node) {
 return parent !== node && parent.contains(node)
}

用我們封裝過后的 contains 函數再去試試上面的例子

contains($list, $item) // true
contains($list, $test) // false
contains($list, $list) // false (主要區別在這里)

這個方法很方便地幫助我們解決了模擬mouseenter事件中的條件2,但是悲催的 ode.contains(otherNode) ,具有瀏覽器兼容性,在一些低級瀏覽器中是不支持的,為了做到兼容我們再來改寫一下contains方法

let contains = docEle.contains ? function (parent, node) {
 return parent !== node && parent.contains(node)
} : function (parent, node) {
 let result = parent !== node

 if (!result) { // 排除parent與node傳入相同的節點
 return result
 }

 if (result) {
 while (node && (node = node.parentNode)) {
  if (parent === node) {
  return true
  }
 }
 }

 return false
}

說了這么多,我們來看看用 mouseover 事件模擬 mouseenter 的最終代碼

// callback表示如果執行mouseenter事件時傳入的回調函數

let emulateEnterOrLeave = function (callback) {
 return function (e) {
 let relatedTarget = e.relatedTarget
 if (relatedTarget !== this && !contains(this, relatedTarget)) {
  callback.apply(this, arguments)
 }
 }
}

詳細代碼點擊

代碼示例點擊

好了,我們已經通過mouseove事件完整的模擬了mouseenter事件,但是反過頭來看看

對于ul上添加的mouseover事件來說,relatedTarget只可能是

ul的父元素wrap(移入ul時,此時也是觸發mouseenter事件的時候, 其實不一定,后面會說明 ), 或者ul元素本身(在其子元素上移出時), 又或者是子元素本身(直接從子元素A移動到子元素B)。

我們通過排查2和3,最后只留下1,也就是mouseenter與mouseover事件一起觸發的時機。既然這樣我們為什么不像這樣判斷呢?

target.addEventListener('mouseover', function (e) {
 if (e.relatedTarget === this.parentNode) {
 // 執行mouseenter的回調要做的事情 
 }
}, false)

這樣不是更加簡單嗎?,何必要折騰通過排查2和3來做?

原因是,target的父元素有一定的占位空間的時后,我們這樣寫是沒有太大問題的,但是反之,這個時候 e.relatedTarget 就可能是target元素的父元素,又祖先元素中的某一個。我們無法準確判斷e.relatedTarget到底是哪個元素。所以通過排除2和3應該是個更好的選擇。

用mouseout模擬mouseleave事件

當mouseout被激活時,relatedTarget表示鼠標離開目標元素時,進入了哪個元素,我們同樣可以對relatedTarget的值進行判斷:如果值不是目標元素,也不是目標元素的子元素,就說明鼠標已移出目標元素

我們同樣可以用上面封裝的函數完成

// callback表示如果執行mouseenter事件時傳入的回調函數

let emulateEnterOrLeave = function (callback) {
 return function (e) {
 let relatedTarget = e.relatedTarget
 if (relatedTarget !== this && !contains(this, relatedTarget)) {
  callback.apply(this, arguments)
 }
 }
}

以上是“javascript中mouseenter與mouseover的異同點有哪些”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

邹平县| 调兵山市| 海丰县| 金秀| 阿合奇县| 邵阳县| 海伦市| 克山县| 娱乐| 虎林市| 中方县| 榕江县| 鹤岗市| 邵阳市| 亚东县| 天台县| 十堰市| 武穴市| 剑河县| 岳普湖县| 遵化市| 利辛县| 习水县| 天等县| 金堂县| 淅川县| 随州市| 平舆县| 惠安县| 营口市| 新竹市| 潞西市| 济南市| 乌鲁木齐市| 丁青县| 金华市| 葵青区| 北宁市| 景洪市| 铁岭县| 新田县|