精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

事件委托的深層原理:當冒泡不夠用時,你該做什么?

開發 前端
并非所有事件都會冒泡——focus、blur、mouseenter和mouseleave?是例外。對于這些事件,使用focusin、focusout或自定義冒泡事件的替代方案。

隨著前端應用的規模擴大,用戶交互管理變得越來越重要。為每個交互元素添加事件監聽器是一種不良實踐,因為它可能導致代碼混亂、內存消耗增加和性能瓶頸。這時就需要事件委托了。

每個交互式網頁都是建立在文檔對象模型(DOM)及其事件系統之上的。當你點擊按鈕、在輸入框中輸入或懸停在圖片上時,就會觸發一個事件。但事件并非孤立發生,它會通過DOM樹傳播,這個過程稱為事件傳播。

對于構建現代Web應用的開發者來說,理解事件委托不僅是“錦上添花”,而是必不可少的。原因如下:

  • 提升效率——數百甚至數千個獨立的事件監聽器會消耗內存和CPU。事件委托集中處理,提高響應速度并減少開銷
  • 降低復雜度——在一個地方處理事件使代碼庫更整潔、更易導航和調試,避免監聽器散布各處
  • 保持功能——事件委托無縫支持動態添加的元素。即使DOM實時更新,應用也能保持響應

理解DOM事件傳播

在深入委托之前,了解事件如何通過DOM傳播非常重要。這個旅程被稱為事件傳播,分為三個不同階段。

三個階段

當事件在DOM元素上觸發時,它不會僅僅到達目標就停止。而是會經過以下階段:

  1. 捕獲階段——旅程從window開始,向下遍歷DOM樹中的每個祖先元素,直到到達目標元素的父元素。帶有useCapture = true(addEventListener的第三個參數)的事件監聽器在此觸發
  2. 目標階段——在此階段,事件到達目標元素。所有直接附加到該元素的事件監聽器都會觸發
  3. 冒泡階段——在擊中目標后,事件“冒泡”回DOM,從目標的父元素到其祖父元素,依此類推,直到到達window。默認情況下,大多數事件監聽器在此階段運行

你可以閱讀一篇全面的文章,了解原生JavaScript中事件傳播的工作原理。

事件在DOM樹中的流動

<div id="grandparent">
  <div id="parent">
    <button id="child">Click Me</button>
  </div>
</div>

如果你點擊<button id="child">,以下是click事件的流動:

  1. 捕獲——window -> document -> <html> -> <body> -> <div id="grandparent"> -> <div id="parent">
  2. 目標——<button id="child">
  3. 冒泡——<button id="child"> -> <div id="parent"> -> <div id="grandparent"> -> <body> -> <html> -> document -> window

我們可以使用event.eventPhase檢查事件階段:

const grandparent = document.getElementById('grandparent');
const parent = document.getElementById('parent');
const child = document.getElementById('child');

grandparent.addEventListener('click', (event) => {
console.log('Grandparent - Phase:', event.eventPhase, 'Target:', event.target.id);
}, true); // 捕獲階段

parent.addEventListener('click', (event) => {
console.log('Parent - Phase:', event.eventPhase, 'Target:', event.target.id);
}, true); // 捕獲階段

child.addEventListener('click', (event) => {
console.log('Child - Phase:', event.eventPhase, 'Target:', event.target.id);
}); // 冒泡階段(默認)

grandparent.addEventListener('click', (event) => {
console.log('Grandparent (Bubbling) - Phase:', event.eventPhase, 'Target:', event.target.id);
}); // 冒泡階段

parent.addEventListener('click', (event) => {
console.log('Parent (Bubbling) - Phase:', event.eventPhase, 'Target:', event.target.id);
}); // 冒泡階段

當你點擊“Click Me”按鈕時,控制臺輸出將顯示階段序列,展示事件如何先捕獲到DOM樹再冒泡回來:

圖片圖片

控制臺輸出顯示DOM點擊事件示例中捕獲、目標和冒泡階段的事件階段和目標

事件委托基礎

現在我們理解了事件傳播,讓我們探索如何利用它進行高效的事件處理。

什么是事件委托?

事件委托是一種將事件監聽器添加到多個子元素的父元素上的方法,而不是單獨添加到每個子元素。當子元素上的事件發生時,它會觸發父元素上的監聽器,監聽器會檢查是哪個子元素觸發了事件。

