jquery学习笔记

jQuery:

文档:

https://www.jquery123.com/

https://jquery.cuishifeng.cn/

什么是jQuery:

jquery一个高效的,精简的且功能丰富的JavaScript工具库,满足了各种浏览器的兼容问题

web应用发展的过程中,jquery起到了不可或缺的推动作用

当下框架流行的时代,jquery不再那么适用

使用jquery感受,简单简洁,链式调用,读写一体

jQuery使用:

下载—— 引入、

引入:

<script src="./js/jquery-3.6.0.min.js"></script>

版本   1.x   ie6+   ,2.X  IE 9+  ,3.X  IE10+

入口:

$(document).ready(function () {
    // 写jquery代码
})
简写:
$(function () {
    // 入口  开始写jq代码
    console.log(123)
})

以上两种写法相当于js中的window.onload = function(){}

区别:
/* 
1:执行时机
window.onload必须再网页中所有的内容都加载完毕之后才可执行(包括图片img)
$(document).ready(function () {})页面当中的DOM结构绘制加载完毕即可执行,可能
与dom元素关联的并未完全加载完
2:编写个数
window.onload只能写一个
$(document).ready(function () {})可以编写多个 并且都会执行
3:简化写法
window.onload没有简化写法
$(document).ready(function () {})可以简化为$(function(){})
*/

选择器函数:

$是jQuery的简写
$()构造函数
$()就是jQuery()函数  通常被当作jQuery的  "选择器函数"
()括号中写选择器  用来获取html元素
$()函数的作用  对圆括号中选取的html元素自动循环遍历,然后组装成一个
jQuery对象返回
基本选择器:

.css css样式设置,多个数据用对象写法

// $('*').css('font-size', '20px')
// $('#box').css({ color: 'red', 'background-color': 'yellow' })
// $('div').css('color', 'blue')
// $('.aa').css('background-color', 'red')
属性选择器:
// $('input[type="text"]').css({ border: '1px solid red' })
// $('input[type]').css({ border: '1px solid red' })
// $('input[name^="news"]').css({ border: '1px solid red' })
// $("input[name!='newsletter']").css({ border: '1px solid red' })
// $("input[name$='letter']").css({ border: '1px solid red' })
关系(层级)选择器:
// $('div ul').css({ border: '1px solid red' })
// $('div>ul').css({ border: '1px solid red' })
// $('li.active').css({ border: '1px solid red' })
// $('p,ul').css({ border: '1px solid red' })

新增选择器函数:

过滤选择器:

:first 获取第一个元素

:last 获取最后一个元素

:even 匹配所有索引值为偶数的元素,从 0 开始计数

:odd 匹配所有索引值为奇数的元素,从 0 开始计数

:eq(index) 匹配一个给定索引值的元素

:gt(index) 匹配所有大于给定索引值的元素,不包括自身

:lt(index) 匹配所有小于给定索引值的元素,不包括自身

// $('li:first').css({ border: '1px solid red' })
// $('.myul>li:last').css({ border: '1px solid red' })
// $('.myul>li:even').css({ border: '1px solid red' })
// $('.myul>li:odd').css({ border: '1px solid red' })
// $('.myul>li:eq(1)').css({ border: '1px solid red' })
// $('.myul>li:gt(1)').css({ border: '1px solid red' })
// $('.myul>li:lt(1)').css({ border: '1px solid red' })

选择器的方法:

.children() 取得当前元素下的所有子元素,不包含后代元素,, 参数指定子元素

.siblings() 取得当前元素的兄弟元素,不包含本身 , 参数指定相对兄弟元素

.next() 取得当前选择的所有元素后面各自的紧邻元素, 参数指定紧邻元素

.prev() 取得当前选择的所有元素前面各自的紧邻元素, 参数指定紧邻元素

.nextAll() 取得当前选择的元素后面所有的元素

.prevAll() 取得当前选择的元素前面所有的元素

.nextUntil(ele) 选取当前元素之后到ele之间的元素,第二个参数设置对应的元素

.prevUntil(ele) 选取当前元素之前到ele之间的元素,第二个参数设置对应的元素

.parent() 选取当前元素的唯一父元素的集合

.parents() 选取当前元素全部父元素,不包括根元素

.parentsUntil(ele) 选取当前元素的全部父元素,直到ele

.find(expr|obj|ele) 取得所有匹配的元素,参数必须填写

.each() 遍历对象

// chi ldren和find都是基于父元素查找子元素
// $('li').eq(1).css({ border: '1px solid red' })
// $('.myul').children().css({ border: '1px solid red' })
// $('li.active').siblings().css({ border: '1px solid red' })
// $('li.active').next().css({ border: '1px solid red' })
// $('li.active').prev().css({ border: '1px solid red' })
// $('li.active').nextAll().css({ border: '1px solid red' })
// $('li.active').prevAll().css({ border: '1px solid red' })
// $('.list').nextUntil('.list5').addClass('one')
// 给.list3前面直到.list前的元素加上类 one
// $('.list3').prevUntil('.list').addClass('one')

// $('.myul').find('.active').css({ border: '1px solid red' })

// 遍历祖先节点  parent  parents  parentUntil
// $('span').parent().addClass('one')
// $('span').parents().addClass('one')
// 查找span的祖先元素  但是不包含body
// $('span').parentsUntil('body').addClass('one')

jQuery对象和js对象:

js对象:

JavaScript通过js相关对象方法获取的对象

var box = document.getElementById('box')
jQuery对象:

通过jQuery包装后产生的对象 jQuery对象

