Fe-7 js-todo

Fe-7-1

數(shù)據(jù)類型

在 js 中, 每一個(gè)變量(也就是每一個(gè)值)都有一個(gè)類型

  • 內(nèi)置的基本數(shù)據(jù)有以下幾種類型
    number 數(shù)字
    string 字符串
    boolean 布爾變量(只有兩個(gè)值 true 或 false)
    object 對(duì)象, 是高級(jí)一點(diǎn)的內(nèi)容
    null 和 undefined

這兩個(gè)東西很相似, 有這么兩個(gè)東西主要是歷史原因造成的
具體細(xì)節(jié)可看這個(gè)鏈接, 不過不需要關(guān)心
http://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html

函數(shù)也是一個(gè)變量, 稍微特殊點(diǎn), 但在 js 中沒什么本質(zhì)不同
它的類型是函數(shù)

// 為一個(gè)變量賦值就創(chuàng)建了一個(gè)變量
// JavaScript 中, 變量只是對(duì)值的一個(gè)引用
// 比如下面, 分別把 3 個(gè)不同類型的值賦值給變量 a

var a
a = 1       // a 是 number
a = 1.1     // number
a = 'good'  // string

// 可以用 typeof 語句得到一個(gè)變量的類型
a = 10
b = true
c = 'I am good'
log('type a', typeof a)
log('type b', typeof b)
log('type c', typeof c)

運(yùn)行, 輸出如下
type a number
type b boolean
type c string

前提定義log函數(shù)

// 定義 log 函數(shù)
var log = function() {
    console.log.apply(console, arguments)
}

微信截圖_20180106125231.png
  • 單行字符串變多行字符串用轉(zhuǎn)意符號(hào)
  • 多行字符串
    多行字符串又稱模板字符串
    使用反引號(hào), 鍵盤左上角波浪線
var a = `多
行
字符串`

log('多行字符串', a)

a = `
i
am
good
`

log('多行字符串 2', a)

不同的數(shù)據(jù)類型是不能混用的
比如 float 就不能當(dāng)下標(biāo)

  • 轉(zhuǎn)義符
    在代碼中表示字符串的時(shí)候, 很多東西不方便表示, 因此我們使用轉(zhuǎn)義符的方式來表示
    轉(zhuǎn)義符是字符串中的特殊符號(hào)翠忠,由反斜杠(backslash)開始
    接另一個(gè)字符結(jié)束
    常用的轉(zhuǎn)義符有
    還有一些別的轉(zhuǎn)義符充择,但極少使用,對(duì)于這種東西色乾,不必記憶辕坝,知道有這么回事就好了窍奋。
// \n     // 表示一個(gè)換行符
// \t     // 表示一個(gè) TAB(制表符)
// \\     // 表示一個(gè)反斜杠 \
// \'     // 表示一個(gè)單引號(hào)
// \"     // 表示一個(gè)雙引號(hào)
//
// 例子:
log('I\'a\tm \n\ngood\n')

微信截圖_20180106165038.png

高階函數(shù) 就是函數(shù)當(dāng)參數(shù)傳遞

// =====
// 高階函數(shù)
// =====
//
// 高階函數(shù)這個(gè)名字很唬人, 實(shí)際上概念很簡(jiǎn)單——函數(shù)可以作為參數(shù)傳遞
//
// 有什么用呢?靈活性高酱畅,舒適度佳
// 請(qǐng)看例子
//
// String 函數(shù)是用來把數(shù)據(jù)轉(zhuǎn)換成 string 類型的一個(gè)函數(shù)
log('string ', String(6.3))

var process = function(array, processor) {
    /*
    array 是一個(gè)數(shù)組
    processor 是一個(gè)函數(shù), 注意, 這是一個(gè)函數(shù), 所以可以調(diào)用

    把 array 中的每個(gè)元素都用 processor 函數(shù)處理并返回一個(gè)
    新的 array
    */
    var l = []
    for (var i = 0; i < array.length; i++) {
        var a = array[i]
        // processor 必須能調(diào)用成功, 否則這里就跪了
        var element = processor(a)
        l.push(element)
    }
    return l
}

// 創(chuàng)建一個(gè) array, 包含 3 個(gè) number
var array = [1.1, -2.2, 3.3]

