国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

Web 框架的替代方案

共 11483字,需瀏覽 23分鐘

 ·

2022-04-14 16:18


點擊上方?前端Q,關(guān)注公眾號

回復加群,加入前端Q技術(shù)交流群

作者 | Noam Rosenthal
譯者 | Sambodhi
策劃 | 閆園園
在本系列第二部分中,Noam 提出了一些模式,說明如何直接用 Web 平臺作為框架提供的一些解決方案的替代方案。

上周,我們從框架試圖解決哪些核心問題的角度出發(fā),考察了使用框架的不同好處和代價,重點放在聲明性編程、數(shù)據(jù)綁定、反應性、列表和條件。今天,我們來看看能否在 Web 平臺上找到替代方案。

推出自己的框架?

在探索沒有框架的生活中,一個看似不可避免的結(jié)果是,推出自己的框架,以進行反應性數(shù)據(jù)綁定。因為之前已經(jīng)試過了,也見識到了這種做法的代價有多大,所以我決定在這次探索中,遵循一條原則:不要推出自己的框架,而要看看能否直接利用 Web 平臺,這樣就能降低對框架的需求。如果你打算推出自己的框架,那么需要考慮的是,本文沒有涉及一系列的成本。

普通的選擇

Web 平臺已經(jīng)提供了一個開箱即用的聲明性編程機制:HTML 和 CSS。這種機制是成熟的、經(jīng)過良好測試的、流行的、廣泛使用的,并且有文檔記錄。然而,它并沒有提供明確的數(shù)據(jù)綁定、條件渲染和列表同步的內(nèi)置概念,并且反應性是一個細微的細節(jié),散布于多個平臺的特性之中。

在瀏覽常見框架的文檔后,我就直接找到了第一部分中提及的特性。我在閱讀諸如 MDN 之類的 Web 平臺的文檔時,會發(fā)現(xiàn)很多工作方式都是雜亂無章的,沒有數(shù)據(jù)綁定,沒有列表同步,也沒有反應性的結(jié)論性表述。我會試圖為在 Web 平臺上解決這些問題提供指導,而不是用框架(也就是說,走普通路線)。

具有穩(wěn)定的 Dom 樹和級聯(lián)的反應性

讓我們回到錯誤標簽的示例上。在 ReactJS 和 SolidJS 中,我們會創(chuàng)建聲明性代碼,并將其轉(zhuǎn)化為命令性代碼,向 DOM 中加入標簽或者刪除標簽。在 Svelte 中,生成這些代碼。

但是,如果我們根本沒有這些代碼,而是用 CSS 來隱藏和顯示錯誤標簽呢?

<style>    label.error { display: none; }    .app.has-error label.error {display: block; }style><label class="error">Messagelabel>
<script> app.classList.toggle('has-error', true);script>

在這種情況下,反應性是在瀏覽器中處理的:應用的類變化會傳播到它的后代,直到瀏覽器的內(nèi)部機制決定是否渲染標簽。

這種技術(shù)有幾個具有以下優(yōu)點:

  • 包大小為零。

  • 無構(gòu)建步驟。

  • 變化傳播經(jīng)過優(yōu)化和良好的測試,在本地瀏覽器代碼中,避免了不必要的昂貴的 DOM 操作,如追加和刪除。

  • 選擇器是穩(wěn)定的。在這種情況下,你可以指望標簽元素的存在。你可以對它應用動畫,而不必依賴復雜的結(jié)構(gòu),如“過渡組”。你可以在 JavaScript 中保持對它的引用。

  • 如果標簽被顯示或隱藏,你可以在開發(fā)工具的樣式面板中看到原因,它顯示了整個級聯(lián),即最終導致標簽可見(或隱藏)的規(guī)則鏈。

即便你閱讀了本文,并且選擇繼續(xù)使用框架工作,但是要讓 DOM 保持穩(wěn)定,使用 CSS 的方式發(fā)生改變,這個想法還是很強大的。想想看,這對你來說有什么用處。

面向表單的“數(shù)據(jù)綁定”

在大量使用 JavaScript 的單頁應用(single-page application,SPA)時代到來之前,表單是創(chuàng)建包含用戶輸入的 Web 應用的主要方式。傳統(tǒng)上,用戶填寫表格并點擊“提交”按鈕,服務器端的代碼就會處理響應。表單是數(shù)據(jù)綁定和互動性的多頁面應用版本。難怪具有 input 和 output 基本名稱的 HTML 元素是表單元素。

表單 API 應用范圍廣,歷史悠久,因此它具有一些潛在優(yōu)勢,可以幫助人們解決在傳統(tǒng)上認為不能通過表單來處理的問題。

表單和表單元素作為穩(wěn)定的選擇器

表單可以通過名稱訪問(使用 document.forms),每個表單元素可以通過其名稱訪問(使用 form.elements)。此外,與一個元素相關(guān)的表單也可以被訪問(使用 form 屬性)。這不僅包括 input 元素,還包括其他表單元素,如 output、textarea 和 fieldset,這允許在一個樹中對元素進行嵌套訪問。

在上一節(jié)的錯誤標簽示例中,我們展示了如何反應性地顯示和隱藏錯誤信息。這就是我們在 React 中更新錯誤信息文本的方法(在 SolidJS 中也類似):

const [errorMessage, setErrorMessage] = useState(null);return?<label?className="error">{errorMessage}label>

當我們有一個穩(wěn)定的 DOM 和穩(wěn)定的樹形表單和表單元素時,我們可以做以下事情:

<form name="contactForm">  <fieldset name="email">     <output name="error">output>  fieldset>form>
<script> function setErrorMessage(message) { document.forms.contactForm.elements.email.elements.error.value = message; }script>

這個原始格式看起來相當冗長,但是它也非常穩(wěn)定、直接和高效。

用于輸入的表單

通常,當我們建立一個 SPA 時,我們有某種類似 JSON 的 API,我們用它來更新我們的服務器,或我們使用的任何模型。

這將是一個熟悉的示例(為了可讀性,用 Typescript 編寫):

interface Contact {  id: string;  name: string;  email: string;  subscriber: boolean;}
function?updateContact(contact:?Contact)?{?…?}

在框架代碼中,通過選擇輸入元素并逐段構(gòu)建對象來生成這個聯(lián)系對象是很常見的。通過對表單的正確使用,有一個簡潔的替代方案。