console.log($('#box'))

注意:jQuery对象无法应用Dom对象的任何方法,Dom对象无法应用jquery的任何方法

jQuery对象和js对象转换:
转为js对象:
// var $c = $('#box')
// 第一种  转换为js对象
// var c = $c[0]
// console.log(c)
// 第二种  转换为js对象
// var c = $c.get(0)
// console.log(c)
转为jQuery对象:
var box = document.getElementById('box')
var $cr = $(box)
console.log($cr)
jQuery的Dom操作:

.text() 获取文本

.html() 获取文本和元素

.width() 获取盒子宽度

.height() 获取盒子高度

// console.log($('.mytext').text())
// console.log($('.mytext').html())
// // $('.box').text("<a href='#'>超链接</a>")
// $('.box').html("<a href='#'>超链接</a>")
// console.log($('.mytext').width())
// console.log($('.mytext').height())
// $('.mytext').width(100)
// $('.mytext').height(100)

// console.log($('.mytext').innerWidth()) //width +padding
// console.log($('.mytext').innerHeight()) //height +padding
// console.log($('.mytext').outerHeight()) //width +padding+border
// console.log($('.mytext').outerWidth()) //height +padding+border
属性获取与操作:
console.log($('a').attr('href'))
$('a').attr('href', 'http://www.baidu.com')
class的操作:

addClass 添加类

removeClass 删除类

toggleClass 交换类

hasClass 判断类是否存在

$('.mytext').addClass('one')
$('.mytext').removeClass('one')
$('.mytext').toggleClass('two')
console.log($('.mytext').hasClass('two')) //true
DOM节点操作:

.append() 添加到当前节点子元素之后

.prepend() 添加到当前节点子元素之前

.before() 添加到当前元素之前

.after() 添加到当前元素之后

.remove() 当前节点全部删除

.empty() 删除节点内的元素和文本,但当前节点还保留

// dom节点的操作
// 添加
// $('.mytext').append('<h1>我是h1标签</h1>')
// $('.mytext').prepend('<h1>我是h1标签</h1>')
// $('.mytext').before('<h1>我是h1标签</h1>')
// $('.mytext').after('<h1>我是h1标签</h1>')

$('#btn').click(function () {
    // $('.mytext').remove()//当前dom全部删除
    $('.mytext').empty() //清空子元素  当前dom还在
})

事件:

常用事件:
// $('#btn').click(function () {
//   console.log('click')
// })

// $('#btn').dblclick(function () {
//   console.log('dblclick')
// })

// $('#btn').mouseenter(function () {
//   console.log('mouseenter')
// })

// $('#btn').mouseleave(function () {
//   console.log('mouseleave')
// })
事件绑定和解绑:
bind/unbind:
function fn() {
    console.log('fn')
}

function fun() {
    console.log('fun')
}
// 绑定
$('#btn2').click(function () {
    $('#btn1').bind('click', fn)
    $('#btn1').bind('click', fun)
})

// 解绑
$('#btn3').click(function () {
    $('#btn1').unbind('click')
})

$('#btn4').click(function () {
    $('#btn1').unbind('click', fn)
})
on/off:
function fn() {
    console.log('fn')
}

function fun() {
    console.log('fun')
}
//绑定
$('#btn2').click(function () {
    $('#btn1').on('click', fn)
    $('#btn1').on('click', fun)
})

// 解绑
$('#btn3').click(function () {
    $('#btn1').off('click')
})

$('#btn4').click(function () {
    $('#btn1').off('click', fn)
})
阻止冒泡:

e.stopPropagation() 阻止向父元素继续冒泡

e.stopImmediatePropagation() 阻止向后继续冒泡

function outFn() {
    console.log('out click')
}
function outFn1() {
    console.log('outFn1')
}
function inFn(e) {
    // e.stopPropagation() // 阻止向父元素继续冒泡
    e.stopImmediatePropagation() //阻止向后继续冒泡
    console.log('inFn')
}
function inFn1() {
    console.log('inFn1')
}

$('.out').on('click', outFn)
$('.out').on('click', outFn1)
$('.in').on('click', inFn)
$('.in').on('click', inFn1)

动画:

speed:三种预定速度之一的字符串(“slow”,“normal”, or “fast”)或表示动画时长的毫秒数值(如:1000)

easing:(Optional) 用来指定切换效果,默认是"swing",可用参数"linear"

fn:在动画完成时执行的函数,每个元素执行一次。

.show() 显示隐藏的匹配元素

.hide() 隐藏显示的元素

.toggle() 如果元素是可见的,切换为隐藏的;如果元素是隐藏的,切换为可见的

.slideDown() 通过高度变化(向下增大)来动态地显示所有匹配的元素,在显示完成后可选地触发一个回调函数

.slideUp() 通过高度变化(向上减小)来动态地隐藏所有匹配的元素,在隐藏完成后可选地触发一个回调函数

.slideToggle() 通过高度变化来切换所有匹配元素的可见性,并在切换完成后可选地触发一个回调函数

.fadeIn() 通过不透明度的变化来实现所有匹配元素的淡入效果,并在动画完成后可选地触发一个回调函数

.fadeOut() 通过不透明度的变化来实现所有匹配元素的淡出效果,并在动画完成后可选地触发一个回调函数

.fadeTo() 把所有匹配元素的不透明度以渐进方式调整到指定的不透明度,并在动画完成后可选地触发一个回调函数

