亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

手把手教你用JS創建幻燈片特效

2024-09-06 12:40:52
字體:
來源:轉載
供稿:網友

javascript創建可維護幻燈片效果。


幻燈片效果

顯然,效果很實用。對于這個效果,我們并不解釋如何去使用效果庫,而是講解如何創建類似的效果,并保持他的可用性,分離式(unobtrusive),可維護性(讓未來的維護者,在不需要修改你的腳本的情況下,修改圖片,外觀或文本標簽)。

無 javascript 狀態下,用戶將看到下面的效果:

添加和移除圖片、改變圖片的順序以及添加標題,這些在 html 中都很容易做到。并且最后的解決并不意味著維護者需要懂任何 javascript 或者在源碼中搜索在哪里修改 css 的 class, id 或者文本標簽。

你有沒有準備好花費一些時間去一步一步的嘗試創建這個效果?

第一步:分析問題(analizing the problem)

創建一個好的腳本,第一步應該是去分析哪些是你要完成的:我們想要創建一個照片的幻燈片效果,并且我們想要保持維護的方便。

如何創建一個幻燈片效果

在一個網站上擁有幻燈片有幾種方法:

  1. 在文檔中包含所有的圖片。
    當他運行在無 javascript 狀態,這是一個安全的選擇。而且,當頁面被載完,所有的圖片也會將被載完。然而,這個方式只適用于少量的圖片。
  2. 在文檔中包含第一張圖片,并且有一個創建幻燈片功能的服務器端腳本。
    這也是相當安全的,但是對于終端用戶來說,這是非常令人厭煩的——因為我不想加載整個頁面,僅想得到下一張照片。但對頁面展示和廣告點擊比較有效,這也是為什么大量的新聞站點使用這個方法。
  3. 在文檔中包含第一張圖片,并按需加載其他圖片。
    這個方法令你厭煩的是,必須依賴于 javascript ,并且要有一個維護照片列表的 javascript 數組。你還需提供一個加載指示器,用來顯示用戶一些正在發生的事情。

在我們的案例中,我們采取下面的圖片列表,用向前和向后的按鈕把他變成一個幻燈片效果,并且一個指示器告訴我們,照片總數中的哪張照片是當前顯示的。

<ul id="slideshow">
    <li><img src="img/flat1.jpg" alt="hallway" /></li>
    <li><img src="img/flat2.jpg" alt="hob" /></li>
    <li><img src="img/flat3.jpg" alt="bathroom" /></li>
    <li><img src="img/flat4.jpg" alt="living room" /></li>
    <li><img src="img/flat5.jpg" alt="bedroom" /></li>
</ul>

最后的輸出會看起來像例子中的幻燈片效果。

依賴關系檢查

我們這里有一些元素依賴于 javascript 生成:文字指示器和向前和向下的鏈接。為了保持我們解決方法的可用性,我們需要確保一些事情:

  1. 僅當 javascript 可用(用戶信賴我們提供給他們使用的功能)時,這些元素應該出現。一個鏈接,不能做任何違反用戶對我們的信任的事情。
  2. 不論輸入設備(讓我們不要依賴用戶是否有鼠標),交互式元素都應該可用。
  3. 圖片不應該被隱藏,除非使用者能再次訪問他們。在技術上,僅顯示第一張圖片,且沒有向前和向后的鏈接是預留退路的做法,但是為什么要用戶已下載所有的圖片僅只看到第一張?

|||

第二步:規劃腳本(planning the script)

一旦你已經評估了問題,并挑選出你想使用的解決方法,你便可以開始規劃腳本。本質上,我們的腳本應該做這些:

  • 檢查幻燈片列表是否存在,并且包含一些圖片(有理由為一張圖片創建一個幻燈片效果嗎?)。
  • 隱藏所有的照片,但不是第一個。
  • 創建向前和向后的鏈接,和一個顯示我們在哪的指示器。
  • 添加事件處理程序,使鏈接增加或減少當前顯示的圖片編號。
  • 確?;脽羝Ч麤]有超出范圍,當圖片編號小于 0 ,他應該變為最后一張圖片,反過來類似。

