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

首頁 > 編程 > JavaScript > 正文

Bootstrap嵌入jqGrid,使你的table牛逼起來

2019-11-20 10:09:27
字體:
來源:轉載
供稿:網友

Bootstrap原生的table組件只能滿足簡單的數據展示,滿足不了更富有操作性的要求。當然了,你可以找到一款叫做“DataTables-1.10.11”的基于bootstrap的table組件,但如果你對API看得不甚了解的話,用起來可就痛苦了,但是如果你選擇使用jqGrid,那么本篇教程就給你帶來了解決這種富操作性table的解決方案。

一、效果展示

這里寫圖片描述

OK,就展示這一張圖片,相信你已經愛上了bootstrap版的jqGrid,和bootstrap很兼容,簡直完美,當然了,這需要我們在緣由的jqGrid上進行一些改動,同時對組件進行一定的封裝。

二、資源下載

我反正挺熱愛分享的,關于jqGrid的組件代碼,你可以從jqGrid的官網上下載,但是下載下來需要一些改動,那么我直接將改動后的jqGrid上傳到了git,你只需要把提供的文件導入到你對應的項目即可。

另外,你還需要下載一個jquery-ui-1.10.0.custom.css,我就不提供下載地址了,不過我相信,你肯定會找得到,就算是用頻出事故的度娘,你也可以找得到。

三、本篇都講一些什么

自從建了QQ群后,“絡繹不絕”的有同學加入到群中,但我也發現,進群的一步人直接來找我要demo,或者項目代碼,這個我可不喜歡,自己動手做一做,去實現以下,改造一下,才會是你自己的東西,完全照搬我的代碼顯然你得不到更多的幫助,希望以上同學學習的時候再主動一些。

說完上面這點小廢話后,我們言歸正傳,來說說我們本篇博客主要來講些什么,什么才是在bootstrap中嵌入jqGrid的關鍵所在,我總結有如下:

jqGrid在bootstrap中的布局方案jqGrid自身的構造化參數jqGrid在bootstrap中的模塊化jqGrid的數據操作

暫定分為以上部分來說明,但必須注意,限于篇幅,博客中只提供思路和部分代碼。

①、 jqGrid在bootstrap中的布局方案

<!DOCTYPE html><html lang="zh-CN"><%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><%@ include file="/components/common/taglib.jsp"%><%@ include file="/components/common/csslib.jsp"%><head><link type="text/css" rel="stylesheet" href="${ctx}/css/deal/my_pay_list.css" /></head><body>  <div class="container">    <form class="form-horizontal" id="jqgridForm" role="form" action="${ctx}/deal/datablePayDealOrdersList"    method="post">    <div class="form-group">      <div class="col-sm-12">        <label for="name" class="control-label pull-left">項目名稱:</label>        <div class="col-sm-3">          <input type="text" name="name" class="form-control" id="name" placeholder="請輸入項目名稱" value="" />        </div>      </div>    </div>    <div class="form-group">      <div class="col-sm-12">        <button type="button" class="btn btn-primary pull-right" id="searchBtn">檢索</button>      </div>    </div>    <div class="form-group">      <div class="col-sm-12">        <table id="pageGrid" rel="jqgridForm" class="jqgrid"></table>        <div id="pageGridPager"></div>      </div>    </div>  </form></div><%@ include file="/components/common/jslib.jsp"%><script type="text/javascript" src="${ctx}/js/deal/my_pay_list.js"></script></body></html>

介于每個人的項目千差萬別,列出的代碼中我們只關注jqGrid部分:

id="jqgridForm",此處我們為jqGrid包含一層檢索條件的form表單,也就是效果圖上列出的search部分,當點擊檢索按鈕時,就把form表單域的查詢條件提交到controller,進而獲取的數據。id="searchBtn",定義檢索按鈕,后面講模塊化會用得到。<table id="pageGrid" rel="jqgridForm" class="jqgrid"></table> <div id="pageGridPager"></div>定義jqGrid的table元素和jqGrid的footer元素,使用的規則我的項目暫時約定這種規則,你也可以有你自己的規則。通過rel指定form的id,可以更便捷的使用table的檢索form。②、 jqGrid自身的構造化參數

構造化參數,我把他提取到了①中的my_pay_list.js中。