$('#btn').click(function () {
    // $('.box').show()
    // $('.box').show('slow')
    // $('.box').show(3000)
    $('.box').show(3000, function () {
        alert('wo的动画执行完成')
    })
})
$('#btn1').click(function () {
    // $('.box').hide()
    $('.box').hide(3000)
})

$('#btn2').click(function () {
    $('.box').toggle(3000)
})

$('#btn3').click(function () {
    $('.box').slideDown(3000, function () {
        alert('wo的动画执行完成')
    })
})
$('#btn4').click(function () {
    $('.box').slideUp(3000)
})

$('#btn5').click(function () {
    $('.box').slideToggle(3000)
})

$('#btn6').click(function () {
    $('.box').fadeIn(3000, function () {
        alert('wo的动画执行完成')
    })
})
$('#btn7').click(function () {
    $('.box').fadeOut(3000)
})

$('#btn8').click(function () {
    //speed:三种预定速度之一的字符串("slow","normal", or "fast")或表示动画时长的毫秒数值(如:1000)

    //opacity:一个0至1之间表示透明度的数字。

    //easing:(Optional) 用来指定切换效果,默认是"swing",可用参数"linear"

    //fn:在动画完成时执行的函数,每个元素执行一次。
    $('.box').fadeTo(3000, 0.6)
})

其他:

.val() 获取文本内容

.trim() 去除文本两边的空格

Ajax:

浏览器中提供的XMLHttpRequest 用法比较复杂,jQuery对XMLHttpRequest进行封装,提供了一些列Ajax相关的函数,降低了Ajax的使用难度

jQuery中发起Ajax请求常用的三个方法:

  • $.get()
  • $.post()
  • $.ajax()
$.get():

专门用来发起get请求,将服务器上的资源请求到客户端进行使用

$.get(url[,data],callback)

url   参数类型 string  必填  要请求的资源地址
data  参数类型 object  不是必填 请求资源要携带的参数
callback  参数类型 function  不是必填 请求成功的回调函数
不带参数的请求:
$('#btn').on('click', function () {
    // $.get 发起不带参数的请求
    $.get('http://www.liulongbin.top:3006/api/getbooks', function (res) {
        // res就是服务器响应回来的数据
        console.log(res)
    })
})
带参数的请求:
$('#btn1').on('click', function () {
    // $.get 发起带参数的请求

    $.get(
        'http://www.liulongbin.top:3006/api/getbooks',
        { id: 1, bookname: '西游记' },
        function (res) {
            console.log(res)
        }
    )
})
$.post():

专门用来发起post请求,向服务器提交数据

$.post(url[,data],callback)

url   参数类型 string  必填  提交数据的地址
data  参数类型 object  不是必填 要提交的数据
callback  参数类型 function  不是必填 数据提交成功的回调函数
$(function () {
    $('#btnPost').on('click', function () {
        $.post(
            'http://www.liulongbin.top:3006/api/addbook',
            { bookname: 'js编程语法', author: 'hello', publisher: '天津' },
            function (res) {
                console.log(res)
            }
        )
    })
})
$.ajax():

是一个功能比较综合的函数,允许我们对ajax请求进行更详细的配置

$.ajax({
    type:"",  //请求的方式   例如 GET或POST
    url:"",   // 请求的url地址
    data:{},   //  请求要携带的数据
    success:function(res){}   //请求成功之后的回调函数
})
$.ajax()发起get请求:
$.ajax({
    type: 'GET',
    url: 'http://www.liulongbin.top:3006/api/getbooks',
    data: { id: 1 },
    success: function (res) {
        console.log(res)
    },
})
$.ajax()发起post请求:
$(function () {
    $('#btn').on('click', function () {
        var obj = {
            bookname: 'ja编程',
            author: 'java',
            publisher: '上海图书出版社',
        }
        $.ajax({
            type: 'POST',
            url: 'http://www.liulongbin.top:3006/api/addbook',
            data: obj,
            // success: function (res) {
            //   console.log(res)
            // },
            // 对象中的方法可以简写为下面
            success(res) {
                console.log(res)
            },
        })
    })
})

接口:

使用Ajax请求数据时,请求的url地址,就叫做 数据接口(简称接口),每个接口必须有请求方式

http://www.liulongbin.top:3006/api/addbook  添加图书接口(post请求)
http://www.liulongbin.top:3006/api/getbooks 获取图书列表接口(get请求)

postman:

为了验证接口能否被正常访问,使用接口测试工具,来对数据接口进行检测

好处:接口测试工具能让我们在不写代码的情况下,对接口进行调用和测试

接口文档:

接口文档可以包含很多信息,也可以按需进行精简,但是一个合格的接口文档,应该包含以下6个内容,为接口的调用提供依据

  • 接口名称 用来标识各个接口的简单说明 如登录接口
  • 接口url 接口的调用地址
  • 调用方式 接口的调用方式 如GET 或POST
  • 参数格式 接口需要传递的参数 每个参数必须包含 参数名称 参数类型 是否必选 参数说明
  • 响应格式 接口的返回值的详细描述 ,包含数据名称 数据类型 说明
  • 返回示例 通过对象的形式,列举服务器返回数据的结构

form表单的具体使用:

什么是表单:

表单在网页中主要负责数据采集的功能,HTML中的form标签,主要用于采集用户输入的信息,并通过form标签的提交操作,把采集到的信息提交到服务器端进行处理

form表单的属性:

action URL地址(后端提供的,这个url地址专门负责接收表单提交过来的数据) 规定提交表单时,向何处发送表单数据