<form name="contactForm">  <input name="id" type="hidden" value="136" />  <input name="email" type="email"/>  <input name="name" type="string" />  <input name="subscriber" type="checkbox" />form>
<script> updateContact(Object.fromEntries( new FormData(document.forms.contactForm));script>

通過使用隱藏的輸入和有用的 FormData 類,我們可以在 DOM 輸入和 JavaScript 函數(shù)之間無縫轉(zhuǎn)換數(shù)值。

結(jié)合表單和反應性

通過結(jié)合表單的高性能選擇器穩(wěn)定性和 CSS 反應性,我們可以實現(xiàn)更復雜的 UI 邏輯:

<form name="contactForm">  <input name="showErrors" type="checkbox" hidden />  <fieldset name="names">     <input name="name" />     <output name="error">output>  fieldset>  <fieldset name="emails">     <input name="email" />     <output name="error">output>  fieldset>form>
<script> function setErrorMessage(section, message) { document.forms.contactForm.elements[section].elements.error.value = message; } function setShowErrors(show) { document.forms.contactForm.elements.showErrors.checked = show; }script>
<style> input[name="showErrors"]:not(:checked) ~ * output[name="error"] { display: none; }style>

請注意,在這個示例中并沒有使用類:我們從表單的數(shù)據(jù)中開發(fā) DOM 的行為和風格,而不是通過手動更改元素的類。

我不喜歡過度使用 CSS 類作為 JavaScript 選擇器。我認為它們應該被用來將風格相似的元素組合在一起,而不是作為改變組件風格的一種萬能機制。

表單的優(yōu)點
  • 與級聯(lián)一樣,表單是內(nèi)置于 Web 平臺的,其大部分特性是穩(wěn)定的。這意味著更少的 JavaScript,更少的框架版本不匹配,而且沒有“構(gòu)建”。

  • 默認情況下,表單是可訪問的。如果你的應用程序正確地使用表單,就不需要 ARIA 屬性、“輔助插件”和最后一分鐘的審核。表單適合于鍵盤導航、屏幕閱讀器和其他輔助技術(shù)。

  • 表單帶有內(nèi)置的輸入驗證特性:通過 regex 模式進行驗證,對 CSS 中無效和有效表單進行反應性驗證,處理必需表單和可選表單,等等。為了享受這些特性,你不需要看起來像表單的東西。

  • 表單的 submit 事件是非常有用的。例如,它允許在沒有提交按鈕的情況下捕獲“Enter”鍵,并允許通過 submitter 屬性來區(qū)分多個提交按鈕(正如我們將在后面的 TODO 示例中看到的)。

  • 默認情況下,元素與它們所包含的表單相關(guān)聯(lián),但也可以使用 form 屬性與文檔中的任何其他表單相關(guān)聯(lián)。這使我們能夠在不對 DOM 樹產(chǎn)生依賴的情況下進行表單關(guān)聯(lián)。

  • 使用穩(wěn)定的選擇器有助于實現(xiàn) UI 測試自動化。我們可以使用嵌套的 API 作為一種穩(wěn)定的方式來鉤住 DOM,而不管它的布局和層次結(jié)構(gòu)如何。form > (fieldsets) > element 的層次結(jié)構(gòu)可以作為你的文檔的互動骨架。

CHACHA 和 HTML 模板

框架提供了它們自己表達可觀察列表的方式。現(xiàn)在很多開發(fā)者也依賴提供這種功能的非框架庫,如 MobX。

通用的可觀察列表的主要問題在于它們是通用的。這以性能為代價增加了便利性,而且還需要特殊的開發(fā)者工具來調(diào)試那些庫在后臺做的復雜動作。

使用這些庫并理解它們的作用是可以的,無論選擇什么樣的 UI 框架,它們都是有用的,但使用替代方案可能不會更復雜,而且可以避免一些在你試圖推出自己的模型時產(chǎn)生的陷阱。

變化通道(或 CHACHA)

CHACHA——也被稱為變化通道(Changes Channel)——是一個雙向流,其目的是通知意圖方向和觀察方向的變化。

  • 在意圖方向上,UI 將用戶意圖的變化通知給模型。

  • 在觀察方向上,模型將對模型所做的改變通知給 UI,而這些改變需要顯示給用戶。

這也許是一個有趣的名字,但它不是一個復雜或新穎的模式。雙向流在 Web 和軟件中隨處可見(例如,MessagePort)。在這種情況下,我們正在創(chuàng)建一個雙向流,它有一個特殊的目的:向 UI 報告實際的模型變化,并向模型報告意圖。

CHACHA 的接口通??梢詮膽玫囊?guī)范中導出,而不需要任何 UI 代碼。

例如,一個允許你添加和刪除聯(lián)系人并從服務器加載初始列表的應用程序(帶有刷新選項)可以有一個 CHACHA,它看起來像這樣:

interface Contact {  id: string;  name: string;  email: string;}// "Observe" Directioninterface ContactListModelObserver {  onAdd(contact: Contact);  onRemove(contact: Contact);  onUpdate(contact: Contact);}// "Intent" Directioninterface ContactListModel {  add(contact: Contact);  remove(contact: Contact);  reloadFromServer();  }

請注意,這兩個接口中的所有函數(shù)都是無效的,只接收普通對象。這是故意的。CHACHA 被構(gòu)建成一個通道,有兩個端口來發(fā)送消息,這使得它可以在 EventSource、HTML MessageChannel、服務工作者或任何其他協(xié)議中工作。

CHACHA 的好處是,它們很容易測試。你發(fā)送動作并期待對觀察者的特定調(diào)用作為回報。

列表項的 HTML 模板元素

HTML 模板是存在于 DOM 中的特殊元素,但不會被顯示。它們的目的是生成動態(tài)元素。

當我們使用 template 元素時,我們可以避免在 JavaScript 中創(chuàng)建元素和填充它們的所有模板代碼。

下面將使用 template 為列表添加名稱:

<ul id="names">  <template>   <li><label class="name" />li>  template>ul><script>  function addName(name) {    const list = document.querySelector('#names');    const item = list.querySelector('template').content.cloneNode(true).firstElementChild;    item.querySelector('label').innerText = name;    list.appendChild(item);  }script>

