jQuery02
复习
DOM的零散知识
- 阻止默认事件:
event.preventDefault()
- 超链接a标签自带
href
属性, 点击之后会进行跳转. 给a标签绑定事件 则通常要阻止自带的 href 跳转操作 - 问题点: 书写外部的js文件 给其他 伙伴 使用, 引入时要防御使用者带有href的情况
- 阻止冒泡:
event.stopPropagation()
- 监听页面滚动:
onscroll
- 读取滚动距离:
document.documentElement.scrollTop || document.body.scrollTop
- 手动创建DOM元素
- 创建:
document.createElement(标签名)
- 添加到子元素:
appendChild
- 文档片段:
document.createDocumentFragment()
- 事件监听器: 可以为同一个事件 添加多个不同的触发方法
addEventListener(事件名, 方法名)
BOM: 浏览器对象模型
- open: 打开新的页面
- location: 获取当前页面相关信息
- navigator: 获取浏览器相关信息
- history: 操作历史, 前进/后退/刷新
history.go()
jQuery
- 理念:
write less, do more
写的少,做的多 - 是利用
函数封装
和函数重载
对原生DOM 进行了封装之后得到的扩展包 - 基础思路
$()
: 一个名称是$
的函数
-
$(字符串)
: 把字符串当 css选择器 使用 -
$(DOM元素)
: 把DOM元素转化成 jQuery 对象 -
$(函数)
: 在页面加载完毕时, 再执行函数
- 事件/属性 等方法
-
$().css()
: 内部带有遍历
操作, 会把查询到的每个元素进行操作 .
- 属性
- css: 操作内联样式 style
-
css(属性名)
: 读取指定属性的值 -
css({名, 值})
: 设置多个属性的值 -
css(属性名, 值)
: 设置单个属性的值
- addClass: 添加样式类
- removeClass: 删除样式类
- toggleClass: 切换样式类
- click: 点击
- mouseover: 鼠标悬浮
- siblings: 选择所有同级别的其他元素
- nextAll: 下方所有同级别元素
- prevAll: 上方所有同级别元素
- 属性操作
- prop: 原生的新写法
- prop(属性名): 读值
- prop(属性名, 值): 写值
- attr: 原生的旧写法
- 双标签内容:
html()
本质是innerHTML
- 包含关系:
-
:contains()
: 标签内容中包含… -
:empty
: 空的标签 -
:parent
: 非空的标签 -
:has()
: 子元素中含有指定的
- eq(): 从查询结果中获取指定序号的元素 并且 封装成JQ对象
昨日作业
<!DOCTYPE html>
<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>
<style>
#menu {
width: 800px;
background-color: #002c69;
user-select: none;
}
#menu > span {
display: inline-block;
padding: 10px 20px;
color: white;
font-size: 1.3em;
}
#menu > span.cur {
background-color: orange;
}
</style>
</head>
<body>
<div id="menu">
<span class="cur">首页</span>
<span>关于净美仕</span>
<span>公司动态</span>
<span>产品中心</span>
<span>联系我们</span>
</div>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
$('#menu>span').click(function () {
// 为当前点击项添加cur, 为他的兄弟们移除cur
// 把 this 封装成JQ的对象 $() 才能用JQ的方法
$(this).addClass('cur').siblings().removeClass('cur')
})
</script>
</body>
</html>
动画切换选中状态
<!DOCTYPE html>
<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>
<style>
#menu {
width: 800px;
background-color: #002c69;
user-select: none;
/* 为了配合子元素的绝对定位 */
position: relative;
}
#menu > span {
display: inline-block;
padding: 10px 20px;
color: white;
font-size: 1.3em;
/* 定位元素: 调整层级 */
position: relative;
z-index: 10;
}
#menu > .block {
background-color: orange;
width: 80px;
height: 100%;
/* 定位方式,实现元素之间的层叠 */
/* 绝对定位 搭配 父元素的 相对定位使用 */
position: absolute;
/* 初始值: 靠左, 动画0.3s */
left: 0;
transition: 0.3s;
}
</style>
</head>
<body>
<div id="menu">
<!-- 小色块 -->
<div class="block"></div>
<span>首页</span>
<span>关于净美仕</span>
<span>公司动态</span>
<span>产品中心</span>
<span>联系我们</span>
</div>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
$('#menu>span').click(function () {
// 能否找到 x,y的值 + 宽和高?
console.dir(this)
const { offsetLeft, offsetWidth } = this
// 宽和偏移量 设置给 色块
$('#menu > .block').css({
left: offsetLeft,
width: offsetWidth,
})
})
</script>
</body>
</html>
输入框相关
<!DOCTYPE html>
<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>
<input type="text" value="666" />
<br />
<button>读取</button>
<button>设置</button>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
// eq: 有两种语法 $().eq(0) 或 如下:
$('button:eq(0)').click(function () {
// val 是 value 的缩写
console.log($('input').val())
})
$('button')
.eq(1)
.click(function () {
// type='text' 可以用 :text 来选择
$(':text').val('高达555')
// val 的函数重载:
// val(): 不带参数是读
// val(值): 带参数是写
})
// 输入框的相关事件:
// 获得焦点
$('input').focus(function () {
console.log('获得焦点')
})
// 失去焦点
$('input').blur(function () {
console.log('失去焦点')
})
// 内容变化: 改->失去焦点
$('input').change(function () {
// this.value: 原生DOM的语法
console.log('内容变化:', this.value)
})
// 键盘事件
$('input').keyup(function (e) {
console.log('键盘:', e)
// 回车的 keyCode 13
if (e.keyCode == 13) console.log('回车')
})
// 实时监听: JQ并没有封装所有的DOM事件, 但是提供了万能方法: on(事件名, 函数)
$('input').on('input', function () {
console.log(this.value)
})
</script>
</body>
</html>
计数器
<!DOCTYPE html>
<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>
<style>
div {
display: flex;
}
div > input {
width: 30px;
text-align: center;
}
</style>
</head>
<body>
<div>
<button disabled>-</button>
<input type="text" value="1" />
<button>+</button>
</div>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
$('button')
.eq(1)
.click(function () {
// 原生的上一个兄弟: previousElementSibling
const $inp = $(this).prev()
console.log($inp)
const newVal = $inp.val() * 1 + 1
$inp.val(newVal)
// 让 减按钮 可用: 不可用 是 假的
// prop(属性名,值): JQ对象提供的属性设置方式
$inp.prev().prop('disabled', false)
})
$('button')
.eq(0)
.click(function () {
// 减按钮的 下一个兄弟: next
const $inp = $(this).next()
// [0] : 获取JQ对象 $inp 中的序号0的元素 -- 原生DOM
$inp[0].value--
// 输入框值为1 则减按钮 无效
if ($inp.val() == 1) this.disabled = true
})
// 如果输入框的值 不是正常的数字, 则变为1
$('input').change(function () {
// this.value: 读取输入框的值
// ^:开头 [1-9]: 1到9之间的数字
// \d: 任意数字 *:前方元素数量 0个及以上 $:结尾
const reg = /^[1-9]\d*$/
// 正则验证: 如果结果不正确, 则值改为1
if (reg.test(this.value) == false) this.value = 1
// 如果新的值是 1, 减按钮不可用, 不是1减按钮可用
$(this).prev().prop('disabled', this.value == 1)
})
</script>
</body>
</html>
动画效果
<!DOCTYPE html>
<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>
<style>
#box {
width: 100px;
height: 100px;
background-color: aqua;
}
</style>
</head>
<body>
<button>显示</button>
<button>隐藏</button>
<button>切换</button>
<div id="box"></div>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
// 显示
$('button:eq(0)').click(function () {
// 参数1: 动画速度, 默认是0, 可选值: slow fast 或 毫秒
// 参数2: 动画结束后的回调函数
$('#box').show('slow', function () {
alert('已完成显示')
}) //显示
})
// 隐藏
$('button:eq(1)').click(function () {
$('#box').hide('fast') //隐藏
})
// 切换
$('button:eq(2)').click(function () {
// 利用回调函数: 实现动画的无限循环
$('#box').toggle(1000, function () {
// click: 没有参数, 代表触发点击事件
$('button:eq(2)').click()
})
})
</script>
</body>
</html>
滑动动画
<!DOCTYPE html>
<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>
<style>
#box {
width: 100px;
height: 100px;
background-color: aqua;
}
</style>
</head>
<body>
<button>显示</button>
<button>隐藏</button>
<button>切换</button>
<div id="box"></div>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
$('button:eq(0)').click(function () {
$('#box').slideDown() //展开
})
$('button:eq(1)').click(function () {
$('#box').slideUp() //收起
})
$('button:eq(2)').click(function () {
// 参数1: 动画时长 slow fast 或 毫秒
// 参数2: 回调函数 -- 动画结束后触发
$('#box').slideToggle('slow', function () {
// alert('动画结束')
// 本次切换效果结束后, 再次触发切换
// 再次触发 切换按钮的点击事件
// click(): 没有值, 函数重载中 会实现触发点击事件的效果
console.log('切换动画已结束, 再次触发切换按钮的事件')
$('button:eq(2)').click()
}) //切换
})
</script>
</body>
</html>
透明度动画
<!DOCTYPE html>
<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>
<style>
#box {
width: 100px;
height: 100px;
background-color: aqua;
}
</style>
</head>
<body>
<button>显示</button>
<button>隐藏</button>
<button>切换</button>
<button>半透明</button>
<div id="box"></div>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
$('button:eq(0)').click(function () {
$('#box').fadeIn() //渐入
})
$('button:eq(1)').click(function () {
$('#box').fadeOut() //渐出
})
$('button:eq(2)').click(function () {
// 参数1: 动画时长 -- slow fast 或 毫秒
// 参数2: 完成时的回调
$('#box').fadeToggle('slow') //切换
})
$('button:eq(3)').click(function () {
// 参数1: 动画时长 - slow fast 或 毫秒数
// 参数2: 目标透明度
$('#box').fadeTo(1000, 0.2)
})
</script>
</body>
</html>
自定义动画
<!DOCTYPE html>
<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>
<style>
#box {
width: 100px;
height: 100px;
background-color: blueviolet;
position: relative;
}
</style>
</head>
<body>
<button>开始动画</button>
<button>结束动画</button>
<div id="box"></div>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
// 开始
$('button:eq(0)').click(function () {
// 参数1: 动画结束时的css样式
// 参数2: 动画时长
// 参数3: 动画完成后的回调
// 动画序列: 多个动画依次执行
$('#box')
.animate({ width: '50px', height: '50px' }, 500)
.animate({ borderRadius: '50%' }, 1000)
.animate({ left: '200px', opacity: 0 }, 500, function () {
//把之前动画修改的值都复原
$(this).css({
width: '100px',
height: '100px',
borderRadius: 0,
left: 0,
opacity: 1,
})
// 反复执行:
$('button:eq(0)').click()
})
})
// JQ不支持: 颜色相关的动画 和 transform相关
// 停止
$('button:eq(1)').click(function () {
// stop(): 默认停止当前进行中的动画, 继续后续的
// 参数1: 是否停止队列中所有动画, 默认是false
// 参数2: 停止动画时, 是否直接变为结束时的样子
$('#box').stop(true, true)
})
</script>
</body>
</html>
轮播图动画
<!DOCTYPE html>
<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>
<style>
#banner {
display: flex;
border: 2px solid black;
width: 200px;
overflow: hidden;
}
/* #banner > img:first-child {
margin-left: -600px;
} */
</style>
</head>
<body>
<div id="banner">
<img src="./images/1.jpg" alt="" />
<img src="./images/2.jpg" alt="" />
<img src="./images/3.jpg" alt="" />
<img src="./images/4.jpg" alt="" />
</div>
<button>上一页</button>
<button>下一页</button>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
// 代表当前是否可以点击 上一页/下一页
let canGoNext = true
// 上一页
$('button:eq(0)').click(function () {
if (canGoNext == false) return //如果有锁,则停止操作
canGoNext = false //进门之后, 上锁
const $img0 = $('#banner > img:eq(0)')
const ml = $img0.css('marginLeft')
console.log(ml)
$img0.animate(
{
marginLeft: ml == '0px' ? '-600px' : '+=200px',
},
300,
function () {
canGoNext = true //结束后, 开锁
}
)
})
// 如何确保上厕所的时候安全? -- 蹲坑时 别人进不来
// 安装门锁
// 上厕所-> 先判断门锁没锁
// 如果 锁==true : 等...
// 如果 锁==false : 进入 并且 把门锁上 -> 完事之后 再开锁
// 关于: canGoNext 的作用
// 问题: 多次点击操作, 每次都会触发动画, 如果点击触发的时机是动画正在执行时, 会导致 最后一页的 边距判断失败
// 解决: 排除掉 动画执行期间的 点击操作
// 做法: 制作一个变量 canGoNext, 让其在动画期间值保持false, 动画结束后 值为true
// 点击后 判断 canGoNext, 为false 说明动画在进行中, 就不执行后续代码
$('button:eq(1)').click(function () {
// 执行后续代码前: 先判断是否允许
// 如果不允许 则 终止执行
if (canGoNext == false) return
canGoNext = false // 无法继续点击下一页
//读取当前的marginLeft
const $img0 = $('#banner>img:eq(0)')
const ml = $img0.css('marginLeft')
console.log(ml)
// 移动 第一张图片的 左侧外边距
$img0.animate(
{
// -= : 当前基础上 -200px
marginLeft: ml == '-600px' ? 0 : '-=200px',
},
300,
function () {
canGoNext = true //开锁, 后续点击可以继续
}
)
})
// 定时器: 每2s 触发一次下一页
setInterval(() => {
// click(): 没有参数, 作用是触发事件 -- 函数重载
$('button:eq(1)').click()
}, 2000)
</script>
</body>
</html>
数据的动态添加
<!DOCTYPE html>
<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>
<button>添加</button>
<button>添加多个</button>
<ul></ul>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
$('button:eq(0)').click(function () {
// 添加子元素: append
$('ul').append('<li>高达</li>')
})
// 加多个
$('button:eq(1)').click(function () {
const els = ['<li>亮亮</li>', '<li>暗暗</li>']
// append: 自动检测参数类型, 如果数组会自动转字符串进行添加
$('ul').append(els)
})
</script>
</body>
</html>
兄弟元素的添加
<!DOCTYPE html>
<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>
<button>前方添加</button>
<button>后方添加</button>
<div>111111</div>
<div id="d2">999999</div>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
//前方
$('button:eq(0)').click(function () {
// before: 在...之前
$('#d2').before('<div>Hello</div>')
})
// 后方
$('button:eq(1)').click(function () {
// after: 在...之后
$('#d2').after('<div>World</div>')
})
</script>
</body>
</html>
删除
<!DOCTYPE html>
<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>
<button>清空</button>
<button>删除最后一个</button>
<div id="box">
<li>达1</li>
<li>达2</li>
<li>达3</li>
<li>达4</li>
</div>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
$('button:eq(0)').click(function () {
// empty: 空的
$('#box').empty()
})
//删除最后一个孩子
$('button:eq(1)').click(function () {
// children: 孩子们
// last: 最后一个 first: 第一个
// remove: 移除
// eq(n): n是负数, 代表倒数第几个
$('#box').children().last().remove()
})
</script>
</body>
</html>
委托
<!DOCTYPE html>
<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>
<!-- 复习: 冒泡机制 -->
<!-- 子元素会把自身发生的事件 传递给祖先元素 -->
<!-- 事件委托: 父元素帮助子元素监听事件 完成操作 -->
<div id="box">
<button>高达</button>
<button>高达</button>
<b>浪浪浪</b>
<button>亮亮</button>
<button>高达</button>
<button>亮亮</button>
<button>高达</button>
<button>亮亮</button>
</div>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
// 委托: 使用 on 方式添加事件
// on: 参数2 可以过滤出想要触发事件的子元素
// 参数2 的值是选择器
$('#box').on('click', 'button:contains(高达)', function () {
// 当添加参数2之后, 函数中this都会发生变化
// 指向的不再是 id=box; 而是 参数2过滤出来的
console.log(this)
$(this).remove()
})
</script>
</body>
</html>
待办事项
<!DOCTYPE html>
<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>
<style>
.cell {
user-select: none;
width: 200px;
border: 1px solid black;
border-radius: 4px;
padding: 4px;
margin-top: 4px;
display: flex;
justify-content: space-between;
}
</style>
</head>
<body>
<div>
<input type="text" placeholder="请输入待办事项" />
<button disabled>确定</button>
</div>
<div class="cells">
<!-- <div class="cell">
<span>1.吃饭</span>
<button>删除</button>
</div> -->
</div>
<h1 style="display: none">暂无待办事项</h1>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
const todos = ['吃饭', '睡觉', '打亮亮']
// 数组映射成 HTML 代码组成的数组: map
const todos_el = todos.map((value, index) => {
return `<div class="cell">
<span>${index + 1}.${value}</span>
<button>删除</button>
</div>`
})
// $('.cells').html(todos_el.join(""))
$('.cells').append(todos_el)
// 后续会动态新增很多条数据项, 通过委托实现每个子元素的删除操作:
$('.cells').on('click', 'button', function () {
// parent: 父母
$(this)
.parent()
.slideUp(function () {
// 隐藏之后: 移除当前元素
$(this).remove()
// 如果子元素的个数是0 说明没东西, 显示暂无
if ($('.cells').children().length == 0) {
$('h1').show()
}
})
})
// 确定按钮点击后, 读取输入框的值, 添加到最后面
$('button:contains(确定)').click(function () {
const $inp = $(this).prev()
const el = `<div class="cell">
<span>*. ${$inp.val()}</span>
<button>删除</button>
</div>`
$('.cells').append(el)
// 清空输入框的值, 更新成空字符串
$inp.val('')
// 让按钮不可点击
this.disabled = true
// 隐藏 暂无待办事项
$('h1').hide()
})
// 输入框的值变化时, 应该实时修改确定按钮的不可用状态
$('input').on('input', function () {
// 空的时候 不可用是真, 非空就是假
$(this)
.next()
.prop('disabled', this.value == '')
})
// 按回车: 13
$('input').keyup(function (e) {
if (e.keyCode == 13) {
//触发与确定按钮点击时 相同的操作
if (this.value != '') $(this).next().click()
}
})
</script>
</body>
</html>
作业
把待办事项完成2遍
明日安排
实战: 结合网络请求进行练习, 需要网络
没开网的校区 找 项目经理 开通网络