​ 未指定action属性值的情况下,action的默认值未当前页面的url地址
method get或post 规定以何种方式把表单数据提交到 action url
​ (get 通过url地址栏传递数据,传递的数量小 不安全
​ post 通过http协议传递 ,传输的数据量大,安全)
enctype 规定在发送表单数据之前如何对其进行编码
​ application/x-www-form-urlencoded 在发送前编码所有的字符(默认)
​ multipart/form-data 不对字符编码,文件上传,使用该值
​ text/plain 空格转换未 + 加号,但不对特殊字符编码(很少用)

<form action="/login" method="get">
    <input type="text" name="email" id="" />
    <br />
    <input type="password" name="password" />
    <br />
    <input type="checkbox" name="remember" checked />
    <br />
    <button type="submit">提交</button>
</form>

表单的组成:

  • 表单标签
  • 表单域 (文本框,密码框,多行文本框,复选框,单选框,下拉选择框,文件上传)
  • 表单按钮

form标签的属性:

form标签用来采集数据,form标签的属性 就是用来规定 如何把采集到的数据发送到服务器

表单的同步提交:

点击submit按钮,触发表单提交的操作,从而使页面跳转到action url的行为,叫做表单的同步提交

缺点
  • form表单同步提交后,整个页面发生跳转,跳转到action url指向的地址,用户体验差
  • form表单同步提交后,页面之前的状态和数据会丢失
解决

表单只负责采集数据,Ajax负责将数据提交到服务器

Ajax提交表单数据:

监听表单提交事件:

.submit()

<body>
    <form action="/login" id="f1">
      <input type="text" name="username" />
      <br />
      <input type="password" name="password" />
      <br />
      <button type="submit">提交</button>
    </form>
  </body>
  <script>
    $(function () {
      $('#f1').submit(function () {
        alert('监听到表单的提交事件')
      })
    })
  </script>

表单的默认行为:

监听到表单提交事件之后,调用事件对象的event.preventDefault()阻止表单的提交和页面的跳转

$(function () {
      $('#f1').submit(function (e) {
        alert('监听到表单的提交事件')
        // 阻止表单的提交和页面的跳转
        e.preventDefault()
      })
    })

快速获取表单内的数据:

jQuery提供了**serialize()**函数,可以一次性的获取到表单中的所有数据(必须为每个表单元素添加name属性)

$(selector).serialize()
 <body>
    <form action="/login" id="f1">
      <input type="text" name="username" />
      <br />
      <input type="password" name="password" />
      <br />
      <button type="submit">提交</button>
    </form>
  </body>
  <script>
    $(function () {
      $('#f1').submit(function (e) {
        // alert('监听到表单的提交事件')
        // 阻止表单的提交和页面的跳转
        e.preventDefault()

        var data = $(this).serialize()
        console.log(data) //username=1111&password=2222
      })
    })
  </script>

同源策略:

什么是同源策略:

如果两个页面的协议 (http) ,域名(www.xxx.com) 和端口(80) 都相同,则两个页面具有相同的源

http://www.test.com/index.html

http://www.test.com/outer.html      同源
https://www.test.com/about.html     不同源    协议不同
http://blog.test.com/index.html     不同源    域名不同
http://www.test.com:80/outer.html   同源

同源策略 是浏览器提供的一个安全策略

浏览器规定:A网站的JavaScript  不允许和非同源的 网站c之间 进行资源交互

跨域:

什么是跨域:

同源是两个url的协议,域名,端口一致,反之就是跨域

出现跨域的原因:浏览器的同源策略不允许非同源的url之间进行数据交换

网页   http://www.test.com/index.html

接口:  https://www.api.com/index.html

报错出现:Access-Control-Allow-Origin 就是跨域

解决跨域:

两种方案解决跨域: JSONPCORS

JSONP:

出现的早,兼容性好,程序员为了解决跨域问题,被迫想出来的一种临时解决方案,缺点:只支持get请求,不支持post请求

浏览器的同源策略限制,网页中无法通过Ajax请求非同源的接口数据,但是script标签不受同源策略的限制,可以通过src属性,请求非同源的js脚本

jsonp的实现原理:就是通过script标签的src属性,请求跨域的数据接口,通过函数调用的形式,接收跨域接口响应回来的数据

callback为响应数据所返回到的函数位置,可在后面直接加参数

和ajax请求没有关系,仅是通过script进行请求

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    function abc(data) {
      console.log('jsonp请求')
      console.log(data)
    }
  </script>

  <!-- 返回的是函数调用 -->
  <script src="http://www.liulongbin.top:3006/api/jsonp?callback=abc"></script>

  <!-- jsonp和ajax之间没有任何关系 -->
</html>
CORS:

出现的较晚,是W3C标准,属于跨域Ajax请求的根本解决方案,支持GET和POST请求,不兼容低版本的浏览器,写法类似于js的ajax

jQuery中JSONP的实现:

jQuery中的JSONP 通过script标签的src属性,实现跨域数据访问的,jQuery采用的是动态创建和移除script标签的方式,来发起JSONP数据请求

在发起JSONP请求的时候,动态向head中append一个script标签

JSONP请求成功之后,动态从head中移除刚才append进去的script标签

$(function () {
    $.ajax({
        url: "http://www.liulongbin.top:3006/api/jsonp?name='zs'&age=12",
        dataType: 'jsonp',
        // 发送到服务器的参数名称,默认值为callback
        jsonp: 'callback',
        // 自定义回调函数名称 默认值为jQueryxxxx
        jsonpCallback: 'abc',
        success(res) {
            console.log(res)
        },
    })
})

防抖[重要]:

var timer = null   //1-1防抖的timer

$('#ipt').on('keyup', function () {
    // 1-3 清除timer
    clearTimeout(timer)

    //省略其他代码....

    // 1-2定义防抖
    // 获取搜索列表
    timer = setTimeout(function () {
        getSuggestList(keywords)
    }, 800)
})

缓存搜索的列表:

1、定义全局缓存对象:
var cacheObj= {}
2、将搜索结果存储到缓存对象中:
// 渲染UI结构
function renderSUggestList(res) {
    // 如果没有数据需要渲染 直接return
    if (res.result.length <= 0) {
        return $('.suggest-list').empty().hide()
    }
    var rows = []
    // console.log(res.result)
    $.each(res.result, function (i, item) {
        // console.log(item[0])

        rows.push(`
        <div class="suggest-item">${item[0]}</div>`
                 )
    })

    $('.suggest-list').empty().append(rows.join('')).show()

    // 1获取用户输入的内容 当做键
    var k = $('#ipt').val().trim()
    // 将数据作为值 进行缓存
    cacheObj[k] = res
    // console.log(cacheObj)
}
3、优先从缓存中获取搜索列表
$('#ipt').on('keyup', function () {
    // 1-3 清除timer
    clearTimeout(timer)
    // 1获取用户输入的内容
    var keywords = $(this).val().trim()
    // 2 判断用户输入的内容是否为空
    // 清空搜索列表
    if (keywords.length <= 0) {
        return $('.suggest-list').empty().hide()
    }
    // console.log(keywords)

    //  先判断缓存中是否有数据
    if (cacheObj[keywords]) {
        return renderSUggestList(cacheObj[keywords])
    }

    // 1-2定义防抖
    // 获取搜索列表
    timer = setTimeout(function () {
        getSuggestList(keywords)
    }, 800)
})

节流[重要]:

节流策略:可以减少一段时间内事件的触发频率

场景:

鼠标连续不断的触发某事件(点击),只在单位时间内触发一次

懒加载时要监听计算滚动条的位置,不必每次滑动都触发,可以降低计算的频率,而不必去浪费CPU资源

高铁卫生间是否被占用,由红绿灯控制,红灯表示被占用,绿灯表示可使用
每个人上厕所都要花费5分钟,五分钟之内,被占用的卫生间无法被其他人使用
上一个人使用完毕后,需要将红的重置为绿灯,表示下一个人可以使用卫生间
下一个人在上卫生间之前,需要先判断灯是否为绿灯,来知晓是否能上卫生间


节流阀为空,可以执行下次操作;不为空,不能执行下次操作
当前操作执行完,必须将节流阀重置为空,表示可以执行下次操作了
每次执行操作前,先判断节流阀是否为空
$(function () {
    // 获取图片
    var angel = $('#angel')

    // 定义一个timer节流阀
    var timer = null

    $(document).on('mousemove', function (e) {
        //每次执行操作前,先判断节流阀是否为空  不为空 不能执行(证明距离上次执行不足16毫秒)
        if (timer) {
            return
        }

        timer = setTimeout(function () {
            console.log(e.pageX, e.pageY)
            angel.css('top', e.pageY + 'px').css('left', e.pageX + 'px')
            timer = null //设置了鼠标跟随效果后,清空节流阀 方便下次开启定时器
        }, 160)
    })
})

防抖和节流的区别:

  • 防抖:事件被频繁触发,防抖能保证只有最后一次触发生效,前面N多次的触发都会被忽略
  • 节流:事件被频繁触发,节流能够减少事件触发的频率,有选择性的执行一部分事件

HTTP:

HTTP协议简介:

什么是通信:

通信就是信息的传递和交互

通信三要素: 通信的主体,通信的内容,通信的方式

现实生活中的通信:

张三要把自己考上北京大学的好消息写信告诉自己的好朋友李四

通信的主体(张三和李四),通信的内容(考上北京大学),通信的方式(写信)

互联网中的通信:

服务器北京大学的介绍通过响应的方式发送给客户端

通信的主体(服务器和客户端),通信的内容(北京大学的介绍),通信的方式(响应)

通信协议:

通信协议是指通信的双方完成通信所必须遵守规则和约定

通信双方采用预定好的格式来发送和接收信息,这种事先约定好的通信格式,就叫做通信协议

现实中的通信:

写信双方必须遵守的规定的规则,信封的填写规则就是一种通信协议

互联网中的通信:

客户端和服务端之间要实现网页内容的传输,通信的双方必须遵守网页内容的传输协议

网页内容又叫做超文本,网页内容的传输协议又叫做超文本传输协议 简称HTTP协议

什么是HTTP协议:

HTTP协议就是超文本传输协议,规定了客户端和服务端之间进行网页内容的传输时,所必须遵守的传输格式

客户端要以HTTP协议要求的格式把数据提交服务器

服务器要以HTTP协议要求的格式把内容响应客户端

HTTP协议交互的模型:

HTTP协议采用了请求/响应的交互模型

在这里插入图片描述

HTTP请求消息:

由于HTTP协议属于客户端浏览器和服务器之间的通信协议,所以,客户端发起的请求叫做http请求客户端发送到服务器的消息,叫做http请求消息

http请求消息又叫做http请求报文

HTTP请求消息组成部分:

HTTP请求消息 由 请求行 ,请求头部,空行和请求体 4个部分组成

在这里插入图片描述

请求行:

请求行由请求方式URLHTTP协议版本3个部分组成,他们之间用空格隔开

在这里插入图片描述

请求头部:

请求头部用来描述客户端的基本信息,把客户端相关的信息告知服务器

User-Agent:当前是什么类型的浏览器

Accept: 用来描述客户端能够接收什么类型的返回内容

Accept-Language :客户端期望接收那种人类语言的文本内容

Host: 请求的服务器名字
Connection:客户端和服务端之间的连接方式

请求头部由多行 键值对组成,每行的键和值之间用英文的冒号分隔

空行:

请求头字段的后面是一个空行,通知服务器请求头部到此结束

请求消息中的空行,用来分隔请求头和请求体

请求体:

请求体中存放的,是要通过post方式提交到服务器的数据

只有post请求才有请求体,GET请求没有请求体

在这里插入图片描述

HTTP响应消息:

响应消息就是服务器响应给客户端的消息内容 ,也叫做响应报文

HTTP响应消息组成部分:

HTTP响应消息由状态行,响应头部,空行,响应体 4个部分组成

在这里插入图片描述

状态行:

http协议版本状态码状态码的描述文本 3个部分组成,之间用空格隔开

在这里插入图片描述

响应头:

响应头用来描述服务器的基本信息,响应头部由多行 键值对 组成,每行的键和值之间用英文的冒号分隔

在这里插入图片描述

空行:

最后一个响应头部字段结束之后,会紧跟一个空行,用来通知客户端响应头部至此结束

响应消息中的空行,用来分隔 响应头和响应体

响应体:

响应体中存放的,是服务器响应给客户端的资源内容

在这里插入图片描述

HTTP请求方法:

什么是HTTP请求方法:

HTTP请求方法 属于http协议中的一部分,请求方法的作用,用来表明 要对服务器上的资源执行的操作

最常用的请求方法 GET和POST

HTTP请求方法:

GET 发送请求来获得服务器上的资源(查询)
POST 向服务器提交资源(提交表单或上传文件) 新增
PUT 向服务器提交新的资源,替换服务器对应的旧的资源(修改)
DELETE 请求服务器删除指定的资源(删除)

HTTP响应状态码:

HTTP响应状态码 属于http协议中的一部分,用来标识响应的状态

响应状态码会随着响应消息一起发送至客户端浏览器,浏览器根据服务器返回的响应状态码,就能知道这次http请求的结果是成功还是失败

http状态码由三个十进制数字组成**,第一个十进制数字定义了状态码的类型**,后两个数字用来对状态码进行细分

1xx   信息,服务器收到请求,需要请求者继续执行操作(实际开发中,很少遇到1xx 的状态码)
2xx   成功,操作被成功接收并处理
3xx   重定向,需要进一步操作以完成请求
4xx   客户端错误,url错误,请求包含语法错误无法完成请求
5xx   服务器错误,服务器在处理请求的过程中发生了错误

2xx成功相关的响应状态码:

2xx表示服务器已成功接收到请求并进行处理

200    ok    请求成功,一般用于get和post请求
201          已创建,成功请求并创建了新的资源,用于put和post请求

3xx成功相关的响应状态码:

服务器要求客户端重定向,需要客户端进一步的操作以完成资源的请求

301  永久移动  请求的资源被永久的移动到新的URL,返回信息包括新的URL
302  临时移动  资源只是临时移动,客户端应继续使用原有的URL
304  未修改   所请求的资源未修改,服务器返回该状态,不会返回任何资源

4xx成功相关的响应状态码:

客户端请求有非法内容跟,从而导致这次请求失败

400   语法有错,  请求参数有错误
401   当前请求需要用户验证  (token)
403   服务器已经理解请求,但是拒绝执行它
404   服务器无法根据客户端请求找到资源(路径错误)
408   请求超时,服务器等待客户端发送的请求超时

5xx成功相关的响应状态码:

服务器未能正常处理客户端的请求而出现的意外错误

500   服务器内部错误,无法完成请求
501   服务器不支持该请求方法,无法完成请求(只有GET和HEAD请求方法是要求每个服务器必须支持的,其它请求方法在不支持的服务器上会返回501)
503   由于超载或者系统维护,服务器暂时无法处理客户端的请求

FormData对象:

为了方便表单处理,HTML5新增了一个FormData对象,可以模拟表单操作

FormData是Ajax 2.0对象用以将数据编译成键值对,以便于XMLHttpRequest来发送数据。XMLHttpRequest Level 2提供的一个接口对象,可以使用该对象来模拟和处理表单并方便的进行文件上传操作。
/* 
FormData键值对的形式 发送数据   ,主要针对表单元素

*/
//  1  创建FormData对象
var fd = new FormData()
//2 调用append函数,向fd中追加数据
// 添加数据
fd.append('username', 'zs')
fd.append('pwd', '123456')
// console.log(fd)
// 获取数据
console.log(fd.get('username'))
fd.append('k1', 'v1')
// 设置修改数据,如果指定的key不存在则会新增一条,如果存在,就会修改对应的value值
fd.set('k1', '1')
console.log(fd.get('k1'))

// 判断是否存在对应数据
console.log(fd.has('k1')) //true
console.log(fd.has('k3')) //false

// 删除数据 delete key
// fd.delete('k1')

fd.append('k1', 'v3')

console.log(fd.getAll('k1')) //[]   ["1","v3"]

发送数据:

// 1创建formdata对象
var fd = new FormData()

// 2 调用append函数 ,向fd中追加数据
fd.append('username', 'ls')
fd.append('pwd', '12345')

// 使用XMLHttpRequest发送数据