不同的功能處理

我們有一些方法處理這個問題。其中之一是使用 dom 遍歷每個 li 條目并隱藏他。在這個事件監聽函數,我們先隱藏先前顯示的 li (如果有的話),并顯示當前的這個。

:顯示和隱藏代替圖片的 li 更有意義,因為他允許維護者在每個幻燈片上添加其他的元素,比如,一些標題。

這個方法的問題在于,我們在 javascript 中做必要的樣式改變,這意味著如果有需要比剛才我們腳本中改變 display 從 block 到 none 更復雜的樣式改變,將使腳本變得更雜亂(沒有從行為中分離表現)。

樣式留給 css 解析器

更簡潔的方法是將所有的外觀改變(在所有列表項下載完之后隱藏某些)都留給瀏覽器的 css 解析器。在我們的例子中,我們可以在幻燈片中使用一個 css 規則很容易地隱藏所有的列表項,并用一個特定的 class 重寫當前條目的樣式。

html:

<ul id="slideshow">
    <li><img src="img/flat1.jpg" alt="hallway" /></li>
    <li><img src="img/flat2.jpg" alt="hob" /></li>
    <li><img src="img/flat3.jpg" alt="bathroom" /></li>
    <li><img src="img/flat4.jpg" alt="living room" /></li>
    <li><img src="img/flat5.jpg" alt="bedroom" /></li>
</ul>

css:

#slideshow li{
    display:none;
}
#slideshow li.current{
    display:block;
}

唯一的問題是,如果我們使 css 和 javascript 不可用,訪客將永遠不能訪問到其他圖片。因此,我們需要僅當 javascript 可用時,應用這些樣式。技巧是,當 javascript 可用,在幻燈片的 ul 上應用 class ,例如名為 js 。這允許我們僅當 javascript 可用時,顯示效果,通過在 css 中簡單的修改:

css:

#slideshow.js li{
    display:none;
}
#slideshow.js li.current{
    display:block;
}

這個 class 的鉤子(hook)也能被用來對幻燈片的靜態和動態版本提供一個完全不同的外觀。

我們所有的腳本需要做的是,通過移除或添加 current 的 class 來顯示和隱藏當前及以前的照片。

為了確保我們的腳本將不會影響同一頁面上的其他腳本,我們將創建一個主要的對象,并在其上構造所有的方法和屬性。這可以確保我們的 init() 函數將不會被覆蓋或覆蓋其他任何相同名字的函數。

javascript::

slideshow = {
    current:0, // 當前幻燈片編碼
    init:function(){
        // 初始化和設置事件處理函數
    },
    show:function(e){
        // 事件監聽器
    }
}

|||

第三步、基本的工具方法( essential tools)

現在,我們有了規劃和建立我們腳本的框架。是時候思考我們需要完成這個功能的一些工具方法。在其最低要求的情況下,dom 腳本的幫助庫應該包括:

  • 一個注冊事件處理函數的方法,我們目前將使用 john resig 的 addevent() 方法。
  • 添加和移除 css 樣式名的方法。
  • 一個覆蓋 html 元素默認行為的方法。我們不希望出現鏈接的目標頁,而僅是執行腳本。

我們添加這些工具方法到主要的對象上,并準備開始:

javascript:

slideshow = {
    current:0, // 當前幻燈片編碼
    init:function(){
        // 初始化和設置事件處理函數
    },
    show:function(e){
        // 事件監聽器
    },
    addevent:function( obj, type, fn ) {
        if ( obj.attachevent ) {
            obj['e'+type+fn] = fn;
            obj[type+fn] = function(){
                obj['e'+type+fn]( window.event );
            }
            obj.attachevent(’on’+type, obj[type+fn] );
        } else
            obj.addeventlistener( type, fn, false );
    },
    removeclass:function(o,c){
        var rep=o.classname.match(’ ‘+c)?’ ‘+c:c;
        o.classname=o.classname.replace(rep,”);
    },
    addclass:function(o,c){
        var test = new regexp(”(^|//s)”+c+”(//s|$)”).test(o.classname);
        if(!test){o.classname+=o.classname?’ ‘+c:c;}
    },
    cancelclick:function(e){
        if (window.event){
            window.event.cancelbubble = true;
            window.event.returnvalue = false;
        }
        if (e && e.stoppropagation && e.preventdefault){
            e.stoppropagation();
            e.preventdefault();
        }
    }
}

當文檔完全載完,第一件事情就是需要執行 init() 方法:

javascript:

slideshow = {
    current:0, // 當前幻燈片編碼
    init:function(){
        // 初始化和設置事件處理函數
    },
    show:function(e){
        // 事件監聽器
    },
    addevent:function( obj, type, fn ) {
        if ( obj.attachevent ) {
            obj['e'+type+fn] = fn;
            obj[type+fn] = function(){
                obj['e'+type+fn]( window.event );
            }
            obj.attachevent(’on’+type, obj[type+fn] );
        } else
            obj.addeventlistener( type, fn, false );
    },
    removeclass:function(o,c){
        var rep=o.classname.match(’ ‘+c)?’ ‘+c:c;
        o.classname=o.classname.replace(rep,”);
    },
    addclass:function(o,c){
        var test = new regexp(”(^|//s)”+c+”(//s|$)”).test(o.classname);
        if(!test){o.classname+=o.classname?’ ‘+c:c;}
    },
    cancelclick:function(e){
        if (window.event){
            window.event.cancelbubble = true;
            window.event.returnvalue = false;
        }
        if (e && e.stoppropagation && e.preventdefault){
            e.stoppropagation();
            e.preventdefault();
        }
    }
}
slideshow.addevent(window,’load’,slideshow.init);

|||

第四步:腳本(the script)

現在,在適當的位置我們有所有的方法工具,以及當窗口載完時被調用的 init() ,我們可以開始具體化此方法。

:這僅是 init() 方法,而不是整個腳本。因為有行號,復制并粘貼腳本將會導致錯誤。

 1: init:function(){
 2:     if(document.getelementbyid && document.createtextnode){
 3:         var list = document.getelementbyid(' ');
 4:         if(list){
 5:             slideshow.items = list.getelementsbytagname('li');
 6:             slideshow.all = slideshow.items.length;
 7:             if(slideshow.all > 1){
 8:                 slideshow.addclass(list, 'js');
 9:                 slideshow.createnav(list);
10:            }
11:         }
12:         slideshow.show();
13:     }
14: },

  1. 第2行,檢測 dom 是否被支持。
  2. 第3和4行,嘗試檢索 id 為 slideshow 的元素,如果沒有被定義則不執行余下的方法。
  3. 第5和6行,檢索列表項及列表項的個數,并分別儲存在屬性 items 和 all 里。
  4. 第7行,檢測是否超多一個列表項,如果不超多則不執行余下的。
  5. 第8行,添加 js 樣式類名到列表上,從而隱藏列表項和應該不同的樣式。
  6. 第9行,調用 createnav(),并提供這個列表作為參數。
  7. 第12行,調用 show() 用來顯示預定義了 current 屬性的滑動門。

createnav() 方法使用 dom 腳本創建幻燈片正常工作所需的 html。

 1: createnav:function(o){
 2:     var p = document.createelement('p');
 3:     slideshow.addclass(p, 'slidenav');
 4:     slideshow.prev = document.createelement('a');
 5:     slideshow.prev.setattribute('href', '#');
 6:     var templabel = document.createtextnode('<<');
 7:     slideshow.prev.appendchild(templabel);
 8:     slideshow.addevent(slideshow.prev, 'click', slideshow.show);
 9:     p.appendchild(slideshow.prev);
10:     slideshow.count = document.createelement('span');
11:     templabel = document.createtextnode( (slideshow.current+1) + ' / ' + slideshow.all);
12:     slideshow.count.appendchild(templabel);
13:     p.appendchild(slideshow.count);
14:     slideshow.next = document.createelement('a');
15:     slideshow.next.setattribute('href', '#');
16:     var templabel = document.createtextnode('>>’);
17:     slideshow.next.appendchild(templabel);
18:     slideshow.addevent(slideshow.next, ‘click’, slideshow.show);
19:     p.appendchild(slideshow.next);
20:     o.parentnode.insertbefore(p, o);
21: },

  1. 第2和3行,剛開始創建一個 p 元素,用來包含整個幻燈片導航,并應用一個名為 slidenav 的 class。
  2. 第4和5行,創建一個新的鏈接元素,儲存在叫 prev 的屬性中,設置 href 屬性為 #。使鏈接顯示為一個真正的鏈接且鍵盤可用,是有必要的。
  3. 第6行,創建一個新的文本標簽。
  4. 第7行,將文本標簽添加到鏈接上。
  5. 第8行,添加一個事件處理函數,指向 show() 監聽方法。
  6. 第9行,將新的鏈接添加到 段落上。
  7. 第10行,開始計數器,我們創建一個 span 元素,并用 count 屬性儲存他。
  8. 第11行,創建一個新的文本節點,顯示當前幻燈片在總數中的位置。我們需要給當前的屬性增加 1,因為人類計數是從 1 開始而非從 0。
  9. 第12行,將文本作為新的子節點,添加至 span 上 。
  10. 第13行,將 span 元素 添加到段落上。
  11. 第14至19行,基本上是復制 4 到 9 行,這次重新創建鏈接唯一不同的是文本標簽,他儲存在 next 屬性上。
  12. 第20行,將最近創建的段落插入到文檔中初始的圖片列表前。

這些被創建的所有標記都是必要的,最后剩下的是去定義一個當鏈接被點擊時調用的監聽方法 show() 。

 1: show:function(e){
 2:     if(this === slideshow.next || this === slideshow.prev){
 3:         slideshow.removeclass(slideshow.items[slideshow.current], ‘current’);
 4:         var addto = (this === slideshow.next) ? 1 : -1;
 5:         slideshow.current = slideshow.current + addto;
 6:         if(slideshow.current < 0){
 7:             slideshow.current = (slideshow.all-1);
 8:         }
 9:         if(slideshow.current > slideshow.all-1){
10:             slideshow.current = 0;
11:         }
12:     }
13:     var templabel = document.createtextnode((slideshow.current+1) + ‘ / ‘ + slideshow.all);
14:     slideshow.count.replacechild(templabel, slideshow.count.firstchild);
15:     slideshow.addclass(slideshow.items[slideshow.current], ‘current’);
16:     slideshow.cancelclick(e);
17: },

  1. 第1行,得到作為參數 e 的當前事件對象,這是稍后調用的 cancelclick() 唯一需要。
  2. 第2行,檢測點擊的元素是否是向下或者向前鏈接(this 由 addevent() 返回)。
  3. 第3行,從當前顯示的幻燈片上移除 current 的 class。由于現在有一個被點擊的鏈接,這將成為可能。
  4. 第4行,通過比較 this 和 next 屬性,決定 current 的計數器是應該增加還是減少。
  5. 第5行,修正計數器。
  6. 第6到11行,確定計數器將永遠不會超出范圍,當你在第一幻燈片并點擊了向前的鏈接,將設置他為最后一個,而當你在最后一個幻燈片,點擊了向后的鏈接,將設置為第一個。
  7. 第13和14行,生成一個新的計數器文本并替代舊的。
  8. 第15行,通過設置名為 current 的 class,顯示新的當前幻燈片。
  9. 第16行,通過調用 cancelclick() 阻止鏈接的默認行為。

這些是腳本的所有內容?,F在這個腳本可以工作,但仍不是真正可維護的。

|||

第五步:輕松維護(easing maintenance)

腳本功能齊全,分離式而且無懈可擊。真正的問題是,現在并不方便維護。

腳本應用的最大的問題大概是,并不是所有的維護者都懂 javascript 和愿意在你的腳本中尋找需要修改的部分。

為了避免維護者做這些,最安全的方法就是把腳本和 css 中使用的命名和 id 從你的腳本功能中分離出來。此外,從使用的腳本中分離出文本標簽也是個好點子,因為他們可能會改變。例如,當腳本使用其他語言本地化時。

工具方法的復用

第一件要做的事情就是,從主要腳本中分離出其他腳本也可以再用的工具函數。這也許是大部分 javascript 庫的開始。

tools.js:

/* 輔助方法 */
tools = {
    addevent:function( obj, type, fn ) {
        if ( obj.attachevent ) {
            obj['e'+type+fn] = fn;
            obj[type+fn] = function(){
                obj['e'+type+fn]( window.event );
            }
            obj.attachevent( ‘on’+type, obj[type+fn] );
        } else
            obj.addeventlistener( type, fn, false );
        },
    removeclass:function(o,c){
        var rep=o.classname.match(’ ‘+c)?’ ‘+c:c;
        o.classname=o.classname.replace(rep,”);
    },
    addclass:function(o,c){
        var test = new regexp(”(^|//s)” + c + “(//s|$)”).test(o.classname);
        if(!test){o.classname+=o.classname?’ ‘+c:c;}
    },
    cancelclick:function(e){
        if (window.event){
            window.event.cancelbubble = true;
            window.event.returnvalue = false;
        }
        if (e && e.stoppropagation && e.preventdefault){
            e.stoppropagation();
            e.preventdefault();
        }
    }
}

css 的 class 和 id —— 外觀

下一步要做的是,分離外觀的 class 和 id 到一個單獨的包含文件。保證他們在 slideshow 命名空間里是安全的,因為其他腳本不太可能用到他們。也不會妨礙寫一個簡短的說明注釋。

slideshow-css.js:

slideshow.css = {
    /*
    這些都是幻燈片效果中使用到的 classe 和 id。
    你可以在這里修改他們中的任何一個。
    務必請使用引號包圍名稱,用逗號結尾(除了最后一個)。
    */

    showid               :'slideshow',
    dynamicclass         :'js',
    slidenavigationclass :'slidenav',
    currentclass         :'current'
}

文本標簽(text labels)—— 解釋給終端用戶

最后但不是最不重要的,讓我們將文本標簽放到一個單獨的包含文件,再次使用 slideshow 命名空間。

slideshow-labels.js:

slideshow.labels = {
    /*
    這些都是幻燈片效果中使用到文本標簽。
    你可以在這里修改他們中的任何一個。
    務必請使用引號包圍名稱。
    最后一個結尾不用逗號。
    */

    previous       : '<<',
    next           : '>>’,
    counterdivider : ‘ of ‘
}

改變的主要腳本

然后,我們需要修改主要腳本使用此信息,而不是依賴嵌入式的數據。沒有太多的改變,很容易用搜索加替換就能做到。

slideshow.js:

slideshow = {
    current:0,
    init:function(){
        if(document.getelementbyid && document.createtextnode){
            var list =document.getelementbyid(slideshow.css.showid);
            if(list){
                slideshow.items = list.getelementsbytagname('li');
                slideshow.all = slideshow.items.length;
                if(slideshow.all > 1){
                    tools.addclass(list, slideshow.css.dynamicclass);
                    slideshow.createnav(list);
                }
            }
            slideshow.show();
        }
     },
    createnav:function(o){
        var p = document.createelement('p');
        tools.addclass(p, slideshow.css.slidenavigationclass);
        slideshow.prev = document.createelement('a');
        slideshow.prev.setattribute('href', '#');
        var templabel = document.createtextnode(slideshow.labels.previous);
        slideshow.prev.appendchild(templabel);
        tools.addevent(slideshow.prev, 'click', slideshow.show);
        p.appendchild(slideshow.prev);
        slideshow.count = document.createelement('span');
        templabel =document.createtextnode((slideshow.current+1) + slideshow.labels.counterdivider + slideshow.all);
        slideshow.count.appendchild(templabel);
        p.appendchild(slideshow.count);
        slideshow.next = document.createelement('a');
        slideshow.next.setattribute('href', '#');
        var templabel = document.createtextnode(
        slideshow.labels.next);
        slideshow.next.appendchild(templabel);
        tools.addevent(slideshow.next, 'click', slideshow.show);
        p.appendchild(slideshow.next);
        o.parentnode.insertbefore(p, o);
    },
    show:function(e){
        if(this === slideshow.next || this === slideshow.prev){
            tools.removeclass(slideshow.items[slideshow.current],
            slideshow.css.currentclass);
            var addto = this === slideshow.next ? 1 : -1;
            slideshow.current = slideshow.current + addto;
            if(slideshow.current < 0){
                slideshow.current = (slideshow.all-1);
            }
            if(slideshow.current > slideshow.all-1){
                slideshow.current = 0;
            }
        }
        var templabel = document.createtextnode((slideshow.current+1) + slideshow.labels.counterdivider + slideshow.all);
        slideshow.count.replacechild(templabel, slideshow.count.firstchild);
        tools.addclass(slideshow.items[slideshow.current], slideshow.css.currentclass);
        tools.cancelclick(e);
    }
}
tools.addevent(window,’load’,slideshow.init);

這些所有文件是確保將來維護者不用麻煩你就可以使用你的腳本工作所需要的。文件名應該很明顯,是什么就是什么,并能隨著時間的推移,成為一個標準的腳本:

tools.js
slideshow.js
slideshow-labels.js
slideshow-css.js
slideshow.css

原作者:christian heilmann   譯者:懌飛
原文:《a detailed explanation how to create a maintainable dynamic slide show in javascript》

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品极品在线观看播放免费视频| 国产精品成人va在线观看| 国产98色在线| 欧美电影《睫毛膏》| 欧美在线视频观看免费网站| 欧美在线观看视频| 国产精品日韩av| 欧美视频专区一二在线观看| 国产精品久久久久久久久久新婚| 国产精品爽黄69天堂a| 亚洲欧美成人在线| 中文欧美日本在线资源| 日韩成人在线网站| 欧美日韩xxx| 成人在线视频网站| 日本电影亚洲天堂| 国产成人+综合亚洲+天堂| 国产精品久久久久久久美男| 国产精欧美一区二区三区| 国产成人aa精品一区在线播放| 日韩成人性视频| 成人午夜高潮视频| 成人信息集中地欧美| 欧美亚洲另类激情另类| 久久久天堂国产精品女人| 91香蕉嫩草神马影院在线观看| 亚洲视频在线观看网站| 国内精品400部情侣激情| 国产精品看片资源| 超碰精品一区二区三区乱码| 日韩电影免费在线观看中文字幕| 97在线视频免费播放| 97精品国产97久久久久久免费| 亚洲精品综合久久中文字幕| 一区二区三区 在线观看视| 日韩av在线一区二区| 精品国产老师黑色丝袜高跟鞋| 亚洲国产成人精品久久久国产成人一区| 午夜精品在线视频| 亚洲3p在线观看| 欧美综合一区第一页| 国产91ⅴ在线精品免费观看| 亚洲国产美女久久久久| 欧美激情在线视频二区| 日韩av在线直播| 中文字幕久久久| 午夜精品福利视频| 成人午夜在线视频一区| 91精品国产自产91精品| 日韩av在线不卡| 美女撒尿一区二区三区| 日本高清不卡在线| 麻豆成人在线看| 国产精品日韩在线| 国产精品久久久久久五月尺| 亚洲第一天堂无码专区| 欧洲亚洲女同hd| 成人av色在线观看| 日韩激情视频在线| 国产精品偷伦一区二区| 国产成人精品网站| 亚洲一区二区三区xxx视频| 日韩免费看的电影电视剧大全| 欧美精品一区在线播放| 精品视频在线导航| 97视频在线看| 国产免费成人av| 欧美一级高清免费| 福利精品视频在线| 国产免费一区二区三区香蕉精| 91产国在线观看动作片喷水| 欧美成年人视频| 国产亚洲欧洲黄色| 91精品国产高清久久久久久久久| 久久视频在线看| 2019国产精品自在线拍国产不卡| 中文字幕精品av| 国产精品久久久久久av福利软件| 成人精品视频99在线观看免费| 在线精品视频视频中文字幕| 成人激情视频在线观看| 亚洲精品美女久久久久| 97视频网站入口| 91在线无精精品一区二区| 亚洲人a成www在线影院| 欧美精品一二区| 88xx成人精品| 久久精品成人一区二区三区| 国产99久久精品一区二区| 亚洲欧洲在线观看| 日韩视频免费在线| 日韩av中文字幕在线| 国产91ⅴ在线精品免费观看| 一本色道久久综合亚洲精品小说| 久久久久久久久久久亚洲| 黄网动漫久久久| 黑人巨大精品欧美一区二区| 日韩中文字幕在线| 性日韩欧美在线视频| 成人有码在线视频| 国产精品天天狠天天看| 色樱桃影院亚洲精品影院| 国产精品一区二区三区免费视频| 久久五月情影视| 91亚洲午夜在线| www.日本久久久久com.| 91精品国产免费久久久久久| 日本精品视频网站| 日本高清+成人网在线观看| 成人中文字幕在线观看| 国产一区av在线| 久久精品电影网站| 日韩午夜在线视频| 91久久久久久久久| 久久久久久久久久久av| 福利一区福利二区微拍刺激| 欧美精品免费在线| 欧美成人国产va精品日本一级| 在线电影av不卡网址| 久久久国产精品亚洲一区| 97超碰国产精品女人人人爽| 欧美性猛交xxxx久久久| 欧美精品videosex性欧美| 日韩欧美亚洲成人| 欧美一区第一页| 国产99久久精品一区二区| 欧美一级视频免费在线观看| 国产原创欧美精品| 日韩在线视频二区| 久久久久亚洲精品成人网小说| 欧美极品少妇与黑人| 国产日韩欧美影视| 2024亚洲男人天堂| 中文字幕在线视频日韩| 国产成人精品视| 亚洲福利视频二区| 在线观看久久久久久| 一本大道香蕉久在线播放29| 久久精品青青大伊人av| 在线亚洲欧美视频| 国产一区二区精品丝袜| 欧美午夜丰满在线18影院| 国产精品中文字幕久久久| 亚洲欧美国产日韩中文字幕| 日韩欧美综合在线视频| 国产一区二区三区在线播放免费观看| 精品国内亚洲在观看18黄| 久久精品国产欧美激情| 久久伊人精品一区二区三区| 国产精品成人aaaaa网站| 91九色单男在线观看| 亚洲精品成人网| 91精品中文在线| 欧美国产日韩一区| 欧美日韩一区二区在线播放| 欧美限制级电影在线观看| 亚洲一区二区免费在线| 日韩欧美中文字幕在线观看| 午夜欧美大片免费观看| 欧美理论电影在线播放| 97超碰色婷婷| 久久久久久免费精品| 久久视频在线观看免费| 亚洲欧美一区二区精品久久久|