// String 內(nèi)置函數(shù)
var stringList = process(array, String)
log('stringList', stringList)

// Math.floor 函數(shù)可以把小數(shù)轉(zhuǎn)成整數(shù), 可以自行試試
process(array, Math.floor)

// 輸出結(jié)果如下
// 我們可以看到, process 函數(shù)通過 參數(shù)傳進(jìn)來的函數(shù) 對(duì)數(shù)據(jù)進(jìn)行了處理
// stringList ['1.1', '-2.2', '3.3']


// =====
// 匿名函數(shù)
// =====
//
// 有時(shí)候要傳遞高階函數(shù)的時(shí)候, 函數(shù)很短, 可能就一行
// 如果去定義一個(gè)新函數(shù)有人覺得劃不來, 就想了一個(gè)偷懶的辦法
// 那就是匿名函數(shù)
// 匿名函數(shù)的意思是沒有函數(shù)名, 一般定義了就用
// 實(shí)際上我們之前寫的函數(shù)都是匿名函數(shù), 只不過把它賦值給了一個(gè)變量而已

// 例子
// 定義一個(gè) square 函數(shù)求平方
var square = function(n) {
    return n * n
}

// 用上面的 process 函數(shù)處理試試
var array = [1, 2, 3]
var squareList = process(array, square)
log('square list', squareList)

var addList = process(array, function(n){
    // 我們定義一個(gè)接受一個(gè)參數(shù)的函數(shù)并且直接使用, 它沒有名字
    return n + 1
})
log('add list', addList)


// 輸出結(jié)果如下
// square list [1, 4, 9]
// add list [2, 3, 4]
微信截圖_20180106130947.png

Fe-7-2 Todo

  • 添加琳袄,刪除,完成纺酸,還有本地存儲(chǔ)


    todo.gif

todo.html

<!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>Todo</title>
  <style>
    .done {
      color: gray;
      text-decoration: line-through;
      background: lightblue;
    }
  </style>
</head>
<body><div class="todo-form">
  <input id="id-input-todo" type="text">
    <button id="id-button-add" name="button">Add</button>
</div>
<div id="id-div-container">
  <div class="todo-cell">
              <!-- <button class='todo-done'>完成</button>
              <button class='todo-delete'>刪除</button>
              <span class='todo-content' contenteditable='true'>上課</span>
            
             -->

  </div>
</div>
<script src="todo.js" charset="utf-8"></script>
</body>
</html>

todo.js

// 2016/12/06
//
// 此為第 7 課的上課內(nèi)容 2
//
// 這部分的主要內(nèi)容有
//
// 通過一個(gè) Todo 應(yīng)用, 學(xué)習(xí)下面這個(gè)概念
// 1, 什么是事件委托
// 2, 為什么需要事件委托
// 3, 如何實(shí)現(xiàn)事件委托
//
// 時(shí)間操作
// content editable (標(biāo)簽的可編輯屬性)
// localStorage (本地存儲(chǔ)) 和 JSON 數(shù)據(jù)格式
//
//
// 應(yīng)該都能看懂, 不懂的稍微做個(gè)筆記, 等上課講解


// 自己定義一個(gè) log 函數(shù)
var log = function() {
    console.log.apply(console, arguments)
}

// 用自己實(shí)現(xiàn)的 e 替代 document.querySelector
// 因?yàn)檫@個(gè)東西太長(zhǎng)了
var e = function(selector) {
    return document.querySelector(selector)
}

// 給 add button 綁定添加 todo 事件
var addButton = e('#id-button-add')
addButton.addEventListener('click', function(){
    // 獲得 input.value
    var todoInput = e('#id-input-todo')
    var todo = todoInput.value
    // 添加到 container 中
    insertTodo(todo, false)
    // 添加之后 保存 todos
    saveTodos()
})

var insertTodo = function(todo, done) {
    // 添加到 container 中
    var todoContainer = e('#id-div-container')
    var t = templateTodo(todo, done)
    // 這個(gè)方法用來添加元素
    // 第一個(gè)參數(shù) 'beforeend' 意思是放在最后
    todoContainer.insertAdjacentHTML('beforeend', t);
}