// var xhr = new XMLHttpRequest()
// xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// xhr.send(fd)
// xhr.onreadystatechange = function () {
//   if (xhr.readyState === 4 && xhr.status === 200) {
//     console.log(JSON.parse(xhr.responseText))
//   }
// }

$.ajax({
    url: 'http://www.liulongbin.top:3006/api/formdata',
    type: 'POST',
    data: fd, //上传formData封装的数据
    dataType: 'JSON',
    processData: false, //jquery不要去处理发送的数据
    success(res) {
        console.log(res)
    },
})

获取表单数据:

// 获取form表单元素
var form = document.querySelector('#form1')

form.addEventListener('submit', function (e) {
    // 阻止默认行为
    e.preventDefault()
    // 创建formData快速获取到form表单中的数据
    var fd = new FormData(form)

    $.ajax({
        url: 'http://www.liulongbin.top:3006/api/formdata',
        type: 'POST',
        data: fd, //上传formData封装的数据
        dataType: 'JSON',
        processData: false, //jquery不要去处理发送的数据
        success(res) {
            console.log(res)
        },
    })
})
<form id="form1">
    <input type="text" name="username" id="" />
    <br />
    <input type="password" name="pwd" />
    <br />
    <button type="submit">提交</button>
</form>

上传文件:

XMLHttpRequest对象,不仅可以发送文本信息,还可以上传文件

思路:

1:定义ui结构

2:验证是否选择了文件

3:向FormData中追加数据

4:使用xhr发起上传文件的请求

// 获取文件上传按钮
var btnEle = document.querySelector('#btnUpload')

// 绑定事件
btnEle.addEventListener('click', function () {
    //  获取用户选择的文件列表
    var files = document.querySelector('#file1').files
    console.log(files)
    if (files.length <= 0) {
        return alert('请选择要上传的文件')
    }
    var fd = new FormData()
    // 用户选择的文件 追加到FormData中
    // avatar  请求的参数
    fd.append('avatar', files[0])

    var xhr = new XMLHttpRequest()
    xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
    xhr.send(fd)

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(xhr.responseText)
            var data = JSON.parse(xhr.responseText)
            if (data.status === 200) {
                document.querySelector('#img').src =
                    'http://www.liulongbin.top:3006' + data.url
            } else {
                alert('图片上传失败')
            }
        }
    }
})
文件上传进度条:

在创建请求对象后监听上传进度事件

// 获取文件上传按钮
var btnEle = document.querySelector('#btnUpload')

// 绑定事件
btnEle.addEventListener('click', function () {
    //  获取用户选择的文件列表
    var files = document.querySelector('#file1').files
    // console.log(files)
    if (files.length <= 0) {
        return alert('请选择要上传的文件')
    }
    var fd = new FormData()
    // 用户选择的文件 追加到FormData中
    // avatar  请求的参数
    fd.append('avatar', files[0])

    var xhr = new XMLHttpRequest()

    // 监听文件上传进度事件
    xhr.upload.onprogress = function (e) {
        console.log(1)
        // 判断所关联的资源是否具有可以计算的长度
        if (e.lengthComputable) {
            // console.log(1)
            // 计算上传的进度,  计算当前上传进度的百分比
            // e.loaded 已经接收的字符数
            // total 文件的字节
            var procentComplete = Math.ceil((e.loaded / e.total) * 100)
            // 动态设置进度条
            $('#percent')
                .attr('style', 'width:' + procentComplete + '%')
                .html(procentComplete + '%')
        }
    }

    // 上传完成事件
    xhr.upload.onload = function () {
        console.log(123)
        $('#percent')
            .removeClass()
            .addClass('progress-bar progress-bar-success')
    }

    xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
    xhr.send(fd)

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(xhr.responseText)
            var data = JSON.parse(xhr.responseText)
            if (data.status === 200) {
                document.querySelector('#img').src =
                    'http://www.liulongbin.top:3006' + data.url
            } else {
                alert('图片上传失败')
            }
        }
    }
})

axios:

Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js

封装了ajax

特性:

  • 从浏览器创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF

使用:

  • 引入
<script src="./axios.min.js"></script>
  • 使用
// axios发起post请求
// bookname=js编程&author=丁鹿学堂学员&publisher=北京出版社
axios({
    method: 'post', //请求方式
    url: 'http://www.liulongbin.top:3006/api/addbook', //请求的url
    data: {
        //请求的数据
        bookname: 'jq编程',
        author: '学员',
        publisher: '上海出版社',
    },
})
    .then((res) => {
    //请求成功执行then方法
    // res 响应成功返回的内容
    console.log(res)
})
    .catch((err) => {
    console.log(err)
})

Promise:

问题:多层回调函数 相互嵌套 就形成了回调地狱

缺点: 大量冗余代码相互嵌套可读性很差 不易维护,所以用promise对象

setTimeout(()=>{
    setTimeout(()=>{
        setTimeout(()=>{
            
        },3000)
    },2000)
},1000)

如何解决回调地狱:

Es6 新增了promise的概念

1:Promise是一个构造函数

创建一个promise实例,const p = new Promise()

new出来的promise实例对象,代表一个异步操作

2:Promise.prototype上包含一个then方法

每次new Promise得到的实例对象

都可以通过原型链的方式访问到then方法

3:then方法用来预先指定成功和失败的回调函数

4:catch方法用来捕获错误的

var p = new Promise()
p.then(成功的回调函数,失败的回调函数)
p.then(()=>{},()=>{})

**注意:**调用then方法,成功的回调函数是必选的,失败的回调函数是可选的

