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

一文帶你徹底搞定Diff算法

云計算 虛擬化 算法
Diff算法實現的是最小量更新虛擬DOM。這句話雖然簡短,但是涉及到了兩個核心要素:虛擬DOM、最小量更新。虛擬DOM指的就是將真實的DOM樹構造為js對象的形式,從而解決瀏覽器操作真實DOM的性能問題。

[[420540]]

一、基礎

Diff算法實現的是最小量更新虛擬DOM。這句話雖然簡短,但是涉及到了兩個核心要素:虛擬DOM、最小量更新。

1.虛擬DOM

虛擬DOM指的就是將真實的DOM樹構造為js對象的形式,從而解決瀏覽器操作真實DOM的性能問題。

例如:如下DOM與虛擬DOM之間的映射關系

2.最小量更新

Diff的用途就是在新老虛擬DOM之間找到最小更新的部分,從而將該部分對應的DOM進行更新。

二、整個流程

Diff算法真的很美,整個流程如下圖所示:

  1. 首先比較一下新舊節點是不是同一個節點(可通過比較sel(選擇器)和key(唯一標識)值是不是相同),不是同一個節點則進行暴力刪除(注:先以舊節點為基準插入新節點,然后再刪除舊節點)。
  2. 若是同一個節點則需要進一步比較

完全相同,不做處理

新節點內容為文本,直接替換完事

新節點有子節點,這個時候就要仔細考慮一下了:若老節點沒有子元素,則直接清空老節點,將新節點的子元素插入即可;若老節點有子元素則就需要按照上述的更新策略老搞定了(記住更新策略,又可以吹好幾年了,666666)。

三、實戰

光說不練假把式,下面直接輸出diff算法的核心內容。

3.1 patch函數

