<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Oracle神諭

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      284 隨筆 :: 9 文章 :: 106 評論 :: 0 Trackbacks
    "Ajax" is a buzzword that is gaining momentum and popularity. Applications such as Gmail and Google Suggest serve as massive advertisements for asynchronous JavaScript. As users gain familiarity and their expectations increase, the demand for such interfaces is rising.

    "Ajax"是一個時髦詞語,獲得動力和普及。像Gmail和Google Suggest的服務為異步Javascript作了大量的廣告。當用戶獲得熟悉和他們期望增長時,類似這些界面的需求也增長了。

    In this article, I will show how to build Ajax-enabled applications using Dojo and JSON--two very different but complementary technologies that can significantly enhance the interface and usability of web applications. With the help of some simple examples, you will learn how to use Dojo and JSON to build Ajax applications. This article will also demonstrate how to create custom Dojo widgets by implementing the popular "autocomplete" feature for HTML text boxes.
    Overview

    在這邊文章中,我將展示使用Dojo和JSON--兩種不同但互相補充的可以重大地促進界面和Web應用程序可用性的技術來如何創建Ajax- enabled應用程序。在這些簡單的例子的幫助下,你可以學會如何使用Dojo和JSON來創建Ajax應用程序。這篇文章也將示范如何為HTML text boxes通過實現流行的"autocomplete"特性創建定制的Dojo widgets 。

    Ajax in the simplest sense is taken to mean the process of exchanging data between a web server and a web browser using JavaScript on a loaded web page. In the practical sense, it means avoiding browser requests in favor of asynchronous JavaScript processing, thus making the request/response process transparent to the user. To accomplish this, we can either write our own verbose JavaScript code or use already tested and functional libraries such as Dojo.
    What Is Dojo?

    在最簡單的感覺中,Ajax是開始意味這在web服務器和瀏覽器之間使用在一個已加載的web頁面上的JavaScript來交換數據的流程。在實際理解上,它意味著避免瀏覽器請求采用異步 JavaScript處理,這樣產生request/response進程傳遞給用戶。為了完成這,我們可以或編寫詳細的代碼或使用已經經過測試的和實用的庫例如Dojo.

    Dojo is a set of powerful JavaScript libraries that provide a simple API to a plethora of features. One of these features is the ability to make HTTP requests and receive their responses. This is the main functionality of Dojo that we will utilize. Aside from providing Ajax functionality, Dojo also provides packages for string manipulation, DOM manipulation, drag-and-drop support, and data structures such as lists, queues, and stacks.

    Dojo是一個強大的提供簡單api到復雜的功能特性的Javascript庫。這些特征之一就是產生HTTP 請求和接收他們的相應的能力。這是Dojo的主要功能性被使用。除提供Ajax功能性以外,Dojo也提供了諸如字符串操作、DOM操作、托放支持、和數據結構例如lists,queue,stack的庫。

    What Is JSON?
    什么是JSON?

    JSON is a Java library that helps convert Java objects into a string representation. This string, when eval()ed in JavaScript, produces an array that contains all of the information that the Java object contained. JSON's object notation grammar is suitable for encoding many nested object structures. Since this grammar is much smaller than its XML counterpart, and given the convenience of the eval() function, it is an ideal choice for fast and efficient data transport between browser and server.

    JSON是一個Java庫,它幫助轉化Java對象成一個字符串表現。這字符串,當在JavaScript中eval()ed,產生一個包含所有Java 對象信息的數組。 JSON's對象符號語法是適合于編碼許多嵌套對象結構。既然這個語法小于它的XML配對物,并且給于eval()函數的方便,它是在瀏覽器和服務器之間理想選擇快速且有效數據傳輸。

    JSON is designed to be used in conjunction with JavaScript code making HTTP requests. Since server-side code can be written in a variety of languages, JSON is available in many different languages such as C#, Python, PHP, and of course, Java!

    JSON是被設計成可用于與JavaScript代碼協力產生HTTP請求。既然服務器端代碼可以被寫成多種語言,JSON是可用于很多語言,例如C#,Python,PHP,并且當然適用于Java.

    Getting Started
    開始

    Download the sample application and do an ant war to generate dojo_json.war. You will need a servlet container like Apache Tomcat. Copy dojo_json.war into the webapps directory and, assuming you're running Tomcat on port 8080 on localhost, browse to the following URL:

    下載例子程序并且使用ant war 產生dojo_json.war。你將需要一個Servlet容器像Apache Tomcat。復制dojo_json.war到你webapps目錄下并且,將設你運行在localhost的端口8080的,瀏覽如下網址:

    http://localhost:8080/dojo_json/index.jsp


    If you see a page with a welcome message, all is well.
    如果你看到一個歡迎的信息的頁面,一切都好了。

    A Simple HTTP Request
    一個簡單的HTTP 請求

    In the first example, we will use Dojo to provide a welcome message when the user clicks on a button. This will illustrate the steps involved with making an Ajax call using Dojo. Browse to http://localhost:8080/dojo_json/example1.jsp and after entering your name, click the Submit button. The JavaScript alert box that pops up contains a welcome message that was generated on the server. Let's look at the source for example1.jsp.

    在第一個例子中,我們將使用Dojo當用戶點擊一個按鈕時,提供一個歡迎的信息。這將示例使用Dojo有關產生一個Ajax調用的步驟。瀏覽http: //localhost:8080/dojo_json/example1.jsp并且輸入你的名字,點擊提交按鈕。Javascript對話框彈出顯示一個在服務器上產生的歡迎信息。讓我們看看example1.jsp的源代碼。

    <html>
    <body onLoad="onLoad();">
    <head>
    ?<title>Example 1</title>
    ?<script language="javascript" src="js/dojo.js"></script>
    ?<script language="javascript">
    ? dojo.require("dojo.io.*");
    ? dojo.require("dojo.event.*");

    ? function onLoad() {
    ?? var buttonObj = document.getElementById("myButton");
    ?? dojo.event.connect(buttonObj, "onclick",
    ????????? this, "onclick_myButton");
    ? }

    ? function onclick_myButton() {
    ?? var bindArgs = {
    ??? url: "welcome.jsp",
    ??? error: function(type, data, evt){
    ???? alert("An error occurred.");
    ??? },
    ??? load: function(type, data, evt){
    ???? alert(data);
    ??? },
    ??? mimetype: "text/plain",
    ??? formNode: document.getElementById("myForm")
    ?? };
    ?? dojo.io.bind(bindArgs);
    ? }
    ?</script>
    </head>
    <body>
    <form id="myForm">
    ?<input type="text" name="name"/>
    ?<input type="button" id="myButton" value="Submit"/>
    </form>
    </body>
    </html>

    The first order of business is to import the Dojo libraries, namely dojo.js. This contains all of the Dojo classes needed to use most of its features. Dojo libraries are organized in packages just like Java code. For this example, we will need to import two packages. The dojo.io package contains classes that allow us to make HTTP requests using protocols such as XMLHTTPTransport. The dojo.event package is designed to provide a unified event system for DOM and programmatic events.

    事務的第一個順序是導入Dojo庫,被命名為dojo.js。這涉及所有的dojo的需要使用它的特性的大部分類。Dojo庫像Java代碼一樣在包內進行組織。例如我們將需要導入兩個包。 dojo.io包包含了允許我們來利用協議例如XMLHTTPTransport來創建HTTP請求。dojo.event包被設計成為DOM和計劃性事件提供一個統一的事件系統。

    Next, we assign an onclick event handler to our button. Traditionally, we might do something like:
    接著,我們賦值一個單擊事件句柄給我們的按鈕。傳統地,我們像這樣做:

    <input type="submit" onclick="someFunc();"/>

    which serves its purpose but has the nasty side effect of associating only one event handler per event. The dojo.event.connect() method allows us to associate functions in different classes to HTML elements. Here, we assign onclick_myButton as the handler for the onclick event for myButton.

    它服務于它的目的但是擁有令人厭惡的每事件只有一個事件句柄聯系的副影響。dojo.event.connect()方法允許我們聯系在不同的功能給HTML元素。這里,我們賦值onlick_myButton 作為myButton的單擊事件句柄。

    Once onclick_myButton executes, we will make the call to welcome.jsp and receive the response. The magical dojo.io.bind() function is where the power lies. It takes as argument bindArgs, an array of name/value pairs. In this example, we specify five pairs:
    一旦onclick_myButton執行,我們制造調用welcome.jsp并且接收響應。這個不可思議的dojo.io.bind()函數是力量強大的位置。它采用bindArgs參數,一個名稱/值對的數組。在這個例子中,我們指定了5個對:

    ?? 1. url: The URL to make the request to.? url: 請求的網址
    ?? 2. mimetype: The response type expected. mimetype:期待響應的類型
    ?? 3. load: Code to execute upon success. load: 執行成功的代碼
    ?? 4. error: Code to execute upon error.? error:執行出錯的代碼
    ?? 5. formNode: The ID of the form whose fields to submit as parameters to the URL.
    ????? formNode: 作為一個參數提交字段的URL的表單的ID.

    A complete list of possible arguments can be found here.
    一個完整的可能參數的列表可以在這里發現。

    Once the call to dojo.io.bind(bindArgs) is made, the wheels are set in motion and, depending on whether the request encountered any errors, either the load or error code is executed. Both load and error take three arguments:

    一旦調用dojo.io.bind(bindArgs)被制造,動力被設置在運行中,依賴請求遭遇任何錯誤,或加載或失敗被執行。加載和失敗包含三個參數:

    ?? 1. type: The type of function; it will always be set to load for load() and error for error().
    ?? 2. data: The response received. If mimetype is specified as text/plain, data contains the raw response. If, however, text/json is used, data contains the value of eval('(' + responseReceived + ')'), where responseReceived is what the call returned.
    ?? 3. evt: The event object.
    ? ?
    ?? 1.類型:功能的類型;它將總是設置為load()成加載和error()成失敗。
    ?? 2.數據:響應接收。如果mimetype被指定為text/plan,數據包含未加工響應。如果,然而,text/json被使用,數據包含eval ('('+responseReceived+')'),這里responseReceived 是調用返回的。
    ?? 3.事件:事件對象。

    Alternately, we could have also specified event handlers using dojo.event.connect() by creating a handleResponse(type,data,evt) function and associating it with the request:
    可替代的,我們也可以擁有指定事件句柄使用dojo.event.connect()通過創建一個handleResponse(type,data,event)函數并且通過request聯系.

    var req = dojo.io.bind(bindArgs);
    dojo.event.connect(req, "load", this, "handleResponse");

    In this case, we wouldn't need to specify the load attribute in bindArgs.
    既然這樣,我們不需要在綁定參數中指定加載屬性。

    Note: For security reasons, Firefox does not allow the value for url in bindArgs to reference a URL on another domain. Internet Explorer is more lenient and allows cross-domain requests.
    Using JSON to Transport Java Objects

    注意:為安全原因,Firefox不允許在綁定參數中為url的值指定一個URL在另一個域中。IE更寬松且允許超域請求。

    As alluded to earlier, JSON helps us transform Java objects into eval()able JavaScript strings. In this example, the user is viewing a list of books. When the user's mouse hovers over a book title, we also retrieve and display all other relevant information about the book using Ajax. Example 2, found at http://localhost:8080/dojo_json/example2.jsp, illustrates this behavior.

    早些提到的那樣,JSON幫助我們轉換Java對象到eval()able JavaScript字符串。在這個例子中,用戶查看書的列表。當用戶的鼠標放在書的標題上,我們獲得和顯示所有其他相關的使用Ajax的書的信息。例子 2,在http://localhost:8080/dojo_json/example2.jsp,示例了這個事件。

    Let us take a closer look at the steps involved in achieving this effect.
    Creating and Instrumenting the Java Objects
    讓我們近距離注視涉及完成這個效果的步驟。

    The Book class is a POJO with four fields. The BookManager has a method that returns a Book object based on a bookId and another that returns List of all books. In this simple example, I've hardcoded five books into the BookManager.

    書類是一個有四個字段的POJO. BookManager有一個方法,它返回一個基于bookId和其他返回所有書的列表的書對象。在這個簡單例子中,我已經硬編碼5本書給BookManager.

    The Book.toJSONString() method is responsible for converting a Book object into a JavaScript eval()able String using the JSON API.
    Book.toJSONString()方法使用JSON API轉換一個書對象JavaScript的 eval()able字符串是可靠的? .


    public String toJSONString() throws JSONException {
    ?JSONObject jsonObj = new JSONObject();
    ?jsonObj.put("bookId", new Integer(this.bookId));
    ?jsonObj.put("title", this.title);
    ?jsonObj.put("isbn", this.isbn);
    ?jsonObj.put("author", this.author);
    ?return jsonObj.toString();
    }

    The JSONObject class acts as a converter for the Book object into a string wrapped in curly braces, with colons between the names and values and commas between the values and names--in other words, an eval()able JavaScript string. In a similar manner as shown above, the JSONArray class can convert collections of Java objects into JavaScript arrays.

    JSONObject 類作為一個將書對象轉換為包裝在curly支持的字符串的轉換器,在名字和值使用冒號,在值和名稱之間用逗號,換句話說,,一個eval()able的 JavaScript字符串。在一個像上面顯示的格式,JSONArray類可以轉化一個Java對象集合類型到一個JavaScript數組。


    Transferring and Handling JSON-Encoded Data
    傳輸和處理JSON編碼數據。

    Based on a bookId, the book.jsp page returns a Book object in the form of a JSON string. The JSP does a lookup for the bookId using the BookManager.getBook(bookId) method and prints out the results of the Book.toJSONString() method. So accessing http://localhost:8080/dojo_json/book.jsp?bookId=1 will print out the JSON string for the Book with the bookId value of 1.

    基于bookId,book.jsp頁返回一個書對象組成JSON字符串。jsp 使用BookMananger.getBook(bookId)方法為指定的bookId查找并且打印出Book.toJSONString()方法的結果。所以通過http://localhost:8080/dojo_json/book.jsp?bookId=1將打印出JSON為bookId值為 1的書的字符串.


    Back on the client side, book information is displayed in a list. Each element in the list has a mouseover (trMouseOver) and mouseout (trMouseOut) event handler attached to its <tr>. On each mouseover, we call book.jsp and pass in the bookId as a parameter. The resulting data will be the JSON String for that Book. We have specified the mime-type as text/json so that the returned value is automatically eval()ed. Let's look at the JavaScript code responsible for sending the request and processing the response:

    返回到客戶端一邊,書的信息被顯示在一個列表中。在列表中的每一個元素都有一個mouseover(trMouseOver)和mouseout (trMouseOut)事件處理追加到它的<tr>。在每一個mouseover,我們調用book.jsp并且傳遞bookID作為一個參數。這個結果數據將是那本書的JSON字符串。我們指定mimetype為text/json以致返回值是自動eval()ed. 讓我們看JavaScript代碼為發送請求和傳遞返回的responsible.

    function trMouseOver(bookId) {
    ?getBookInfo(bookId);
    }

    function trMouseOut(evt) {
    ?var bookDiv = document.getElementById("bookInfo");
    ?bookDiv.style.display = "none";
    }

    function getBookInfo(bookId) {
    ?var params = new Array();
    ?params['bookId'] = bookId;
    ?var bindArgs = {
    ? url: "book.jsp",
    ? error: function(type, data, evt){
    ????????? alert("error");
    ???????? },
    ? mimetype: "text/json",
    ? content: params
    ?};
    ?var req = dojo.io.bind(bindArgs);
    ?dojo.event.connect(req, "load", this, "populateDiv");
    }

    function populateDiv(type, data, evt) {
    ?var bookDiv = document.getElementById("bookInfo");
    ?if (!data) {
    ? bookDiv.style.display = "none";
    ?} else {
    ? bookDiv.innerHTML = "ISBN: " + data.isbn +
    ??????????????? "<br/>Author: " + data.author;
    ? bookDiv.style.display = "";
    ?}
    }

    Another subtle difference in this example is the use of the content property of bindArgs instead of formNode. The content attribute is a key/value mapping of properties to be constructed into parameters passed with the data request.

    subtle 『sub.tle』微秒的?? 采用了content而不是formNode, content的屬性是鍵/值映射
    construct『con.struct』建造 構造

    Once data is transformed into a JavaScript object, we can easily access properties of a Book and display it to the user in a <div> element, as shown above.
    Advanced Dojo: Creating an Autocompletion Widget

    數據轉換成JavaScript對象,我們可以容易通過書的屬性顯示在一個div上。

    The two examples seen above cover the core of most Ajax applications: exchanging data with a web server using JavaScript. Once the basics are understood, it is up to the developer to deliver powerful and useful UIs using Ajax tools such as Dojo. Dojo's extensible framework for widget and module development can greatly ease this process. In this section, we will create a custom widget that will allow us to offer autocompletion for our form fields.
    What Is a Dojo Widget?

    In the general sense, widget is a name given to a UI element such as a button, text box, scroll bar, etc. When creating a Dojo widget, we have the entire HTML language at our disposal and can create widgets that have multiple input elements, custom styles, and more. You may define event handlers for your widgets, customize their behavior, and even reuse them when creating other widgets. In this example, we will create a widget that will provide an autocompletion feature for any text box in an HTML form.
    Components of a Widget

    When developing widgets, the developer must decide which UI elements the widget has and how they will work. When using Dojo, this means deciding on what HTML elements to use and writing the JavaScript code to make these elements behave as needed. The autocomplete example has four files associated with it:

    ??? *

    ????? dojo.js: All required Dojo libraries.
    ??? *

    ????? js/dojo/utils/templates/AutoComplete.html: Contains UI elements, including HTML tags such as <div> and <input>. The template file can contain any valid HTML and is bound by the single requirement that it contain one root element. If more than one element is found at the top level, the first one is considered the root.
    ??? *

    ????? js/dojo/utils/AutoComplete.js: JavaScript code for the widget. Usually a class extending one of the Dojo Widget classes.
    ??? *

    ????? example3.jsp: The file where the widget is used. Usually contains a tag exported by the widget.

    Learning and understanding how UI elements can be accessed and manipulated using JavaScript is the key to creating custom widgets. Once Ajax functionality is baked into the JavaScript, creating rich UIs becomes a task of creativity rather than difficulty.
    Accessing UI Elements

    As mentioned above, specifying a root element of the UI is mandatory. In the autocomplete example, the root element is a <div>. This element can be accessed in the AutoComplete class using this.domNode. The variable this.domNode stores a reference to the HTML object, so code like the following is possible:

    this.domNode.style.display = "none";

    To access any other element of the UI from the JavaScript, you may traverse this.domNode until you find what you're looking for, or instead use the dojoAttachPoint property.

    <input type="text" name="someTextField" dojoAttachPoint="myTextField"/>

    If the above has been defined in the HTML file, it can be accessed using this.myTextField in the JavaScript. Like this.domNode, this.myTextField is also a reference to the HTML object.

    Dojo makes it easier to attach multiple event handlers to UI elements, both using JavaScript and element attributes. As illustrated earlier, to programatically attach an event handler to an element, we can use dojo.event.connect():

    dojo.event.connect(this.domNode, "onclick", this, "myFunction")

    The above will attach an onclick event handler myFunction() from the current class to the root element of the UI. Alternately, we may also specify this in the HTML code for the <div>:

    <div dojoAttachEvent="onclick: myFunction">

    <div dojoAttachEvent="onclick, onmouseover: myFunction">

    Programming the Widget

    Now that there is a way to access and manipulate the UI and detect all types of user actions, all that's left is writing the JavaScript code to make the widget behave as desired. Each widget is backed by a corresponding class that has access to its UI elements and is responsible for responding to user actions. The following snippet of the JavaScript code from the AutoComplete class is enough to illustrate the skeleton of the widget.

    dojo.provide("utils.AutoComplete");

    dojo.require("dojo.dom");
    ...

    dojo.widget.tags.addParseTreeHandler("dojo:AutoComplete");

    utils.AutoComplete = function() {

    ?// call super constructor
    ?dojo.widget.HtmlWidget.call(this);

    ?// load template
    ?this.templatePath =
    ??? dojo.uri.dojoUri("utils/templates/AutoComplete.html");

    ?this.widgetType = "AutoComplete";

    ?// Instance variables
    ?this.action = "";
    ?this.formId = "";
    ?this.form = {};
    ?...

    ?this.postCreate = function() {
    ? this.form = document.getElementById(this.formId);
    ? this.textbox = document.getElementById(this.textboxId);
    ? dojo.event.connect(this.textbox, "onkeyup",
    ??????????????????? this, "textboxOnKeyUp");
    ? ...
    ?}

    ?this.textboxOnKeyUp = function(evt) {
    ? if (this.isKey(evt.keyCode, 38, 40)) {
    ?? this.checkUpDownArrows(evt.keyCode);
    ? } else {
    ?? bindArgs = {
    ??? url:? this.action,
    ??? mimetype:?? "text/javascript",
    ??? formNode:?? this.form
    ?? };
    ?? var req = dojo.io.bind(bindArgs);
    ?? dojo.event.connect(req, "load", this, "populateChoices");
    ? }
    ?}

    ?// Handler for "load" action of dojo.io.bind() call.
    ?this.populateChoices = function(type, data, evt) {
    ? ...
    ?}
    }

    // define inheritance
    dj.inherits(utils.AutoComplete, dojo.widget.HtmlWidget);

    We have defined a JavaScript class, AutoComplete, that is the "code behind" the widget. When defining a custom widget, Dojo requires the developer to explicitly specify the class being provided using the dojo.provide() function. The inheritance is indicated using the dj.inherits() function, and is realized via the call to dojo.widget.HtmlWidget.call(this). The template file for the widget is loaded by assigning a value to the this.templatePath variable of the parent class.

    Dojo widgets are used on HTML pages using custom tags. Tags can be defined when writing the associated widget class. In the above example, the exported tag is dojo:AutoComplete, which is used in the HTML file in the following manner:

    <dojo:AutoComplete
    ?action="getBooks.jsp"
    ?textboxId="bookName"
    ?formId="bookForm"/>

    The above will output the contents of the AutoComplete.html template to the browser. Any attributes specified in the tag can be accessed using the this.<attribute> syntax in the JavaScript class.

    The nature of the autocomplete is to detect user input and provide a list of possible values that the user might be trying to enter. When a user enters any input, the textboxOnKeyUp is executed, and a call to the web server is made with the user input passed through. The web server returns a list of values to be displayed to the user as choices. We display these choices to the user in a <div> tag.

    Any code omitted from the listing is just JavaScript that populates the <div> tag, choices. It also detects user key strokes, such as Tab to move to the next form field and other such details.

    It's important to understand the role each of these four files plays in defining and using a widget, so take a look at them and see how they fit into the big picture. The creators of Dojo have made an honest effort to separate UI, programming, and usage into distinct files and, best of all, this methodology is easily extensible when developing powerful UIs.

    The autocomplete example can be seen at http://localhost:8080/dojo_json/example3.jsp.
    Conclusion

    Dojo is a fine choice for a toolkit when developing Ajax and other JavaScript-intensive applications. However, there are other products, such as Scriptaculous and AjaxAnywhere, that offer similar functionality and need to be considered when writing small- to mid-size applications. Dojo's usefulness lies in a core set of libraries that features not just Ajax functionality but an entire API geared towards full-scale application development.
    Resources

    ??? * Sample application: Complete source of all examples
    ??? * Dojo Toolkit: Official website
    ??? * JSON: Official website for JSON
    ??? * Dojo manual: Growing documentation
    ??? * Custom widget example: Creating a slideshow using Dojo widgets
    ??? * Dojo FAQ
    ??? * Building dojo.js: Building a custom dojo.js using profiles

    posted on 2006-05-06 17:38 java世界暢談 閱讀(1587) 評論(1)  編輯  收藏 所屬分類: JavaScript

    評論

    # re: Use Dojo and JSON to Build Ajax Applications 2007-07-13 11:09 yao
    幾處翻譯不妥  回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲狠狠爱综合影院婷婷| 天天爽亚洲中文字幕| 亚洲精品在线电影| 亚洲人成电影网站免费| 亚洲高清免费视频| 84pao强力永久免费高清| 免费国产黄线在线观看| yy6080久久亚洲精品| 国产亚洲综合一区柠檬导航| 亚洲成av人片不卡无码| 男女猛烈无遮掩视频免费软件| 中文字幕免费不卡二区| 久久久久久久久免费看无码| 亚洲精品麻豆av| 亚洲成av人片在线看片| 一级做a爰片久久免费| 免费观看无遮挡www的视频| 亚洲国产V高清在线观看| 亚洲国产av一区二区三区丶| 一级毛片免费播放视频| 免费可以在线看A∨网站| 最新亚洲成av人免费看| 国产午夜亚洲精品国产| 美女视频黄的免费视频网页| 国产成人免费手机在线观看视频 | 亚洲无码精品浪潮| 亚洲综合一区国产精品| 久久精品视频免费播放| 亚洲国产精品嫩草影院久久 | 国产精品嫩草影院免费| 亚洲视频免费在线播放| 黄色短视频免费看| 日本免费v片一二三区| 亚洲欧洲中文日产| 日本在线免费播放| 自拍偷自拍亚洲精品第1页| 亚洲第一成年网站视频| 1000部拍拍拍18勿入免费凤凰福利 | 亚洲AV日韩AV永久无码下载| 猫咪免费观看人成网站在线| 国产v精品成人免费视频400条|