首先在寫代碼之前我們需要理清如何穿插圖片呢?
可以讓所有圖片都float:left,用一個(gè)大盒子裝進(jìn)所有圖片,在用一個(gè)小盒子顯示圖片,溢出圖片就hidden,之后以每張圖片的寬度來scrollLeft.
可以給每張圖片一個(gè)name/id,用循環(huán)遍歷所有圖片
可以用float:left,但是除了我要顯示的圖片外,其他圖片都hidden,之后每當(dāng)我需要某張圖片時(shí),我就把它制定到某位置
…
在這里,我將用第二種方法,因?yàn)樗苤庇^明了,我要哪張圖片我就調(diào)哪張圖片。
HTML部分:在div里面我裝了一張圖片,name:0, 這是為了在剛打開的時(shí)候,我們的頁面是有東西的而不是一片空白。其他部分都好理解,不理解的可在下方評(píng)論。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>輪播圖</title> <link rel="stylesheet" href="輪播圖.css" /> <script src="輪播圖.js"> </script> </head> <body> <header> <div id="oImg"> <!-- 輪流播放圖片 --> <img id="insert" src="img/輪1.jpg" name="0"/> </div> <!-- 左右切換圖片 --> <p id="left" οnclick="goBack()"></p> <p id="right" οnclick="goForward()"></p> <ul id="nav"> <!-- 指定某張圖片 --> <li id="1" οnclick="move(this)">1</li> <li id="2" οnclick="move(this)">2</li> <li id="3" οnclick="move(this)">3</li> <li id="4" οnclick="move(this)">4</li> <li id="5" οnclick="move(this)">5</li> </ul> </header> </body> </html>
CSS:
* { margin: 0 auto; padding: 0 auto; } header { width: 100%; height: 680px; position: relative; } img { width: 100%; height: 680px; } #nav { position: absolute; bottom: 5px; left: 30%; } #nav li { width: 30px; height: 30px; line-height: 30px; text-align: center; background: #ccc; font-size: 24px; border-radius: 9px; color: darkslategrey; font-family: 'Times New Roman', Times, serif; margin: 0 25px; float: left; cursor: pointer; list-style: none; } #nav li:hover { background: peru; } #left { width: 25px; height: 24px; left: 0; top: 50%; cursor: pointer; position: absolute; background: url(img/fx1.png); } #right { width: 25px; height: 24px; right: 0; top: 50%; cursor: pointer; position: absolute; background: url(img/fx2.png); }之后我們來看重中之重JS部分
JavaScript:
// 五張圖片的url var oImg1 = "img/輪1.jpg"; var oImg2 = "img/輪2.jpg"; var oImg3 = "img/輪3.jpg"; var oImg4 = "img/輪4.jpg"; var oImg5 = "img/輪5.jpg"; // 把5張圖片存入一個(gè)數(shù)組 var arr = [oImg1, oImg2, oImg3, oImg4, oImg5]; window.onload = function() { //剛加載時(shí)第一張圖片1號(hào)背景顏色 document.getElementById("1").style.background = "peru"; run() } //輪播 function run() { timer = setInterval(function() { //隨機(jī)點(diǎn)數(shù)字時(shí)能接著變化 var pic = document.getElementById("insert").name; var shade = document.getElementById("insert"); //如果為最后一張圖片則重新循環(huán) if (pic == 4) { pic = -1; } //點(diǎn)一個(gè)數(shù)字該數(shù)字背景顏色變化其余的不變 var aLi = document.getElementsByTagName("li"); for (var j = 0; j < aLi.length; j++) { aLi[j].style.backgroundColor = "#CCCCCC"; } var i = parseInt(pic); document.getElementById("insert").src = arr[i + 1]; document.getElementById("insert").name = i + 1; //數(shù)字隨圖片變化 switch (i) { case 0: var temp = '2'; break; case 1: var temp = '3'; break; case 2: var temp = '4'; break; case 3: var temp = '5'; break; case -1: var temp = '1'; break; } document.getElementById(temp).style.background = "peru" }, 5000) } //右箭頭 function goForward() { var temp = document.getElementById("insert").name; var oBox = document.getElementById("insert"); var aLi = document.getElementsByTagName("li"); // 數(shù)字跟著圖片一起變 for (var i = 0; i < aLi.length; i++) { aLi[i].style.backgroundColor = "#CCCCCC"; } switch (temp) { case "0": var n = '2'; break; case "1": var n = '3'; break; case "2": var n = '4'; break; case "3": var n = '5'; break; case "4": var n = '1'; break; } document.getElementById(n).style.background = "peru" // 向右移動(dòng)圖片 for (var j = 0; j < arr.length; j++) { if (j < 4) { if (temp == j) { oBox.src = arr[j + 1]; } } else { if (temp == 4) { oBox.src = arr[0]; } } } // 輪到最后一張圖片時(shí)返回第一張 if (temp < 4) { oBox.name = parseInt(temp) + 1; } else { oBox.name = 0; } } //左箭頭 function goBack() { var temp = document.getElementById("insert").name; var oBox = document.getElementById("insert") var aLi = document.getElementsByTagName("li"); // 圖片移動(dòng)時(shí)數(shù)字也跟著變 for (var i = 0; i < aLi.length; i++) { aLi[i].style.backgroundColor = "#CCCCCC"; } switch (temp) { case "0": var n = '5'; break; case "1": var n = '1'; break; case "2": var n = '2'; break; case "3": var n = '3'; break; case "4": var n = '4'; break; } document.getElementById(n).style.background = "peru" // 向左移動(dòng)圖片 for (var j = 0; j < arr.length; j++) { if (j > 0) { if (temp == j) { oBox.src = arr[j - 1]; } } else { if (temp == 0) { oBox.src = arr[4]; } } } // 輪到第一張圖片時(shí)返回最后一張 if (temp > 0) { oBox.name = parseInt(temp) - 1; } else { oBox.name = 4; } } //指定圖片 function move(num) { var oBox = document.getElementById("insert"); var temp = document.getElementById("insert").name; var aLi = document.getElementsByTagName("li"); for (var i = 0; i < aLi.length; i++) { aLi[i].style.backgroundColor = "#CCCCCC"; } document.getElementById(num.innerHTML).style.background = "peru" switch (num.innerHTML) { case "1": oBox.src = arr[0]; oBox.name = 0; break; case "2": oBox.src = arr[1]; oBox.name = 1; break; case "3": oBox.src = arr[2]; oBox.name = 2; break; case "4": oBox.src = arr[3]; oBox.name = 3; break; case "5": oBox.src = arr[4]; oBox.name = 4; break; } }JavaScript部分我寫的很詳細(xì),仔細(xì)看的話是可以看懂的,主要分3個(gè)重要部分:
用src來調(diào)用每張圖片并給每張圖片一個(gè)name,這樣方便后面的重復(fù)使用
為下方的數(shù)字按鈕匹配圖片,點(diǎn)擊1跳到第1張圖片,點(diǎn)擊2跳到第2張圖片…因?yàn)槲野阉械膱D片都存在了一個(gè)數(shù)組里,所以在匹配的時(shí)候要注意數(shù)組0位置才是數(shù)字1指定的圖片
可以來回翻頁,當(dāng)?shù)竭_(dá)最后一張圖片時(shí),我再點(diǎn)擊下一張圖片又能返回到第一張圖片了,亦或者當(dāng)我點(diǎn)擊到第一張圖片時(shí),再上一張圖片又回到第五張圖片了
效果如下:
大家有問題可以在下方評(píng)論哦,看到了會(huì)及時(shí)回復(fù)噠!
————————————————
版權(quán)聲明:本文為CSDN博主「weixin_43964414」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_43964414/article/details/104844041
CSS介紹
整理完了HTML的筆記,接下來就是CSS了。我們可以使用HTML構(gòu)建穩(wěn)定的結(jié)構(gòu)基礎(chǔ),而頁面的風(fēng)格樣式控制則交給CSS來完成。網(wǎng)頁的樣式包括各種元素的顏色、大小、線形、間距等等,這對(duì)于設(shè)計(jì)或維護(hù)一個(gè)數(shù)據(jù)較多的網(wǎng)站來說,工作量是巨大的。好在可以使用CSS來控制這些樣式,這將大大提高網(wǎng)頁設(shè)計(jì)和維護(hù)的效率,并且使網(wǎng)頁的整體風(fēng)格很容易做到統(tǒng)一。
CSS概述
CSS是英文Cascading Style Sheet的縮寫,中文譯為層疊樣式表,也有人翻譯為級(jí)聯(lián)樣式表,簡稱樣式表。它是一種用來定義網(wǎng)頁外觀樣式的技術(shù),在網(wǎng)頁中引入CSS規(guī)則,可以快捷地對(duì)頁面進(jìn)行布局設(shè)計(jì),可以的控制HTML標(biāo)記對(duì)象的寬度、高度、位置、字體、背景等外觀效果。
CSS是一種標(biāo)識(shí)性語言,不僅可以有效的控制網(wǎng)頁的樣式,更重要的是實(shí)現(xiàn)了網(wǎng)頁內(nèi)容與樣式的分離,并允許將CSS規(guī)則單獨(dú)存放于一個(gè)文檔中, CSS文件的擴(kuò)展名為“css”。
CSS3
CSS3標(biāo)準(zhǔn)早在1995年就開始制訂, 2001年提上W3C研究議程,但是,10年來CSS3可以說是基本上沒有什么很大的變化,一直到2011年6月才發(fā)布了全新版本的CSS3,目前,許多瀏覽器都廣泛支持CSS3。
CSS3是CSS技術(shù)的一個(gè)升級(jí)版本,CSS3語言將CSS劃分為更小的模塊,在朝著模塊化的方向發(fā)展。以前的版本是一個(gè)比較龐大而且比較復(fù)雜模塊,所以,把它分解成為一個(gè)個(gè)小的簡單的模塊,同時(shí)也加入了更多新的模塊。在CSS3中有字體、顏色、布局、背景、定位、邊框、多列、動(dòng)畫、用戶界面等等多個(gè)模塊。
CSS的基本用法
CSS的使用規(guī)則由兩部分組成:選擇器和一條或多條聲明。其基本基本語法如下:
選擇器{ 屬性1: 值; 屬性2: 值; …
屬性n: 值; }
CSS的使用規(guī)則由兩部分組成:選擇器和一條或多條聲明。其基本基本語法如下:
選擇器{ 屬性1: 值; 屬性2: 值; …
屬性n: 值; }
CSS屬性
CSS的屬性按照相關(guān)功能進(jìn)行了分組,包含了字體、文本、背景、列表、動(dòng)畫等多個(gè)分組,這些屬性的具體使用方法和示例將會(huì)在后續(xù)中提到。
在HTML文檔中使用CSS的方法
根據(jù)CSS在HTML文檔中的使用方法和作用范圍不同,CSS樣式表的使用方法分為三大類:行內(nèi)樣式、內(nèi)部樣式表和外部樣式表,而外部樣式表又可分為鏈入外部樣式表和導(dǎo)入外部樣式表。本節(jié)我們從四個(gè)分類來認(rèn)識(shí)在HTML中使用CSS的方法。
行內(nèi)樣式
內(nèi)部樣式表
外部樣式表
鏈入外部樣式表
導(dǎo)入外部樣式表
行內(nèi)樣式
行內(nèi)樣式(inline style),也叫內(nèi)聯(lián)樣式,它是CSS四種使用方法中最為直接的一種,它的實(shí)現(xiàn)借用HTML元素的全局屬性style,把CSS代碼直接寫入其中即可。
嚴(yán)格意義上行內(nèi)樣式是一種不嚴(yán)謹(jǐn)?shù)氖褂梅绞?,它不需要選擇器,這種方式下CSS代碼和HTML代碼混合在一起,因此不推薦使用行內(nèi)樣式。行內(nèi)樣式的基本語法如下:
<標(biāo)記 style="屬性:值; 屬性:值; …">
當(dāng)單個(gè)文檔需要特殊的樣式時(shí),應(yīng)該使用內(nèi)部樣式表。內(nèi)部樣式表是將樣式放在頁面的head區(qū)里,這樣定義的樣式就應(yīng)用到本頁面中了,內(nèi)部樣式表使用style標(biāo)記進(jìn)行聲明,是較為常用的一種使用方法。其基本語法如下:
<head> <meta charset="utf-8" /> <title></title> <style type="text/css"> 選擇器1{屬性:值;…} 選擇器2{屬性:值;…} …… 選擇器n{屬性:值;…} </style> </head>
<head> <meta charset="utf-8" /> <title></title> <link href="樣式表路徑" rel="stylesheet" type="text/css" /> </head>其中:
<head> <meta charset="utf-8" /> <title></title> <style type="text/css"> @import url("樣式表路徑"); </style> </head>其中:
<head> <meta charset="utf-8" /> <title></title> <style type="text/css"> @import url("樣式表路徑"); </style> </head>
記錄倉促,遺漏之處日后補(bǔ)充,如有錯(cuò)誤或不足之處,還望指正
————————————————
版權(quán)聲明:本文為CSDN博主「狗狗狗狗狗樂啊」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_44122062/article/details/104848745
文章目錄
前言
一、白屏?xí)r間過長分析
二、針對(duì)性優(yōu)化
針對(duì)animate.css
針對(duì)mint-ui的優(yōu)化
針對(duì)圖片的優(yōu)化
三、webpack打包優(yōu)化與分析
webpack-bundle-analyzer打包分析
打包優(yōu)化
四、優(yōu)化后線上測試速度提升
五、優(yōu)化總結(jié)
前言
最近在做項(xiàng)目時(shí),測試提出了在App端的H5項(xiàng)目入口加載時(shí)間過長,白屏等待過久,需要優(yōu)化的問題,于是著手開始分析:
項(xiàng)目技術(shù)棧:基于Vue全家桶做的一個(gè)移動(dòng)端類似WebApp的項(xiàng)目,使用到的第三方庫有:mint-ui, echarts,momentjs。
項(xiàng)目痛點(diǎn):白屏?xí)r間過長
一、白屏?xí)r間過長分析
通過訪問線上環(huán)境,結(jié)合Chrome devtool中Network和Performance功能可以具體分析整個(gè)白屏的耗時(shí)主要在哪一塊兒
Network耗時(shí)記錄:
Performance性能面板
通過上面兩張圖分析,從瀏覽器發(fā)起請求到解析HTML完成這一過程中:
animate.css, mini-ui.css的請求耗時(shí)最長。
圖片過大耗時(shí)。
二、針對(duì)性優(yōu)化
針對(duì)animate.css
animate.css由于使用的是第三方CDN(國外服務(wù)器)所有請求時(shí)間相對(duì)較長,所以如果必須要用animate.css那么可以下載下來作為本地資源,也可以使用國內(nèi)CDN,或者不用animate.css,而是針對(duì)使用到的幾個(gè)CSS動(dòng)畫,直接自己造輪子
針對(duì)mint-ui的優(yōu)化
由于mint-ui在原項(xiàng)目中使用的是全局引用的方式,這才導(dǎo)致打包資源過大,css單獨(dú)請求耗時(shí)過長的問題,所以主要解決方案是按需引入mint-ui,借助 babel-plugin-component,我們可以只引入需要的組件,以達(dá)到減小項(xiàng)目體積的目的。
安裝babel-plugin-component, 若已安裝可忽略
修改 .babelrc (重點(diǎn)在plugins中):
{ "presets": [ ["env", { "modules": false }], "stage-2" ], "plugins": ["transform-runtime",["component", [ { "libraryName": "mint-ui", "style": true } ]]], "comments": false, "env": { "test": { "presets": ["env", "stage-2"], "plugins": [ "istanbul" ] } } }
在main.js中引用使用到的插件
import Vue from 'vue' import { Button, Cell } from 'mint-ui' import 'mint-ui/lib/style.min.css' // 引用CSS import App from './App.vue' Vue.component(Button.name, Button) Vue.component(Cell.name, Cell) /* 或?qū)憺? * Vue.use(Button) * Vue.use(Cell) */ new Vue({ el: '#app', components: { App } })
在使用的組件中改為按需引用組件
import Vue from 'vue' var Popup = Vue.component('mt-popup') var Swipe = Vue.component('mt-swipe') var SwipeItem = Vue.component('mt-swipe-item') export default { name:'my-component', components:{ Popup, Swipe, SwipeItem } }
此按需引入方案也同樣適用于其他第三方UI組件庫
圖片小圖通過webpack可以直接轉(zhuǎn)為base64,而大圖可以通過壓縮或者換格式的方式來優(yōu)化,這里推薦一個(gè)好用的圖片壓縮工具,工具:tinyPNG,如下是圖片轉(zhuǎn)換前后對(duì)比
在完成了上述優(yōu)化以后,下面著重關(guān)注下webpack打包后生成的文件大小,看還有沒有可以優(yōu)化的余地。由于項(xiàng)目中已經(jīng)通過路由按需加載
的方式來做了功能拆分,所以通過webpack打包后生成了很多分散的js文件,如下圖:
通過上圖分析可以知道打包后有幾個(gè)文件相對(duì)較大,vendor.js都知道是第三方庫文件打包形成,之前通過mint-ui按需加載會(huì)有一定的變化,后面記錄。這里著重看另兩個(gè)帶hash的js文件,這里并看不出來它為什么這么大,所以這里需要用到webpack打包分析工具來做進(jìn)一步的打包文件分析:webpack-bundle-analyzer
它的作用如下圖,即在打包后生成打包文件大小分析圖,方便我們更加直觀的看到文件大小和引用情況
npm intall -D webpack-bundle-analyzer
webpack.pro.conf.js
. (這里由于只是用于生產(chǎn)打包分析且是通過vue-cli生成的項(xiàng)目框架)
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin module.exports = { // ... plugins:[ new BundleAnalyzerPlugin() ] }
運(yùn)行npm run build
,(webpack默認(rèn)會(huì)在打包完成時(shí)生成分析圖)
版權(quán)聲明:本文為CSDN博主「Sophie_U」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Sophie_U/article/details/104840167
數(shù)據(jù)類型的轉(zhuǎn)化(JavaScript)—自動(dòng)轉(zhuǎn)化和強(qiáng)制轉(zhuǎn)化
這一周,我來分享一下在JavaScript中的數(shù)據(jù)類型轉(zhuǎn)化。
首先我們要知道在JavaScript中的數(shù)據(jù)類型有什么?在這里我就不詳細(xì)介紹了,幫你總結(jié)好了。
1.布爾類型-----Boolean---isNaN()
用來判斷一個(gè)變量是否為非數(shù)字的類型,是數(shù)字返回false,不是數(shù)字返回true。
2.數(shù)值類型-----Number
存儲(chǔ)時(shí),是按照二進(jìn)制數(shù)值存儲(chǔ),輸出時(shí),默認(rèn)都是按照十進(jìn)制數(shù)值輸出。
在JavaScript中二進(jìn)制前加0b/0B,八進(jìn)制前面加0 ,十六進(jìn)制前面加0x。
如果需要按照原始進(jìn)制數(shù)值輸出,用格式為:
變量名稱.toString(進(jìn)制) ;
注意的是:S必須大寫,將數(shù)值轉(zhuǎn)化為字符串形式輸出
如:console.log( a.toString(2) );將a轉(zhuǎn)換成2進(jìn)制的形式輸出。
3.字符串類型-----String
JavaScript可以用單引號(hào)嵌套雙引號(hào), 或者用雙引號(hào)嵌套單引號(hào)(外雙內(nèi)單,外單內(nèi)雙)
字符串是由若干字符組成的,這些字符的數(shù)量就是字符串的長度。
通過字符串的length屬性可以獲取整個(gè)字符串的長度。
例子:var str = 'my name is xiaoming';
console.log(str.length);
輸出的結(jié)果是19??梢灾揽崭褚泊硪粋€(gè)字符。
4.undefined
表示沒有數(shù)值-----應(yīng)該有數(shù)值,但是現(xiàn)在沒有數(shù)值
5.null
表示數(shù)值為空-----表示有數(shù)值,但是數(shù)值是“空”
上面就是數(shù)據(jù)類型的五種形式。那么它是如何轉(zhuǎn)化呢?聽我詳細(xì)給你講解。
在 JavaScript 程序中 , 變量中存儲(chǔ)的數(shù)據(jù)類型沒有限制,也就是在變量中可以存儲(chǔ)任何符合JavaScript語法規(guī)范的數(shù)據(jù)類型。但是在 JavaScript 程序的執(zhí)行過程中,往往需要變量中存儲(chǔ)的數(shù)值是某種特定的數(shù)據(jù)類型,別的數(shù)據(jù)類型不行,此時(shí)就需要進(jìn)行數(shù)據(jù)類型的轉(zhuǎn)化。
————————————————
版權(quán)聲明:本文為CSDN博主「什什么都繪」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_39406353/article/details/104864224上面就是數(shù)據(jù)類型的五種形式。那么它是如何轉(zhuǎn)化呢?聽我詳細(xì)給你講解。
在 JavaScript 程序中 , 變量中存儲(chǔ)的數(shù)據(jù)類型沒有限制,也就是在變量中可以存儲(chǔ)任何符合JavaScript語法規(guī)范的數(shù)據(jù)類型。但是在 JavaScript 程序的執(zhí)行過程中,往往需要變量中存儲(chǔ)的數(shù)值是某種特定的數(shù)據(jù)類型,別的數(shù)據(jù)類型不行,此時(shí)就需要進(jìn)行數(shù)據(jù)類型的轉(zhuǎn)化。
JavaScript中數(shù)據(jù)類型的轉(zhuǎn)化,分為自動(dòng)轉(zhuǎn)化和強(qiáng)制轉(zhuǎn)化:
自動(dòng)轉(zhuǎn)化是計(jì)算機(jī)程序,自動(dòng)完成的轉(zhuǎn)化。
強(qiáng)制轉(zhuǎn)化是程序員,強(qiáng)行完成的轉(zhuǎn)化
1.布爾類型的自動(dòng)轉(zhuǎn)化:
在 執(zhí)行 if 判斷時(shí) ,其他數(shù)據(jù)類型會(huì)自動(dòng)轉(zhuǎn)化為布爾類型
其他類型轉(zhuǎn)化為布爾類型的原則
0 '' undefined null NaN 這五種情況轉(zhuǎn)化為false
特別提醒 0.0 0.00000 都算是0
其他的所有都會(huì)轉(zhuǎn)化為 true
2.字符串的自動(dòng)轉(zhuǎn)化:
執(zhí)行字符串拼接, +號(hào)的兩側(cè),應(yīng)該都是字符串類型,會(huì)將其他數(shù)據(jù)類型轉(zhuǎn)化為字符串類型
轉(zhuǎn)化原則:
//基本數(shù)據(jù)類型 / 簡單數(shù)據(jù)類型------將數(shù)據(jù)數(shù)值直接轉(zhuǎn)化為字符串 , 然后執(zhí)行拼接操作
布爾值 true ---> 字符串 'true'
布爾值 false ---> 字符串 'fasle'
undefined ---> 字符串 'undefined'
unll ---> 字符串 'null'
數(shù)值 ---> 將數(shù)值解析轉(zhuǎn)化為'對(duì)應(yīng)的純數(shù)字的字符串'
// 引用數(shù)據(jù)類型 / 復(fù)雜數(shù)據(jù)類型
數(shù)組 ---> 將 [] 中的內(nèi)容,轉(zhuǎn)化為字符串的形式,執(zhí)行拼接操作
對(duì)象 ---> 任何對(duì)象,任何內(nèi)容,都會(huì)轉(zhuǎn)化為 [object Object] 固定的內(nèi)容形式,執(zhí)行拼接操作
函數(shù) ---> 將所有的程序代碼,轉(zhuǎn)化為字符串,執(zhí)行拼接操作
3.數(shù)值的自動(dòng)轉(zhuǎn)化:
在執(zhí)行運(yùn)算時(shí),會(huì)觸發(fā)數(shù)據(jù)類型的自動(dòng)轉(zhuǎn)化。
轉(zhuǎn)化原則:
布爾類型 : true ---> 1
false ---> 0
undefined : 轉(zhuǎn)化為 NaN
null : 轉(zhuǎn)化為 0
字符串 :
如果整個(gè)字符串,是純數(shù)字字符串,或者符合科學(xué)計(jì)數(shù)法 ---> 轉(zhuǎn)化為對(duì)應(yīng)的數(shù)值
如果字符串內(nèi)有不符合數(shù)字規(guī)范的內(nèi)容 ---> 轉(zhuǎn)化為 NaN
數(shù)組,對(duì)象,函數(shù):
如果是+加號(hào)執(zhí)行的是字符串拼接效果,按照這些數(shù)據(jù)類型轉(zhuǎn)化為字符串的原則來轉(zhuǎn)化
如果是其他形式的運(yùn)算 執(zhí)行結(jié)果都是 NaN
4.布爾類型的強(qiáng)制轉(zhuǎn)化:
布爾類型的強(qiáng)制轉(zhuǎn)化就是使用JavaScript中定義好的 方法/函數(shù) Boolean( 數(shù)據(jù)/變量 )
Boolean() 這個(gè)方法 不會(huì)改變 變量中存儲(chǔ)的原始數(shù)值
轉(zhuǎn)化原則與自動(dòng)轉(zhuǎn)化原則相同
0 '' undefined null NaN --------> false
其他數(shù)據(jù),都轉(zhuǎn)化為true
5.字符串類型的強(qiáng)制轉(zhuǎn)化:
方法1,變量.toString(進(jìn)制類型)
將數(shù)值強(qiáng)制轉(zhuǎn)化為字符串,并且可以設(shè)定轉(zhuǎn)化的進(jìn)制,.toString() 之前,不能直接寫數(shù)值,必須是寫成變量的形式
進(jìn)制常用的數(shù)值是 2 8 16 ,可以設(shè)定的范圍是 2 - 36 進(jìn)制
方法2,String( 變量 / 數(shù)據(jù) )
將變量或者數(shù)據(jù),轉(zhuǎn)化為字符串,原則按照自動(dòng)轉(zhuǎn)化的原則來執(zhí)行,不會(huì)改變變量中存儲(chǔ)的原始數(shù)值
但是在字符串拼接時(shí),會(huì)將其他數(shù)據(jù)類型自動(dòng)轉(zhuǎn)化為字符串
6.數(shù)字類型的強(qiáng)制轉(zhuǎn)化:
————————————————方法1 , Number(變量/數(shù)值)
console.log( Number(true) ); // 1
console.log( Number(false) ); // 0
console.log( Number(null) ); // 0
console.log( Number(undefined) ); // NaN
console.log( Number('100') ); // 對(duì)應(yīng)的數(shù)值
console.log( Number('100.123') ); // 對(duì)應(yīng)的數(shù)值
console.log( Number('2e4') ); // 對(duì)應(yīng)的數(shù)值
console.log( Number('123abc') ); // NaN
console.log( Number( [1,2,3,4,5] ) ); // NaN
console.log( Number( {name:'zhangsan'} ) ); // NaN
console.log( Number( function fun(){console.log('abc')} ) ); // NaN
將其他類型強(qiáng)制轉(zhuǎn)化為數(shù)值類型,轉(zhuǎn)化原則與自動(dòng)轉(zhuǎn)化選擇相同
方法2, parseInt(變量 / 數(shù)據(jù)) 是獲取變量或者數(shù)據(jù)的整數(shù)部分
從數(shù)據(jù)的 左側(cè)起 解析獲取 整數(shù)內(nèi)容
console.log( parseInt(true) ); // 都是 NaN
console.log( parseInt(false) );
console.log( parseInt(null) );
console.log( parseInt(undefined) );
console.log( parseInt( {name:'zhangsan'} ) );
console.log( parseInt( function fun(){console.log('abc')} ) );
數(shù)組執(zhí)行,是獲取 數(shù)值部分 也就是 沒有 []的部分
1,2,3,4,5 整數(shù)部分是 1 1之后是逗號(hào) 逗號(hào)不是整數(shù),之后的部分也就不算整數(shù)
獲取第一個(gè)數(shù)值的整數(shù)部分,如果有就獲取,如果沒有,結(jié)果是NaN
console.log( parseInt( [1,2,3,4,5] ) ); // 結(jié)果是 1
console.log( parseInt( [null,2,3,4,5] ) ); // 結(jié)果是 NaN
如果是整數(shù)就直接獲取,如果是浮點(diǎn)數(shù),或者科學(xué)計(jì)數(shù)法,就獲取整數(shù)部分
console.log( parseInt( 100 ) ); // 整數(shù)是直接獲取
console.log( parseInt( 0.0123 ) ); // 浮點(diǎn)數(shù)是獲取整數(shù)部分
console.log( parseInt( 3.123456e3 ) ); // 科學(xué)計(jì)數(shù)法是解析之后,獲取整數(shù)部分
字符串不同了
如果是純數(shù)字的字符串
console.log( parseInt( '100' ) ); // 與數(shù)字的結(jié)果相同
console.log( parseInt( '0.0123' ) ); // 與數(shù)字的結(jié)果相同
console.log( parseInt( '3.123456e3' ) ); //3
console.log( parseInt( '3abc' ) ); //3
console.log( parseInt( '3.123' ) ); //3
方法3 , parseFloat( 變量 / 數(shù)值 )
獲取浮點(diǎn)數(shù)部分
console.log( parseFloat(true) ); // 都是 NaN
console.log( parseFloat(false) );
console.log( parseFloat(null) );
console.log( parseFloat(undefined) );
console.log( parseFloat( {name:'zhangsan'} ) );
console.log( parseFloat( function fun(){console.log('abc')} ) );
//數(shù)值, 整數(shù),浮點(diǎn)數(shù),都會(huì)完整獲取
console.log( parseFloat(100) ); //100
console.log( parseFloat(100.1234) ); //100.1234
console.log( parseFloat(1.234567e3) ); //1234.567
// 關(guān)鍵是字符串
// 從字符串的左側(cè)起 解析 符合浮點(diǎn)數(shù)的部分
console.log( parseFloat( '100' ) ); // 與數(shù)字的結(jié)果相同
console.log( parseFloat( '0.0123' ) ); // 與數(shù)字的結(jié)果相同
console.log( parseFloat( '3.123456e3' ) ); // 科學(xué)技術(shù)法會(huì)解析
console.log( parseFloat( '3.1223abc' ) );
console.log( parseFloat( '3.123' ) );
好了,這就是在JavaScript中數(shù)據(jù)類型的轉(zhuǎn)化,希望可以幫助到你。
版權(quán)聲明:本文為CSDN博主「什什么都繪」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_39406353/article/details/104864224
jQuery超詳細(xì)總結(jié)
文章目錄
jQuery超詳細(xì)總結(jié)
一 選擇器
特殊選擇器
二 篩選器
用在 jQuery 選擇的元素后面
都是方法,對(duì)選擇出來的元素進(jìn)行二次篩選
三 文本操作
總結(jié)
四 元素類名操作
五 元素屬性操作
在 H5 的標(biāo)準(zhǔn)下, 給了一個(gè)定義, 當(dāng)你需要寫自定義屬性的時(shí)候,最好寫成 data-xxx="值",當(dāng)大家看到 data-xxx 的時(shí)候, 就知道這是一個(gè)自定義屬性
六 元素樣式操作
七 綁定事件
on()
方法是專門用來綁定事件one()
方法是專門用來綁定一個(gè)只能執(zhí)行一次的方法off()
方法是專門用來解綁一個(gè)元素的事件的trigger()
方法是專門用來觸發(fā)事件的方法hover()
常用事件
offset()
position()
scrollTop()
scrollLeft()
ready()
事件each()
方法jQuery 發(fā)送一個(gè) GET 請求
jQuery 發(fā)送一個(gè) POST 請求
jQuery 的 $.ajax 方法
position()
postition: 定位
只讀的方法
讀取:
元素相對(duì)于定位父級(jí)的位置關(guān)系
得到的也是一個(gè)對(duì)象 { left: xxx, top: xxx }
如果你寫的是 right 或者 bottom, 會(huì)自動(dòng)計(jì)算成 left 和 top 值給你
十一 獲取卷去的尺寸(頁面滾動(dòng)條)
scrollTop()
原生 js 里面 document.documentElement.scrollTop
讀寫的方法
不傳遞參數(shù)的時(shí)候就是獲取卷去的高度
傳遞一個(gè)參數(shù)就是設(shè)置卷去的高度
scrollLeft()
原生 js 里面 document.documentElement.scrollLeft
讀寫的方法
不傳遞參數(shù)的時(shí)候就是獲取卷去的寬度
傳遞一個(gè)參數(shù)的時(shí)候就是設(shè)置卷去的寬度
十二 jQuery中的函數(shù)
ready() 事件
類似于 window.onload 事件,但是有所不同
window.onload 會(huì)在頁面所有資源加載行
ready() 會(huì)在頁面 html 結(jié)構(gòu)加載完畢后執(zhí)行
也叫做 jQuery 的入口函數(shù)
有一個(gè)簡寫的形式 $(function () {})
each() 方法
類似于 forEach(), 遍歷數(shù)組的
jQuery 的元素集合, 是一個(gè) jQuery 數(shù)組, 不是一個(gè)數(shù)組, 不能使用 forEach()
forEach語法: forEach(function (item, index) {})
each語法:each(function (index, item) {})
比較少用到, 因?yàn)?jQuery 隱式迭代 自動(dòng)遍歷
十三 jQuery中的動(dòng)畫
讓元素出現(xiàn)不同的移動(dòng), 改變
transition -> 過渡動(dòng)畫
animation -> 幀動(dòng)畫
標(biāo)準(zhǔn)動(dòng)畫
show() 顯示元素
語法: show(時(shí)間, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
hide() 隱藏元素
語法: hide(時(shí)間, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
toggle() 改變元素顯示或隱藏(如果顯示就隱藏,如果隱藏就顯示)
語法: toggle(時(shí)間, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
三個(gè)方法的參數(shù)都可以選填,不需要每個(gè)都填寫
折疊動(dòng)畫
slideDown() 下滑顯示
語法: slideDown(時(shí)間, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
slideUp() 上滑隱藏
語法: slideUp(時(shí)間, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
slideToggle() 切換滑動(dòng)和隱藏
語法: slideToggle(時(shí)間, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
漸隱漸顯動(dòng)畫
實(shí)質(zhì)是透明的opacity的變化
fadeIn() 逐漸顯示
fadeIn(時(shí)間, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
fadeOut() 逐漸消失
fadeOut(時(shí)間, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
fadeToggle() 切換顯示和消失
fadeToggle(時(shí)間, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
以上三個(gè)方法的參數(shù),均有默認(rèn)值
fadeTo() 設(shè)置元素透明度變?yōu)槟阒付ǖ臄?shù)字
fadeTo(時(shí)間, 你指定的透明度, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
綜合動(dòng)畫
animate()
基本上大部分的 css 樣式都可以動(dòng)畫
transform 不行, 顏色不行
語法: animate({}, 時(shí)間, 運(yùn)動(dòng)曲線, 運(yùn)動(dòng)結(jié)束的函數(shù))
{ }里面就寫你要運(yùn)動(dòng)的 css 屬性,默認(rèn)單位為px
停止動(dòng)畫
讓當(dāng)前的動(dòng)畫結(jié)束
因?yàn)?jQuery 的動(dòng)畫你一直點(diǎn)擊,就會(huì)一直觸發(fā)。即使不再點(diǎn)擊讓事件發(fā)生,還是會(huì)把沒執(zhí)行完的動(dòng)畫執(zhí)行完畢。
你點(diǎn)擊 10 次, 他就會(huì)觸發(fā) 10 次, 直到 10 次全都完畢才結(jié)束
stop()
當(dāng)這個(gè)函數(shù)觸發(fā)的時(shí)候, 就會(huì)讓運(yùn)動(dòng)立刻停下來
你運(yùn)動(dòng)到哪一個(gè)位置了就停止在哪一個(gè)位置
finish()
當(dāng)這個(gè)函數(shù)觸發(fā)的時(shí)候, 就會(huì)讓運(yùn)動(dòng)立刻停下來
不管你運(yùn)動(dòng)到了哪一個(gè)位置, 瞬間到達(dá)運(yùn)動(dòng)完成位置
十四 jQuery發(fā)送ajax請求
jQuery 里面幫我們封裝好了幾個(gè)方法
專門用來發(fā)送 ajax 請求的
$.get() -> 專門用來發(fā)送 get 請求的
$.post() -> 專門用來發(fā)送 post 請求的
$.ajax() ->
發(fā)送什么請求都可以(get, post, put, delete)
并且還可以發(fā)送一個(gè) jsonp 請求
jQuery 發(fā)送一個(gè) GET 請求
語法: $.get(請求地址, 需要攜帶到后端的參數(shù), 成功的回調(diào)函數(shù), 期望后端返回的數(shù)據(jù)類型)
請求地址: 你要請求的后端接口地址(必填)
攜帶參數(shù): 你需要給后端傳遞的參數(shù)
可以是一個(gè)固定格式的字符串 ‘key=value&key=value’
也可以是一個(gè)對(duì)象 { a: 100, b: 200 }
成功回調(diào): 當(dāng)請求成功的時(shí)候會(huì)執(zhí)行的函數(shù)
期望數(shù)據(jù)類型: 就是你是不是需要 jQuery 幫你解析響應(yīng)體
$.ajax({
url: '', // => 請求地址(必填)
type: '', // => 請求方式(GET, POST, ...) 默認(rèn)是 GET
data: '', // => 攜帶到后端的參數(shù)
dataType: '', // => 期望后端返回的數(shù)據(jù)類型, 默認(rèn)不解析
async: true, // => 是否異步, 默認(rèn)是 true
success: function () {}, // => 成功的回調(diào)
error: function () {}, // => 失敗的回調(diào)
timeout: 數(shù)字, // 單位是 ms, 超時(shí)時(shí)間(超過你寫的時(shí)間沒有響應(yīng), 那么就算失敗)
cache: true, // 是否緩存, 默認(rèn)是 true
context: 上下文, // 改變回調(diào)函數(shù)里面的 this 指向
...
})
$.ajax 里面失敗的回調(diào)
不光是請求失敗的時(shí)候會(huì)觸發(fā)
jQuery 認(rèn)定失敗就是失敗
當(dāng) dataType 寫成 json 的時(shí)候, jQuery 會(huì)幫我們執(zhí)行 JSON.parse()
當(dāng)后端返回一個(gè)不是 json 格式的字符串的時(shí)候
執(zhí)行 JSON.parse() 就會(huì)報(bào)錯(cuò)
也會(huì)執(zhí)行失敗的回調(diào), 請求雖然成功, 但是解析失敗了, 也是失敗
JSON.parse(‘你好 世界’) -> 就會(huì)報(bào)錯(cuò)了
$.ajax 里面是否緩存的問題
這個(gè)請求要不要緩存
當(dāng)兩次請求地址一樣的時(shí)候, 就會(huì)緩存
如果你寫成 false, 表示不要緩存
jQuery 就會(huì)自動(dòng)再你的請求后面加一個(gè)參數(shù) =時(shí)間戳
第一次請求 ./server/get.php?=11:10:01.325的時(shí)間戳
第二次請求 ./server/get.php?_=11:10:02.326的時(shí)間戳
$.ajax 里面的回調(diào) this 指向問題
ajax 的回調(diào)里面默認(rèn) this 指向被 jQuery 加工過的 ajax 對(duì)象
context 的值你寫的是誰, 回調(diào)函數(shù)里面的 this 就時(shí)誰
$.ajax 里面的請求方式的問題
$.ajax 這個(gè)方法里面, type 表示請求方式
jQuery 還給了我們一個(gè)參數(shù)叫做 method,也表示請求方式
當(dāng)你寫請求方式的時(shí)候
可以寫成 type: ‘POST’
也可以寫成 method: ‘POST’
$.ajax 里面的接收響應(yīng)的問題(2015年以后的版本才有 promise 的形式)
jQuery 默認(rèn)把 ajax 封裝成了 promsie 的形式
你可以用 success 選項(xiàng)接收成功的回調(diào)
也可以用 .then() 的方式接收響應(yīng)
jQuery 的 ajax 全局鉤子函數(shù)
鉤子: 掛在你的身上, 你的所有動(dòng)作都和它有關(guān)系
這些全局函數(shù)都是掛在 ajax 身上的, 這個(gè) ajax 的每一個(gè)動(dòng)作都和全局函數(shù)有關(guān)系
全局的鉤子函數(shù)
1.ajaxStart()
會(huì)在同一個(gè)作用域下多個(gè) ajax 的時(shí)候, 第一個(gè) ajax 之前開始的時(shí)候觸發(fā)
如果有多個(gè) ajax 他只觸發(fā)一次
2.ajaxSend()
每一個(gè) ajax 再發(fā)送出去之前, 都會(huì)觸發(fā)一下
xhr.send() 之前觸發(fā)
ajaxSuccess()
每一個(gè) ajax 再成功的時(shí)候觸發(fā)
只要有一個(gè) ajax 成功了就會(huì)觸發(fā)
ajaxError()
每一個(gè) ajax 再失敗的時(shí)候觸發(fā)
只要有一個(gè) ajax 失敗了就會(huì)觸發(fā)
ajaxComplete()
每一個(gè) ajax 完成的時(shí)候觸發(fā)
只要有一個(gè) ajax 完成了, 不管成功還是失敗, 都會(huì)觸發(fā)
ajaxStop()
會(huì)在同一個(gè)作用域內(nèi)多個(gè) ajax 的時(shí)候, 最后一個(gè) ajax 完成以后觸發(fā)
如果有多個(gè) ajax 它只觸發(fā)一次
作用: 通常用來做 loading 效果
<img src="./loading.gif" alt="">
// 利用ajax鉤子函數(shù) 做一個(gè)lading效果 等待頁面
// 提前利用鉤子函數(shù)準(zhǔn)備 loading 效果
// 每一次發(fā)送出去的時(shí)候都要顯示圖片
$(window).ajaxSend(() => {
$('img').show()
})
// 每一次完成的時(shí)候都要圖片再隱藏起來
$(window).ajaxComplete(() => {
$('img').hide()
})
// 每次點(diǎn)擊按鈕的時(shí)候都會(huì)發(fā)送一個(gè) ajax 請求
$('button').click(() => {
// 發(fā)送一個(gè) ajax 請求
$.ajax({
url: './server/get.php',
data: { a: 100, b: 200 },
dataType: 'json',
success: function (res) {
console.log('請求成功了')
console.log(res)
}
})
})
十五 jQuery 發(fā)送一個(gè) jsonp 請求
jQuery 也提供給我們發(fā)送 jsonp 請求的方式
jsonp: 利用 script 標(biāo)簽的 src 屬性來請求
返回值: 是一個(gè)字符串, 字符串里面寫了一個(gè) 函數(shù)名(后端傳遞給前端的參數(shù))
使用 $.ajax() 這個(gè)方法
必須寫的:dataType: 'jsonp'
發(fā)送 jsonp 請求
jQuery 幫我們準(zhǔn)備好了一個(gè)函數(shù)名, 并且以參數(shù)的形式帶到了后端
jQuery 幫我們帶過去的 callback 參數(shù), 就是它準(zhǔn)備好的函數(shù)名
后端就應(yīng)該返回一個(gè) jQuery 準(zhǔn)備好的函數(shù)名()
其他參數(shù)
jsonp: '', 你帶到后端表示你函數(shù)名的那個(gè) key, 默認(rèn)值是 callback
cache: false, 當(dāng) dataType === ‘jsonp’ 的時(shí)候, 默認(rèn) cache 就是 false
// 發(fā)送一個(gè) jsonp 請求
$.ajax({
url: '
dataType: 'jsonp', // 表示我要發(fā)送一個(gè) jsonp 請求
jsonp: 'cb', // 表示參數(shù)里面的 cb 屬性時(shí)我準(zhǔn)備好的函數(shù)名
cache: true, // 表示緩存本次請求
success: function (res) {
console.log(res)
}
})
// jQuery 準(zhǔn)備好的函數(shù)名
// + jQuery34108160883644340862_1582255906750
// + 變量名包含 數(shù)字 字母 下劃線 $
// + function jQuery34108160883644340862_1582255906750() {}
十六 jQuery 的多庫并存機(jī)制
因?yàn)?jQuery 引入頁面以后, 向全局添加了兩個(gè)名字
一個(gè)叫做 $
一個(gè)叫做 jQuery
萬一有別的類庫也起名叫做 jQuery 或者$ 怎么辦
當(dāng)我兩個(gè)庫都需要使用的時(shí)候
因?yàn)橄蛉直┞兜拿忠粯? 就會(huì)發(fā)生沖突了
誰的文件引再后面, 誰的名字就占主要位置了
兩個(gè)只能選擇一個(gè)使用
jQuery 提供了一個(gè)方法
我可以不占用$ 或者 jQuery 這個(gè)名字
noConflict()
語法: $.noConflict() 或者jQuery.noConflict()
當(dāng)你執(zhí)行了 noConflict() 以后, jQuery 就交出了$的控制權(quán)。
jQuery向全局暴露的不在有$ 這個(gè)名字了。當(dāng)你執(zhí)行了noConflict(true) 以后, jQuery就交出了 $ 和jQuery 的控制權(quán)。
交出去以后, 我的 jQuery 就用不了
noConflict() 的返回值: 就是一個(gè)新的控制權(quán)
你只要接收一個(gè)返回值, 你定好的變量是什么,jQuery 的控制權(quán)就是什么
// 交出 $ 的控制權(quán)
// $.noConflict()
// 交出 $ 和 jQuery 的控制權(quán)
// $.noConflict(true)
// 改變 jQuery 的控制權(quán)
var $$ = $.noConflict(true)
十七 jQuery 的插件擴(kuò)展機(jī)制
jQuery 還提供給我們了一個(gè)機(jī)制, 就是你可以向 jQuery 里面擴(kuò)展一些方法
兩個(gè)方法
$.extend()
擴(kuò)展給 jQuery本身使用的
語法:
$.extend({ 你要擴(kuò)展的方法名: function () {}, 你要擴(kuò)展的方法名: function () {}, ... })
使用的時(shí)候就是 $.你擴(kuò)展的方法名()
$.fn.extend() => $.extend($.fn, { 你擴(kuò)展的方面名 })
擴(kuò)展給 jQuery 元素集合使用的
語法 $.fn.extend({ 你要擴(kuò)展的方法名: function () {}, 你要擴(kuò)展的方法名: function () {}, ... })
使用的時(shí)候就是 $(選擇器).你擴(kuò)展的方法名()
$('div').html()
// 1. 擴(kuò)展給 jQuery 本身
// jQuery 本身沒有操作 cookie 的方法
// $.extend({
// setCookie: function (key, value, expires) {
// // 寫上設(shè)置 cookie 的方法
// if (expires) {
// var time = new Date()
// time.setTime(time.getTime() - 1000 60 60 8 + 1000 expires)
// document.cookie = ${key}=${value};expires=${time}
// } else {
// document.cookie = ${key}=${value}
// }
// },
// getCookie: function (key) {
// // ...
// }
// })
// 使用我們擴(kuò)展的方法去設(shè)置 cookie
// $.setCookie('a', 100)
// $.setCookie('b', 200, 10)
// 2. 擴(kuò)展給元素集合
// 擴(kuò)展一個(gè)全選的方法
// 方法以執(zhí)行, 就能讓 input checkbox 變成選中狀態(tài)或者不選中狀態(tài)
$.fn.extend({
selectAll: function (type = true) {
// type 就是你傳遞進(jìn)來的選中或者不選中一個(gè)標(biāo)志
// 你不傳遞的時(shí)候, 我默認(rèn)是 true, 你傳遞了就用你傳遞的
// console.log(this) // 就是你調(diào)用的時(shí)候前面的哪個(gè)元素集合
this.each(function (index, item) {
// 讓元素集合中的每一個(gè) input 的 checked 屬性為 true
item.checked = type
})
// return 這個(gè)元素集合, 達(dá)到一個(gè)鏈?zhǔn)骄幊痰男Ч?br />
return this
}
})
$('button').click(() => {
// 讓所有 input 框變成選中狀態(tài)
console.log($('input').selectAll().attr('hello', 'world'))
})
十八 jQuery 的拷貝對(duì)象問題
$.extend() 深拷貝 與 淺拷貝
傳遞一個(gè)對(duì)象的時(shí)候, 可以做到插件擴(kuò)展機(jī)制
傳遞多個(gè)對(duì)象的時(shí)候, 可以將后面幾個(gè)對(duì)象的內(nèi)容復(fù)制到第一個(gè)對(duì)象里面
語法:
$.extend(是否深拷貝, 對(duì)象1, 對(duì)象2, 對(duì)象3, ...)
是否深拷貝: 默認(rèn)是 false, 可以不寫
從 對(duì)象2 開始, 后面所有對(duì)象的內(nèi)容都會(huì)被拷貝到 對(duì)象1 里面
再拷貝的時(shí)候, 如果有重復(fù)的 key, 那么以寫在后面的為準(zhǔn)(后來者居上)
十九 jQuery 的插件
基于 jQuery 使用的, 別人封裝好的插件
我們拿來使用就可以了, 前提就是要有 jQuery
例子 一個(gè)叫做 jquery-validate 的插件
專門用來做表單驗(yàn)證的
你輸入的內(nèi)容是不是符合規(guī)則
下載
引入文件
去復(fù)制粘貼
<!-- 引入文件 --> <!-- 注意: 先引入 jQuery, 后引入 jquery-validate --> <script src="./jquery/jquery.min.js"></script> <!-- jquery-validate 這個(gè)文件依賴的 jquery --> <script src="./jquery-validate/jquery.validate.min.js"></script> <!-- 引入中文信息提示包, 必須在 jquery-validate 的后面 --> <script src="./jquery-validate/localization/messages_zh.min.js"></script> <script>
// 選擇到你要驗(yàn)證的表單的 form 標(biāo)簽 // 執(zhí)行 validate 方法 // {} 里面就寫我們的驗(yàn)證規(guī)則 $('#login').validate({ // 你需要的驗(yàn)證規(guī)則 rules: { // key 就是你要驗(yàn)證的哪個(gè) input 框的 name 屬性 username: 'required', // 用戶名必填 password: { // 一個(gè)字段可以寫多個(gè)驗(yàn)證方式 required: true, minlength: 6, // 最少是六個(gè) maxlength: 12, // 最多十二個(gè) } }, // 你自定義提示的文本內(nèi)容 messages: { // key 就是你驗(yàn)證的哪個(gè) input 框的 name 屬性 username: '請輸入用戶名! ^_^', password: { required: '請輸入密碼!', minlength: '最少要輸入 6 個(gè)字符噢!' } }, // 表單的提交事件 // 這個(gè)函數(shù)會(huì)在表單驗(yàn)證通過以后執(zhí)行 submitHandler: function (form) { // form 接收的就是你的 form 標(biāo)簽 // console.log(form) // console.log('表單驗(yàn)證通過了, 我需要使用 ajax 去提交數(shù)據(jù)了') // 有一個(gè) jQuery 的方法 // serialize() 快速獲取表單輸入的數(shù)據(jù) // $(form).serialize() 就能拿到這個(gè) form 標(biāo)簽里面的表單數(shù)據(jù) // console.log($(form).serialize()) // username=admin&password=123456 // 發(fā)送請求到后端 $.post('./server/login.php', $(form).serialize(), res => { console.log(res) }, 'json') } })————————————————
所謂閉包就是說,閉包是指有權(quán)訪問另外一個(gè)函數(shù)作用域中的變量的函數(shù).可以理解為(能夠讀取其他函數(shù)內(nèi)部變量的函數(shù))
閉包的三大特點(diǎn)為(既是優(yōu)點(diǎn),也是缺點(diǎn)):
1,函數(shù)作用域空間不會(huì)被銷毀
優(yōu)點(diǎn)是:空間中的內(nèi)容,永遠(yuǎn)存在
缺點(diǎn)是:占用大量的內(nèi)存空間
2,可以從外部訪問函數(shù)內(nèi)部的變量
優(yōu)點(diǎn)是:使用變量數(shù)據(jù)方便
缺點(diǎn)是:容易泄露數(shù)據(jù)信息
3,保護(hù)私有作用域變量
優(yōu)點(diǎn)是:確保私有作用域變量一直存在
缺點(diǎn)是:占用內(nèi)存空間 閉包的最大問題是:有可能造成占用大量的內(nèi)存空間,降低程序的執(zhí)行效率,甚至有可能造成數(shù)據(jù)溢出或者是數(shù)據(jù)泄露 因?yàn)闉榱吮Wo(hù)數(shù)據(jù)的安全性,特殊情況下,才會(huì)使用閉包舉例來說:
// 記數(shù)器:
//全局變量 全局變量降低函數(shù)的獨(dú)立性
1
// var count = 0;
// function add(){
// return count++;
// }
// console.log(add());
// console.log(add());
// console.log(add());
//局部變量 函數(shù)執(zhí)行外 局部變量銷毀
1
// function add(){
// var count = 0;
// return count++;
// }
// console.log(add());
// console.log(add());
// console.log(add());
//plus定義在add的內(nèi)部,可以訪問add局部變量count
//f為一個(gè)全局變量,通過賦值后,成為add的返回值,也就是plus方法
//訪問到了add中的局部變量count
//所以count雖然是局部變量,但不允許被銷毀,plus就是閉包
1
2
3
4
// function add(){
// var count = 0;
// function plus(){
// return count++;
// }
// return plus;
// }
//
// var f = add();
//
// console.log(f());
// console.log(f());
// console.log(f());
//變身
1
// function add(){
// var count = 0;
// return function(){
// return count++;
// }
// }
//
// var f = add();
//
// console.log(f());
// console.log(f());
// console.log(f());
//繼續(xù)變身
1
// var f = (function (){
// var count = 0;
// return function(){
// return count++;
// }
// }());
//
// console.log(f());
// console.log(f());
// console.log(f());
//JS中,沒有塊作用域,但是在閉包的寫法里,可以體現(xiàn)出來。
function outerFunc(){
var outVar = 10;
var innerF = function (){
var innerVar = 20;//該變量雖然隸屬于outerFunc內(nèi)部,但是它的作用域范圍只在innerF對(duì)應(yīng)的函數(shù)體內(nèi),屬于塊級(jí)作用域
}
alert(innerVar);
return innerF;
}
閉包的作用:
正常函數(shù)執(zhí)行完畢后,里面聲明的變量被垃圾回收處理掉,但是閉包可以讓作用域里的 變量,在函數(shù)執(zhí)行完之后依舊保持沒有被垃圾回收處理掉
可以讀取函數(shù)內(nèi)部的變量
讓這些變量的值始終保持在內(nèi)存中。
增加塊級(jí)作用域
總結(jié):
1、 閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的最常見的方式就是在一個(gè)函數(shù)內(nèi)創(chuàng)建另一個(gè)函數(shù),通過另一個(gè)函數(shù)訪問這個(gè)函數(shù)的局部變量。
2、 閉包的缺點(diǎn)就是常駐內(nèi)存,會(huì)增大內(nèi)存使用量,使用不當(dāng)很容易造成內(nèi)存泄露。
3、不必糾結(jié)到底怎樣才算閉包,其實(shí)你寫的每一個(gè)函數(shù)都算作閉包,即使是全局函數(shù),你訪問函數(shù)外部的全局變量時(shí),就是閉包的體現(xiàn)。
————————————————
版權(quán)聲明:本文為CSDN博主「澈野」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/fie_ld/article/details/104595753
HTML 樣式
通過使用 HTML4.0,所有格式化代碼均可移出 HTML 文檔,然后移入一個(gè)獨(dú)立的樣式表。
先來看一個(gè)例子,代碼如下:
<head>
<style type="text/css">
h1 {color: red}
p {color: blue}
</style>
</head>
<body>
<h1>header 1</h1>
<p>A paragraph.</p>
</body>
頁面上顯示為:
header 1
A paragraph.
當(dāng)瀏覽器讀到一個(gè)樣式表,它就會(huì)按照這個(gè)樣式表來對(duì)文檔進(jìn)行格式化。有以下三種方式來插入樣式表:
外部樣式表 link
當(dāng)樣式需要被應(yīng)用到很多頁面的時(shí)候,外部樣式表將是理想的選擇。使用外部樣式表,你就可以通過更改一個(gè)文件來改變整個(gè)站點(diǎn)的外觀。
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
link : 定義資源引用
rel : 告訴瀏覽器引用的是一個(gè)樣式表文件
type : 文件類型
href : 文件地址
內(nèi)部樣式表
當(dāng)單個(gè)文件需要特別樣式時(shí),就可以使用內(nèi)部樣式表。你可以在 head 部分通過 <style> 標(biāo)簽定義內(nèi)部樣式表。
<head>
<style type="text/css">
body {background-color: red}
p {margin-left: 20px}
</style>
</head>
style : 定義樣式定義
新建一個(gè)前端學(xué)習(xí)qun438905713,在群里大多數(shù)都是零基礎(chǔ)學(xué)習(xí)者,大家相互幫助,相互解答,并且還準(zhǔn)備很多學(xué)習(xí)資料,歡迎零基礎(chǔ)的小伙伴來一起交流。
內(nèi)聯(lián)樣式
當(dāng)特殊的樣式需要應(yīng)用到個(gè)別元素時(shí),就可以使用內(nèi)聯(lián)樣式。 使用內(nèi)聯(lián)樣式的方法是在相關(guān)的標(biāo)簽中使用樣式屬性。樣式屬性可以包含任何 CSS 屬性。以下實(shí)例顯示出如何改變段落的顏色和左外邊距。
<p style="color: red; margin-left: 20px">
This is a paragraph
</p>
優(yōu)先級(jí)說明
(外部樣式)External style sheet < (內(nèi)部樣式)Internal style sheet < (內(nèi)聯(lián)樣式)In
1.下列方法表示調(diào)用外部樣式表的是?
A<style type="text/css">h1 {color: red }</style>
B<link rel="stylesheet" type="text/css" href="css/style.css">
C<p style="color: red; margin-left: 20px">style</p>
2.下面三種方法可以起到改變文檔樣式的是?
A<style type="text/css">h1 {color: red }</style>
B<link rel="stylesheet" type="text/css" href="css/style.css">
C<p style="color: red; margin-left: 20px"></p>
D以上三種都可以
————————————————
版權(quán)聲明:本文為CSDN博主「html前端基礎(chǔ)入門教程」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/htkms87/article/details/104600003
原理
keyCode 對(duì)于keypress 事件,該屬性聲明了被敲擊的鍵生成的 Unicode 字符碼。對(duì)于 keydown 和 keyup 事件,它指定了被敲擊的鍵的虛擬鍵盤碼。虛擬鍵盤碼可能和使用的鍵盤的布局相關(guān)。 因此我們可以根據(jù)keycode返回的字符碼來判斷用戶所按下的鍵,下面就是一個(gè)用于測試上下左右按鍵的js代碼,經(jīng)過我的測試之后,返回37 38 39 40;
window.onload = function(){ var box = document.getElementById("box"); document.onkeydown = function(event){ event = event || window.event; console.log(event.keyCode); } }; 3
3.方塊的移動(dòng)實(shí)際上就是坐標(biāo)的改變,因此需要offsetLeft 和offsetTop 來獲得當(dāng)前方塊的坐標(biāo),然后將坐標(biāo)進(jìn)行一定的更改,就可以實(shí)現(xiàn)移動(dòng)的效果了,下面給出代碼
window.onload = function() { document.onkeydown = function(event) { event = event || window.event; //設(shè)置移動(dòng)速度 var speed = 10; //當(dāng)ctrl和方向按鍵同時(shí)按下時(shí),提升移動(dòng)速度 if(event.ctrlKey) { speed = 50; } //獲取div var box01 = document.getElementById("box01"); switch(event.keyCode) { /*keyCode返回按下按鍵的編碼 * 37 向左 * 38向上 * 39向右 * 40向下 */ case 37: box01.style.left = box01.offsetLeft - speed + "px"; break; case 39: box01.style.left = box01.offsetLeft + speed + "px"; break; case 38: box01.style.top = box01.offsetTop - speed + "px"; break; case 40: box01.style.top = box01.offsetTop + speed + "px"; break; } }; };
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> #box01 { width: 100px; height: 100px; background-color: #008000; position: absolute; } </style> <script type="text/javascript"> window.onload = function() { //獲取div var box01 = document.getElementById("box01"); //設(shè)置移動(dòng)速度 var speed = 10; //設(shè)置移動(dòng)的方向 var dir = 0; setInterval(function() { switch(dir) { /*keyCode返回按下按鍵的編碼 * 37 向左 * 38向上 * 39向右 * 40向下 */ case 37: box01.style.left = box01.offsetLeft - speed + "px"; break; case 39: box01.style.left = box01.offsetLeft + speed + "px"; break; case 38: box01.style.top = box01.offsetTop - speed + "px"; break; case 40: box01.style.top = box01.offsetTop + speed + "px"; break; } }, 50) document.onkeydown = function(event) { event = event || window.event; //當(dāng)ctrl和方向按鍵同時(shí)按下時(shí),提升移動(dòng)速度 if(event.ctrlKey) { speed = 50; } else { speed = 10; } //使dir等于keycode的值 dir = event.keyCode; //當(dāng)鼠標(biāo)松開時(shí),停止移動(dòng) ---如果不寫這一個(gè)會(huì)造成無法停止移動(dòng)的效果 document.onkeyup = function() { dir = 0; }; }; }; </script> </head> <body> <div id="box01"></div> </body>
</html>
————————————————
版權(quán)聲明:本文為CSDN博主「loving-cat」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_42878211/article/details/104558443
vuex的基礎(chǔ)
1,狀態(tài)管理(共享)
緩存數(shù)據(jù)==>內(nèi)存, 只要刷新頁面,數(shù)據(jù)就丟了
訂單,詳情等,,,不適用vuex緩存數(shù)據(jù)
用于
非父子通信的問題
緩存后端數(shù)據(jù),提高用戶體驗(yàn)
注意:
vuex只能有一個(gè)store,
為了防止多人修改,我們切割成子store, 再合并成唯一一個(gè)大的store對(duì)象
模塊寫法
import Vue from 'vue' import Vuex from 'vuex' import cinema from './module/cinemaModule' import tabbar from './module/tabbarshowModule' Vue.use(Vuex) const store = new Vuex.Store({ state: { }, // "全局"狀態(tài) mutations:{ },//唯一修改狀態(tài)的地方 //異步處理 actions:{ }, // 對(duì)上面的“全局狀態(tài)”進(jìn)行數(shù)據(jù)處理, 類似于vue中的計(jì)算屬性 getters:{ }, modules:{ cinema, tabbar } }) export default store
const module = { namespaced:true, //命名空間 state :{ cinemaList:[] }, actions:{ store.commit("setCinemaList",res.data.data.cinemas) //支持傳參 }, mutations:{ setCinemaList(state,data){ console.log("setCinemaList",data) state.cinemaList = data } }, getters:{ topDataList(state){ //state形參s, vuex自動(dòng)調(diào)用時(shí)候,傳來值 return state.cinemaList.slice(0,5) } } } export default module
import createPersistedState from "vuex-persistedstate"; //在index.js頁面加入這個(gè)插件 // 加入下面的代碼 const store = new Vuex.Store({ plugins: [createPersistedState({ reducer(val){ return { user: val.user } } })]
————————————————
版權(quán)聲明:本文為CSDN博主「m0_46436313」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/m0_46436313/article/details/104572076
中介者對(duì)象踐行了最少知識(shí)原則,指一個(gè)對(duì)象盡可能少的了解別的對(duì)象,從而盡量減少對(duì)象間耦合程度。這樣各個(gè)對(duì)象只需關(guān)注自身實(shí)現(xiàn)邏輯,對(duì)象間的交互關(guān)系交由中介者對(duì)象來實(shí)現(xiàn)和維護(hù)。
需求背景:
手機(jī)購買頁面,在購買流程中,可以選擇手機(jī)的顏色及輸入購買數(shù)量,同時(shí)頁面有兩個(gè)展示區(qū)域,分別向用戶展示剛選擇好的顏色和數(shù)量。還有一個(gè)按鈕動(dòng)態(tài)顯示下一步的操作,我們需要查詢該顏色手機(jī)對(duì)應(yīng)的庫存,如果庫存數(shù)量少于這次購買的數(shù)量,按鈕將被禁用并顯示庫存不足,反之按鈕可以點(diǎn)擊并顯示放入購物車。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>中介者模式 購買商品</title> </head> <body> 選擇顏色: <select id="colorSelect"> <option value="">請選擇</option> <option value="red">紅色</option> <option value="blue">藍(lán)色</option> </select> 輸入購買數(shù)量: <input type="text" id="numberInput"> 您選擇了顏色:<div id="colorInfo"></div><br> 您輸入了數(shù)量:<div id="numberInfo"></div><br> <button id="nextBtn" disabled>請選擇手機(jī)顏色和購買數(shù)量</button> </body> <script> // 最初級(jí)的寫法 var colorSelect = document.getElementById('colorSelect'), numberInput = document.getElementById('numberInput'), colorInfo = document.getElementById('colorInfo'), numberInfo = document.getElementById('numberInfo'), nextBtn = document.getElementById('nextBtn'); var goods = { 'red': 3, 'blue': 6 } colorSelect.onchange = function(){ var color = this.value, number = numberInput.value, stock = goods[color] colorInfo.innerHTML = color; if(!color){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機(jī)顏色'; return; } if( ( (number-0) | 0 ) !== number-0 ){ //用戶輸入的購買數(shù)量是否為正整數(shù) nextBtn.disabled = true; nextBtn.innerHTML = '請輸入正確的購買數(shù)量'; return; } if(number > stock){ //當(dāng)前選擇數(shù)量大于庫存量 nextBtn.disabled = true; nextBtn.innerHTML = '庫存不足'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購物車'; } numberInput.oninput = function(){ var color = colorSelect.value, number = this.value, stock = goods[color] colorInfo.innerHTML = color; if(!color){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機(jī)顏色'; return; } if( ( (number-0) | 0 ) !== number-0 ){ //用戶輸入的購買數(shù)量是否為正整數(shù) nextBtn.disabled = true; nextBtn.innerHTML = '請輸入正確的購買數(shù)量'; return; } if(number > stock){ //當(dāng)前選擇數(shù)量大于庫存量 nextBtn.disabled = true; nextBtn.innerHTML = '庫存不足'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購物車'; } </script> </html>
在上個(gè)示例中,對(duì)象間聯(lián)系高度耦合,只是兩個(gè)輸入框還好,但如果有多個(gè)的話,相互聯(lián)系就非常復(fù)雜了,此時(shí)就要考慮用到中介者模式。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>中介者模式 購買商品</title> </head> <body> 選擇顏色: <select id="colorSelect"> <option value="">請選擇</option> <option value="red">紅色</option> <option value="blue">藍(lán)色</option> </select> 選擇內(nèi)存: <select id="memorySelect"> <option value="">請選擇</option> <option value="32G">32G</option> <option value="16G">16G</option> </select> 輸入購買數(shù)量: <input type="text" id="numberInput"> 您選擇了顏色:<div id="colorInfo"></div><br> 您選擇了內(nèi)存:<div id="memoryInfo"></div><br> 您輸入了數(shù)量:<div id="numberInfo"></div><br> <button id="nextBtn" disabled>請選擇手機(jī)顏色、內(nèi)存和購買數(shù)量</button> </body> <script> var goods = { 'red|32G': 3, 'red|16G': 0, 'blue|32G': 1, 'blue|16G': 6 } //引入中介者 var mediator = (function(){ var colorSelect = document.getElementById('colorSelect'), memorySelect = document.getElementById('memorySelect'), numberInput = document.getElementById('numberInput'), colorInfo = document.getElementById('colorInfo'), memoryInfo = document.getElementById('memoryInfo'), numberInfo = document.getElementById('numberInfo'), nextBtn = document.getElementById('nextBtn'); return { changed: function(obj){ var color = colorSelect.value, memory = memorySelect.value, number = numberInput.value, stock = goods[color + '|' + memory]; if(obj == colorSelect){ //如果改變的是選擇顏色下拉框 colorInfo.innerHTML = color; }else if(obj == memorySelect){ memoryInfo.innerHTML = memory; }else if(obj == numberInput){ numberInfo.innerHTML = number; } if(!color){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機(jī)顏色'; return; } if(!memory){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機(jī)內(nèi)存'; return; } if(!number){ nextBtn.disabled = true; nextBtn.innerHTML = '請?zhí)顚懯謾C(jī)數(shù)量'; return; } if( ( (number-0) | 0 ) !== number-0 ){ //用戶輸入的購買數(shù)量是否為正整數(shù) nextBtn.disabled = true; nextBtn.innerHTML = '請輸入正確的購買數(shù)量'; return; } if(number > stock){ //當(dāng)前選擇數(shù)量大于庫存量 nextBtn.disabled = true; nextBtn.innerHTML = '庫存不足'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購物車'; } } })() colorSelect.onchange = function(){ mediator.changed(this) } memorySelect.onchange = function(){ mediator.changed(this) } numberInput.oninput = function(){ mediator.changed(this) } //以后如果想要再增加選項(xiàng),如手機(jī)CPU之類的,只需在中介者對(duì)象里加上相應(yīng)配置即可。 </script> </html>在實(shí)際開發(fā)中,還是要注意選擇利弊,中介者對(duì)象因?yàn)榘瑢?duì)象間交互的復(fù)雜性,所以維護(hù)成本可能也會(huì)較高。在實(shí)際開發(fā)中,最優(yōu)目的還是要快速完成項(xiàng)目交付,而非過度設(shè)計(jì)和堆砌模式。有時(shí)對(duì)象間的耦合也是有必要的,只有當(dāng)對(duì)象間復(fù)雜耦合確實(shí)已經(jīng)導(dǎo)致調(diào)用與維護(hù)難以為繼,才考慮用中介者模式。
————————————————
版權(quán)聲明:本文為CSDN博主「一期一會(huì)」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_34832846/article/details/85989945
藍(lán)藍(lán)設(shè)計(jì)的小編 http://tweetduck.com