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阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • JavaScript 将字符串转换为数字 parseInt() ◆只保留数字的整数部分,不会进行四舍五入运算。 ...
    AkaTBS阅读 972评论 0 9
  • JS基础讲解 JavaScript组成ECMAScript:解释器、翻译DOM:Document Object M...
    FConfidence阅读 567评论 0 1
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,703评论 2 17
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,045评论 1 10
  • 《ijs》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 10...
    叶染柒丶阅读 5,009评论 0 7