var templateTodo = function(todo, done) {
    var status = ''
    if(done) {
        status = 'done'
    }
    var t = `
        <div class='todo-cell ${status}'>
            <button class='todo-done'>完成</button>
            <button class='todo-delete'>刪除</button>
            <span class='todo-content' contenteditable='true'>${todo}</span>
        </div>
    `
    return t
}

// 事件委托相關(guān)概念
// ===
//
// 問題在于, todo 都是運(yùn)行的時(shí)候才添加的元素
// 對(duì)于這樣的元素, 我們沒辦法實(shí)現(xiàn)綁定事件
// 我們可以把 click 事件綁定在事先存在的父元素上
// 然后在運(yùn)行的時(shí)候檢查被點(diǎn)擊的對(duì)象(通過 event.target 屬性)
// 是否是我們需要的對(duì)象, 這個(gè)概念就是事件委托

var todoContainer = e('#id-div-container')

// 通過 event.target 的 class 來檢查點(diǎn)擊的是什么
todoContainer.addEventListener('click', function(event){
    log('container click', event, event.target)
    var target = event.target
    // classList.contains 可以檢查元素是否有一個(gè) class
    if(target.classList.contains('todo-done')) {
        log('done')
        // target.parentElement 用來獲取按鈕的父節(jié)點(diǎn)
        // 給 todo div 開關(guān)一個(gè)狀態(tài) class
        var todoDiv = target.parentElement
        toggleClass(todoDiv, 'done')
        // 改變 todo 完成狀態(tài)之后窖逗,保存 todos
        saveTodos()
    } else if (target.classList.contains('todo-delete')) {
        log('delete')
        // 找到按鈕的父節(jié)點(diǎn)并且刪除
        var todoDiv = target.parentElement
        todoDiv.remove()
        // 刪除之后 保存 todos
        saveTodos()
    }
})

// 這個(gè)函數(shù)用來開關(guān)一個(gè)元素的某個(gè) class
var toggleClass = function(element, className) {
    // 檢查元素是否擁有某個(gè) classs
    if (element.classList.contains(className)) {
        // 擁有則刪除之
        element.classList.remove(className)
    } else {
        // 沒有則加上
        element.classList.add(className)
    }
}


// localStorage(本地存儲(chǔ)) 是瀏覽器自帶的功能
// localStorage 可以用來存儲(chǔ)字符串?dāng)?shù)據(jù), 在瀏覽器關(guān)閉后依然存在
// 但是不同頁面擁有各自獨(dú)立的 localStorage
// 存儲(chǔ)方法如下
localStorage.name = 'gua'
// 關(guān)閉瀏覽器, 再次打開, 仍然能獲取到這個(gè)值
// log('關(guān)閉瀏覽器后', localStorage.name)
//
// 利用 localStorage 就可以存儲(chǔ) todo
// 但是 todo 存在 array 中
// 而 localStorage 只能存儲(chǔ) string 數(shù)據(jù)
// 所以沒辦法直接存儲(chǔ)
//
// 可行的辦法如下
// 存儲(chǔ)的時(shí)候把 array 轉(zhuǎn)換為字符串
// 讀取的時(shí)候把字符串轉(zhuǎn)成 array
// 這個(gè)過程通常被稱之為 序列化 和 反序列化
//
// 在 js 中, 序列化使用 JSON 數(shù)據(jù)格式
// 全稱 JavaScript Object Notation (js對(duì)象標(biāo)記)
// 這個(gè)格式已經(jīng)是現(xiàn)在用于互聯(lián)網(wǎng)數(shù)據(jù)交換的事實(shí)標(biāo)準(zhǔn)格式了
// ISO 是國(guó)際標(biāo)準(zhǔn)
// IEEE 國(guó)際電子電氣工程師協(xié)會(huì)
// GB 中國(guó)國(guó)標(biāo)

var s = JSON.stringify([1, 2, 3, 4])
log('序列化后的字符串', typeof s, s)
var a = JSON.parse(s)
log('反序列化后的數(shù)組', typeof a, a)

// 使用 JSON 序列化后, 就可以把 todo 存入瀏覽器的 localStorage 了

// 定義一個(gè)函數(shù), 用于把 數(shù)組 寫入 localStorage
var save = function(array) {
    var s = JSON.stringify(array)
    localStorage.todos = s
}

// 定義一個(gè)函數(shù)餐蔬, 讀取 localStorage 中的數(shù)據(jù)并解析返回
var load = function() {
    var s = localStorage.todos
    return JSON.parse(s)
}

