代碼筆記
JavaScript
封裝自己的log函數(shù)
-
eg
- 普通封裝
var log = function() { // arguments是保存函數(shù)所有參數(shù)的值 console.log.apply(console,arguments) }- 箭頭函數(shù)封裝
var log = (args) => { console.log(...args) } log([1,2,3]) -> 1 2 3 穿衣服:這樣才能真正看到變量是什么
log(`(${變量})`)
- 作用
- 確保代碼執(zhí)行
- 打印所有能打印的值
測試函數(shù)(套路)
- 定義一個通用判斷函數(shù)
var ensure = function(condition,message) {
if (!condition) {
log(message)
}
}
// 增強(qiáng)版
var ensureEqual = function(a,b,message) {
if(a !== b){
log(`測試失敗,a:${a}和b:$不相等,${message}`)
}
}
- 定義一個測試函數(shù)
var testSum = function() {
let numbers = [1,2,3,4]
let value = 10
ensure(value === sum(numbers),'sum 錯誤')
ensure(1 === sum([1]),'sum 1 錯誤')
}
對象(字典)
eg :var op = {'fuck':1}
- 通過點(diǎn)運(yùn)算符訪問
log(op.fuck) ==> 1
- 通過中括號訪問
log(op['fuck']) ==> 1
DOM(文檔對象模型)
- 查找元素
document.querySelector(選擇器) // 查找一個元素
document.querySelectorAll(選擇器) // 查找全部元素
- 操作元素屬性
- 設(shè)置元素的屬性: setAttribute(屬性名,值)
- 獲得元素的屬性值:getAttribute(屬性名)
- 判斷屬性是否存在 : hasAttribute(屬性名)
- 刪除某個屬性 : removeAttribute(屬性名)
- 所有屬性 : .attributes
-
操作元素(創(chuàng)建、刪除、修改)
- 創(chuàng)建:document.createElement(元素)
- 修改:用appendChild增加子元素
父元素.appendChild(元素)- 刪除
父元素.removeChild(元素) 元素.remove() 元素.parenElement可以得到自己的父元素- 插入一段html
元素.insertAdjavenHtml('查文檔',html語句)
事件
- 添加事件addEventListener(事件名字,事件處理函數(shù))
// 給多個元素掛上同一個事件
// 選擇多個元素使用函數(shù) querySelectorAll
var buttons = document.querySelectorAll('.radio-button')
// 循環(huán)遍歷每個元素, 并且綁定點(diǎn)擊事件
for (var i = 0; i < buttons.length; i++) {
var buttonFuck = buttons[i]
buttonFuck.addEventListener('click', function(event){
// 注意, 這次我們直接定義了函數(shù)作為參數(shù)傳遞, 這樣做是合法的
// 另外, 我們增加了一個 event 參數(shù)
// 瀏覽器會給事件響應(yīng)函f數(shù)傳遞一個參數(shù), 它代表了事件本身 (指buttonFuck的click)
// 我們可以用 event.target 取出響應(yīng)事件的元素 (buttonFuck)
var self = event.target
// clearActive 函數(shù)是我們自己定義的
// 目的是刪除其他元素的 active class
clearActive()
// add 可以增加一個 class
self.classList.add('active')
})
}
var clearActive = function() {
var active = document.querySelector('.active')
if (active != null) {
// 使用 classList 可以訪問一個元素的所有 class
// remove 可以刪除一個 class
active.classList.remove("active")
}
}
- 事件冒泡/捕獲
-
事件冒泡
- 微軟做的
- 定義:事件發(fā)生后一直往最外層。(最底層先觸發(fā))
- 阻止事件冒泡:event.cancelBubble = true
-
事件捕獲
- 網(wǎng)景公司做的
- 就是添加事件addEventListener函數(shù)的第三個參數(shù),設(shè)置為true的時候意思為useCapture
- 最外層攔住了事件,再看看下一級元素有沒有觸發(fā)了的,有就傳遞
- 事件觸發(fā)順序會與事件冒泡反過來
它們同時發(fā)生的時候,先進(jìn)行事件捕獲,再進(jìn)行事件冒泡
-
樣式開關(guān)函數(shù)的套路
// 樣式開關(guān)函數(shù)套路
var toggleClass = (element,className) =>{
if(element.classList.contains(className)) {
element.classList.remove(className)
} else {
element.classList.add(className)
}
}
序列化和反序列化
// 序列化和反序列化套路
var infoList = ['b','f','q']
var s = JSON.stringify(infoList)
log('序列化之后的s ',typeof s ,s)
var a = JSON.parse(s)
log('反序列化之后的s ',typeof a ,a)
時間標(biāo)準(zhǔn)庫
// 時間標(biāo)準(zhǔn)庫
// ===
// 常用用法如下
var d = new Date()
d.getFullYear()
年份, 2016
d.getMonth()
月份, 0-11
d.getDate()
日期, 1-31
d.getHours()
小時, 0-23
d.getMinutes()
分鐘, 0-59
d.getSeconds()
秒數(shù), 0-59
d.getMilliseconds()
毫秒, 0-999
d.getDay()
星期幾, 0-6
事件取消
event.preventDefault()
老javascript類
- 一個例子
var Student = function(name,sex){
this.name = name
this.sex = sex
this.say=()=>{
log('我是一個類')
}
}
// 創(chuàng)建一個類的實(shí)例
var s = new Student('g','man')
s.say() -> 我是一個類
// prototype可以給所有實(shí)例加上一個值,函數(shù)盡量在這里定義
Student.prototype.get = ()=>{
log('所有的實(shí)例都能擁有這個函數(shù) ',this.name)
}
s.get() -> 所有的實(shí)例都能擁有這個函數(shù) g
- ps:可以擴(kuò)展內(nèi)置的類
String.prototype.say = ()=>{
log('你敢用我嗎? ')
}
''.say() -> 你敢用我嗎?
拆分函數(shù)的依據(jù)
- 上層函數(shù)不關(guān)心下層函數(shù)的難點(diǎn)
- 描繪what 不是描繪how
編碼
瀏覽器的url是有規(guī)范的 eg:空格會變成 %20
-
javaScript里
- URL
// 這個函數(shù)就是URL轉(zhuǎn)碼的函數(shù) encodeURIComponent(需要轉(zhuǎn)碼的字符串) // 這個是URL解碼的函數(shù) decodeURIComponent(需要解碼的字符串)- base64
jquery
- 找jquery
- 常見用法
-
選擇器
- 類似querySelector函數(shù)
$('選擇器')- find
// find函數(shù)只能用在jq對象上 var form = $('.form') form.find('#id-input-add')-
closest函數(shù)
- closest(選擇器) : 往自己的父節(jié)點(diǎn)找,沒找到就一直往上找
- 例子
$(選擇器).on(事件名,function(event)=>{ // dom對象轉(zhuǎn)成jq對象 var 元素 = $(event.target) // 刪除自己 元素.closest(選擇器).remove() })
-
取值
- val
// 取值(目前特指input) var value = $(選擇器).val()- text :返回text內(nèi)容,如果text(有參數(shù))就改成你設(shè)的參數(shù)
// 無參數(shù) var 元素 = $(選擇器) var t = 元素.text() log(t) -> hello // 有參數(shù) 元素.text('fuck') log(元素.text()) -> fuck- html :返回帶標(biāo)簽的內(nèi)容,帶參數(shù)就設(shè)置為你設(shè)的參數(shù)
// 無參數(shù) var 元素 = $(選擇器) var t = 元素.html() log(t) -> <h1>hello</h1> // 有參數(shù) 元素.html('<h2>hello</h2>') log(元素.html()) -> <h2>hello</h2> -
事件委托
var 父節(jié)點(diǎn) = $(選擇器).on(事件名,響應(yīng)對象,回調(diào)函數(shù)) -
dom操作
- 添加元素
// 添加元素 $(選擇器).append(元素)- 刪除元素
$(選擇器).remove()- 刪掉子元素
$(選擇器).empty()- 顯示、隱藏、開關(guān)
// 顯示 $(選擇器).show() // 隱藏 $(選擇器).hide() // 開關(guān) $(選擇器).toggle() -
class操作
- addClass
- removeClass
- toggleClass
-
屬性、特性操作
attr :查屬性的值
prop
-
data
- 設(shè)置數(shù)據(jù):對任意一個元素掛上data-名字來存數(shù)據(jù)
- 用法
- html
<div data-id='401'/> <div data-id='402'/>- javaScript
var divList = $(選擇器) // dom取法 var domDiv = divList[0] var id = domDiv.dataset.id log(id) -> 401 // jq取法 var jqDiv = $(divList[0]) var id = jqDiv.data('id') log(id) -> 401
removeAttr 刪除一個屬性
-
事件
- on
$(選擇器).on(事件名,function(event)=>{ })- change (暫時指input、下拉框)
$(選擇器).change(function(event)=>{ })- event.target :要轉(zhuǎn)成jq才能使用jq的函數(shù)
-
數(shù)組方法
- each :簡化版的for
$(選擇器).each(function(i,element){ log('element ',i,element) })- map 對數(shù)組每一個元素處理然后返回一個值,生成一個新的數(shù)組
var foo = [1,2,3,4,5] newFoo = $.map(foo,function(value){ return value*value }) log(newFoo) -> [1,4,9,16,25]- grep 過濾,生成新數(shù)組
var foo = [1,2,3,4,5] newFoo = $.map(foo,function(value){ return value %2 == 0 }) log(newFoo) -> [2,4] -
ajax
- 引入jq
var h = document.querySelector('head') h.insertAdjacentHTML('beforeend', '<script src="https://cdn.bootcss.com/jquery/3.2.1/core.js"></script>')- 用法
$.ajax({ url:一個api地址, type:'get', contentType:'application/json', success:function(){ log(arguments) }, error:function(){ log(arguments) } })- dataType
所有元素全部加載完回調(diào)
$('document').ready(function(){ }) -
高級一點(diǎn)的東西
-
bind 處理this的一個動態(tài)的this的問題
- 體現(xiàn)this會變的例子
var o = { foo: 1, bar: function(){ return this.foo } } var a = o.bar // 調(diào)用字典里的函數(shù) o.bar() -> 1 // 調(diào)用a的時候,this變成里Windows a() -> undefined- a函數(shù)的this被bind到了o上
var o = { foo: 1, bar: function(){ return this.foo } } var a = o.bar.bind(o) a() -> 1 -
apply(直接傳參數(shù))和call(要一個個傳) 都是為了改變動態(tài)this的
- apply特殊用法
var log = function() { console.log.apply(console,arguments) }- 普通用法
貓吃魚,狗吃肉,奧特曼打小怪獸。 有天狗想吃魚了 貓.吃魚.call(狗,魚) 狗就吃到魚了 貓成精了,想打怪獸 奧特曼.打小怪獸.call(貓,小怪獸) function cat() {} cat.prototype = { food: "fish", say: function() { alert("I love " + this.food) } } var blackCat = new cat blackCat.say() // 但是如果我們有一個對象 whiteDog = {food:"bone"} // 我們不想對它重新定義say方法 // 那么我們可以通過call或apply用blackCat的say方法: blackCat.say.call(whiteDog) /* 所以,可以看出call和apply是為了動態(tài)改變this而出現(xiàn)的, 當(dāng)一個object沒有某個方法,但是其他的有, 我們可以借助call或apply用其它對象的方法來操作。 */
es6
-
擴(kuò)展符號 ...可以解開數(shù)組
- eg1
var a = [1,2,3] var b = [...a,5] log(b) -> [1,2,3,5]- 傳參數(shù)
var add = function(a,b,c){ return a+b+c } var numbers = [1,2,3] var value = add(...numbers) log(value) -> 6- 復(fù)制一個數(shù)組
var a = [1,2,3] var b = [...a]- 合并數(shù)組
var a = [1,2,3] var b = [4,5,6] var c = [7,8,9] var o = [...a,...b,...c] -
解包(從python學(xué)來的)
- 賦值
var [a,b] = [1,3] log(a,b) -> 1 3- 鬼畜賦值
var [a,b,_] = [1,2,3,4,5] log(a,b,_) -> 1 2 [3,4,5]- 交換值
var a = 1 var b = 2 [a,b] = [b,a] log(a,b) -> 2 1 -
箭頭函數(shù)
- 跟c#的lambda差不多意思
- 蕭大說是垃圾
- 等價例子
// 兩者等價 var log1 = function(){} var log2 = ()=>{} for…of循環(huán)
let iterable = [10, 20, 30];
for (let idx in iterable){
console.log(idx) // 依次輸出:0, 1, 2
}
for (let value of iterable){
console.log(value) // 依次輸出:10, 20, 30
}
-
新增的函數(shù)
-
Array.from()
- 任何有l(wèi)ength屬性的都可以轉(zhuǎn)成真正的數(shù)組
var a = {length:3} var b = Array.from(a) log(b) -> [undefined,undefined,undefined]- 如果它本身就是一個數(shù)組,會返回一個一摸一樣的數(shù)組
- 可以有第二個參數(shù),類似map函數(shù)。對每一個元素處理再返回
數(shù)組填充 fill
var ['a','b','c'] = fill(7) -> [7,7,7]- includes 判斷數(shù)組是否存在這個元素
-
if的條件一定不要是隱含條件
HTML
HTML5
* 游戲庫 phaser
普通HTML
CSS
CSS寫在哪里
- 內(nèi)聯(lián)屬性寫CSS(不推薦)
<h1 style="color:red;" > hello gua </h1>
- <head> 標(biāo)簽內(nèi)的<style> 標(biāo)簽
- <link> 標(biāo)簽的外聯(lián)
選擇器
- 元素選擇器(標(biāo)簽選擇器)
h1 {
background:blue;
}
- class 選擇器
.gua-title {
background: :blue;
}
- id選擇器
#id-h1 {
background: yellow;
}
CSS命名規(guī)矩 -- ( 屬性名-元素名-名稱 )
樣式優(yōu)先級(從高到低)
- !important
h1 {
color:white !important;
}
- 內(nèi)聯(lián)
- <style> 中的樣式
- link中的樣式
選擇器優(yōu)先級
- !important
- 內(nèi)聯(lián)
- id
- class
- 元素
盒模型
- 內(nèi)容
- padding
- border
- margin
元素定位(position)
- 非 static 元素可以用top、left、bottom、right設(shè)置坐標(biāo)
- relative :相對定位
- absolute :完全絕對定位,忽略其他的東西,往上浮動到非 static 的元素
- fixed :基于windows的絕對定位,不隨頁面滾動改變
display
- block : 獨(dú)占一行
- inline : 跟別人擠一行
- inline-block : 可以跟別人擠一行,并且可以設(shè)置寬度
- ps : block 屬性使得元素具有自己的盒模型
偽類選擇器
a::hover {
樣式
}
使得一個元素屏幕居中
.類 {
top: 50%;
position: relative;
transform: translateX(-50%)
}
改變元素的樣式可以通過改變class來完成
事件委托-子元素的事件,可以綁定在父級元素
- ps:子元素執(zhí)行事件函數(shù)的時候,如果父元素也有這個事件函數(shù),也會執(zhí)行
- 一個例子,TODO程序
html
<html>
<head>
<meta charset="utf-8">
<style>
.done {
text-decoration: line-through;
}
</style>
</head>
<body>
<input id="id-input-value" type="text">
<button id="id-button-add">add</button>
<div id="id-div-Cell" class="cell">
<div>
<button class="overClass">over</button>
<button class="delClass">del</button>
<span contenteditable="true">test</span>
</div>
</div>
</body>
JavaScript
<script>
var log = function() {
console.log.apply(console,arguments)
}
let divCell = document.querySelector('#id-div-Cell')
divCell.addEventListener('click',(event)=>{
log('父元素調(diào)用這個函數(shù)了 ')
var item = event.target
if(item.classList.contains('overClass')) {
item.parentElement.classList.add('done')
} else if(item.classList.contains('delClass')) {
item.parentElement.remove()
}
})
var testButton = document.querySelector('.overClass')
testButton.addEventListener('click',()=>{
log('子元素調(diào)函數(shù)')
})
var addButton = document.querySelector('#id-button-add')
addButton.addEventListener('click',(event)=>{
log('event ',event.target)
let input_ = document.querySelector('#id-input-value')
let todo = input_.value
var t = newDiv(todo)
divCell.insertAdjacentHTML('beforeend',t)
})
var newDiv = (todo)=>{
t = `
<div>
<button class="overClass">over</button>
<button class="delClass">del</button>
<span contenteditable="true">${todo}</span>
</div>
`
return t
}
</script>
</html>
// 當(dāng)點(diǎn)擊overButton的時候,會輸出 父元素調(diào)用和子元素調(diào)用
http協(xié)議
- 請求行或者響應(yīng)行:決定做的事情的性質(zhì)
- head和body是用空行隔開的
- 瀏覽器會解析head,body自己處理
掌握http有什么用?
-
可以用js動態(tài)抓取網(wǎng)頁內(nèi)容
- 動態(tài)評論、加載數(shù)據(jù)
- 天氣預(yù)報
- 壁紙圖片庫
瀏覽器提供了使用 HTTP 協(xié)議收發(fā)數(shù)據(jù)的接口,名為 AJAX
瀏覽器安全問題
- 跨域
- file不能使用ajax
ajax
-
ajax請求的套路
- GET請求
// 創(chuàng)建一個ajax請求對象 var r = new XMLHttpRequest() // 注冊響應(yīng)函數(shù) r.onreadystatechange = ()=>{console.log('start begin ',r)} // 設(shè)置請求方法和請求地址(open第三個參數(shù)代表是否使用異步) r.open('GET','#signin',true) // 發(fā)送請求 r.send()以下是打印的內(nèi)容
start begin XMLHttpRequest {readyState: 2, ……} VM203:1 start begin XMLHttpRequest {readyState: 3, ……} VM203:1 start begin XMLHttpRequest {readyState: 4, ……} 當(dāng)readyState==4的時候表明這個請求完成- POST請求
// 創(chuàng)建一個ajax請求對象 var r = new XMLHttpRequest() // 注冊響應(yīng)函數(shù) r.onreadystatechange = () => { if(r.readyState === 4){ console.log('start begin ',r) } } //設(shè)置發(fā)送的數(shù)據(jù)的格式 r.setRequestHeader('Content-Type','application/json') // 設(shè)置請求方法和請求地址(open第三個參數(shù)代表是否使用異步) r.open('POST','#signin',true) var form = { userName:'123', pwd:'123' } var data = JSON.stringify(form) // 發(fā)送請求 r.send(data)- 封裝它們
var ajax = (method,path,formData,callBack,content='application/json',async=true) => { var r = new XMLHttpRequest() // 注冊響應(yīng)函數(shù) r.onreadystatechange = callBack if(method === 'POST') { // 設(shè)置發(fā)送的內(nèi)容的格式 r.setRequestHeader('Content-Type',content) } else {} // 設(shè)置請求方法和請求地址(open第三個參數(shù)代表是否使用異步) r.open(method,path,async) if(method === 'GET') { // 發(fā)送請求 r.send() } else { var data = JSON.stringify(formData) r.send(data) } } // 隨手封裝 豆瓣api例子