<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          56個JavaScript 實用工具函數(shù)助你提升開發(fā)效率!

          共 6428字,需瀏覽 13分鐘

           ·

          2021-10-23 13:18

          文章來自掘金:https://juejin.cn/post/7019090370814279693#heading-56
          作者:CUGGZ?

          又到周五啦,快來一起摸魚呀!今天來看看JavaScript中的一些實用的工具函數(shù),希望能幫助你提高開發(fā)效率!整理不易,如果覺得有用就點(diǎn)個贊吧!

          1. 數(shù)字操作

          (1)生成指定范圍隨機(jī)數(shù)

          export const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
          復(fù)制代碼

          (2)數(shù)字千分位分隔

          export const format = (n) => {
          let num = n.toString();
          let len = num.length;
          if (len <= 3) {
          return num;
          } else {
          let temp = '';
          let remainder = len % 3;
          if (remainder > 0) { // 不是3的整數(shù)倍
          return num.slice(0, remainder) + ',' + num.slice(remainder, len).match(/\d{3}/g).join(',') + temp;
          } else { // 3的整數(shù)倍
          return num.slice(0, len).match(/\d{3}/g).join(',') + temp;
          }
          }
          }
          復(fù)制代碼

          2. 數(shù)組操作

          (1)數(shù)組亂序

          export const arrScrambling = (arr) => {
          for (let i = 0; i < arr.length; i++) {
          const randomIndex = Math.round(Math.random() * (arr.length - 1 - i)) + i;
          [arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]];
          }
          return arr;
          }
          復(fù)制代碼

          (2)數(shù)組扁平化

          export const flatten = (arr) => {
          let result = [];

          for(let i = 0; i < arr.length; i++) {
          if(Array.isArray(arr[i])) {
          result = result.concat(flatten(arr[i]));
          } else {
          result.push(arr[i]);
          }
          }
          return result;
          }
          復(fù)制代碼

          (3)數(shù)組中獲取隨機(jī)數(shù)

          export const sample = arr => arr[Math.floor(Math.random() * arr.length)];

          復(fù)制代碼

          3. 字符串操作

          (1)生成隨機(jī)字符串

          export const randomString = (len) => {
          let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz123456789';
          let strLen = chars.length;
          let randomStr = '';
          for (let i = 0; i < len; i++) {
          randomStr += chars.charAt(Math.floor(Math.random() * strLen));
          }
          return randomStr;
          };
          復(fù)制代碼

          (2)字符串首字母大寫

          export const fistLetterUpper = (str) => {
          return str.charAt(0).toUpperCase() + str.slice(1);
          };
          復(fù)制代碼

          (3)手機(jī)號中間四位變成*

          export const telFormat = (tel) => {
          tel = String(tel);
          return tel.substr(0,3) + "****" + tel.substr(7);
          };
          復(fù)制代碼

          (4)駝峰命名轉(zhuǎn)換成短橫線命名

          export const getKebabCase = (str) => {
          return str.replace(/[A-Z]/g, (item) => '-' + item.toLowerCase())
          }
          復(fù)制代碼

          (5)短橫線命名轉(zhuǎn)換成駝峰命名

          export const getCamelCase = (str) => {
          return str.replace( /-([a-z])/g, (i, item) => item.toUpperCase())
          }
          復(fù)制代碼

          (6)全角轉(zhuǎn)換為半角

          export const toCDB = (str) => {
          let result = "";
          for (let i = 0; i < str.length; i++) {
          code = str.charCodeAt(i);
          if (code >= 65281 && code <= 65374) {
          result += String.fromCharCode(str.charCodeAt(i) - 65248);
          } else if (code == 12288) {
          result += String.fromCharCode(str.charCodeAt(i) - 12288 + 32);
          } else {
          result += str.charAt(i);
          }
          }
          return result;
          }

          復(fù)制代碼

          (7)半角轉(zhuǎn)換為全角

          export const toDBC = (str) => {
          let result = "";
          for (let i = 0; i < str.length; i++) {
          code = str.charCodeAt(i);
          if (code >= 33 && code <= 126) {
          result += String.fromCharCode(str.charCodeAt(i) + 65248);
          } else if (code == 32) {
          result += String.fromCharCode(str.charCodeAt(i) + 12288 - 32);
          } else {
          result += str.charAt(i);
          }
          }
          return result;
          }

          復(fù)制代碼

          4. 格式轉(zhuǎn)化

          (1)數(shù)字轉(zhuǎn)化為大寫金額

          export const digitUppercase = (n) => {
          const fraction = ['角', '分'];
          const digit = [
          '零', '壹', '貳', '叁', '肆',
          '伍', '陸', '柒', '捌', '玖'
          ];
          const unit = [
          ['元', '萬', '億'],
          ['', '拾', '佰', '仟']
          ];
          n = Math.abs(n);
          let s = '';
          for (let i = 0; i < fraction.length; i++) {
          s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');
          }
          s = s || '整';
          n = Math.floor(n);
          for (let i = 0; i < unit[0].length && n > 0; i++) {
          let p = '';
          for (let j = 0; j < unit[1].length && n > 0; j++) {
          p = digit[n % 10] + unit[1][j] + p;
          n = Math.floor(n / 10);
          }
          s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
          }
          return s.replace(/(零.)*零元/, '元')
          .replace(/(零.)+/g, '零')
          .replace(/^整$/, '零元整');
          };
          復(fù)制代碼

          (2)數(shù)字轉(zhuǎn)化為中文數(shù)字

          export const intToChinese = (value) => {
          const str = String(value);
          const len = str.length-1;
          const idxs = ['','十','百','千','萬','十','百','千','億','十','百','千','萬','十','百','千','億'];
          const num = ['零','一','二','三','四','五','六','七','八','九'];
          return str.replace(/([1-9]|0+)/g, ( $, $1, idx, full) => {
          let pos = 0;
          if($1[0] !== '0'){
          pos = len-idx;
          if(idx == 0 && $1[0] == 1 && idxs[len-idx] == '十'){
          return idxs[len-idx];
          }
          return num[$1[0]] + idxs[len-idx];
          } else {
          let left = len - idx;
          let right = len - idx + $1.length;
          if(Math.floor(right / 4) - Math.floor(left / 4) > 0){
          pos = left - left % 4;
          }
          if( pos ){
          return idxs[pos] + num[$1[0]];
          } else if( idx + $1.length >= len ){
          return '';
          }else {
          return num[$1[0]]
          }
          }
          });
          }
          復(fù)制代碼

          5. 操作存儲

          (1)存儲loalStorage

          export const loalStorageSet = (key, value) => {
          if (!key) return;
          if (typeof value !== 'string') {
          value = JSON.stringify(value);
          }
          window.localStorage.setItem(key, value);
          };
          復(fù)制代碼

          (2)獲取localStorage

          export const loalStorageGet = (key) => {
          if (!key) return;
          return window.localStorage.getItem(key);
          };
          復(fù)制代碼

          (3)刪除localStorage

          export const loalStorageRemove = (key) => {
          if (!key) return;
          window.localStorage.removeItem(key);
          };
          復(fù)制代碼

          (4)存儲sessionStorage

          export const sessionStorageSet = (key, value) => {
          if (!key) return;
          if (typeof value !== 'string') {
          value = JSON.stringify(value);
          }
          window.sessionStorage.setItem(key, value)
          };
          復(fù)制代碼

          (5)獲取sessionStorage

          export const sessionStorageGet = (key) => {
          if (!key) return;
          return window.sessionStorage.getItem(key)
          };
          復(fù)制代碼

          (6)刪除sessionStorage

          export const sessionStorageRemove = (key) => {
          if (!key) return;
          window.sessionStorage.removeItem(key)
          };
          復(fù)制代碼

          6. 操作cookie

          (1)設(shè)置cookie

          export const setCookie = (key, value, expire) => {
          const d = new Date();
          d.setDate(d.getDate() + expire);
          document.cookie = `${key}=${value};expires=${d.toUTCString()}`
          };

          復(fù)制代碼

          (2)讀取cookie

          export const getCookie = (key) => {
          const cookieStr = unescape(document.cookie);
          const arr = cookieStr.split('; ');
          let cookieValue = '';
          for (let i = 0; i < arr.length; i++) {
          const temp = arr[i].split('=');
          if (temp[0] === key) {
          cookieValue = temp[1];
          break
          }
          }
          return cookieValue
          };
          復(fù)制代碼

          (3)刪除cookie

          export const delCookie = (key) => {
          document.cookie = `${encodeURIComponent(key)}=;expires=${new Date()}`
          };
          復(fù)制代碼

          7. 格式校驗

          (1)校驗身份證號碼

          export const checkCardNo = (value) => {
          let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
          return reg.test(value);
          };
          復(fù)制代碼

          (2)校驗是否包含中文

          export const haveCNChars => (value) => {
          return /[\u4e00-\u9fa5]/.test(value);
          }
          復(fù)制代碼

          (3)校驗是否為中國大陸的郵政編碼

          export const isPostCode = (value) => {
          return /^[1-9][0-9]{5}$/.test(value.toString());
          }
          復(fù)制代碼

          (4)校驗是否為IPv6地址

          export const isIPv6 = (str) => {
          return Boolean(str.match(/:/g)?str.match(/:/g).length<=7:false && /::/.test(str)?/^([\da-f]{1,4}(:|::)){1,6}[\da-f]{1,4}$/i.test(str):/^([\da-f]{1,4}:){7}[\da-f]{1,4}$/i.test(str));
          }
          復(fù)制代碼

          (5)校驗是否為郵箱地址

          export const isEmail = (value) {
          return /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(value);
          }
          復(fù)制代碼

          (6)校驗是否為中國大陸手機(jī)號

          export const isTel = (value) => {
          return /^1[3,4,5,6,7,8,9][0-9]{9}$/.test(value.toString());
          }
          復(fù)制代碼

          (7)校驗是否包含emoji表情

          export const isEmojiCharacter = (value) => {
          value = String(value);
          for (let i = 0; i < value.length; i++) {
          const hs = value.charCodeAt(i);
          if (0xd800 <= hs && hs <= 0xdbff) {
          if (value.length > 1) {
          const ls = value.charCodeAt(i + 1);
          const uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
          if (0x1d000 <= uc && uc <= 0x1f77f) {
          return true;
          }
          }
          } else if (value.length > 1) {
          const ls = value.charCodeAt(i + 1);
          if (ls == 0x20e3) {
          return true;
          }
          } else {
          if (0x2100 <= hs && hs <= 0x27ff) {
          return true;
          } else if (0x2B05 <= hs && hs <= 0x2b07) {
          return true;
          } else if (0x2934 <= hs && hs <= 0x2935) {
          return true;
          } else if (0x3297 <= hs && hs <= 0x3299) {
          return true;
          } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030
          || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b
          || hs == 0x2b50) {
          return true;
          }
          }
          }
          return false;
          }
          復(fù)制代碼

          8. 操作URL

          (1)獲取URL參數(shù)列表

          export const GetRequest = () => {
          let url = location.search;
          const paramsStr = /.+\?(.+)$/.exec(url)[1]; // 將 ? 后面的字符串取出來
          const paramsArr = paramsStr.split('&'); // 將字符串以 & 分割后存到數(shù)組中
          let paramsObj = {};
          // 將 params 存到對象中
          paramsArr.forEach(param => {
          if (/=/.test(param)) { // 處理有 value 的參數(shù)
          let [key, val] = param.split('='); // 分割 key 和 value
          val = decodeURIComponent(val); // 解碼
          val = /^\d+$/.test(val) ? parseFloat(val) : val; // 判斷是否轉(zhuǎn)為數(shù)字
          if (paramsObj.hasOwnProperty(key)) { // 如果對象有 key,則添加一個值
          paramsObj[key] = [].concat(paramsObj[key], val);
          } else { // 如果對象沒有這個 key,創(chuàng)建 key 并設(shè)置值
          paramsObj[key] = val;
          }
          } else { // 處理沒有 value 的參數(shù)
          paramsObj[param] = true;
          }
          })
          return paramsObj;
          };
          復(fù)制代碼

          (2)檢測URL是否有效

          export const getUrlState = (URL) => {
          let xmlhttp = new ActiveXObject("microsoft.xmlhttp");
          xmlhttp.Open("GET", URL, false);
          try {
          xmlhttp.Send();
          } catch (e) {
          } finally {
          let result = xmlhttp.responseText;
          if (result) {
          if (xmlhttp.Status == 200) {
          return true;
          } else {
          return false;
          }
          } else {
          return false;
          }
          }
          }
          復(fù)制代碼

          (3)鍵值對拼接成URL參數(shù)

          export const params2Url = (obj) => {
          let params = []
          for (let key in obj) {
          params.push(`${key}=${obj[key]}`);
          }
          return encodeURIComponent(params.join('&'))
          }
          復(fù)制代碼

          (4)修改URL中的參數(shù)

          export const replaceParamVal => (paramName, replaceWith) {
          const oUrl = location.href.toString();
          const re = eval('/('+ paramName+'=)([^&]*)/gi');
          location.href = oUrl.replace(re,paramName+'='+replaceWith);
          return location.href;
          }
          復(fù)制代碼

          (5)刪除URL中指定參數(shù)

          export const funcUrlDel = (name) => {
          const baseUrl = location.origin + location.pathname + "?";
          const query = location.search.substr(1);
          if (query.indexOf(name) > -1) {
          const obj = {};
          const arr = query.split("&");
          for (let i = 0; i < arr.length; i++) {
          arr[i] = arr[i].split("=");
          obj[arr[i][0]] = arr[i][1];
          }
          delete obj[name];
          return baseUrl + JSON.stringify(obj).replace(/[\"\{\}]/g,"").replace(/\:/g,"=").replace(/\,/g,"&");
          }
          }
          復(fù)制代碼

          9. 設(shè)備判斷

          (1)判斷是移動還是PC設(shè)備

          export const isMobile = () => {
          if ((navigator.userAgent.match(/(iPhone|iPod|Android|ios|iOS|iPad|Backerry|WebOS|Symbian|Windows Phone|Phone)/i))) {
          return 'mobile';
          }
          return 'desktop';
          }
          復(fù)制代碼

          (2)判斷是否是蘋果還是安卓移動設(shè)備

          export const isAppleMobileDevice = () => {
          let reg = /iphone|ipod|ipad|Macintosh/i;
          return reg.test(navigator.userAgent.toLowerCase());
          }
          復(fù)制代碼

          (3)判斷是否是安卓移動設(shè)備

          export const isAndroidMobileDevice = () => {
          return /android/i.test(navigator.userAgent.toLowerCase());
          }
          復(fù)制代碼

          (4)判斷是Windows還是Mac系統(tǒng)

          export const osType = () => {
          const agent = navigator.userAgent.toLowerCase();
          const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
          const isWindows = agent.indexOf("win64") >= 0 || agent.indexOf("wow64") >= 0 || agent.indexOf("win32") >= 0 || agent.indexOf("wow32") >= 0;
          if (isWindows) {
          return "windows";
          }
          if(isMac){
          return "mac";
          }
          }
          復(fù)制代碼

          (5)判斷是否是微信/QQ內(nèi)置瀏覽器

          export const broswer = () => {
          const ua = navigator.userAgent.toLowerCase();
          if (ua.match(/MicroMessenger/i) == "micromessenger") {
          return "weixin";
          } else if (ua.match(/QQ/i) == "qq") {
          return "QQ";
          }
          return false;
          }
          復(fù)制代碼

          (6)瀏覽器型號和版本

          export const getExplorerInfo = () => {
          let t = navigator.userAgent.toLowerCase();
          return 0 <= t.indexOf("msie") ? { //ie < 11
          type: "IE",
          version: Number(t.match(/msie ([\d]+)/)[1])
          } : !!t.match(/trident\/.+?rv:(([\d.]+))/) ? { // ie 11
          type: "IE",
          version: 11
          } : 0 <= t.indexOf("edge") ? {
          type: "Edge",
          version: Number(t.match(/edge\/([\d]+)/)[1])
          } : 0 <= t.indexOf("firefox") ? {
          type: "Firefox",
          version: Number(t.match(/firefox\/([\d]+)/)[1])
          } : 0 <= t.indexOf("chrome") ? {
          type: "Chrome",
          version: Number(t.match(/chrome\/([\d]+)/)[1])
          } : 0 <= t.indexOf("opera") ? {
          type: "Opera",
          version: Number(t.match(/opera.([\d]+)/)[1])
          } : 0 <= t.indexOf("Safari") ? {
          type: "Safari",
          version: Number(t.match(/version\/([\d]+)/)[1])
          } : {
          type: t,
          version: -1
          }
          }
          復(fù)制代碼

          10. 瀏覽器操作

          (1)滾動到頁面頂部

          export const scrollToTop = () => {
          const height = document.documentElement.scrollTop || document.body.scrollTop;
          if (height > 0) {
          window.requestAnimationFrame(scrollToTop);
          window.scrollTo(0, height - height / 8);
          }
          }
          復(fù)制代碼

          (2)滾動到頁面底部

          export const scrollToBottom = () => {
          window.scrollTo(0, document.documentElement.clientHeight);
          }
          復(fù)制代碼

          (3)滾動到指定元素區(qū)域

          export const smoothScroll = (element) => {
          document.querySelector(element).scrollIntoView({
          behavior: 'smooth'
          });
          };
          復(fù)制代碼

          (4)獲取可視窗口高度

          export const getClientHeight = () => {
          let clientHeight = 0;
          if (document.body.clientHeight && document.documentElement.clientHeight) {
          clientHeight = (document.body.clientHeight < document.documentElement.clientHeight) ? document.body.clientHeight : document.documentElement.clientHeight;
          }
          else {
          clientHeight = (document.body.clientHeight > document.documentElement.clientHeight) ? document.body.clientHeight : document.documentElement.clientHeight;
          }
          return clientHeight;
          }
          復(fù)制代碼

          (5)獲取可視窗口寬度

          export const getPageViewWidth = () => {
          return (document.compatMode == "BackCompat" ? document.body : document.documentElement).clientWidth;
          }
          復(fù)制代碼

          (6)打開瀏覽器全屏

          export const toFullScreen = () => {
          let element = document.body;
          if (element.requestFullscreen) {
          element.requestFullscreen()
          } else if (element.mozRequestFullScreen) {
          element.mozRequestFullScreen()
          } else if (element.msRequestFullscreen) {
          element.msRequestFullscreen()
          } else if (element.webkitRequestFullscreen) {
          element.webkitRequestFullScreen()
          }
          }
          復(fù)制代碼

          (7)退出瀏覽器全屏

          export const exitFullscreen = () => {
          if (document.exitFullscreen) {
          document.exitFullscreen()
          } else if (document.msExitFullscreen) {
          document.msExitFullscreen()
          } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen()
          } else if (document.webkitExitFullscreen) {
          document.webkitExitFullscreen()
          }
          }
          復(fù)制代碼

          11. 時間操作

          (1)當(dāng)前時間

          export const nowTime = () => {
          const now = new Date();
          const year = now.getFullYear();
          const month = now.getMonth();
          const date = now.getDate() >= 10 ? now.getDate() : ('0' + now.getDate());
          const hour = now.getHours() >= 10 ? now.getHours() : ('0' + now.getHours());
          const miu = now.getMinutes() >= 10 ? now.getMinutes() : ('0' + now.getMinutes());
          const sec = now.getSeconds() >= 10 ? now.getSeconds() : ('0' + now.getSeconds());
          return +year + "年" + (month + 1) + "月" + date + "日 " + hour + ":" + miu + ":" + sec;
          }
          復(fù)制代碼

          (2)格式化時間

          export const dateFormater = (formater, time) => {
          let date = time ? new Date(time) : new Date(),
          Y = date.getFullYear() + '',
          M = date.getMonth() + 1,
          D = date.getDate(),
          H = date.getHours(),
          m = date.getMinutes(),
          s = date.getSeconds();
          return formater.replace(/YYYY|yyyy/g, Y)
          .replace(/YY|yy/g, Y.substr(2, 2))
          .replace(/MM/g,(M<10 ? '0' : '') + M)
          .replace(/DD/g,(D<10 ? '0' : '') + D)
          .replace(/HH|hh/g,(H<10 ? '0' : '') + H)
          .replace(/mm/g,(m<10 ? '0' : '') + m)
          .replace(/ss/g,(s<10 ? '0' : '') + s)
          }
          // dateFormater('YYYY-MM-DD HH:mm:ss')
          // dateFormater('YYYYMMDDHHmmss')
          復(fù)制代碼

          12. JavaScript操作

          (1)阻止冒泡事件

          export const stopPropagation = (e) => { 
          e = e || window.event;
          if(e.stopPropagation) { // W3C阻止冒泡方法
          e.stopPropagation();
          } else {
          e.cancelBubble = true; // IE阻止冒泡方法
          }
          }
          復(fù)制代碼

          (2)防抖函數(shù)

          export const debounce = (fn, wait) => {
          let timer = null;

          return function() {
          let context = this,
          args = arguments;

          if (timer) {
          clearTimeout(timer);
          timer = null;
          }

          timer = setTimeout(() => {
          fn.apply(context, args);
          }, wait);
          };
          }
          復(fù)制代碼

          (3)節(jié)流函數(shù)

          export const throttle = (fn, delay) => {
          let curTime = Date.now();

          return function() {
          let context = this,
          args = arguments,
          nowTime = Date.now();

          if (nowTime - curTime >= delay) {
          curTime = Date.now();
          return fn.apply(context, args);
          }
          };
          }
          復(fù)制代碼

          (4)數(shù)據(jù)類型判斷

          export const getType = (value) => {
          if (value === null) {
          return value + "";
          }
          // 判斷數(shù)據(jù)是引用類型的情況
          if (typeof value === "object") {
          let valueClass = Object.prototype.toString.call(value),
          type = valueClass.split(" ")[1].split("");
          type.pop();
          return type.join("").toLowerCase();
          } else {
          // 判斷數(shù)據(jù)是基本數(shù)據(jù)類型的情況和函數(shù)的情況
          return typeof value;
          }
          }
          復(fù)制代碼

          (5)對象深拷貝

          export const deepClone = (obj, hash = new WeakMap() => {
          // 日期對象直接返回一個新的日期對象
          if (obj instanceof Date){
          return new Date(obj);
          }
          //正則對象直接返回一個新的正則對象
          if (obj instanceof RegExp){
          return new RegExp(obj);
          }
          //如果循環(huán)引用,就用 weakMap 來解決
          if (hash.has(obj)){
          return hash.get(obj);
          }
          // 獲取對象所有自身屬性的描述
          let allDesc = Object.getOwnPropertyDescriptors(obj);
          // 遍歷傳入?yún)?shù)所有鍵的特性
          let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)

          hash.set(obj, cloneObj)
          for (let key of Reflect.ownKeys(obj)) {
          if(typeof obj[key] === 'object' && obj[key] !== null){
          cloneObj[key] = deepClone(obj[key], hash);
          } else {
          cloneObj[key] = obj[key];
          }
          }
          return cloneObj
          }
          復(fù)制代碼


          瀏覽 56
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  台湾成人中文网 | 亚洲色播中文字幕 | 曰韩欧美综合黄色 | 婷婷色五月在线 | 国产极品久久久久久久久久 |