考慮一個簡單的列表<ul>,其中包含<li>項:

<ul id="myList">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
</ul>

而不是為每個<li>添加點擊監聽器:

const listItems = document.querySelectorAll('#myList li');
listItems.forEach(item => {
  item.addEventListener('click', (event) => {
    console.log(`Clicked on: ${event.target.textContent}`);
  });
});

使用事件委托,你只需將一個監聽器附加到父元素<ul>:

const myList = document.getElementById('myList');

myList.addEventListener('click', (event) => {
  // 檢查點擊的元素是否是<li>
  if (event.target.tagName === 'LI') {
    console.log(`Clicked on: ${event.target.textContent}`);
  }
});

在這個例子中,當任何<li>被點擊時,click事件會冒泡到myList。myList上的單個事件監聽器然后檢查event.target.tagName,確認是<li>觸發了事件,并相應地執行操作:

圖片圖片

控制臺輸出顯示使用事件委托在四個列表項上點擊事件(標記為Item 1到Item 4)

為什么重要

事件委托非常有益,因為:

  • 相比可能添加數百或數千個監聽器,少數父容器就足夠了,大大減少內存占用
  • 更少的監聽器提高了瀏覽器的整體系統內存使用效率,并減少了JavaScript引擎在事件管理和分發方面的負載
  • 它支持動態創建的元素,這對于動態創建帶有事件處理器的JavaScript元素非常有幫助。假設在頁面加載后(例如API調用后)向#myList添加新的<li>元素,#myList上的監聽器仍然有效。無需重新附加監聽器

事件委托中的常見陷阱

雖然事件委托功能強大,但也有其注意事項。理解這些陷阱有助于你更可靠地實現它。

event.target與event.currentTarget

這兩個屬性經常被混淆,但它們有不同的用途:

  • event.target 是觸發事件的具體元素。在ul > li示例中,點擊<li>會使該<li>成為event.target,即使監聽器附加在<ul>上
  • event.currentTarget 是事件監聽器實際附加的元素。在我們的委托ul > li示例中,如果監聽器在myList(<ul>)上,那么event.currentTarget始終是myList

何時使用哪個

  • 使用event.target 當你需要確定在委托設置中哪個子元素被點擊或交互時
  • 使用event.currentTarget 當你需要引用帶有監聽器的元素本身時,例如在移除監聽器或事件發生后對容器執行操作:
myList.addEventListener('click', (event) => {
  console.log('Target element:', event.target.tagName);
  console.log('Current element with listener:', event.currentTarget.id);

  if (event.target.tagName === 'LI') {
    event.target.style.backgroundColor = 'lightblue'; // 修改被點擊的LI
  }
});

圖片圖片

控制臺輸出顯示點擊事件中的目標元素和帶有監聽器的當前元素

stopPropagation()和stopImmediatePropagation()

雖然這些技術可以有效地管理事件流,但它們可能會削弱委托處理程序的影響。

  • event.stopPropagation()——此方法將阻止事件繼續冒泡或捕獲。如果在子元素的事件處理程序中執行此操作,則其祖先上的任何委托監聽器都無法訪問該事件
  • event.stopImmediatePropagation()——這不是stopPropagation()的簡單復制粘貼。它們的相似之處在于這種效果:它阻止進一步的事件傳播,以及阻止附加到同一元素的其他任何監聽器執行

在某些情況下,它們會破壞委托處理程序,例如:子元素的事件處理程序調用stopPropagation將為DOM層次結構中任何委托監聽器創建功能空白。委托監聽器將不會收到事件。這對分析、集中式UI邏輯或可訪問的自定義控件功能尤其麻煩。

在這種情況下,除非有充分理由,否則不建議使用stopPropagation()和stopImmediatePropagation()。大多數情況下,其他技術(如event對象的屬性或管理組件狀態)可以讓事件流動而不產生意外后果。

Shadow DOM和事件傳播

Shadow DOM構成了組件的內部結構和樣式,并封裝了組件的邊界。Web組件的這一部分會影響事件流:

  • 事件重新定位——當事件冒泡出Shadow DOM時,event.target屬性會將指針重置為Shadow Host(自定義元素)。這是封裝和安全措施。外部世界不需要知道組件的組成部分
  • composed標志——某些事件不會跨越陰影邊界。composed的事件(例如click、keydown等)將打破Shadow DOM的束縛,繼續到下一個階段,即Light DOM。帶有composed: false的事件(如focus和blur)將保持在陰影邊界內,因此只能在Shadow DOM中觀察到
  • bubbles標志——bubbles標志用于創建自定義事件。對于自定義事件要跨越陰影邊界,必須設置bubbles: true和composed: true:
// 在Web組件的Shadow DOM內部
classMyShadowComponentextendsHTMLElement {
constructor() {
    super();
    const shadowRoot = this.attachShadow({ mode: 'open' });
    shadowRoot.innerHTML = 'Shadow Button';

    shadowRoot.querySelector('#shadowButton').addEventListener('click', (e) => {
      console.log('Inside Shadow DOM click:', e.target.id); 
    });
  }
}
customElements.define('my-shadow-component', MyShadowComponent);

// 在Light DOM(主文檔)中
document.body.innerHTML += '';
document.body.addEventListener('click', (e) => {
console.log('Outside Shadow DOM click:', e.target.tagName);
});

這個例子展示了當事件跨越陰影邊界時event.target的變化。在帶有Shadow DOM的事件委托中,請記住你的委托監聽器在Light DOM中會收到Shadow Host作為event.target。你需要監聽Shadow Host本身上的事件,或者考慮在你的Web組件中創建自定義事件并用bubbles: true和composed: true分發它們:

圖片圖片

控制臺輸出顯示Shadow DOM內部和外部的事件目標

不冒泡的事件(及解決方法)

雖然大多數常見UI事件會冒泡,但有明顯的例外事件無法通過標準冒泡機制委托。

不冒泡的事件

最明顯的不冒泡事件包括:

  • focus——當元素獲得焦點時觸發
  • blur——當元素失去焦點時觸發
  • mouseenter——當指針進入元素時觸發
  • mouseleave——當指針離開元素時觸發

為什么它們不冒泡

這些事件通常無法觸發,因為瀏覽器的運作方式以及過去的兼容性問題。focus和blur旨在觸發在獲得或失去焦點的特定元素上,因此沒有冒泡。mouseenter和mouseleave與mouseover和mouseout(它們會冒泡)配對;但是,與mouseover和mouseout不同,mouseenter和mouseleave僅在指針位于元素上時觸發(而不是在其子元素上)。

因此,由于你不能使用冒泡委托這些事件,你需要使用替代策略,包括:

  • 使用focusin/focusout代替focus/blur:focus和blur事件無法通過冒泡委托,但focusin和focusout事件可以。這些是用戶交互的極佳替代方案:
const form = document.getElementById('myForm'); // 包含輸入字段的父元素

form.addEventListener('focusin', (event) => {
if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
    console.log(`Input focused: ${event.target.id}`);
    event.target.classList.add('focused-input');
  }
});

form.addEventListener('focusout', (event) => {
if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
    console.log(`Input blurred: ${event.target.id}`);
    event.target.classList.remove('focused-input');
  }
});

圖片控制臺輸出顯示使用focusin和focusout事件處理輸入框的焦點事件

  • 手動分發自定義事件:對于mouseenter/mouseleave或其他不冒泡的事件,如果focusin/focusout不適用,你可以將單個監聽器附加到子元素,然后從該子元素手動分發一個自定義事件,確保它冒泡且可組成。這為你提供了細粒度的控制:
const items = document.querySelectorAll('.item'); // 許多項目

items.forEach(item => {
  item.addEventListener('mouseenter', (e) => {
    const customHoverEvent = newCustomEvent('item-hover', {
      bubbles: true,
      composed: true,
      detail: { itemId: e.target.id, action: 'entered' }
    });
    e.target.dispatchEvent(customHoverEvent);
  });
});

// 父元素上的委托監聽器
document.getElementById('container').addEventListener('item-hover', (e) => {
console.log('Delegated hover event:', e.detail.itemId, e.detail.action);
});
  • 雖然不直接與事件委托相關,MutationObserver允許你對DOM樹的變化做出反應,例如元素被添加或移除。在極少數邊緣情況下,如果你需要為動態添加且不冒泡的元素附加監聽器,而其他技術不起作用,你可以使用MutationObserver檢測新元素并將監聽器綁定到它們。

然而,這重新引入了事件委托旨在避免的處理開銷。因此,僅在其他所有選項都窮盡時才使用此方法,作為最后的手段:

const observer = newMutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
    if (mutation.type === 'childList') {
      mutation.addedNodes.forEach(node => {
        if (node.nodeType === 1 && (node.tagName === 'INPUT' || node.querySelector('input'))) {
          const inputElement = node.tagName === 'INPUT' ? node : node.querySelector('input');
          if (inputElement) {
            inputElement.addEventListener('focus', () => {
              console.log('Focus (individual listener):', inputElement.id);
            });
          }
        }
      });
    }
  }
});

observer.observe(document.body, { childList: true, subtree: true });

由于附加許多單個監聽器的性能影響,這通常不被推薦。盡可能使用focusin/focusout。

框架中的事件委托

現代JavaScript框架通常會優化并利用事件委托等技術,即使它們抽象了DOM事件及其相關操作。

React如何實現委托

每個瀏覽器都有其管理原生事件的方式,因此React創建了其事件委托策略,稱為合成事件系統。該系統展示了高級事件委托技術。

例如,在React 17之前,大多數事件監聽器(如onClick和onChange)都與document關聯,React的合成事件系統會在那里攔截和處理它們。在標準化和重新分發它們到相關組件后,React會觸發原生事件。這是一種高效的事件委托,因為只有少數監聽器附加到document的更高層級。

React的合成事件系統確保跨瀏覽器的行為一致,即使對于復雜、深度嵌套的結構也是如此(請參閱我們關于比較React樹組件的指南)。

React 17+和React 18+的變化

  • React 17——React不再將事件附加到document。現在它將它們附加到React樹掛載的根DOM容器(例如root.render(<App />)將監聽器添加到<div id="root">>)。這旨在改進React應用的漸進式升級支持(在同一頁面上運行多個React版本)以及依賴文檔級事件處理器的非React應用和框架。它仍然是委托,因為React仍然在不同的地方分發事件處理,但React委托事件的位置發生了變化
  • React 18——通過實現自動批處理進一步優化了合成事件系統。這不是事件委托的更改,但它使用事件系統將單個事件引起的多個狀態更新合并為一個更新和一個重新渲染。React仍然委托大量事件內部架構以提高性能和跨瀏覽器的兼容性

Vue、Svelte和Angular的比較

每個框架都以自己的細微差別處理事件處理和委托:

框架

事件綁定語法

事件處理方式

手動委托需求

備注

Vue

@click

v-on:click

使用標準DOM監聽器,Vue通過其響應式系統高效地附加和分離它們

不總是需要,但對高度動態列表很有用

Vue的虛擬DOM自動處理大多數委托

Svelte

on:click

編譯為原生事件監聽器,針對直接目標

通常不需要,但對大型動態列表可能有所幫助

無運行時;稀疏動態輸出減少委托需求

Angular

(click)

使用原生DOM監聽器;變更檢測使DOM更新平滑

如果動態輸出導致問題,大型列表可選

HostListener

支持監聽宿主或全局目標并啟用委托

結論

事件委托通過將單個監聽器附加到父元素來簡化事件處理。當子元素觸發事件時,它會冒泡到父元素,減少內存使用并簡化代碼。

這種技術在管理大型相似元素集(如列表項或按鈕,尤其是動態生成的)時效果顯著。父監聽器可以處理新添加元素的事件,無需額外配置。

并非所有事件都會冒泡——focus、blur、mouseenter和mouseleave是例外。對于這些事件,使用focusin、focusout或自定義冒泡事件的替代方案。

要識別觸發事件的確切元素,請依賴event.target。除非絕對必要,否則避免使用stopPropagation(),因為它會阻止事件到達你的委托處理程序。

在處理Shadow DOM時,事件可能不會按預期冒泡,使用composed標志允許它們通過陰影邊界。

責任編輯:武曉燕 來源: 前端小石匠
相關推薦

2021-08-08 08:17:45

事件響應日志網絡安全

2021-03-15 23:11:12

內存虛擬化技術

2013-05-02 09:16:16

程序員

2019-11-15 10:41:10

Vim分屏終端

2013-12-19 10:08:52

AWS服務器

2017-12-29 08:16:43

2024-10-16 10:50:00

2013-06-14 13:27:36

內存Linux交換分區

2024-07-25 12:33:45

2016-11-25 15:03:33

FacebookWIFI

2024-12-09 16:00:00

代碼引用

2018-11-22 14:34:01

局域網IP擴容