Diff算法的入口函數,主要判斷新舊節點是不是同一個節點,然后交由不同的邏輯進行處理。

  1. export default function patch(oldVnode, newVnode) { 
  2.     // 判斷傳入的第一個參數,是DOM節點還是虛擬節點 
  3.     if (oldVnode.sel === '' || oldVnode.sel === undefined) { 
  4.         // 傳入的第一個參數是DOM節點,此時要包裝成虛擬節點 
  5.         oldVnode = vnode(oldVnode.tagName.toLowerCase(), {}, [], undefined, oldVnode); 
  6.     } 
  7.  
  8.     // 判斷oldVnode和newVnode是不是同一個節點 
  9.     if (oldVnode.key === newVnode.key && oldVnode.sel === newVnode.sel) { 
  10.         //是同一個節點,則進行精細化比較 
  11.         patchVnode(oldVnode, newVnode); 
  12.     } 
  13.     else { 
  14.         // 不是同一個節點,暴力插入新的,刪除舊的 
  15.         let newVnodeElm = createElement(newVnode); 
  16.  
  17.         // 將新節點插入到老節點之前 
  18.         if (oldVnode.elm.parentNode && newVnodeElm) { 
  19.             oldVnode.elm.parentNode.insertBefore(newVnodeElm, oldVnode.elm); 
  20.         } 
  21.         // 刪除老節點 
  22.         oldVnode.elm.parentNode.removeChild(oldVnode.elm); 
  23.     } 

3.2 patchVnode函數

該函數主要負責精細化比較,通過按照上述流程圖中的邏輯依次判斷屬于哪一個分支,從而采取不同的處理邏輯。(思路清晰,算法太牛了)

  1. export default function patchVnode(oldVnode, newVnode) { 
  2.     // 判斷新舊vnode是否是同一個對象 
  3.     if (oldVnode === newVnode) { 
  4.         return
  5.     } 
  6.     // 判斷vnode有沒有text屬性 
  7.     if (newVnode.text !== undefined && (newVnode.children === undefined || newVnode.children.length === 0)) { 
  8.         console.log('新vnode有text屬性'); 
  9.         if (newVnode.text !== oldVnode.text) { 
  10.             oldVnode.elm.innerText = newVnode.text; 
  11.         } 
  12.     } 
  13.     else { 
  14.         // 新vnode沒有text屬性,有children 
  15.         console.log('新vnode沒有text屬性'); 
  16.         // 判斷老的有沒有children 
  17.         if (oldVnode.children !== undefined && oldVnode.children.length > 0) { 
  18.             // 老的有children,新的也有children 
  19.             updateChildren(oldVnode.elm, oldVnode.children, newVnode.children); 
  20.         } 
  21.         else { 
  22.             // 老的沒有children,新的有children 
  23.             // 清空老的節點的內容 
  24.             oldVnode.elm.innerHTML = ''
  25.             // 遍歷新的vnode的子節點,創建DOM,上樹 
  26.             for (let i = 0; i < newVnode.children.length; i++) { 
  27.                 let dom = createElement(newVnode.children[i]); 
  28.                 oldVnode.elm.appendChild(dom); 
  29.             } 
  30.         } 
  31.     } 

3.3 updateChildren函數

核心函數,主要負責舊虛擬節點和新虛擬節點均存在子元素的情況,按照比較策略依次進行比較,最終找出子元素中變化的部分,實現最小更新。對于該部分,涉及到一些指針,如下所示:

  1. 舊前指的就是更新前虛擬DOM中的頭部指針
  2. 舊后指的就是更新前虛擬DOM中的尾部指針
  3. 新前指的就是更新后虛擬DOM中的頭部指針
  4. 新后指的就是更新后虛擬DOM中的尾部指針

按照上述的更新策略,上述舊虛擬DOM更新為新虛擬DOM的流程為:

  1. 命中“新后舊前”策略,然后將信后對應的DOM節點(也就是節點1)移動到舊后節點(節點3)后面,然后舊前節點指針下移,新后節點指針上移。
  2. 仍然命中“新后舊前”策略,做相同的操作,將節點2移動到舊后節點(節點3)后面,下移舊前節點,上移新后節點。
  3. 命中“新前舊前”策略,DOM節點不變,舊前和新前節點均下移。
  4. 跳出循環,移動結束。
  1. export default function updateChildren(parentElm, oldCh, newCh) { 
  2.     // 舊前 
  3.     let oldStartIdx = 0; 
  4.     // 新前 
  5.     let newStartIdx = 0; 
  6.     // 舊后 
  7.     let oldEndIdx = oldCh.length - 1; 
  8.     // 新后 
  9.     let newEndIdx = newCh.length - 1; 
  10.     // 舊前節點 
  11.     let oldStartVnode = oldCh[0]; 
  12.     // 舊后節點 
  13.     let oldEndVnode = oldCh[oldEndIdx]; 
  14.     // 新前節點 
  15.     let newStartVnode = newCh[0]; 
  16.     // 新后節點 
  17.     let newEndVnode = newCh[newEndIdx]; 
  18.  
  19.     let keyMap = null
  20.  
  21.     while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { 
  22.         // 略過已經加undefined標記的內容 
  23.         if (oldStartVnode == null || oldCh[oldStartIdx] === undefined) { 
  24.             oldStartVnode = oldCh[++oldStartIdx]; 
  25.         } 
  26.         else if (oldEndVnode == null || oldCh[oldEndIdx] === undefined) { 
  27.             oldEndVnode = oldCh[--oldEndIdx]; 
  28.         } 
  29.         else if (newStartVnode == null || newCh[newStartIdx] === undefined) { 
  30.             newStartVnode = newCh[++newStartIdx]; 
  31.         } 
  32.         else if (newEndVnode == null || newCh[newEndIdx] === undefined) { 
  33.             newEndVnode = newCh[--newEndIdx]; 
  34.         } 
  35.         else if (checkSameVnode(oldStartVnode, newStartVnode)) { 
  36.             // 新前與舊前 
  37.             console.log('新前與舊前命中'); 
  38.             patchVnode(oldStartVnode, newStartVnode); 
  39.             oldStartVnode = oldCh[++oldStartIdx]; 
  40.             newStartVnode = newCh[++newStartIdx]; 
  41.         } 
  42.         else if (checkSameVnode(oldEndVnode, newEndVnode)) { 
  43.             // 新后和舊后 
  44.             console.log('新后和舊后命中'); 
  45.             patchVnode(oldEndVnode, newEndVnode); 
  46.             oldEndVnode = oldCh[--oldEndIdx]; 
  47.             newEndVnode = newCh[--newEndVnode]; 
  48.         } 
  49.         else if (checkSameVnode(oldStartVnode, newEndVnode)) { 
  50.             console.log('新后和舊前命中'); 
  51.             patchVnode(oldStartVnode, newEndVnode); 
  52.             // 當新后與舊前命中的時候,此時要移動節點,移動新后指向的這個節點到老節點舊后的后面 
  53.             parentElm.insertBefore(oldStartVnode.elm, oldEndVnode.elm.nextSibling); 
  54.             oldStartVnode = oldCh[++oldStartIdx]; 
  55.             newEndVnode = newCh[--newEndIdx]; 
  56.         } 
  57.         else if (checkSameVnode(oldEndVnode, newStartVnode)) { 
  58.             // 新前和舊后 
  59.             console.log('新前和舊后命中'); 
  60.             patchVnode(oldEndVnode, newStartVnode); 
  61.             // 當新前和舊后命中的時候,此時要移動節點,移動新前指向的這個節點到老節點舊前的前面 
  62.             parentElm.insertBefore(oldEndVnode.elm, oldStartVnode.elm); 
  63.             oldEndVnode = oldCh[--oldEndIdx]; 
  64.             newStartVnode = newCh[++newStartIdx]; 
  65.         } 
  66.         else { 
  67.             // 四種都沒有命中 
  68.             // 制作keyMap一個映射對象,這樣就不用每次都遍歷老對象了 
  69.             if (!keyMap) { 
  70.                 keyMap = {}; 
  71.                 for (let i = oldStartIdx; i <= oldEndIdx; i++) { 
  72.                     const key = oldCh[i].key
  73.                     if (key !== undefined) { 
  74.                         keyMap[key] = i; 
  75.                     } 
  76.                 } 
  77.             } 
  78.             // 尋找當前這項(newStartIdx)在keyMap中的映射的位置序號 
  79.             const idxInOld = keyMap[newStartVnode.key]; 
  80.             if (idxInOld === undefined) { 
  81.                 // 如果idxInOld是undefined表示踏實全新的項,此時會將該項創建為DOM節點并插入到舊前之前 
  82.                 parentElm.insertBefore(createElement(newStartVnode), oldStartVnode.elm); 
  83.             } 
  84.             else { 
  85.                 // 如果不是undefined,則不是全新的項,則需要移動 
  86.                 const elmToMove = oldCh[idxInOld]; 
  87.                 patchVnode(elmToMove, newStartVnode); 
  88.                 // 把這項設置為undefined,表示已經處理完這項了 
  89.                 oldCh[idxInOld] = undefined; 
  90.                 // 移動 
  91.                 parentElm.insertBefore(elmToMove.elm, oldStartVnode.elm); 
  92.             } 
  93.             // 指針下移,只移動新的頭 
  94.             newStartVnode = newCh[++newStartIdx]; 
  95.         } 
  96.     } 
  97.  
  98.     // 循環結束后,處理未處理的項 
  99.     if (newStartIdx <= newEndIdx) { 
  100.         console.log('new還有剩余節點沒有處理,要加項,把所有剩余的節點插入到oldStartIdx之前'); 
  101.         // 遍歷新的newCh,添加到老的沒有處理的之前 
  102.         for (let i = newStartIdx; i <= newEndIdx; i++) { 
  103.             // insertBefore方法可以自動識別null,如果是null就會自動排到隊尾去 
  104.             // newCh[i]現在還沒有真正的DOM,所以要調用createElement函數變為DOM 
  105.             parentElm.insertBefore(createElement(newCh[i]), oldCh[oldStartIdx].elm); 
  106.         } 
  107.     } 
  108.     else if (oldStartIdx <= oldEndIdx) { 
  109.         console.log('old還有剩余節點沒有處理,要刪除項'); 
  110.         // 批量刪除oldStart和oldEnd指針之間的項 
  111.         for (let i = oldStartIdx; i <= oldEndIdx; i++) { 
  112.             if (oldCh[i]) { 
  113.                 parentElm.removeChild(oldCh[i].elm); 
  114.             } 
  115.         } 
  116.     } 

【編輯推薦】

責任編輯:姜華 來源: 前端點線面
相關推薦

2023-10-27 08:15:45

2023-12-15 09:45:21

阻塞接口

2023-12-12 07:31:51

Executors工具開發者

2021-04-19 17:32:34

Java內存模型

2021-04-02 06:17:10

大數加減乘除數據結構算法

2018-10-22 08:14:04

2021-08-05 06:54:05

觀察者訂閱設計

2024-10-16 10:11:52

2022-05-11 07:38:45

SpringWebFlux

2022-03-14 08:01:06

LRU算法線程池

2020-06-03 08:19:00

Kubernetes

2020-05-11 14:35:11

微服務架構代碼

2023-11-20 08:18:49

Netty服務器

2023-12-21 17:11:21

Containerd管理工具命令行

2022-12-20 07:39:46

2023-07-31 08:18:50

Docker參數容器

2023-11-06 08:16:19

APM系統運維

2021-05-29 10:11:00

Kafa數據業務

2022-11-11 19:09:13

架構

2020-05-13 09:14:16

哈希表數據結構
點贊
收藏

51CTO技術棧公眾號

四虎影视在线观看2413| 欧美黑人性猛交xxx| jizz久久久久久| 中文字幕综合网| 国内一区二区在线视频观看| 亚洲天堂五月天| 在线中文字幕第一区| 日韩av在线免费播放| 亚洲一区二区三区四区五区xx| а√天堂资源地址在线下载| 97久久精品人人做人人爽50路| 国产精品扒开腿做爽爽爽视频| 裸体武打性艳史| 最新亚洲精品| 日韩欧美美女一区二区三区| 日日碰狠狠躁久久躁婷婷| 91亚洲天堂| 欧美激情资源网| 99se婷婷在线视频观看| 黄色一区二区视频| 亚洲一区国产一区| 久久国产精品久久久久| 三级网站在线免费观看| 91麻豆精品激情在线观看最新| 91国偷自产一区二区三区观看| 国产午夜精品视频一区二区三区| 精品无人乱码| av电影在线观看一区| 亚洲精品日韩激情在线电影| 天天干,天天干| 亚洲片区在线| 免费成人高清视频| 国精品人伦一区二区三区蜜桃| 日韩三区视频| 亚洲第一福利视频| 女人扒开双腿让男人捅| 99热这里有精品| 欧美吻胸吃奶大尺度电影| 又粗又黑又大的吊av| 激情在线视频播放| 亚洲视频一区二区免费在线观看| 日本一区二区精品视频| 熟妇人妻中文av无码| 国产老妇另类xxxxx| 国产有码一区二区| 波多野结衣在线观看一区| 亚洲专区免费| 欧美在线免费看| 欧美一区二区激情视频| 一本久道久久久| 午夜精品一区二区三区在线视 | 中文字幕在线网址| 天堂一区二区在线| 91成人性视频| 女人十八岁毛片| 亚洲美女黄网| 91av国产在线| 在线观看黄网站| 在线亚洲一区| 欧美中文在线观看| 麻豆精品久久久久久久99蜜桃| 亚洲影音先锋| 国产97在线视频| 波多野结衣二区三区| 久久亚洲精品伦理| 国产成人激情小视频| 波多野结衣av无码| 奇米在线7777在线精品| 成人国产精品一区| 精品人妻无码一区二区色欲产成人 | 久久伊人免费视频| 久草视频免费在线播放| 亚洲久久视频| 日本精品久久中文字幕佐佐木| 国产一区二区视频免费| 免费av网站大全久久| 成人午夜激情网| 亚洲精品国产精品国| 97久久精品人人做人人爽| 久久手机视频| av男人的天堂在线| 亚洲免费大片在线观看| 你真棒插曲来救救我在线观看| 涩涩视频在线免费看| 在线看国产一区| 欧洲美女亚洲激情| 精品视频自拍| 在线丨暗呦小u女国产精品| 老熟妻内射精品一区| 韩日在线一区| 日韩美女主播视频| 国产巨乳在线观看| 成人免费毛片片v| 欧美专区一二三| www在线视频| 日韩欧美中文第一页| a在线观看免费视频| 91精品尤物| 亚洲欧洲日产国码av系列天堂| 国精产品久拍自产在线网站| 樱桃成人精品视频在线播放| 国产精品精品久久久| www日本高清| 欧美韩国日本不卡| 日韩亚洲欧美视频| 国产精品一区二区免费福利视频| 日韩免费观看高清完整版| 欧美图片第一页| 亚洲手机视频| 91精品久久久久久久久青青 | 中文字幕亚洲一区在线观看| 久一视频在线观看| 美腿丝袜在线亚洲一区| 久久久久久精| 性xxxxfjsxxxxx欧美| 欧美视频一二三区| 国产精品第七页| 亚洲无中文字幕| 国产精品欧美日韩一区二区| 污视频在线免费观看| 亚洲激情图片qvod| 艹b视频在线观看| 宅男在线一区| 992tv成人免费视频| 国产欧美日韩成人| 日本一区二区高清| 国产精品无码专区av在线播放 | 欧美成人免费网站| 国产日产在线观看| 日韩制服丝袜先锋影音| 国产精品我不卡| 理论片午午伦夜理片在线播放| 一本色道a无线码一区v| 成人区人妻精品一区二| 中文无码久久精品| 国产日韩欧美在线看| 成人在线免费视频| 91九色02白丝porn| 国产特级黄色录像| 国产欧美成人| 久草精品电影| 2020av在线| 精品国产乱码久久| 免费毛片在线播放免费| 国产一区二区精品久久99| 中文字幕一区二区中文字幕| 精品福利在线| 色七七影院综合| 中国精品一区二区| 国产精品黄色在线观看| 高清一区二区视频| 欧美亚洲高清| 国产欧美欧洲在线观看| 欧美尤物美女在线| 欧美精品丝袜中出| xxxx日本少妇| 国产精品888| 中文字幕日韩精品无码内射| 亚洲午夜免费| 国内伊人久久久久久网站视频| 亚洲伦理在线观看| 婷婷中文字幕综合| 亚洲黄色免费视频| 久久99精品久久久久久久久久久久| 亚洲天堂电影网| 不卡的国产精品| 欧美日韩成人在线观看| 囯产精品久久久久久| 午夜精品福利一区二区蜜股av| 日本黄色免费观看| 久久精品动漫| 一区二区免费在线视频| 精品国产亚洲日本| 国产69精品久久久久9999| 日韩私人影院| 欧美日韩激情一区二区三区| 国产少妇在线观看| 成人av在线资源网站| 狠狠爱免费视频| 日本欧美国产| 2022国产精品| 欧美aa一级| 日韩中文有码在线视频| 亚洲精品911| 日本高清不卡在线观看| 日韩三级久久久| 成+人+亚洲+综合天堂| 九色porny91| 综合久久一区| 欧美二区在线看| 自拍偷拍亚洲图片| 91极品视频在线| 三区四区电影在线观看| 精品剧情v国产在线观看在线| 国产区一区二区三| 亚洲欧美另类综合偷拍| 久久无码人妻精品一区二区三区| 麻豆免费看一区二区三区| 欧美亚洲黄色片| 青青草91久久久久久久久| 成人欧美一区二区三区黑人免费| 成人小电影网站| 久久99视频免费| 国产福利在线看| 精品国产伦一区二区三区观看体验| 香蕉影院在线观看| 一区二区三区**美女毛片| 亚洲一区二区自偷自拍 | 国产高清一区二区三区四区| 国精产品一区一区三区mba视频| 欧美 日韩 激情| 亚洲欧美综合| 色综合久久av| 精品国内亚洲2022精品成人| 成人福利网站在线观看| 欧美一级大黄| 性色av一区二区三区免费| 麻豆tv入口在线看| 国产一区二区三区精品久久久 | 91麻豆精品国产91久久久久推荐资源| 国产精品美女视频网站| 欧美aaaaa性bbbbb小妇| 欧美大学生性色视频| 日本欧美在线视频免费观看| 亚洲全黄一级网站| 三级小视频在线观看| 91精品免费在线| 中文字幕一二区| 色欧美日韩亚洲| 日韩精品视频免费播放| 亚洲午夜激情av| 日韩精品一区二区亚洲av性色| 国产欧美精品一区二区色综合| 国产福利短视频| 高清不卡一二三区| 欧美熟妇另类久久久久久多毛| 秋霞午夜av一区二区三区| 久久无码高潮喷水| 亚洲精品一级| 日韩一级性生活片| 亚洲午夜黄色| 91成人综合网| 亚洲天堂偷拍| 日韩精品视频在线观看视频| 国精品一区二区三区| 日韩人妻一区二区三区蜜桃视频| 午夜国产一区二区| 在线免费一区| 91成人免费| 少妇高潮流白浆| 亚洲五月综合| 精品一二三四五区| 99在线|亚洲一区二区| 欧美 日韩 国产在线观看| 国产日韩1区| 鲁一鲁一鲁一鲁一澡| 国产亚洲精品v| 日韩精品一区二区三区久久| 午夜一区二区三区不卡视频| 日本三级免费观看| 久热综合在线亚洲精品| 2025韩国理伦片在线观看| 久久99国产精品成人| 天天综合天天添夜夜添狠狠添| 精品一区二区免费| 久久精品亚洲天堂| 国产成人精品免费看| 欧类av怡春院| 久久九九久久九九| 免费在线观看a级片| 亚洲综合激情另类小说区| 中文字幕在线字幕中文| 日韩欧美精品中文字幕| 亚洲一区二区人妻| 日韩欧美国产一区在线观看| 日本激情一区二区| 国产亚洲欧美日韩美女| 国内外激情在线| 欧美国产日韩xxxxx| a一区二区三区| 国产区亚洲区欧美区| 亚洲伊人影院| 农村寡妇一区二区三区| 欧美激情偷拍自拍| 97中文字幕在线| 久久天堂精品| 亚洲自拍第三页| 99久久久国产精品免费蜜臀| 中文字幕第20页| 亚洲精品国产a久久久久久| 97免费在线观看视频| 欧美日韩情趣电影| 人妻无码一区二区三区久久99| 国产亚洲欧美日韩精品| 污污的网站在线免费观看| 国产成人自拍视频在线观看| 亚洲国产欧美在线观看| 免费在线一区二区| 欧美啪啪一区| 在线观看免费成人av| 国产成人av资源| 九一在线免费观看| 精品女厕一区二区三区| 97精品人妻一区二区三区香蕉| 亚洲国产91精品在线观看| 视频免费一区| 奇门遁甲1982国语版免费观看高清 | 国产视频第一区| 欧美成人免费一级人片100| 电影一区二区三| 波多野结衣精品久久| 日韩免费在线| 午夜肉伦伦影院| 成人免费视频一区二区| 日本黄色片免费观看| 欧美在线啊v一区| 香蕉视频911| 欧美多人爱爱视频网站| 少妇高潮一区二区三区99| 欧美精品123| 亚洲区欧美区| 美女又黄又免费的视频| 国产精品污污网站在线观看 | 在线播放国产精品二区一二区四区| 亚洲人成色777777老人头| 久久免费视频在线| 免费观看亚洲视频大全| 亚洲一区二区三区乱码| 天堂va蜜桃一区二区三区| 加勒比精品视频| 亚洲国产精品久久一线不卡| 国产手机av在线| 色噜噜久久综合伊人一本| 97精品国产99久久久久久免费| 蜜桃91精品入口| 一区二区三区国产盗摄| 男人的天堂影院| 亚洲va国产天堂va久久en| 亚洲第一色网站| 久久99精品久久久久久琪琪| 精品一区二区三区四区五区| 中文字幕第一页亚洲| 精品一区二区免费| 欧美手机在线观看| 欧美日韩精品欧美日韩精品| 婷婷在线视频| 成人激情视频在线播放| 91精品精品| 99九九精品视频| 亚洲久草在线视频| 亚洲精品国产片| 97精品久久久| 丝袜av一区| 欧美一级黄色影院| 国产精品女人毛片| 国产情侣激情自拍| 久久艳片www.17c.com | 亚洲精品福利资源站| 2021天堂中文幕一二区在线观| 国产免费一区二区三区| 亚洲九九精品| 国产精品久久久久无码av色戒| 色菇凉天天综合网| jzzjzzjzz亚洲成熟少妇| 国产精品一香蕉国产线看观看| 亚洲成人精品| 无码人妻精品一区二区三| 欧美午夜激情在线| av播放在线| 91福利视频导航| 日韩视频在线一区二区三区 | 日韩美女免费线视频| 日韩精品久久久久久久电影99爱| 国产情侣av自拍| 久久国产精品99久久人人澡| 国产精品视频一区二区在线观看| 欧美一区二区视频在线观看| 美女日批视频在线观看| 精品国产二区在线| 日韩精品一级二级| h色网站在线观看| 亚洲国产成人av在线| 精品欧美一区二区三区在线观看 | 午夜影院久久久| 麻豆av电影在线观看| 成人综合网网址| 99国产一区| 日本美女黄色一级片| 亚洲国产精品久久久久秋霞不卡 | 超碰97网站| 久久天天综合| 欧美日韩免费做爰视频| 亚洲男人天堂古典| 精品国产伦一区二区三区观看说明 | 51国偷自产一区二区三区的来源| 亚洲黄网站黄| 日韩av手机在线免费观看| 亚洲电影av在线| 国产视频网站一区二区三区| 精品视频在线观看一区|