$(function() {  var jqOption = {    datatype : "xml",    mtype : "POST",    shrinkToFit : true,    viewrecords : false,    rownumbers : false,    autowidth : true,    height : "100%",    colNames : [ 'id', 'status', '項目信息', '項目狀態', '訂單號', '項目名稱', '下單時間', '支付金額', '支持數量', '訂單狀態', '操作' ],    colModel : [        {          name : 'id',          index : 'id',          hidden : true        },        {          name : 'status',          index : 'status',          hidden : true        },        {          name : 'image_str',          index : 'image_str',          width : 140,          resizable : false,          sortable : false,          formatter : function(cellvalue, options, rowObject) {            if (cellvalue == '支付總花費:') {              return cellvalue;            }          },          align : 'left'        }, {          name : 'oper',          index : 'oper',          width : 90,          resizable : false,          sortable : false,          align : 'center',          formatter : function(cellvalue, options, rowObject) {            var status = parseInt($(rowObject).find("status").text());            var id = $(rowObject).find("id").text();            if (status == 0) {              return '<a class="color0088cc" width="700" target="dialog" href="' + common.ctx + '/deal/initPayg/' + id + '">去支付</a>';            }            if (status == 1 || status == 3) {              return '<a class="color0088cc" target="_blank" href="' + common.ctx + '/deal/showDealOr/' + id + '">查看詳情</a>';            }            if (status == 2) {              return '<a class="color0088cc" target="ajaxTodo" href="' + common.ctx + '/deal/receivder/' + id + '">確認收貨</a>';            }          },        } ],    xmlReader : {      repeatitems : false,      root : "PageGrid",      row : "map",      page : 'page',      total : 'total',      records : 'records',      id : 'ID'    },    rowNum : 50,    rowList : [ 50, 100, 200, 300 ],    pager : "#pageGridPager",    footerrow : true,    loadError : YUNM.ajaxError,    gridComplete : function() {      var $form = $("#" + $("#pageGrid").attr("rel"));      $.ajax({        type : $form.method || 'POST',        url : common.ctx + "/deal/getAllOrded",        data : $form.serializeArray(),        dataType : "json",        cache : false,        success : function(json) {          $("#pageGrid").footerData("set", {            image_str : "支付總花費:",            order_price : json.message          });        },        error : YUNM.ajaxError      });      if ($.fn.ajaxTodo) {        $("a[target=ajaxTodo]", $("#pageGrid")).ajaxTodo();      }      // dialog      if ($.fn.ajaxTodialog) {        $("a[target=dialog]", $("#pageGrid")).ajaxTodialog();      }    },  };  initEnv(jqOption);});

一點都不熟悉jqGrid的同學,建議先看jqGrid的demo,以及jqGrid的官方文檔,當然了,對于已經熟悉jqGrid的同學,doc和demo肯定是必看的。

以上文件列出的屬性非常多,對于jqGrid,我不做過多的介紹,本篇的主旨主要來介紹如何將jqGrid嵌入到bootstrap,那么重點就不在于介紹jqGrid上,我只介紹幾個關鍵點:

formatter: function(cellvalue, options, rowObject) {,formatter還是很經常要使用的,那么對于如何獲得對應單元格的值就很重要,我的jqGrid使用的是xml(datatype : “xml”)數據格式,那么可通過$(rowObject).find("deal_id").text()找到對應deal_id列的值。xmlReader : { repeatitems : false, root : "PageGrid",,注意xmlReader中的參數值,在接下來介紹④jqGrid的數據操作會細節介紹,和后臺的xml數據封裝有關系。$("#pageGrid").footerData("set", {image_str : "支付總花費:", order_price : json.message});,關于footerData方法,使用起來也很方便,效果可參照效果圖。initEnv(jqOption);方法,在頁面onload后,我們將jqGrid的初始化參數傳遞給initEnv方法,后續③jqGrid在bootstrap中的模塊化會介紹initEnv方法。③、jqGrid在bootstrap中的模塊化

②中我們注意到initEnv方法,那么這個方法內部就是專門針對jqGrid做的模塊化封裝工作。

initEnv方法

function initEnv(jqOption) {  $(window).resize(function() {    initLayout();  });  initUI(null, jqOption);}

該方法中,我們將會看到initLayout方法和initUI方法,具體內容稍候介紹。

initLayout

function initLayout() {  $("table[rel=jqgridForm]").each(function() {    var rel = $(this).attr("rel");    if (rel) {      var $form = $("#" + rel);      var tableWidth = $form.width();      $(this).setGridWidth(tableWidth, true);    }  });}

也就是說,在窗口縮放的時候,我們為jqGrid重新繪制寬度,使其自適應于bootstrap的響應式布局。使用的方法就是jqGrid的setGridWidth方法。

initUI

function initUI(_box, jqOption) {  var $p = $(_box || document);  if (jqOption) {    YUNM.debug("初始化jqgrid");    var $form = $("#" + $("#pageGrid").attr("rel"));    YUNM.debug(YUNM.array2obj($form.serializeArray()));    // 初始化    var op = $.extend({      url : $form.attr("action"),      postData : YUNM.array2obj($form.serializeArray()),    }, jqOption);    $("#pageGrid").jqGrid(op);    // 檢索按鈕    $("#searchBtn", $form).click(function() {      $("#pageGrid").jqGrid('setGridParam', {        url : $form.attr("action"),        page : 1,        postData : YUNM.array2obj($form.serializeArray()),      });      $("#pageGrid").trigger("reloadGrid");    });    // toolbar,將button的圓角去掉    $(".btn", $form).each(function() {      var $this = $(this);      $this.css({        "border-radius" : "0px",        "border-bottom" : "0",      });    });  }}array2obj : function(array) {  var params = $({});  $.each(array, function(i) {    var $param = $(this)[0];    params.attr($param.name, $param.value);  });  return params[0];},

如果你曾看過我之前的系列文章,對于initUi方法就不會太陌生,熟悉dwz的朋友,自然也不會陌生,我項目中的大部分模板還是依賴于dwz,謝謝這些前輩們。

var $form = $("#" + $("#pageGrid").attr("rel"));由于我們在jqGrid上關聯了form檢索條件的form表單,此處就可以將form表單對象取到,取到form表單對象,自然也就去得到了檢索域的值($form.serializeArray())。拿到form表單的檢索域值后,此時就需要做一番處理了。我們知道,jqGrid在向controller傳遞參數時,必然需要上送分頁、排序的相關字段(page、rows、sord、sidx),使用的方法是$("#pageGrid").jqGrid({postData:xxx});,通常情況下,我們上送form表單時,只需要使用$form.serializeArray()就可以,但如果此時,只是將xxx替換為$form.serializeArray(),那么controller中將不會獲得分頁、排序的相關字段(page、rows、sord、sidx),這是一個沖突,此時怎么處理呢?解決辦法就是將form表單數據對象化(array2obj 方法),然后我們再通過var op =$.extend({url:$form.attr("action"),postData:YUNM.array2obj($form.serializeArray()),},jqOption);$("#pageGrid").jqGrid(op);將檢索域的值和分頁、排序的相關字段一起上送到controller。$("#searchBtn", $form).click通過封裝click事件,將jqGrid的數據重新加載。$(".btn", $form).each(function() {此處的方法將檢索button去圓角,使其更貼合jqGrid,見效果圖。④ 、jqGrid的數據操作

數據操作部分,我認為包含有 檢索參數傳遞、分頁排序參數傳遞、sql語句的編寫。

關于參數傳遞,前端的參數封裝在③中已有介紹,我們來看一看controller中如何處理數據的。

首先,我們來定義PageGrid,也就是jqGrid中xmlReader的數據源。

package com.honzh.common.page;import java.util.List;import com.thoughtworks.xstream.annotations.XStreamAlias;@XStreamAlias("pageGrid")@SuppressWarnings("rawtypes")public class PageGrid {  private int page;  private int total;  private int records;  private List data;  public int getPage() {    return this.page;  }  public void setPage(int page) {    this.page = page;  }  public int getTotal() {    return this.total;  }  public void setTotal(int total) {    this.total = total;  }  public int getRecords() {    return this.records;  }  public void setRecords(int records) {    this.records = records;  }  public List getData() {    return this.data;  }  public void setData(List data) {    this.data = data;  }}

項目中需要xstream.jar,自行下載。

XStreamComponent.java

package com.honzh.common.page;import org.apache.commons.lang.StringUtils;import com.thoughtworks.xstream.XStream;import com.thoughtworks.xstream.converters.Converter;import com.thoughtworks.xstream.io.xml.DomDriver;import com.thoughtworks.xstream.mapper.DefaultMapper;import com.thoughtworks.xstream.mapper.XStream11XmlFriendlyMapper;public class XStreamComponent {  private XStream xstream;  public static XStreamComponent newInstance() {    XStreamComponent xmlComponent = new XStreamComponent();    xmlComponent.alias(new Class[] { PageGrid.class });    return xmlComponent;  }  public XStreamComponent() {    this.xstream = new XStream(new DomDriver());  }  public String toXML(Object obj) {    return this.xstream.toXML(obj);  }  public String toPageXML(Object obj) {    registerConverter(new MapCustomConverter(new DefaultMapper(XStream11XmlFriendlyMapper.class.getClassLoader())));    return toXML(obj);  }  public Object fromPageXML(String xml) {    registerConverter(new MapCustomConverter(new DefaultMapper(XStream11XmlFriendlyMapper.class.getClassLoader())));    return fromXML(xml);  }  public Object fromXML(String xml) {    return this.xstream.fromXML(xml);  }  @SuppressWarnings("rawtypes")  public void processAnnotations(Class type) {    this.xstream.processAnnotations(type);  }  @SuppressWarnings("rawtypes")  public void processAnnotations(Class[] types) {    this.xstream.processAnnotations(types);  }  @SuppressWarnings("rawtypes")  public void alias(String name, Class type) {    this.xstream.alias(name, type);  }  @SuppressWarnings("rawtypes")  public void alias(Class[] types) {    for (Class type : types) {      String className = type.getName();      try {        String[] classNames = StringUtils.split(className, ".");        this.xstream.alias(classNames[(classNames.length - 1)], type);      } catch (Exception ex) {        this.xstream.alias(className, type);      }    }  }  public void registerConverter(Converter converter) {    this.xstream.registerConverter(converter);  }  @SuppressWarnings("rawtypes")  public void useAttributeFor(Class definedIn, String fieldName) {    this.xstream.useAttributeFor(definedIn, fieldName);  }}

主要將pageGrid封裝為xml對象,進而傳遞會前端。

MapCustomConverter.java

package com.honzh.common.page;import java.util.HashMap;import java.util.Hashtable;import java.util.Iterator;import java.util.Map;import com.thoughtworks.xstream.converters.MarshallingContext;import com.thoughtworks.xstream.converters.UnmarshallingContext;import com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter;import com.thoughtworks.xstream.io.HierarchicalStreamReader;import com.thoughtworks.xstream.io.HierarchicalStreamWriter;import com.thoughtworks.xstream.mapper.Mapper;public class MapCustomConverter extends AbstractCollectionConverter {  public MapCustomConverter(Mapper mapper) {    super(mapper);  }  @SuppressWarnings("rawtypes")  public boolean canConvert(Class type) {    return (type.equals(HashMap.class)) || (type.equals(Hashtable.class))        || (type.getName().equals("java.util.LinkedHashMap"))        || (type.getName().equals("sun.font.AttributeMap"));  }  @SuppressWarnings({ "rawtypes" })  public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {    Map map = (Map) source;    for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {      Map.Entry entry = (Map.Entry) iterator.next();      writer.startNode(entry.getKey() == null ? "null" : entry.getKey().toString());      writer.setValue(entry.getValue() == null ? "" : entry.getValue().toString());      writer.endNode();    }  }  @SuppressWarnings("rawtypes")  public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {    Map map = (Map) createCollection(context.getRequiredType());    populateMap(reader, context, map);    return map;  }  @SuppressWarnings({ "rawtypes", "unchecked" })  protected void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, Map map) {    while (reader.hasMoreChildren()) {      reader.moveDown();      Object key = reader.getNodeName();      Object value = reader.getValue();      map.put(key, value);      reader.moveUp();    }  }}

主要將數據庫中獲取的hashmap轉換為標準的xml格式數據。

BaseConditionVO.java

package com.honzh.common.persistence;import java.util.HashMap;import java.util.Map;import org.apache.ibatis.session.RowBounds;/** * 分頁查詢時的參數設置類.<br> *  * <P> * 1.PAGE_SHOW_COUNT──當然默認一頁顯示10。<br> * 2.pageNum──第幾頁。<br> * 3.numPerPage──一頁顯示多少,為空時,顯示PAGE_SHOW_COUNT。<br> * 4.totalCount──總共數目。totalCount/numPerPage=多少頁<br> * 5.orderField──排序的列。<br> * 6.orderDirection──排序的方向。 * </P> */public class BaseConditionVO {  public final static int PAGE_SHOW_COUNT = 50;  private int pageNum = 1;  private int numPerPage = 0;  private long totalCount = 0;  private String orderField = "";  private String orderDirection = "";  /**   * @Fields ps : 對參數類型進行封裝.   */  private Map<String, Object> mo = new HashMap<String, Object>();  public int getPageNum() {    return pageNum;  }  public void setPageNum(int pageNum) {    this.pageNum = pageNum;  }  public int getNumPerPage() {    return numPerPage > 0 ? numPerPage : PAGE_SHOW_COUNT;  }  public void setNumPerPage(int numPerPage) {    this.numPerPage = numPerPage;  }  public String getOrderField() {    return orderField;  }  public void setOrderField(String orderField) {    this.orderField = orderField;  }  public String getOrderDirection() {    return "desc".equals(orderDirection) ? "desc" : "asc";  }  public void setOrderDirection(String orderDirection) {    this.orderDirection = orderDirection;  }  public long getTotalCount() {    return totalCount;  }  public void setTotalCount(long totalCount) {    this.totalCount = totalCount;  }  public int getStartIndex() {    int pageNum = this.getPageNum() > 0 ? this.getPageNum() - 1 : 0;    return pageNum * this.getNumPerPage();  }  public RowBounds createRowBounds() {    RowBounds ro = new RowBounds(this.getStartIndex(), this.getNumPerPage());    return ro;  }  /**   * @Title: addParams   * @Description: 添加查詢條件   * @param key   * @param value   */  public void addParams(String key, Object value) {    this.getMo().put(key, value);  }  /**   * @Title: getParams   * @Description: 獲取查詢條件   * @param key   * @return   */  public Object getParams(String key) {    return this.getMo().get(key);  }  /**   * @return the mo   */  public Map<String, Object> getMo() {    return mo;  }  /**   * @param mo   *      the mo to set   */  public void setMo(Map<String, Object> mo) {    this.mo = mo;  }  @Override  public String toString() {    return "條件:" + pageNum + "," + numPerPage + "," + totalCount + "," + orderField + "," + orderDirection + ","        + mo;  }}

分頁的查詢數據對象,包括分頁、排序、檢索域。

 protected BaseConditionVO getBaseConditionVOForTable() {    BaseConditionVO vo = new BaseConditionVO();    // 分頁的參數    int currentPage = getParaToInt("page");    int sizes = getParaToInt("rows");    String sortOrder = getPara("sord");    String sortCol = getPara("sidx");    vo.setNumPerPage(sizes);    vo.setPageNum(currentPage);    vo.setOrderField(sortCol);    vo.setOrderDirection(sortOrder);    return vo;  }將jqGrid傳遞的參數轉換為BaseConditionVO分頁查詢對象。protected void renderXml(HttpServletResponse res, String xmlResponse) {    try {      res.setCharacterEncoding("UTF-8");      res.setHeader("Content-type", "text/xml");      PrintWriter out = res.getWriter();      out.print(xmlResponse);      if (out != null) {        out.close();      }    } catch (IOException e) {      logger.error(e.getMessage());      logger.error(e.getMessage(), e);    }  }

將xml寫入到輸出流中。

定義完了這些基礎的對象,接下來,我們就要著手獲取數據和傳遞數據了。

@SuppressWarnings("rawtypes")  @RequestMapping(value = "datablePayDealOrdersList")  public void datablePayDealOrdersList(HttpServletResponse response) {    try {      logger.debug("獲取我支付的訂單");      XStreamComponent xstreamComponent = XStreamComponent.newInstance();      // 獲取列表參數      BaseConditionVO vo = getBaseConditionVOForTable();      vo.addParams("name", getPara("name"));      logger.debug("我支付的訂單查詢" + vo);      // 我創建的項目      List myDealOrders = dealOrderService.getByIssueUid(vo, vo.createRowBounds());      Long count = dealOrderService.searchIssueTotalCount(vo);      String xmlResponse = xstreamComponent.toPageXML(createPageGrid(myDealOrders, vo, count.intValue()));      renderXml(response, xmlResponse.replaceAll("__", "_"));    } catch (UncategorizedSQLException e) {      logger.error(e.getMessage());      logger.error(e.getMessage(), e);      renderXml(response, Constants.QUERY_ERROR);    } catch (Exception e) {      logger.error(e.getMessage());      logger.error(e.getMessage(), e);      renderXml(response, Constants.SERVER_ERROR);    }  }

我們來詳細說明一下:
1. XStreamComponent.newInstance()創建xml流對象。
2. BaseConditionVO vo = getBaseConditionVOForTable();創建分頁查詢參數對象。
3. vo.addParams("name", getPara("name"));將檢索域的值放入到查詢對象中。
4. dealOrderService.getByIssueUid(vo, vo.createRowBounds());mybatis的分頁查詢方式,超簡單,之前一個群里的朋友專門做了一種mybatis的分頁組件,我覺得用原始的mybatis查詢方法更有效率,之后,我們會寫出對應的mybatis中xml的sql寫法。
5. renderXml(response, xmlResponse.replaceAll("__", "_"));將數據寫入到jsp的out輸出流中。

最后,我們來介紹,通過mybatis如何獲取分頁數據。

mapper.java

package com.honzh.biz.database.mapper;import java.math.BigDecimal;import java.util.HashMap;import java.util.List;import org.apache.ibatis.session.RowBounds;import com.honzh.common.persistence.BaseConditionVO;public interface DealOrderMapper {  @SuppressWarnings("rawtypes")  List<HashMap> getByIssueUid(BaseConditionVO vo, RowBounds createRowBounds);}

想mapper.xml傳遞的兩個對象,分別是BaseConditionVO 還有分頁的RowBounds ,xml中sql就會自動分頁。

mapper.xml

<select id="getByIssueUid" resultType="hashmap" parameterType="map">    select * from daa    WHERE is_delete=0    <if test="mo.name != null and mo.name != ''">      and y.name like CONCAT('%','${mo.name}','%')    </if>     <choose>      <when test="orderField !=null and orderField !=''">         ORDER BY ${orderField} <if test="orderDirection != null and orderDirection != ''">${orderDirection}</if>      </when>      <otherwise>         order by d.order_time DESC      </otherwise>    </choose>  </select>

你完全可以不關注RowBounds ,mybatis內部會自動為你封裝好limit的。檢索域的name可以直接通過mo.name或得到。orderField、orderDirection也傳遞過來了。

到此為止,整篇的Bootstrap嵌入jqGrid就圓滿結束了,ok,使你的table牛逼起來吧!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久综合av爱欲tv| 国产一区二区三区四区福利| 亚洲欧美日韩中文视频| 日韩高清欧美高清| 亚洲精品小视频| 国内成人精品视频| 亚洲尤物视频网| 97精品国产91久久久久久| 国产美女精品免费电影| 欧美精品精品精品精品免费| 51ⅴ精品国产91久久久久久| 国产成人久久久| 97精品视频在线播放| 亚洲人成网站免费播放| 性欧美亚洲xxxx乳在线观看| 日韩美女视频中文字幕| 国产精品九九久久久久久久| 欧美日韩国产精品一区二区三区四区| 国产丝袜一区视频在线观看| 97视频在线观看播放| 日韩高清电影免费观看完整| 久久久久99精品久久久久| 欧美成人午夜影院| 亚洲欧美在线一区| 中文字幕精品一区二区精品| 亚洲成人在线网| 亚洲最大的免费| 77777少妇光屁股久久一区| 欧美日韩国产色视频| 亚洲一区久久久| 亚洲国产欧美久久| 亚洲午夜国产成人av电影男同| 色偷偷av一区二区三区| 91亚洲va在线va天堂va国| 久久91亚洲精品中文字幕| 午夜精品一区二区三区视频免费看| 日韩欧美国产激情| 91精品成人久久| 欧美精品18videos性欧美| 欧美极品少妇xxxxⅹ喷水| 亚洲国产美女久久久久| 国产美女久久精品香蕉69| 欧美成人精品在线观看| 国产精选久久久久久| 96精品视频在线| 国产精品美女www爽爽爽视频| 国产视频精品自拍| 欧美色播在线播放| 一二美女精品欧洲| 精品国产一区二区三区四区在线观看| 欧美成人h版在线观看| 欲色天天网综合久久| 国产精品一区二区电影| 国产精品黄视频| 91禁外国网站| 国产精品观看在线亚洲人成网| 午夜精品视频在线| 人人澡人人澡人人看欧美| 国产成人精品一区二区三区| 亚洲一区二区三区四区视频| 欧美国产日韩一区二区在线观看| 欧美www在线| 97色在线观看免费视频| 在线观看不卡av| 成人在线视频福利| 国产欧美欧洲在线观看| 日韩在线视频观看正片免费网站| 国产精品久久久久久久7电影| 成人黄色激情网| 欧美性xxxx极品hd欧美风情| 51精品国产黑色丝袜高跟鞋| 亚洲视频视频在线| 欧美精品在线免费观看| 成人免费看片视频| 欧美成人中文字幕| 国内精品久久久久久影视8| 久久久国产视频| 国产亚洲欧洲黄色| 亚洲加勒比久久88色综合| 国产在线观看精品一区二区三区| 国产精品入口免费视| 色婷婷综合久久久久| 精品国产鲁一鲁一区二区张丽| 欧美大片在线看| 欧美成人全部免费| 亚洲成年人在线| 亚洲第一中文字幕| 国产精品99久久久久久久久久久久| 中文亚洲视频在线| 成人a视频在线观看| 伊人伊人伊人久久| 韩剧1988在线观看免费完整版| 亚洲天堂男人的天堂| 国产精品一区二区3区| 欧美在线视频在线播放完整版免费观看| 国产精品美女av| 国产精品久久久久久av福利软件| 一区二区国产精品视频| 成人妇女淫片aaaa视频| 黑人巨大精品欧美一区免费视频| 国产91成人在在线播放| 热re91久久精品国99热蜜臀| 全色精品综合影院| 亚洲精品国产欧美| 欧美一级在线播放| 欧美天堂在线观看| 欧美裸体男粗大视频在线观看| 亚洲国内精品视频| 国产精品日日做人人爱| 51ⅴ精品国产91久久久久久| 国产成人高潮免费观看精品| 孩xxxx性bbbb欧美| 日韩精品在线免费播放| 欧美精品国产精品日韩精品| 国产一区二区视频在线观看| 97视频在线观看播放| 国产精品丝袜白浆摸在线| 97香蕉久久夜色精品国产| 国产97在线亚洲| 欧美性69xxxx肥| 91在线免费网站| 亚洲电影免费观看高清| 亚洲美女精品久久| 国产精品成人va在线观看| 久久福利网址导航| 日韩av男人的天堂| 欧美一级大片视频| 亚洲色图15p| 精品国产乱码久久久久久虫虫漫画| 精品国产乱码久久久久久虫虫漫画| 亚洲欧美一区二区三区在线| 亚洲国产成人在线视频| 国产丝袜一区二区三区| 国产va免费精品高清在线观看| 日韩av第一页| 国产视频精品自拍| 日韩av综合中文字幕| 日韩精品日韩在线观看| 日韩av最新在线观看| 91麻豆国产语对白在线观看| 亚洲人成五月天| 97视频在线观看视频免费视频| 一区二区欧美在线| 亚洲精品电影网在线观看| 亚洲性无码av在线| 国产精品久久久久久久久久99| 亚洲激情成人网| 久久久久久久久久久91| 欧美与黑人午夜性猛交久久久| 亚洲香蕉成人av网站在线观看| 亚洲mm色国产网站| 亚洲一区二区三区毛片| 久久精品国产91精品亚洲| 欧美福利视频网站| 大荫蒂欧美视频另类xxxx| 91免费电影网站| 欧美日韩在线视频一区| 欧美巨乳美女视频| 国产精品视频资源| 日韩av日韩在线观看| 日本免费一区二区三区视频观看| 疯狂做受xxxx欧美肥白少妇| 精品av在线播放| 日韩有码片在线观看|