// 定義一個(gè)函數(shù)碎紊, 把頁面上所有的 todo 用 save 保存
var saveTodos = function() {
    // 1 先選出所有的 content 標(biāo)簽
    // 2 取出 todo
    // 3 添加到一個(gè) 數(shù)組中
    // 4 保存數(shù)組
    log('save todos')
    var contents = document.querySelectorAll('.todo-content')
    var todos = []
    for (var i = 0; i < contents.length; i++) {
        var c = contents[i]
        var done = c.parentElement.classList.contains('done')
        var todo = {
            done: done,
            content: c.innerHTML,
        }
        // 添加到數(shù)組中
        todos.push(todo)
    }
    // 保存數(shù)組
    save(todos)
}

var loadTodos = function() {
    var todos = load()
    log('load todos', todos)
    // 添加到頁面中
    for (var i = 0; i < todos.length; i++) {
        var todo = todos[i]
        insertTodo(todo.content, todo.done)
    }
}

loadTodos()

// 時(shí)間標(biāo)準(zhǔn)庫
// 常用用法如下
// var d = new Date()
// d.getFullYear()
// 年份, 2016
// d.getMonth()
// 月份, 0-11
// d.getDate()
// 日期, 1-31
// d.getHours()
// 小時(shí), 0-23
// d.getMinutes()
// 分鐘, 0-59
// d.getSeconds()
// 秒數(shù), 0-59
// d.getMilliseconds()
// 毫秒, 0-999
// d.getDay()
// 星期幾, 0-6

var now = function() {
    var d = new Date()
    var nm = d.getFullYear()
    var yt = d.getMonth() + 1
    var ri = d.getDate()
    var ui = d.getHours()
    var ff = d.getMinutes()
    var mc = d.getSeconds()

    return `${nm}/${yt}/${ri} ${ui}:${ff}:${mc}`
    // return nm + '/' + yt + '/' + ri + ' ' + ui + ':' + ff + ':' + mc
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市樊诺,隨后出現(xiàn)的幾起案子仗考,更是在濱河造成了極大的恐慌,老刑警劉巖词爬,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秃嗜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)痪寻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門螺句,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人橡类,你說我怎么就攤上這事⊙看剑” “怎么了顾画?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)匆笤。 經(jīng)常有香客問我研侣,道長(zhǎng),這世上最難降的妖魔是什么炮捧? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任庶诡,我火速辦了婚禮,結(jié)果婚禮上咆课,老公的妹妹穿的比我還像新娘末誓。我一直安慰自己,他們只是感情好书蚪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布喇澡。 她就那樣靜靜地躺著,像睡著了一般殊校。 火紅的嫁衣襯著肌膚如雪晴玖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天为流,我揣著相機(jī)與錄音呕屎,去河邊找鬼。 笑死敬察,一個(gè)胖子當(dāng)著我的面吹牛秀睛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播静汤,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼琅催,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了虫给?” 一聲冷哼從身側(cè)響起藤抡,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抹估,沒想到半個(gè)月后缠黍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡药蜻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年瓷式,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了替饿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贸典,死狀恐怖视卢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情廊驼,我是刑警寧澤据过,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站妒挎,受9級(jí)特大地震影響绳锅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酝掩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一鳞芙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧期虾,春花似錦原朝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宾尚,卻和暖如春丙笋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背煌贴。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工御板, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牛郑。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓怠肋,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親淹朋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笙各,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,131評(píng)論 0 13
  • 原文: https://github.com/ecomfe/spec/blob/master/javascript...
    zock閱讀 3,371評(píng)論 2 36
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,216評(píng)論 0 4
  • 母親础芍,是一個(gè)詞語杈抢,一個(gè)千百年來被人們歌頌的詞語; 母親仑性,是一種大愛惶楼,一種舍我忘我,只為兒女的付出之情; 母親歼捐,是一...
    讀娘閱讀 1,665評(píng)論 2 2
  • 一大早沈碧云就被叫到慈寧宮來何陆,她被引入一喧曲折的迷陣似的欄桿,她彎來彎去走了許久才走出這個(gè)迷陣豹储。前面是幾十個(gè)大花壇...
    褚褚一閱讀 512評(píng)論 2 4