JavaScript筆記

代碼筆記

JavaScript

封裝自己的log函數

  • eg

    • 普通封裝
    var log = function() {
        // arguments是保存函數所有參數的值
        console.log.apply(console,arguments)
    }
    
    • 箭頭函數封裝
    var log = (args) => {
        console.log(...args)
    }
    log([1,2,3]) -> 1 2 3
    
  • 穿衣服:這樣才能真正看到變量是什么

log(`(${變量})`)
  • 作用
    • 確保代碼執行
    • 打印所有能打印的值

測試函數(套路)

  • 定義一個通用判斷函數
var ensure = function(condition,message) {
    if (!condition) {
        log(message)
    }
}
// 增強版
var ensureEqual = function(a,b,message) {
    if(a !== b){
        log(`測試失敗,a:${a}和b:${b}不相等,${message}`)
    }
}
  • 定義一個測試函數
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}
  • 通過點運算符訪問
log(op.fuck) ==> 1
  • 通過中括號訪問
log(op['fuck']) ==> 1

DOM(文檔對象模型)

  • 查找元素
document.querySelector(選擇器)    // 查找一個元素
document.querySelectorAll(選擇器) // 查找全部元素
  • 操作元素屬性
    • 設置元素的屬性: setAttribute(屬性名,值)
    • 獲得元素的屬性值:getAttribute(屬性名)
    • 判斷屬性是否存在 : hasAttribute(屬性名)
    • 刪除某個屬性 : removeAttribute(屬性名)
    • 所有屬性 : .attributes
  • 操作元素(創建、刪除、修改)

    • 創建:document.createElement(元素)
    • 修改:用appendChild增加子元素
    父元素.appendChild(元素)
    
    • 刪除
    父元素.removeChild(元素)
    元素.remove()
    元素.parenElement可以得到自己的父元素
    
    • 插入一段html
    元素.insertAdjavenHtml('查文檔',html語句)
    

事件

  • 添加事件addEventListener(事件名字,事件處理函數)
// 給多個元素掛上同一個事件
// 選擇多個元素使用函數 querySelectorAll

var buttons = document.querySelectorAll('.radio-button')

// 循環遍歷每個元素, 并且綁定點擊事件
for (var i = 0; i < buttons.length; i++) {
    var buttonFuck = buttons[i]
    buttonFuck.addEventListener('click', function(event){
        // 注意, 這次我們直接定義了函數作為參數傳遞, 這樣做是合法的
        // 另外, 我們增加了一個 event 參數
        // 瀏覽器會給事件響應函f數傳遞一個參數, 它代表了事件本身 (指buttonFuck的click)
        // 我們可以用 event.target 取出響應事件的元素 (buttonFuck)
        var self = event.target
        // clearActive 函數是我們自己定義的
        // 目的是刪除其他元素的 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")
    }
}
  • 事件冒泡/捕獲
    • 事件冒泡

      • 微軟做的
      • 定義:事件發生后一直往最外層。(最底層先觸發)
      • 阻止事件冒泡:event.cancelBubble = true
    • 事件捕獲

      • 網景公司做的
      • 就是添加事件addEventListener函數的第三個參數,設置為true的時候意思為useCapture
      • 最外層攔住了事件,再看看下一級元素有沒有觸發了的,有就傳遞
      • 事件觸發順序會與事件冒泡反過來
    • 它們同時發生的時候,先進行事件捕獲,再進行事件冒泡

樣式開關函數的套路

// 樣式開關函數套路
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)

時間標準庫

// 時間標準庫
// ===
// 常用用法如下
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()
秒數, 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('我是一個類')
    }
}
// 創建一個類的實例
var s = new Student('g','man')
s.say() -> 我是一個類
// prototype可以給所有實例加上一個值,函數盡量在這里定義
Student.prototype.get = ()=>{
    log('所有的實例都能擁有這個函數 ',this.name)
}
s.get() -> 所有的實例都能擁有這個函數 g
  • ps:可以擴展內置的類
String.prototype.say = ()=>{
    log('你敢用我嗎? ')
}
''.say() -> 你敢用我嗎?

拆分函數的依據

  • 上層函數不關心下層函數的難點
  • 描繪what 不是描繪how

編碼

  • 瀏覽器的url是有規范的 eg:空格會變成 %20

  • javaScript里

    • URL
    // 這個函數就是URL轉碼的函數
    encodeURIComponent(需要轉碼的字符串)
    // 這個是URL解碼的函數
    decodeURIComponent(需要解碼的字符串)
    
    • base64