通過使用列表項的 template 元素,我們可以在原始 HTML 中看到列表項——它不是用 JSX 或其他語言“渲染”的。你的 HTML 文件現(xiàn)在包含了應用程序的所有 HTML——靜態(tài)部分是渲染的 DOM 的一部分,而動態(tài)部分在模板中表達,準備在時機成熟時被克隆并追加到文檔中。

集大成者:TodoMVC

TodoMVC 是一個 TODO 列表的應用規(guī)范,用于展示不同的框架。TodoMVC 模板帶有現(xiàn)成的 HTML 和 CSS,幫助你專注于框架。

你可以在 GitHub 資源庫中使用這個結(jié)果,并且可以獲得完整的源代碼。

從規(guī)范派生的 CHACHA 開始

我們將從規(guī)范開始,并使用它來構(gòu)建 CHACHA 接口:

interface Task {   title: string;   completed: boolean;}
interface TaskModelObserver { onAdd(key: number, value: Task); onUpdate(key: number, value: Task); onRemove(key: number); onCountChange(count: {active: number, completed: number});}
interface TaskModel { constructor(observer: TaskModelObserver); createTask(task: Task): void; updateTask(key: number, task: Task): void; deleteTask(key: number): void; clearCompleted(): void; markAll(completed: boolean): void;}

任務模型中的函數(shù)直接來自規(guī)范和用戶可以做的事情(清除已完成的任務,將所有任務標記為已完成或正在進行,獲得正在進行和已完成的計數(shù))。

請注意,它遵循 CHACHA 的準則。

  • 有兩個界面,一個是動作的,一個是觀察的。

  • 所有的參數(shù)類型都是基元或普通對象(很容易翻譯成 JSON)。

  • 所有的函數(shù)都返回 void。

TodoMVC 的實現(xiàn)使用 localStorage 作為后端。

該模型非常簡單,與關(guān)于 UI 框架的討論沒有多大關(guān)系。它在需要的時候保存到 localStorage,并在某些情況發(fā)生變化時向觀察者觸發(fā)回調(diào),這些變化可能是用戶操作的結(jié)果,也可能是模型第一次從 localStorage 加載的時候。

精簡的、面向表單的 HTML

接下來,我將采用 TodoMVC 模板,并將其修改為面向表單的模板:表單的層次結(jié)構(gòu),輸入和輸出元素代表可以用 JavaScript 改變的數(shù)據(jù)。

我怎么知道某個東西是否需要成為表單元素?作為一個經(jīng)驗法則,如果它與模型中的數(shù)據(jù)綁定,那么它就應該是一個表單元素。

完整的 HTML 文件是可用的,但這里是其主要部分:

<section class="todoapp">   <header class="header">       <h1>todosh1>       <form name="newTask">           <input name="title" type="text" placeholder="What needs to be done?" autofocus>       form>   header>
<main> <form id="main">form> <input type="hidden" name="filter" form="main" /> <input type="hidden" name="completedCount" form="main" /> <input type="hidden" name="totalCount" form="main" /> <input name="toggleAll" type="checkbox" form="main" />
<ul class="todo-list"> <template> <form class="task"> <li> <input name="completed" type="checkbox" checked> <input name="title" readonly /> <input type="submit" hidden name="save" /> <button name="destroy">Xbutton> li> form> template> ul> main>
<footer> <output form="main" name="activeCount">0output> <nav> <a name="/" href="#/">Alla> <a name="/active" href="#/active">Activea> <a name="/completed" href="#/completed">Completeda> nav> <input form="main" type="button" name="clearCompleted" value="Clear completed" /> footer>section>

此 HTML 包括以下內(nèi)容:

  • 我們有一個 main 表單,其中有所有的全局輸入和按鈕,還有一個新的表單用于創(chuàng)建一個新任務。請注意,我們使用 form 屬性將元素與表單聯(lián)系起來,以避免表單中的元素嵌套。

  • template 元素代表一個列表項,它的根元素是另一個表單,代表與特定任務相關(guān)的互動數(shù)據(jù)。當任務被添加時,這個表單將通過克隆模板的內(nèi)容而被重復。

  • 隱藏的輸入表示不直接顯示的數(shù)據(jù),但用于樣式設計和選擇。

注意這個 DOM 是如何簡潔的。它沒有在其元素中散布類。它包括應用程序所需的所有元素,以合理的層次結(jié)構(gòu)排列。多虧了隱藏的輸入元素,你已經(jīng)可以很好地感覺到以后文檔中可能會有什么變化。

這個 HTML 不知道它將如何被樣式化,也不知道它到底與什么數(shù)據(jù)綁定。讓 CSS 和 JavaScript 為你的 HTML 工作,而不是讓你的 HTML 為某個特定的造型機制工作。這將使你在改變設計時變得更加容易。

最小控制器 JavaScrip

現(xiàn)在我們在 CSS 中已經(jīng)有了大部分的反應性,在模型中也有了列表處理,剩下的就是控制器的代碼了,也就是把所有的東西固定在一起的“膠帶”。在這個小程序中,控制器的 JavaScript 大約是 40 行。

下面是一個版本,每個部分都有解釋:

import TaskListModel from './model.js';
const?model?=?new?TaskListModel(new?class?{

上面,我們創(chuàng)建了一個新模型。

onAdd(key, value) {   const newItem = document.querySelector('.todo-list template').content.cloneNode(true).firstElementChild;   newItem.name = `task-${key}`;   const save = () => model.updateTask(key,  Object.fromEntries(new FormData(newItem)));   newItem.elements.completed.addEventListener('change', save);   newItem.addEventListener('submit', save);   newItem.elements.title.addEventListener('dblclick', ({target}) => target.removeAttribute('readonly'));   newItem.elements.title.addEventListener('blur', ({target}) => target.setAttribute('readonly', ''));   newItem.elements.destroy.addEventListener('click', () => model.deleteTask(key));   this.onUpdate(key, value, newItem);   document.querySelector('.todo-list').appendChild(newItem);}

當一個項目被添加到模型中,我們在用 UI 中創(chuàng)建其相應的列表項。

在上面的代碼段中,我們克隆了項目 template 的內(nèi)容,為一個特定的項目分配了事件監(jiān)聽器,并將新的項目添加到列表中。

注意,這個函數(shù),以及 onUpdate、onRemove 和 onCountChange,都是要從模型中調(diào)用的回調(diào)。

onUpdate(key, {title, completed}, form = document.forms[`task-${key}`]) {   form.elements.completed.checked = !!completed;   form.elements.title.value = title;   form.elements.title.blur();}

當一個項目被更新時,我們設置它的 completed 和 title 值,然后 blur(退出編輯模式)。

onRemove(key)?{?document.forms[`task-${key}`].remove();?}

當從模型中移除一個項時,我們將從視圖中移除其對應的列表項。

onCountChange({active, completed}) {   document.forms.main.elements.completedCount.value = completed;   document.forms.main.elements.toggleAll.checked = active === 0;   document.forms.main.elements.totalCount.value = active + completed;   document.forms.main.elements.activeCount.innerHTML = `${active} item${active === 1 ? '' : 's'} left`;}

在上面的代碼中,當完成的或活動的項目數(shù)量發(fā)生變化時,我們設置適當?shù)妮斎雭碛|發(fā) CSS 反應,并格式化顯示計數(shù)的輸出。

const updateFilter = () => filter.value = location.hash.substr(2);window.addEventListener('hashchange', updateFilter);window.addEventListener('load',?updateFilter);

而我們從 hash 片段中更新過濾器(以及在啟動時)。我們在上面所做的只是設置一個表單元素的值:CSS 處理其余部分。

document.querySelector('.todoapp').addEventListener('submit',?e?=>?e.preventDefault(),?{capture:?true});

在這里,我們確保當表單被提交時我們不會重新加載頁面。這一行代碼把這個應用程序變成了一個 SPA。

document.forms.newTask.addEventListener('submit', ({target: {elements: {title}}}) =>       model.createTask({title: title.value}));document.forms.main.elements.toggleAll.addEventListener('change', ({target: {checked}})=>    model.markAll(checked));document.forms.main.elements.clearCompleted.addEventListener('click', () =>????model.clearCompleted());

而這就處理了主要的操作(創(chuàng)建、標記所有、清除完成)。

與 CSS 的反應性

完整的 CSS 文件可以供你查看。

CSS 處理了規(guī)范中的很多要求(做了一些有利于無障礙的修正)。我們來看看一些示例。

根據(jù)規(guī)范,“X”(destroy)按鈕只在懸停時顯示。我還添加了一個輔助位,使它在任務被聚焦時可見。

.task:not(:hover,?:focus-within)?button[name="destroy"]?{?opacity:?0?}

當 filter 鏈接是當前鏈接時,它會得到一個紅色邊框:

.todoapp input[name="filter"][value=""] ~ footer a[href$="#/"] 。nav a:target {   border-color: #CE4646;}

注意,我們可以使用鏈接元素的 href 作為部分屬性選擇器 -- 不需要 JavaScript 來檢查當前的過濾器,并在適當?shù)脑厣显O置一個 selected 類。

我們還使用了 :target 選擇器,這讓我們不必擔心是否要添加過濾器。

title 輸入的視圖和編輯樣式根據(jù)其只讀模式而改變:

.task input[name="title"]:read-only {}
.task input[name="title"]:not(:read-only) {}

過濾(即只顯示活動的和已完成的任務)是用選擇器完成的:

input[name="filter"][value="active"] ~ * .task      :is(input[name="completed"]:checked, input[name="completed"]:checked ~ *),input[name="filter"][value="completed"] ~ * .task     :is(input[name="completed"]:not(:checked), input[name="completed"]:not(:checked) ~ *) {   display: none;}

上面的代碼可能看起來有點冗長,用 Sass 這樣的 CSS 預處理程序可能更容易閱讀。但它所做的事情很簡單:如果過濾器處于 active 狀態(tài),而 completed 的復選框被選中,或者相反,那么我們就會隱藏復選框及其同級。

我選擇在 CSS 中實現(xiàn)這個簡單的過濾器,以顯示它能走多遠,但如果它開始變得棘手,那么把它移到模型中是完全有意義的。

總結(jié)及要點

我相信,框架為實現(xiàn)復雜的任務提供了方便的方法,而且它們有超越技術(shù)的好處,比如使一組開發(fā)人員向特定的風格和模式看齊。Web 平臺提供了許多選擇,而采用一個框架可以讓每個人至少部分地在這些選擇上達成一致,這是有價值的。另外,聲明式編程的優(yōu)雅性也是值得稱道的,而且組件化的大特點也不是我在這篇文章中所處理的。

但請記住,替代模式是存在的,通常成本較低,而且不一定需要較少的開發(fā)者經(jīng)驗。允許自己對這些模式感到好奇,即使你決定在使用框架時從它們中挑選。

模式概述
  • 保持 DOM 樹的穩(wěn)定。它啟動了一個連鎖反應,使事情變得簡單。

  • 如果可以的話,依靠 CSS 的反應性而不是 JavaScript。

  • 使用表單元素作為表示互動數(shù)據(jù)的主要方式。

  • 使用 HTML template 元素而不是 JavaScript 生成的模板。

  • 使用雙向的變化流作為模型的接口。

作者簡介:

Noam Rosenthal,Web 平臺顧問,WebKit 和 Chromium 的貢獻者,標準編輯,也是經(jīng)驗豐富的 Web 開發(fā)者。他的工作主要是在 Web 開發(fā)和瀏覽器 / 標準開發(fā)之間架起橋梁。

原文鏈接:

https://www.smashingmagazine.com/2022/02/web-frameworks-guide-part2/


往期推薦


秒啊!答好這5個問題,就入門Docker了
(字節(jié)/華為/美團)前端面經(jīng)記錄冷冷清清的金三銀四
最新 955 不加班的公司名單(2022版)

最后


  • 歡迎加我微信,拉你進技術(shù)群,長期交流學習...

  • 歡迎關(guān)注「前端Q」,認真學前端,做個專業(yè)的技術(shù)人...

點個在看支持我吧
瀏覽 101
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 天堂网av在线| 成人精品永久免费视频99久久精品| 俺去俺来也www色视频| 97在线国产| 综合久久亚洲| 成人一区视频| 操屄视频免费观看| 欧美日韩中文在线视频| 青草社区在线观看| 91精品一区| 国产福利在线观看| 免费观看黄色电影| 国产精品乱子伦一区二区三区视频 | 337p粉嫩噜噜噜| 日韩色小说| 大鸡巴黄色视频免费观看| 国产伦精品一区二区三区妓女| 丝袜足交视频| 被黑人猛躁10次高潮视频| 久久婷五月天| 亚洲精品成人一二三区| 天堂中文在线播放| 狠狠色噜噜狠狠狠888| 欧美特黄AAA| 香蕉网站操逼片| 一级黄色大片| 伊人成人在线观看| 色色五月婷婷| 午夜无码熟妇丰满人妻| 无码AV电影| 天天草天天干| 婷婷久久婷婷| 人人干97| 亚洲A片一区二区三区电影网| 97人人爽人人爽人人爽人人爽 | 亚洲无码免费看| 国产AV三级片| 一级A片60分钟免费看| 欧美毛片A| 亚洲无码字幕| 在线视频日本| 人人草人人摸人人看| 成人毛片在线视频| 一级黄色录像视频| 俺去俺来也在线www色情网 | 胖老板办公室沙发无套爆秘书 | 狠狠干在线| 久久久久91| 国产小骚逼| 一级全黄120分钟免费| www男人天堂| 中文字幕熟女| www九九九| 日本aa视频| 日韩色婷婷| 无码五区| 人人操超碰在线观看| 精品一区二区三区四区五区| 在线a视频免费观看| 欧美成人69| 午夜xxx| 国产精品一区一区三区| 五月丁香色色| 大香蕉久操网| 欧美熟妇另类久久久久久不卡| 加勒比一区二区| 超碰在线免费播放| 人与鲁牲交| 午夜成人黄色电影| 久久久无码人妻精品无码| 色色色999| 影视先锋久久| 国产欧美在线观看不卡| 99久久精品一区二区成人| 免费V片在线观看| 国产三级日本三级国产三级| 婷婷激情丁香五月天| 免费在线观看中文字幕| 伊人久久AV诱惑悠悠| 天天干强奸视频在线综合| 一区二区在线不卡| 婬乱欧美一二三区| 蜜臀AV成人| 美女久草| 少妇搡BBBB搡BBB搡毛片| 国产成人毛片18女人18精品 | 久久久久91| 日韩人妻一区二区三区| 国产无遮挡又黄又爽免费网站| 亚洲va国产va天堂va久久| 插菊花综合网2| 高清无码免费在线| 一区二区三区成人| 丁香六月婷婷久久综合| 久久电影五月天| 欧美午夜乱伦电影| 精品久久久久久AV2025| 亚洲国产成人精品综合99| 成人毛片18毛片女人| 中文字幕成人av| 一级操逼大片| 大香蕉在线播| 亚洲加勒比久久88色综合| 18禁网站免费观看| 肏逼综合网| 人人干日日干| 日韩免费中文字幕| 91久久国产综合久久91精品网站 | 免费在线无码视频| 五月天成人导航| 久草国产在线视频| 四川少妇bbbbbbbbb| 欧美一级AA大片免费看视频| 亚洲高清成人动漫| 青草无码视频| 亚洲黄色精品| 热久久免费视频| 色青草影院久久综合| S牛牛AV| 久久g热| 国产婬片一级A片AAA毛片AⅤ| 日韩蜜桃视频| 国产精品国产三级国产AⅤ中文| 超碰2023| 亚洲国产激情视频| 亚洲无码成人在线观看| 亚洲操逼片| 人妻视频网站| 国产精品国产伦子伦露看| 夫妻成人免费看片一区二区| 日区无码| 一区高清| 成人一区视频| 伊人性爱网| 亚洲欧洲成人在线| 欧美日韩国产一区二区| 亚洲成人AV在线| 亚洲福利| 免费一级欧美片在线观看| 欧美日韩国产成人在线观看| 伊人久久无码| 美日韩一区二区三区| 亚洲无线视频| 蜜桃AV一区二区三区| 无码专区一区二区三区| 无码国产精品一区二区三| 11孩岁女精品A片BBB| 日韩A级视频| 粉嫩99精品99久久久久久特污| 久久午夜无码鲁丝片主演是谁| 国产精品蜜| 免费网站观看www在线观看| 中文字幕永久免费| 一级操逼黄色视频| 91一区二区在线播放精品| 亚洲女同在线| 久久精品视频一区| 精品免费国产一区二区三区四区 | 伊人网在线免费视频| 蝌蚪窝在线视频观看| 制服丝袜在线视频| 又黄又爽的网站| 国产精品一区在线| 欧美天堂在线| 黄色片免费视频网站| 免看一级a一片| 日韩成人大片| 无码国产一区二区三区四区五区| 精品人妻一区二区三区-国产精品 无码人妻av黄色一区二区三区 | 日韩av小电影| 亲子伦视频一区二区三区| 国产精品国产精品国产专区不| 免费在线黄色电影| 日韩精品欧美一区二区三区| 久久香蕉电影| ww亚洲ww| 超碰人人在线观看| 日韩成人一区| 日本中文字幕在线| 99在线观看视频在线高清| 无码高潮视频| 国产又大又黄| 国产成人AⅤ| 欧美伊人网在线观看| 97精产国品久久蜜桃臀| 一级黄色免费片| 青春草免费视频| 亚洲无码系列| 激情导航| 欧美一区在线视频| 777777国产7777777| 无码一二三四| 日韩一级黄色电影| 黄色激情av| chinese搡老熟老妇人| www.狠狠干| 亚洲成人AV在线| 开心激情播播网| 91亚洲影院| 亚洲免费毛片| 亚洲第一av| 国产欧美综合视频一区二区在线 | jizz久久| 亚洲最新中文字幕| 高清无码黄片| 不卡AV在线播放| jizz久久| 黄色小视频在线免费观看| 最新中文字幕在线观看| 大香蕉久久久久久久| 粉嫩av在线| 一级无码高清| 91网站18| 亚洲香蕉视频网站| 中文字幕国产AV| 蜜桃传媒一区| 亚洲激情性爱| 九九热视频99| 欧美不卡一区二区三区| 欧美中文字幕在线| 婷婷在线观看免费| A级片免费| 国产精品综合激情| 国产熟女一区二区视频网站| 日韩欧美人妻无码精品| 国产在线视频一区二区| AV在线天堂| 日本免费一二三区| 无码一级二级| 成人黄色性爱视频| 亚洲国产高清视频| 精品交换一区二区三区无码| 五月天色色网站| 欧美一卡二卡三卡| 伊人影院在线免费观看| 日皮在线观看| 婷婷午夜| 日本无码成人片在线播放| 色色大香蕉| 午夜福利不卡视频| 欧美操逼电影| 免费在线看黄网站| 成人二区三区| 91成人在线电影| 免费黄色A片| 亚洲AV无码精品岛国| 欧美日韩亚洲视频| www.狠狠操| 免费观看黄片网站| 成人一级黄片| 91麻豆福利在线| 成人黄网站免费视频| 久久亚洲AV| 超碰在线网| 337P人体美鮑高清| 高清无码视频网站| 国产精品人人| 国产黄色视频免费| 色吧五月| 一本无码视频| 人妻无码精品| 久久久久久久久黄色| 久久亚洲av| 国产做受精品网站在线观看| 久久国产毛片| 中文字幕有码在线| 婷婷综合欧美| 欧美l∨视| 人人操人人操人人操人人操人人操 | 成人精品一区日本无码网站suv/ | 亚洲高清无码在线播放| 超碰在线进入| 69福利视频| 亚洲视屏| 香蕉午夜视频| 国产在线观看国产精品产拍| 激情开心站| 久久国产黄色视频| 精品无码一区二区人妻久久蜜桃 | 91视频亚洲| 国产成人精品久久二区二区91| 波多野结衣在线观看一区二区| 欧美一级黃色A片免费看小优视频| 91精品婷婷国产| 天堂网av2025| 成人做爰A片一区二区app| 久久久成人网| 欧美亚韩| 香蕉伊人在线| 国产男女无套免费| 91欧美日韩综合| 97中文在线| 热久久这里只有精品| 天天色免费视频| 蜜臀av在线免费观看| 一区二区三区不卡视频| 在线看v片| 小處女末发育嫩苞AV| 大BBBw大BBBW另类| 伊人88| 五月花在线视频| 婷婷成人综合| 九九九在线观看视频| 精品人妻二区三区蜜桃| www.97yy| 欧美视频基地| 日韩视频在线播放| 中国婬乱a| 成人无码在线观看免费视频| 日韩中文字幕av在线| 欧美性爱小说| 国产欧美日韩在线播放| 欧美亚洲一区| 一区二区三区四区av| 国产高清精品软件丝瓜软件| 亚洲精品白浆高清久久久久久| 婷婷精品国产a久久综合| 操逼免费观看视频| 亚洲性爱无码| 色呦呦视频| 91福利导航| 福利视频免费观看| 男人天堂v| 欧美最猛黑A片黑人猛交蜜桃视频 色噜噜狠狠一区二区三区300部 | 人妻第一页| 日韩精品丰满无码一级A片∴| 成人超碰在线| 人妻少妇精品无码| 波多野结衣av在线| 狠狠狠狠狠狠狠狠狠| 亚洲五月婷婷| 成人无码日韩精品| www.a日逼| 日韩亚洲天堂| 18禁二区| 黄片免费视频观看| 欧美一区电影| 成人做爰100部免费网站| 日本一级片中文字幕| 五月开心激情网| 国产欧美第一页| 伊人五月天激情| 激情五月天开心网| 五月天丁香社区| 在线免费中文字幕| 97精品国产| 波多野结衣一二三区| 青青草无码成人AV片| 偷拍视频第一页| 午夜精品18码视频国产17c| 成人日批视频| 影音先锋AV资源网站| 色综合综合色| 人人看人人摸人人插| 一级黄色电影在线观看| 无码专区在线播放| 1024在线视频| 麻豆91精品91久久久| 亚洲在线| 日本高清无码在线观看| 日本免费福利视频| 99爱在线观看| 久久精品婷婷| 免费无码成人片在线观看在线 | 99人妻人人爽人人添人人精品| 狠狠干2024| 性爱免费视频| 亚洲无码入口| 国产精品无码毛片| 精品一区二区三区四区视频| 日韩中文字幕视频在线| 黄色大片在线免费观看| 成人精品秘免费波多野结衣| 国产十欧洲十美国+亚洲一二三区在线午夜 | 五月天婷婷影院| 国产成人午夜精品无码区久久麻豆| 色色欧美色色| 乱子伦国产精品视频| 久久成人久久爱| 无码视频一区二区| 蜜臀久久久99久久久久久久| 色吧视频| 欧美特黄AAAAAAAAA片 | 国产精品秘久久久久久1-~/\v7-/ 囯产精品一区二区三区线一牛影视1 | 今天成全在线观看高清| 免费视频亚洲| 欧洲三级片| AA毛片| 一牛影视精品av| 免费A片国产毛无码A片| 国产高清小视频| 国产在线欧美在线| 亚洲av男人天堂| 欧美+日韩+国产+成人+在线| 91AV在线播放| 人人草大香蕉| 蜜桃在线一区| 天天射日日干| 无码在线高清| 激情啪啪网站| 99热66| 亚洲大片在线观看| 久久久久久国产免费A片| 久久免费小视频| 日韩在线91| 亚洲狠狠| 国产91精品在线观看| 亚洲综合网在线观看| 日日夜夜干| 91九色91蝌蚪91成人| 亚洲无码成人AV| 国产无码激情视频| 亚洲熟女av中文字幕| 人人人人人妻| 成人毛片在线观看| 九九综合网| 69堂在线观看| 久久麻豆| 成人大片在线观看| 精品多人P群无码视频| 色婷婷色| 天堂资源中文在线| 亚洲黄色视频在线免费观看| AV在线天堂| 色婷婷一区二区三区久久午夜| 日本成人不卡| 欲色AV| 欧美亚洲日韩成人| 欧美日韩中| 台湾无码| 亚洲久久久久久| 成人综合娱乐网| 欧美日韩有码视频网址大全| 久久99精品久久久水蜜桃| 91久久久久久久18| 夜夜AV| A片小视频| 国产农村妇女精品一二区| 亚洲色视频在线| 国产AA| 欧美成人精品欧美一级| 中文字幕婷婷五月天| 亚洲777| 欧美一級黃色A片免費看| www.xxx国产| 黄色免费a级片一级片| 偷拍第一页| 99久热在线精品视频| 综合久久av| 91狠狠综合久久| 亚洲AV无一区二区三区久久 | 国产精品美女| ThePorn日本无码| 亚洲高清电影| 国产综合亚洲精品一区二| 大香蕉伊人在线观看| 成人免费视频一区二区| 国产精品欧美日韩| 亚洲一本在线电影av| 大香蕉操| 国产精品久久久久久精| 免费高清无码在线| 国产福利在线视频| 蜜桃视频网站18| 逼逼影院| 欧美日韩亚洲一区二区三区| 伊人在线视频| 亚洲无码视频在线看| 大香蕉黄色片| 91精品国产综合久久久蜜臀图片| 中文字幕有码在线观看| 国产一级婬片A片AAA樱花| 影音先锋成人AV资源| 国产精品成人69| 亚洲电影在线观看| 亚洲AV成人无码精品直播在线| 久久99精品国产.久久久久久| 亚洲成人自拍无码| 天天久久综合| 超碰人人人人人| 俺去俺来也在线www色情网 | 操碰视频| 污视频在线看| 免费内射网站| 一区二区国产视频| 亚洲中文字幕久久日| 神马午夜久久| 日日干日日干| 中文字幕av一区| 操www| 黄片网站免费观看| 欧美AAA视频| 在线免费观看无码视频| 亚洲中文字幕在线无码| 岛国A视频| 伊人网综合| 四虎精品一区二区| 日本精品黄色| 亚洲日韩在线看| 亚洲中文自拍| 久久免费精品| 波多野结衣无码电影| 四虎黄色影院| AV无码网| 亚洲国产成人无码| 成人视频网| 成人在线精品| 九九九免费| 亚洲AV无码秘翔田| 淫色AV| 曰本精品综合网在线| 蜜臀久久99精品久久久老牛影视| 日本親子亂子倫XXXX50路| v天堂| 蜜臀久久99精品久久| 青青草做爱视频| 亚洲日韩在线视频| 高清国产mv在线观看| 乱子伦国产精品一区二区| 色五月婷婷激情| 夜夜操天天| 自拍无码视频| 国产综合自拍| 日本爱爱网站| 六月婷婷激情| 99久久99久久精品免费看小说。 | 一区二区三区精品无码| 欧美在线A| 俺也去com| 日本操骚逼| 国产性爱AV| 无码一区二区视频| 国产黄色视频在线观看免费| 水蜜桃成人网| 人妻无码精品蜜桃| 国产日本在线视频| 黄色毛片网站| 天堂在线免费视频| 国产成人无码免费看片| 自拍偷拍综合网| 成人日韩在线| 成人在线黄片| 日本午夜影院| 丝袜足交视频在线观看| 日韩二区| 在线成人| 日韩成人在线免费观看| 亚洲精品一区二区三区新线路| 黄色视频在线免费观看网站| 日韩亚洲在线视频| 91精品国产一区二区三区四区大| 国产欧美日韩综合| 好吊一区二区三区| 操逼天堂| 国产精品精品| 黄色成人网站在线观看免费| 91成人在线播放| 亚洲在线成人视频| 九月丁香婷婷| 91ThePorn国产| 国产久久精品视频| 鲁一鲁视频| 国产综合自拍| 狼友视频在线| 伊人大香蕉久久| 激情av| 中文字幕av一区二区| 特级AV| 波多野结衣一级| 国产卡一卡二在线| 99久久成人| 日本人妻在线播放| 国产a一级a毛一级视频| 欧美综合亚洲图片综合区| 欧美中文字幕在线| 中文字幕综合| 欧美一级特黄A片免费看视频小说| 亚洲AV无码精品| 精品视频免费| 日韩免费成人| 精品尤物| www免费视频在线观看播放| 亚洲在线a| 人人舔人人草| 欧洲a视频| 日本成人不卡| 俺也来俺也去WWW色| 美女久草| 国产精品伦理| 99热精品免费在线观看| 国产综合自拍| 性爱无码| 日本无码嫩草一区二区| 欧美9999| 久久波多野结衣| 人人爽夜夜爽| 日韩午夜成人电影| 欧美中文日韩| 亚洲图片在线观看| 超碰97在线免费观看| 中文字幕亚洲欧美| 久久私拍| 国产午夜视频在线| 东方av在线免费观看| 国产黄色视频免费看| 亚洲欲色| 免费黄色片子| 中文字幕巨肉乱码中文乱码| 色综合色综合色综合| 日韩中文字幕在线高清| 69成人精品| 二级黄色视频| 韩国成人免费无码免费视频| sm视频网站| 91艹艹| 大香蕉啪啪啪啪| 日日夜夜草| A视频免费在线观看| www黄片视频| 狠狠撸狠狠撸| 日韩欧美中文在线观看| 91香蕉国产在线观看| 丁香花在线小说免费阅读| 亚洲高清视频一区| 呦呦av| 成人无码欧美大片免费看| 婷婷成人小说| 亚洲欧美婷婷五月色综合| 俺去了俺来也| 亚洲人人色| 欧美成人精品一级| 国产精品探花熟女| 东京热观看| 人人人人摸| 日韩AⅤ无码一区二区三区| 亚洲激情国产| 国产一区在线观看视频| 麻豆网站91| 秋霞午夜福利影院| 三级片无码在线| 91色在线视频| 欧美国产第一页| 亚洲a电影| 人人超碰人人| 欧美久久久久久| 毛片精品| 久久精品99久久久久久| 久久九色| 国产精品成人99一区无码| 香蕉三级片| 欧美日韩性爱| 理论片熟女奶水哺乳| 国产精品黄| 成人午夜免费视频| 水蜜桃视频在线观看| 欧美黄色一级| 人妻电影亚洲av| 午夜AV大片| 成人在线观看无码| 精品视频久久久久久| 起碰在线视频| 日韩av综合| 在线观看亚洲中文字幕| 亚洲精品女人| 玖玖在线播放| 国产一毛a一毛a在线观看| 天天综合网久久| 爱爱电影无码| 婷婷综合av| 日韩亚洲在线视频| 成人视频A片| 国产又粗又黄| 老司机午夜电影| 大香蕉综合闲人| www.豆花社区成人| 亚洲免费人妻| 久久国产精品免费视频| 再深点好爽灬轻点久久国产| 丰满人妻一区二区| 国产精品一卡| 久久人妻熟女中文字幕av蜜芽| AV免费网站| 午夜黄电影| 午夜精品久久久久久久久无码99热| 伊人久久大香线蕉| 99热高清| 无码六区| 视色视频在线观看18| 欧美成人在线视频网站| 好吊妞在线| 中文字幕网址在线| av天天干| 99电影网手机在线观看| 亚洲V在线观看| 大香蕉啪啪啪啪| 欧美v在线观看| 大鸡巴久久久久久久| 无码一级二级| 中文字幕日韩高清| 91精品国自产在线观看| 内射视频在线观看| 日韩精品在线观看视频| 一级片黄色电影| 黄色高清视频在线观看| 99在线观看免费| 成人网大香蕉| 久久久人妻熟妇精品无码蜜桃| 无码一道本一区二区无码| 国产在线观看| 成人国产精品秘久久久网站| 2025毛片| 国产AV一卡| 亚洲男同tv| 久久久成人免费视频| 久久永久视频| 午夜综合| 影音先锋成人资源| 周晓琳AV| 亚洲av高清| 国产口爆视频| 91热久久| 天堂成人在线| 8050网午夜| 抽插视频欧美| 色五月婷婷五月天激情| 伊人大香蕉网站| 在线婷婷| 亚洲综合社区| 米奇色色| 麻豆精东一区二区欧美国产| 黄色a片网站| 51妺妺嘿嘿午夜成人| 2024天天操| 在线视频免费观看| 日韩无码中文字幕| 日本高清版色视频| 国产成人内射| 91九色蝌蚪91POR成人| 安微妇搡BBBB搡BBBB| 七十路の高齢熟妇无码| 91久久欧美极品XXXXⅩ| 天天躁狠狠躁av| 久久依人大香蕉| 晚上碰视频| 老熟妇一区二区三区啪啪| 午夜无码熟妇丰满人妻| 欧美成人视频18| 韩日高清无码| 2019天天操| 日本一区二区三区在线观看网站| 日韩免费在线观看视频| 成人精品无码| 久草视频在线免费| 国产美女免费视频| 亚洲精选一区二区三区| 欧美中文在线观看| 婷婷性爱| 国产日本在线视频| 中文无码AV在线| 91AV在线电影| 老鸭窝在线观看视频| 中文字幕亚洲视频| 欧美九九九九| 欧美性成人| 91乱子伦国产乱| 欧美综合色| 女人卖婬视频播放| 色丁香在线| 色操网| 色综合一区二区三区| 黄视频免费在线观看| 婷婷免费| 亚洲黄v| 国产成人黄色| 欧美强开小嫩苞| 三级乱伦86丝袜无码| 欧美日韩中文在线观看| 亚洲中文字幕色| www.色悠悠| 黄色福利| 午夜精品18视频国产| 中文字幕在线观看有码| 亚洲黄色小视频| 国产XXXX| 欧美偷拍一区二区| av资源观看| 亚洲色久悠悠| 成人AV天堂| 999久久久久| 丰满人妻一区二区三区四区不卡| 日本一区二区三区免费观看| 精品国产无码怀孕| 老女人操逼网| 91香蕉视频免费| 超碰碰碰碰碰| 男人的天堂在线视频| 日本成人A| 99自拍网| 中文三级片| 亚洲中文字幕在线视频| 免费无码婬片AAAAA片| 国产精品视频99| sesese999| 日韩99在线观看| 伊人色五月天| 91足浴店按摩漂亮少妇| 伊人大香蕉在线视频| www.伊人大香蕉| 99综合久久| 亚洲欧美视频在线| 欧美亚洲综合手机在线| 狠狠撸天天操| 成人午夜av| 国产午夜无码福利视频| 欧美操B在线| 国产精品综合| 春色av| 日韩人妻无码一区二区三区中文 | 搞AV网| 在线免费观看成人视频| 黄片无码在线观看| 午夜福利无码视频| 东北女人毛多又黑A片| 成人中文字幕在线观看| 超碰首页| 一本色道精品久久一区二区三区| 精品视频日韩| 国产黄片网站| 久久永久免费精品人妻专区| 久久久久久少妇| 日日拍夜夜拍| 91在线无码精品秘国产三年| 性爱xxxxx| 粉嫩av懂色av蜜臀av熟妇| 亚洲成人高清无码| 嫩草99| 免费一级大片| 黄色片在线免费看| 香蕉大综合| 亚洲男人的天堂网| 国产成人精品无码免费| 安徽妇搡BBBB搡BBBB,另类老妇| 狠狠干狠狠艹| www.yw尤物| 久久无码影院| 91人人妻人人操| 国产福利精品视频| 在线观看国产欧美| 免费内射网站| 香蕉伊人在线| 大香蕉第一页| 嫩BBB| 免费无码在线观看| 日本免费一二三区| 免费欧美A片| 爱搞逼综合网| 成年人AV| 2018人人操| 国产精品乱伦| 欧美AA级毛片| 水蜜桃在线观看视频| 亚洲天堂人妻少妇| 日韩免费视频一区| 亚洲无码中文字幕在线播放| 88av在线观看| aaaaaa在线观看免费高清| 欧美精品综合| 吴梦梦无码| 影音先锋色先锋| 欧美成人一区二区| 国产成人精品a视频一区| 中文字幕在线观看网址最新地址 | 肏屄视频在线| 四川少妇搡bbbb搡bbbb| 国产香蕉在线视频| 亚洲综合电影| 揄拍成人国产精品视频| 中文字幕无码日韩| 久操视频在线| 无码一区二区高清| 偷拍第一页| 做爱视频91| 亚洲黄色免费电影| 免费黄色在线观看| 波多野结衣在线精品| 日逼A片| 啊哈嗯| 大香蕉婷婷五月天| 亚欧精品久久久久久久久久久| 欧美极品少妇| 怡春院在线| 久草视频免费在线播放| 91人人操人人爽| 欧美成人精品一区二区| 亚洲AV毛片成人精品网站| 91爱爱网| 鸭子av| 亚洲国产精品成人综合| av一区二区三区| 成人性爱视频网|