2017-03-23 11:24:26

Windows 10Windows系統盤

2013-10-23 14:28:30

2013-08-08 10:27:03

云計算

2020-11-12 07:47:18

程序員管理時間

2015-07-16 15:16:41

內存泄露解決辦法

2024-04-10 08:00:00

點贊
收藏

51CTO技術棧公眾號

国产精品高清一区二区三区| 一区二区三区国产视频| 日b视频免费观看| 国产成人无码www免费视频播放| 99亚洲精品| 夜夜嗨av一区二区三区四区| 91丝袜超薄交口足| 成人av观看| 亚洲欧美日韩国产一区二区三区| 国产伦精品一区二区三区高清版| 波多野结衣黄色| 欧美激情综合| 亚洲欧美国内爽妇网| 在线观看免费不卡av| 99热99re6国产在线播放| 91蝌蚪porny九色| 91精品综合久久久久久五月天| 日本一区二区免费在线观看| 99九九热只有国产精品| 精品呦交小u女在线| 涩多多在线观看| 老司机2019福利精品视频导航| 洋洋成人永久网站入口| 亚洲精品视频一二三| 亚洲av成人无码久久精品老人| 久久97超碰国产精品超碰| 欧美专区在线播放| 久久久久久久久久久97| 希岛爱理一区二区三区| 亚洲视频一区二区| 亚洲av无码一区二区三区观看| 国产精品成人**免费视频| 欧美最猛性xxxxx直播| 欧美三级在线观看视频| 在线三级电影| 综合欧美亚洲日本| 亚洲欧美丝袜| 国产三级在线观看| 99国产精品国产精品久久| 91久久精品www人人做人人爽| 超碰在线免费97| 狂野欧美一区| 57pao成人永久免费视频| 中文字幕另类日韩欧美亚洲嫩草| 欧美国产一区二区三区激情无套| 亚洲欧洲第一视频| 国产精品亚洲无码| 日韩伦理一区二区三区| 亚洲国产精品国自产拍av秋霞| 两性午夜免费视频| 羞羞视频在线观看一区二区| 欧美日韩国产高清一区二区三区| 国产小视频精品| 成人在线网站| 欧美吞精做爰啪啪高潮| 亚洲日本中文字幕区| 成人在线视频电影| 国内毛片毛片毛片毛片| 韩国欧美国产一区| 成人欧美在线观看| 国产美女裸体无遮挡免费视频| 免费视频一区二区| 国产精品亚洲精品| 亚洲一区二区三区网站| 九九热在线视频观看这里只有精品| 国产精品va在线播放| 小泽玛利亚一区二区三区视频| 日本美女一区二区| 91在线观看免费高清| 精品人妻一区二区三区日产乱码| 国产成人av自拍| 99在线观看| 五月天激情婷婷| 国产亚洲欧美在线| 尤物一区二区三区| 亚洲区欧洲区| 亚洲成人自拍网| 黄在线观看网站| 国产亚洲精彩久久| 日韩午夜激情免费电影| 成人在线视频免费播放| 亚洲最大在线| 日韩中文字幕免费看| 麻豆影视在线播放| 日韩亚洲国产欧美| 国产精品久久久久福利| 国产欧美第一页| 成人精品视频.| 欧美精品人人做人人爱视频| 嫩草香蕉在线91一二三区| 一区二区激情视频| 国产精品无码专区av在线播放| 欧美日韩卡一| 精品国产区一区| 免费看91的网站| 欧美99在线视频观看| 欧美怡春院一区二区三区| 成人黄色三级视频| 国产高清成人在线| 日本一区二区三区四区在线观看| 黄色成人在线观看| 日韩欧美亚洲成人| 51自拍视频在线观看| 欧美激情久久久久久久久久久| 中日韩美女免费视频网站在线观看| 18岁成人毛片| 可以看av的网站久久看| 成人av蜜桃| 97超碰人人在线| 黄色成人在线播放| 欧洲在线免费视频| 久草在线成人| 欧美精品激情在线观看| 欧美激情一区二区三区免费观看| 国产99久久久久久免费看农村| 日日骚一区二区网站| 久色国产在线| 777亚洲妇女| 精品人伦一区二区三电影 | 久久精品国产第一区二区三区最新章节| 国产粉嫩一区二区三区在线观看| 亚洲最新视频在线观看| 亚洲综合婷婷久久| 国产精品免费99久久久| 91精品国产成人| 国产草草影院ccyycom| 中文字幕不卡三区| 成年人视频网站免费观看| 91成人福利| 欧美精品一本久久男人的天堂| 中文字幕乱码无码人妻系列蜜桃| 91视频在线看| 日韩免费视频播放| 中文久久电影小说| 欧美成人精品激情在线观看| 中文字字幕在线中文乱码| 久久久国产一区二区三区四区小说| 草b视频在线观看| 97成人在线| 欧美成人一二三| 91精品人妻一区二区三区果冻| 国产欧美精品日韩区二区麻豆天美| 人妻精品无码一区二区三区| 国内毛片久久| 国外成人在线播放| 老司机午夜福利视频| 亚洲国产视频网站| 99久久久无码国产精品性波多 | 成人av一级片| 偷拍精品福利视频导航| 98精品国产自产在线观看| 欧美一级一区二区三区| 性做久久久久久免费观看| 动漫美女无遮挡免费| 亚洲日本视频| 久久久久久九九九九| 极品在线视频| 亚洲毛片在线观看.| 加勒比在线一区| 国产精品人妖ts系列视频| 男女男精品视频站| 国产精品99久久精品| 成人免费看吃奶视频网站| 久草中文在线观看| 欧美va亚洲va香蕉在线| 久久精品欧美一区二区| av一本久道久久综合久久鬼色| 日韩欧美一区二| 久久综合亚洲| 国产主播喷水一区二区| а√天堂资源地址在线下载| 日韩一区二区电影网| 久久久久久久久久久97| 91蜜桃在线观看| 中文字幕在线导航| 91精品国产91久久久久久黑人| 91精品视频免费看| 女囚岛在线观看| 精品一区二区电影| 一级二级三级视频| 一区二区三区91| 中国毛片在线观看| 精久久久久久久久久久| 欧美一区二区激情| 精品一级毛片| 91久久极品少妇xxxxⅹ软件| 中文字幕在线视频网站| www.亚洲天堂| 人妻va精品va欧美va| 欧美无砖砖区免费| 国语对白一区二区| 欧美韩国日本不卡| 理论片大全免费理伦片| 日韩高清不卡一区二区三区| 一二三四中文字幕| 日韩欧美黄色| 亚洲精品女av网站| 国产高清不卡| 欧美成人精品一区| 黄色在线网站| 欧美精品一区二区精品网| 国产情侣呻吟对白高潮| 一区二区三区视频在线看| 亚洲午夜精品久久久久久高潮| 国产精品一级在线| 在线观看免费成人av| 国语精品一区| 天天成人综合网| 久久99久久人婷婷精品综合| 91久久国产自产拍夜夜嗨| 最新日韩一区| 69av成年福利视频| 最新超碰在线| 中国china体内裑精亚洲片| 姝姝窝人体www聚色窝| 在线播放欧美女士性生活| www五月天com| 午夜伊人狠狠久久| 久久久一二三区| 国产精品灌醉下药二区| 这里只有久久精品| av亚洲精华国产精华精| 国产xxx在线观看 | 成人欧美在线观看| 麻豆精品蜜桃| 欧美最猛性xxxxx(亚洲精品)| 国产盗摄精品一区二区酒店| 久久久久99精品久久久久| 9191在线观看| 国产亚洲欧美视频| 免费黄色在线视频网站| 亚洲国产欧美在线成人app | 精品国产免费观看| 亚洲国产精品久久久久秋霞影院| 91高清免费观看| 国产精品伦理在线| 懂色av粉嫩av浪潮av| 久久精品人人做人人综合| 99久久国产精| 91亚洲国产成人精品一区二三 | 国产欧美啪啪| 国产精品 日韩| 综合中文字幕| 国产精品久久久对白| 国产96在线亚洲| 国产精品v欧美精品v日韩| 在线视频亚洲欧美中文| 国产经典一区二区三区| 加勒比中文字幕精品| 国产日韩一区二区三区| 风间由美中文字幕在线看视频国产欧美| 亚洲aa在线观看| 日本超碰一区二区| 99电影在线观看| 成人偷拍自拍| 久久久久久久久久久久久久久久av| 欧美综合自拍| 欧美中日韩免费视频| 欧美色女视频| 在线码字幕一区| 欧美三区视频| 婷婷五月综合缴情在线视频| 午夜综合激情| 欧美 日韩 国产 激情| 久久国产精品一区二区| 亚洲日本黄色片| 懂色av一区二区三区蜜臀| 99久久久无码国产精品性波多 | 久久久久性色av无码一区二区| 亚洲一区在线观看视频| 日本一区二区免费在线观看| 色悠悠久久综合| 在线免费看91| 精品捆绑美女sm三区| 性感美女福利视频| 一本色道久久综合狠狠躁篇怎么玩 | 欧美色999| 91色精品视频在线| 东京久久高清| 色狠狠久久av五月综合| 欧美三级在线| 国产精品拍拍拍| 国v精品久久久网| 自拍偷拍视频亚洲| 亚洲欧美日韩系列| 亚洲欧美综合另类| 欧美精品三级在线观看| 天堂av在线免费| 色多多国产成人永久免费网站| 中日韩高清电影网| 日韩av123| 精品网站999| 欧美一区二区影视| 欧美在线免费一级片| 亚洲色欲综合一区二区三区| 国产一二精品视频| 亚洲天堂视频一区| 亚洲激情男女视频| 中文字幕一区二区三区四区视频| 精品少妇一区二区| 1区2区3区在线观看| 777777777亚洲妇女| 国产精区一区二区| 少妇免费毛片久久久久久久久| 激情久久中文字幕| 在线看免费毛片| 久久久久久电影| 久久免费少妇高潮99精品| 欧美丝袜自拍制服另类| 日本天堂影院在线视频| 欧美精品亚州精品| 亚洲精品伦理| 欧美精品免费观看二区| 亚洲大胆视频| 三日本三级少妇三级99| 国产欧美久久久精品影院| 男女啊啊啊视频| 精品欧美久久久| 麻豆视频在线| 国产精品视频网站| 女厕嘘嘘一区二区在线播放 | 久久精品国产77777蜜臀| 国产特黄级aaaaa片免| 亚洲国产一二三| 国产富婆一级全黄大片| 日韩中文理论片| 全球最大av网站久久| 日本不卡一区二区三区视频| 日韩天天综合| 99re这里只有| 性做久久久久久免费观看欧美| 亚洲国产999| 欧美精品免费在线| 免费看日产一区二区三区| 国产精品99久久久久久大便| 美日韩一区二区| 亚洲av毛片基地| 欧美亚洲国产一区二区三区| 蜜芽tv福利在线视频| 欧美做受高潮电影o| 日韩美女国产精品| 日本精品久久久久中文字幕| 久久久蜜臀国产一区二区| 人妻丰满熟妇av无码区| 亚洲免费伊人电影在线观看av| 美女露胸视频在线观看| 久久久久久久久久码影片| 先锋影音国产一区| theav精尽人亡av| 欧美性猛交xxxx黑人| 日本一区高清| 国产精品27p| 欧美久久综合网| 可以看污的网站| 亚洲女与黑人做爰| 亚洲精品福利网站| 午夜精品久久久久久久99黑人 | 亚洲精品一区中文字幕乱码| 亚洲天堂av在线| 日本成人黄色免费看| 久久成人免费电影| 欧美成人精品欧美一级| 亚洲国产精品免费| 欧美成人h版| 亚洲一区二区高清视频| 国产乱子伦视频一区二区三区 | 欧美色精品天天在线观看视频| 在线视频二区| 91精品国产99久久久久久红楼| 亚洲夜间福利| 亚洲国产av一区| 欧美精品免费视频| 日本乱理伦在线| 欧美国产综合视频| 国内久久婷婷综合| 国产一级久久久| 一道本无吗dⅴd在线播放一区| 综合久草视频| www..com日韩| 欧美激情一区二区三区蜜桃视频| jizz中国少妇| 欧美在线观看日本一区| 手机亚洲手机国产手机日韩| 国产精品一级无码| 欧美在线啊v一区| 日本伦理一区二区| 色播亚洲视频在线观看| 国产a区久久久| 亚洲天堂国产精品| 久久久日本电影| 波多野结衣的一区二区三区| 性一交一黄一片| 欧美丝袜自拍制服另类| √天堂8资源中文在线| 亚洲欧美日韩国产成人综合一二三区| 国产成人精品www牛牛影视| 中文无码av一区二区三区| 久久久久久91| 999国产精品永久免费视频app| 污片免费在线观看|