jquery

  • 找jquery
  • 常見用法
    • 選擇器

      • 類似querySelector函數
      $('選擇器')
      
      • find
      // find函數只能用在jq對象上
      var form = $('.form')
      form.find('#id-input-add')
      
      • closest函數

        • closest(選擇器) : 往自己的父節點找,沒找到就一直往上找
        • 例子
        $(選擇器).on(事件名,function(event)=>{
            // dom對象轉成jq對象
            var 元素 = $(event.target)
            // 刪除自己
            元素.closest(選擇器).remove()
        })
        
    • 取值

      • val
      // 取值(目前特指input)
      var value = $(選擇器).val()
      
      • text :返回text內容,如果text(有參數)就改成你設的參數
      // 無參數
      var 元素 = $(選擇器)
      var t = 元素.text()
      log(t) -> hello
      
      // 有參數
      元素.text('fuck')
      log(元素.text()) -> fuck
      
      
      • html :返回帶標簽的內容,帶參數就設置為你設的參數
      // 無參數
      var 元素 = $(選擇器)
      var t = 元素.html()
      log(t) -> <h1>hello</h1>
      
      // 有參數
      元素.html('<h2>hello</h2>')
      log(元素.html()) -> <h2>hello</h2>
      
    • 事件委托

      var 父節點 = $(選擇器).on(事件名,響應對象,回調函數)
      
    • dom操作

      • 添加元素
      // 添加元素
      $(選擇器).append(元素)
      
      • 刪除元素
      $(選擇器).remove()
      
      • 刪掉子元素
      $(選擇器).empty()
      
      • 顯示、隱藏、開關
      // 顯示
      $(選擇器).show()
      // 隱藏
      $(選擇器).hide()
      // 開關
      $(選擇器).toggle()
      
    • class操作

      • addClass
      • removeClass
      • toggleClass
    • 屬性、特性操作

      • attr :查屬性的值

      • prop

      • data

        • 設置數據:對任意一個元素掛上data-名字來存數據
        • 用法
          • 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 :要轉成jq才能使用jq的函數
    • 數組方法

      • each :簡化版的for
      $(選擇器).each(function(i,element){
          log('element ',i,element)
      })
      
      • map 對數組每一個元素處理然后返回一個值,生成一個新的數組
      var foo = [1,2,3,4,5]
      newFoo = $.map(foo,function(value){
          return value*value
      })
      log(newFoo) -> [1,4,9,16,25]
      
      • grep 過濾,生成新數組
      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
    • 所有元素全部加載完回調

    $('document').ready(function(){
    
    })
    

高級一點的東西

  • bind 處理this的一個動態的this的問題

    • 體現this會變的例子
    var o = {
    foo: 1,
    bar: function(){
        return this.foo
    }
    }
    var a = o.bar
    // 調用字典里的函數
    o.bar() -> 1
    // 調用a的時候,this變成里Windows
    a() -> undefined
    
    • a函數的this被bind到了o上
    var o = {
        foo: 1,
        bar: function(){
            return this.foo
        }
    }
    var a = o.bar.bind(o)
    a() -> 1
    
  • apply(直接傳參數)和call(要一個個傳) 都是為了改變動態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是為了動態改變this而出現的,
    當一個object沒有某個方法,但是其他的有,
    我們可以借助call或apply用其它對象的方法來操作。
    */
    

es6

  • 擴展符號 ...可以解開數組

    • eg1
    var a = [1,2,3]
    var b = [...a,5]
    log(b) -> [1,2,3,5]
    
    • 傳參數
    var add = function(a,b,c){
        return a+b+c
    }
    var numbers = [1,2,3]
    var value = add(...numbers)
    log(value) -> 6
    
    • 復制一個數組
    var a = [1,2,3]
    var b = [...a]
    
    • 合并數組
    var a = [1,2,3]
    var b = [4,5,6]
    var c = [7,8,9]
    var o = [...a,...b,...c]
    
  • 解包(從python學來的)

    • 賦值
    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
    
  • 箭頭函數

    • 跟c#的lambda差不多意思
    • 蕭大說是垃圾
    • 等價例子
    // 兩者等價
    var log1 = function(){}
    var log2 = ()=>{}
    
  • for…of循環

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
}
  • 新增的函數

    • Array.from()

      • 任何有length屬性的都可以轉成真正的數組
      var a = {length:3}
      var b = Array.from(a)
      log(b) -> [undefined,undefined,undefined]
      
      • 如果它本身就是一個數組,會返回一個一摸一樣的數組
      • 可以有第二個參數,類似map函數。對每一個元素處理再返回
    • 數組填充 fill

    var ['a','b','c'] = fill(7) -> [7,7,7]
    
    • includes 判斷數組是否存在這個元素

if的條件一定不要是隱含條件

HTML

HTML5

* 游戲庫 phaser

普通HTML

CSS

CSS寫在哪里

  • 內聯屬性寫CSS(不推薦)
<h1 style="color:red;" > hello gua </h1>
  • <head> 標簽內的<style> 標簽
  • <link> 標簽的外聯

選擇器

  • 元素選擇器(標簽選擇器)
h1 {
    background:blue;
}
  • class 選擇器
.gua-title {
    background: :blue;
}
  • id選擇器
#id-h1 {
    background: yellow;
}