// Promise  构造函数  参数是一个回调函数,回调函数有两个参数resolve reject
// new出来的promise实例对象,代表一个异步操作
// 异步请求成功执行resolve方法   异步请求失败执行reject方法
//promise状态: 等待 pending   成功 fulfilled   失败rejected  状态一旦改变,不能再更改
new Promise((resolve, reject) => {
    console.log($)
    //  异步请求
    $.ajax({
        type: 'GET',
        url: 'http://www.liulongbin.top:3006/api/getbooks',
        success(res) {
            // resolve(res)
            reject('错误')
        },
    })
})
    .then((res) => {
    console.log(res, 'res')
    return res.data
})
    .then((res1) => {
    console.log(res1, 'res1')
    return 4
})
    .then((res2) => {
    console.log(res2)
})
    .catch((err) => {
    //专门用来捕获错误的
    console.log(err, 'catch')
})

all方法:

Promise.all()方法会发起并行的Promise异步操作,等所有的异步操作全部结束后才会执行下一步的then操作

// http://www.liulongbin.top:3006/api/news
// Promise.all()方法会发起**并行**的Promise异步操作,
// 等所有的异步操作全部结束后才会执行下一步的then操作
function fn() {
    return axios({
        method: 'GET',
        url: 'http://www.liulongbin.top:3006/api/news',
    })
}

function fn1() {
    return axios({
        method: 'GET',
        url: 'http://www.liulongbin.top:3006/api/getbooks',
    })
}

Promise.all([fn(), fn1()])
    .then(([res1, res2]) => {
    console.log(res1, res2)
})
    .catch((err) => {
    console.log(err)
})

race:

Promise.race()方法会发起并行的Promise异步操作,只要任何一个异步操作完成,就立即执行下一步的then操作

// Promise.race()方法会发起**并行**的Promise异步操作,只要任何一个异步操作完成,就立即执行下一步的then操作
function fn() {
    return axios({
        method: 'GET',
        url: 'http://www.liulongbin.top:3006/api/news',
    })
}

function fn1() {
    return axios({
        method: 'GET',
        url: 'http://www.liulongbin.top:3006/api/getbooks',
    })
}

Promise.race([fn(), fn1()])
    .then((res) => {
    // 只要任何一个异步操作完成,就立即执行下一步的then操作
    console.log(res)
})
    .catch((err) => {
    console.log(err)
})

基于promise封装异步请求:

1:定义方法getPromise

2:方法接收参数请求的数据,请求的url

3:方法的返回值未promise实例对象

function getBookList(data, url) {
    return new Promise((resolve, reject) => {
        //异步请求
        axios({
            method: 'GET',
            url: url,
            params: data,
        })
            .then((res) => {
            resolve(res)
        })
            .catch((err) => {
            reject(err)
        })
    })
}

getBookList({}, 'http://www.liulongbin.top:3006/api/getbooks')
    .then((res) => {
    console.log(res)
})
    .catch((err) => {
    console.log(err)
})

async/await:

async/await 是es6引入的新语法,用来简化promise异步操作,在async/await出现之前,我们只能通过then的方法处理promise异步操作

如果在function中使用了await 那么function必须被async修饰

在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行

function fn() {
    return axios({
        method: 'GET',
        url: 'http://www.liulongbin.top:3006/api/news',
    })
}

function fn1() {
    return axios({
        method: 'GET',
        url: 'http://www.liulongbin.top:3006/api/getbooks',
    })
}
// async 说明函数是一个异步操作的函数
// 按照顺序执行异步请求数据
async function getData() {
    console.log(2)
    // await等待
    let res1 = await fn1()
    console.log(res1)
    let res2 = await fn()
    console.log(res2)
    console.log(1)
}

getData()
// async -await  用同步的写法 执行异步操作

ction fn1() {
return axios({
method: ‘GET’,
url: ‘http://www.liulongbin.top:3006/api/getbooks’,
})
}

Promise.race([fn(), fn1()])
.then((res) => {
// 只要任何一个异步操作完成,就立即执行下一步的then操作
console.log(res)
})
.catch((err) => {
console.log(err)
})


### 基于promise封装异步请求:

> 1:定义方法getPromise
>
> 2:方法接收参数请求的数据,请求的url
>
> 3:方法的返回值未promise实例对象

```JavaScript
function getBookList(data, url) {
    return new Promise((resolve, reject) => {
        //异步请求
        axios({
            method: 'GET',
            url: url,
            params: data,
        })
            .then((res) => {
            resolve(res)
        })
            .catch((err) => {
            reject(err)
        })
    })
}

getBookList({}, 'http://www.liulongbin.top:3006/api/getbooks')
    .then((res) => {
    console.log(res)
})
    .catch((err) => {
    console.log(err)
})

async/await:

async/await 是es6引入的新语法,用来简化promise异步操作,在async/await出现之前,我们只能通过then的方法处理promise异步操作

如果在function中使用了await 那么function必须被async修饰

在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行

function fn() {
    return axios({
        method: 'GET',
        url: 'http://www.liulongbin.top:3006/api/news',
    })
}

function fn1() {
    return axios({
        method: 'GET',
        url: 'http://www.liulongbin.top:3006/api/getbooks',
    })
}
// async 说明函数是一个异步操作的函数
// 按照顺序执行异步请求数据
async function getData() {
    console.log(2)
    // await等待
    let res1 = await fn1()
    console.log(res1)
    let res2 = await fn()
    console.log(res2)
    console.log(1)
}

getData()
// async -await  用同步的写法 执行异步操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小刘私坊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值