CSS命名規矩 -- ( 屬性名-元素名-名稱 )

樣式優先級(從高到低)

  • !important
h1 {
    color:white !important;
}
  • 內聯
  • <style> 中的樣式
  • link中的樣式

選擇器優先級

  • !important
  • 內聯
  • id
  • class
  • 元素

盒模型

  • 內容
  • padding
  • border
  • margin

元素定位(position)

  • 非 static 元素可以用top、left、bottom、right設置坐標
  • relative :相對定位
  • absolute :完全絕對定位,忽略其他的東西,往上浮動到非 static 的元素
  • fixed :基于windows的絕對定位,不隨頁面滾動改變

display

  • block : 獨占一行
  • inline : 跟別人擠一行
  • inline-block : 可以跟別人擠一行,并且可以設置寬度
  • ps : block 屬性使得元素具有自己的盒模型

偽類選擇器

a::hover {
    樣式
}

使得一個元素屏幕居中

.類 {
    top: 50%;
    position: relative;
    transform: translateX(-50%)
}

改變元素的樣式可以通過改變class來完成

事件委托-子元素的事件,可以綁定在父級元素

  • ps:子元素執行事件函數的時候,如果父元素也有這個事件函數,也會執行
  • 一個例子,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('父元素調用這個函數了 ')
    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('子元素調函數')
})
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>
// 當點擊overButton的時候,會輸出 父元素調用和子元素調用

http協議

  • 請求行或者響應行:決定做的事情的性質
  • head和body是用空行隔開的
  • 瀏覽器會解析head,body自己處理

掌握http有什么用?

  • 可以用js動態抓取網頁內容

    • 動態評論、加載數據
    • 天氣預報
    • 壁紙圖片庫
  • 瀏覽器提供了使用 HTTP 協議收發數據的接口,名為 AJAX

瀏覽器安全問題

  • 跨域
  • file不能使用ajax

ajax

  • ajax請求的套路

    • GET請求
    // 創建一個ajax請求對象
    var r = new XMLHttpRequest()
    // 注冊響應函數
    r.onreadystatechange = ()=>{console.log('start begin ',r)}
    // 設置請求方法和請求地址(open第三個參數代表是否使用異步)
    r.open('GET','#signin',true)
    // 發送請求
    r.send()
    

    以下是打印的內容

    start begin  XMLHttpRequest {readyState: 2, ……}
    VM203:1 start begin  XMLHttpRequest {readyState: 3, ……}
    VM203:1 start begin  XMLHttpRequest {readyState: 4, ……}
    當readyState==4的時候表明這個請求完成
    
    • POST請求
    // 創建一個ajax請求對象
    var r = new XMLHttpRequest()
    // 注冊響應函數
    r.onreadystatechange = () => {
        if(r.readyState === 4){
            console.log('start begin ',r)
        }
    }
    //設置發送的數據的格式
    r.setRequestHeader('Content-Type','application/json')
    // 設置請求方法和請求地址(open第三個參數代表是否使用異步)
    r.open('POST','#signin',true)
    var form = {
        userName:'123',
        pwd:'123'
    }
    var data = JSON.stringify(form)
    // 發送請求
    r.send(data)
    
    • 封裝它們
    var ajax = (method,path,formData,callBack,content='application/json',async=true) => {
        var r = new XMLHttpRequest()
        // 注冊響應函數
        r.onreadystatechange = callBack
        if(method === 'POST') {
            // 設置發送的內容的格式
            r.setRequestHeader('Content-Type',content)
        } else {}
        // 設置請求方法和請求地址(open第三個參數代表是否使用異步)
        r.open(method,path,async)
        if(method === 'GET') {
            // 發送請求
            r.send()
        } else {
            var data = JSON.stringify(formData)
            r.send(data)
        }
    }
    // 隨手封裝
    
  • 豆瓣api例子

Github

Bootstrap

Pure

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,202評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,742評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,297評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,688評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,875評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,438評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,183評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,384評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,612評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,093評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,330評論 2 377

推薦閱讀更多精彩內容

  • JavaScript 將字符串轉換為數字 parseInt() ◆只保留數字的整數部分,不會進行四舍五入運算。 ...
    AkaTBS閱讀 996評論 0 9
  • JS基礎講解 JavaScript組成ECMAScript:解釋器、翻譯DOM:Document Object M...
    FConfidence閱讀 579評論 0 1
  • 工廠模式類似于現實生活中的工廠可以產生大量相似的商品,去做同樣的事情,實現同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 7,804評論 2 17
  • 單例模式 適用場景:可能會在場景中使用到對象,但只有一個實例,加載時并不主動創建,需要時才創建 最常見的單例模式,...
    Obeing閱讀 2,088評論 1 10
  • 《ijs》速成開發手冊3.0 官方用戶交流:iApp開發交流(1) 239547050iApp開發交流(2) 10...
    葉染柒丶閱讀 5,264評論 0 7