一 · css动画
1.动画原理及2D变换
平移:translate
第一个参数: x轴的平移量,正方向向右
第二个参数: y轴的平移量,正方向向下
transform: translate(100px, 200px) ps:填一个参数的话,只有横坐标进行了平移
translateX x轴上平移
translateY y轴上平移
translateZ z轴上平移
旋转:rotate
.参数代表旋转的角度
代表角度的单位是 deg
代表弧度的单位是 rad
.元素的旋转角度是参考的元素的正上方
顺时针旋转为正方向
旋转中心默认为元素中心
缩放:scale
.参数代表的是缩放比列,值为1,则为原始大小
参说只写一个代表的是水平和竖直方向缩放相同的比列
负数代表的就是指定轴上的镜像
ps:隐藏元素的方法:将缩放调为0
倾斜:skew
第一个参数: 水平轴的倾斜度数
第二个参数: 竖直轴的倾斜度数
transform: skew(0, 30deg);
只设置一个参数 则只有水平轴倾斜有效
transform: skew(30deg);
transform: skewX(30deg);
transform: skewY(30deg);
设置transform的原点
原点的位置会影响旋转的圆心,缩放的位置
值的带选项:center, top, bottom, left, right, 还可以写具体的长度值
transform-origin: center;
transform-origin: right bottom;
原点若x值和y值都为0,代表的是元素左上角的位置
第一参数值代表横向移动的距离,正数代表向右移动,负数代表向左移动
第二参数值代表纵向移动的距离,正数代表向下移动,负数代表向上移动
transform-origin: 50px 100px;
transform: rotate(0deg);
变换原点还会影响缩放的位置
transform-origin: left top;
transform: scaleY(1);
2.过度动画
transition复合属性可以拆解成以下属性
过渡属性:声明一个需要产生过渡动画的属性 ,可以同时声明多个属性,属性之间用逗号隔开
待选项:
all: 代表所有属性
none: 没有任何属性
transition-property: opacity, transform;
transition-property: all;
补间动画的时长
transition-duration: 1s;
transition-duration: 1000ms;
补间动画的速度曲线
带选项:
linear: 匀速播放动画
ease-in: 慢进匀速出
ease-out: 匀速进慢出
ease-in-out: 慢进慢出
steps(n): 声明有n个过渡阶段
transition-timing-function: linear;
除了使用预制带选项,也可以手动赋值如下
transition-timing-function: cubic-bezier(0.76, 0.19, 0.19, 0.8);
steps 函数
transition-timing-function: steps(5);
延迟播放动画的时间
transition-delay: 1s;
使用transition属性设置所有的过渡动画属性
属性顺序如下:过渡属性名 过渡时长 速度曲线 延迟时间
transition: all 3s ease-in-out 2s;
.使用class来控制动画
.box {
width: 100px;
height: 100px;
background-color: #f00;
/* 初始状态 */
transform: translateX(0px);
}
/* 通过添加 active 类名来开启动画 */
.box.active {
transition: all 1s;
/* 结束状态 */
transform: translateX(200px);
}
3d变换和animation动画
animation和transition的区别:
transition 是通过属性变化,而产生过渡状态,而由浏览器自动创建补间动画
transition 在浏览器上动态修改css属性后,依然可以播放过渡动画
animation的状态是事先定义好的,后续改变css属性也不会播放新的动画
animation的动画状态不止起始状态和结尾状态,可以定义多个状态
animation是一个复合属性,由以下属性构成:
动画名称
作用:用于告诉浏览器,该动画应用哪一个动画关键帧序列
animation-name: move;
动画播放时长
animation-duration: 2s;
动画播放的速度曲线
animation-timing-function: linear;
延迟播放的时间
animation-delay: 1s;
动画播放次数
带选项:
infinite: 无限循环播放
animation-iteration-count: infinite;
animation-iteration-count: 2;
动画播放方向
带选项:
normal:正向播放
reverse: 反向播放
alternate: 正向播放一次然后反向再播放一次
alternate-reverse: 反向播放一次然后正向再播放一次
animation-direction: alternate-reverse;
播放结束后,元素的最终状态模式
带选项:
forwards:动画播放完后,保留最后一帧的状态
backwards:动画播放完后,保留第一帧的状态
both:动画播放完后,保留第一帧和最后一帧的状态和
animation-fill-mode: forwards;
关键帧:动画播放时的几个关键状态、
序列:有序的队列
定义一个关键帧序列 如下:
使用@keyframes定义关键帧序列,后面参数为:动画名
@keyframes move {
/* 起始状态 */
/* from { */
0% {
transform: translateX(0);
color: #000;
font-size: 16px;
}
/* 用百分比定义中间状态 */
50% {
transform: translateX(1000px);
color: pink;
font-size: 32px;
}
/* 结束状态 */
/* to { */
100% {
transform: translateX(500px);
color: green;
font-size: 64px;
}
}
暂停和播放动画
// 读取动画播放状态 animationPlayState
console.log(getComputedStyle(box).animationPlayState)
// running 代表正在播放
if (getComputedStyle(box).animationPlayState === 'running') {
// 在播放就暂停动画
box.style.animationPlayState = 'paused'
btn.textContent = '继续'
} else {
// 若已暂停动画,则重新设置为running
box.style.animationPlayState = 'running'
btn.textContent = '暂停'
}
3d变换
.scene {
width: 400px;
height: 400px;
border: 5px solid #000;
/* 开启3d变换 */
transform-style: preserve-3d;
/* 设置灭点距离屏幕的距离 */
perspective: 500px;
}
3d变换 是让我们的元素看上去在三维空间中发生变换(平移 旋转 缩放 倾斜)
总结:
要使用3d变换需要依序执行以下步骤:
1. 搭建3d场景,在父元素上设置:transform-style: preserve-3d;
2. 在父元素上设置透视距离:perspective: 100px;
3. 给场景添加演员,给场景元素添加子元素
4. 在子元素上使用3d变换
4.渐变色分栏布局与响应式
属性选择器补充
匹配属性值包含指定内容的元素
input[name*=e] {
border: 3px solid red;
}
匹配属性值以指定内容开头的元素
input[name^=s] {
font-size: 24px;
}
匹配属性值以指定内容结束的元素
input[name$=e] {
background-color: greenyellow;
}
匹配属性值包含 dep- 开头的元素
input[name|=dep] {
border: 3px solid blue;
}
渐变色
background-color: yellow;
线性渐变色
注意:渐变色的值,适用于 background-image 属性,而不是 background-color
linear-gradient
第一个参数: 渐变的方向,也可以是个角度值
默认方向为: to bottom
后续颜色参数可以追加一个距离值
background-image: linear-gradient(to right, red, yellow 100px, green 200px); */
background-image: linear-gradient(30deg, red, red 100px, blue 100px, blue 200px, black 200px);
/* 径向渐变 */
background-image: radial-gradient(red, yellow);
background-image: radial-gradient(red, red 100px, yellow 100px, yellow 200px, black 200px);
/* 重复线性渐变 */
background-image: repeating-linear-gradient(to right, black, black 50px, white 50px, white 100px);
/* 重复径向渐变 */
background-image: repeating-radial-gradient(red, red 50px, yellow 50px, yellow 100px);
分栏布局
/* 设置文本列数 */
column-count: 3;
/* 设置列宽度 */
column-width: 256px;
/* 分栏边框,属性值和边框的属性值相同 */
column-rule: 5px double red;
/* 两列文本中间的间距 */
column-gap: 100px;
word-break: keep-all;
响应式布局
什么是页面的响应式?
页面的元素样式会根据页面的宽度做出变化
如何实现响应式?
使用媒体查询,来实现响应式布局
媒体查询的作用:当媒体查询条件成立时,将应用花括号中代码块的样式
语法:@media media-type and (condition1) and (condition2)
二·jquery
jquery 使用的方法:
1. 查询并存储元素
2. 操作元素,包括修改元素样式,绑定事件等
let box = document.querySelector('.box')
// 查询并构造一个jquery对象
let $box = $('.box')
console.log($box);
// 修改样式
$box.css('background-color', '#f00')
创建一个jquery对象
// 方法一:使用选择器调用$()函数直接获得jquery对象
let $box = $('.box')
console.log($box);
// 方法二:可以通过dom对象获取jquery对象
let box = document.querySelector('.box')
$box = $(box)
console.log($box);
eq和get
// 查询一个jquery对象
let $boxs = $('.box')
console.log($boxs);
// eq() 该函数将返回对应索引位置的jquery对象
let $box = $boxs.eq(0)
console.log($box);
// 用索引获取到的是dom对象
let box = $boxs[0]
console.log(box);
// jquery对象类似一个数组,可以获取上述jquery对象的dom对象,如下:
// 也可以通过函数get来获取,
box = $boxs.get(0) // 与 $boxs[0]等价
console.log(box);
设置样式
// 使用css函数来设置和读取样式
// 读取样式
console.log($boxs.css('width'));
console.log($boxs.css('height'));
// 读取多个样式
console.log($boxs.css(['width', 'height']));
// 设置样式
// $boxs.css('background-color', '#f00')
// 通过函数设置样式
$boxs.css('background-color', function (index, value) {
// 当前成员的索引
console.log(index);
// 当前元素的对应属性值
console.log(value);
// 返回一个新的属性值
return index % 2 === 0? '#0f0': '#00f'
设置类
let $boxs = $('.box')
// 添加类
$boxs.addClass('my-box')
// 删除类
$boxs.removeClass('active')
// 判断是否存在某个类
console.log($boxs.hasClass('box'));
console.log($boxs.hasClass('active'));
// 开关类
$boxs.toggleClass('box2')
设置属性
// 读取自定义属性
// console.log(document.querySelector('.box').getAttribute('my-data'));
console.log($boxs.attr('my-data'));
// 设置属性值
$boxs.attr('src', './img/1.png')
// 删除属性值
$boxs.removeAttr('class')
绑定事件
// 使用 on 函数绑定事件
const click1 = function (ev) {
console.log('click1');
console.log(ev);
}
// 使用 off 解绑事件
// 如果只写一个参数,会解绑所有的对应事件
// $box.off('click')
$box.off('click', click1)
// 使用 one 函数,可以让绑定的事件只触发一次
// $box.one('click', (ev) => {
// console.log('one click');
// console.log(ev);
// })
遍历元素
$lis.each(function (index, element) {
// 每个成员索引
console.log(index);
// 每个dom对象
console.log(element);
$(element).css('background-color', index % 2 === 0 ? '#f00' : '#0f0')
})
特效
// jquery 特效
// 基本动画
$('.section1 button:nth-child(1)').click(() => {
// 显示元素 原理是设置元素的display属性
$box1.show()
})
$('.section1 button:nth-child(2)').click(() => {
// 隐藏元素
$box1.hide()
})
$('.section1 button:nth-child(3)').click(() => {
// 开关元素
$box1.toggle()
})
// 自定义动画
$('.section2 button:nth-child(1)').click(() => {
// 自定义动画
// 第一个参数:要播放的动画属性,有些属性无法生效例如:transform background-color 等
// 第二个参数: 动画播放时长
// 第三个参数: 动画播放曲线
// 第四个参数: 动画播放结束回调
$box2.animate({
marginLeft: '300px',
paddingTop: '100px',
backgroundColor: 'rgb(0,0,255)'
}, 3000, 'swing', () => {
console.log('动画播放完成');
})
})
// 渐变动画
$('.section3 button:nth-child(1)').click(() => {
// 渐变函数的第一个参数,可以指定动画播放的时长,单位是毫秒
// 元素渐入
$box3.fadeIn(3000)
})
$('.section3 button:nth-child(2)').click(() => {
// 元素渐出
$box3.fadeOut(5000)
})
$('.section3 button:nth-child(3)').click(() => {
// 第一个参数:动画播放时长
// 第二个参数:目标透明度
// 渐变到指定透明度
$box3.fadeTo(3000, 0.5)
})
$('.section3 button:nth-child(4)').click(() => {
// 开关渐变
$box3.fadeToggle(3000)
})
// 滑动动画
$('.section4 button:nth-child(1)').click(() => {
// 滑下
$box4.slideDown(3000)
})
$('.section4 button:nth-child(2)').click(() => {
// 滑上
$box4.slideUp(3000)
})
$('.section4 button:nth-child(3)').click(() => {
// 滑动开关
$box4.slideToggle(2000)
})
三·canvas画布
canvas基础使用方法
查询canvas
const canvas = document.querySelector('canvas')
// 获取画布上下文对象(所谓的上下文对象,就是用来直接控制画布绘画的对象)
const ctx = canvas.getContext('2d')
// 图片加载完成后
// img.addEventListener('load', () => {
// // 画图
// ctx.drawImage(img, 0, 0)
// })
// 绘制矩形
ctx.fillRect(50, 100, 100, 100)
绘制矩形
获取画布
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
// 修改填充色
ctx.fillStyle = '#ff0'
// 绘制填充颜色的矩形
// rectangle 矩形
// 第一个和第二个参数代表矩形左上角的坐标
// 第三个和第四个参数是矩形的宽高
ctx.fillRect(100, 50, 200, 100)
// 修改镂空描边的颜色
ctx.strokeStyle = '#f00'
// 绘制镂空矩形
ctx.strokeRect(100, 300, 200, 100)
// 清空画布
ctx.clearRect(0, 0, 500, 500)
绘制文本
// 获取画布
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
// 编辑字体
ctx.font = '32px 华文行楷'
ctx.fillStyle = '#f00'
// 填充文本
// 语法:ctx.fillText(text, x, y, max-width)
// text: 要渲染的文本
// x,y: 文本渲染的坐标位置
// max-width: 文本最大宽度,当大于该宽度,文本字体将自动缩小以自适应宽度
ctx.fillText('你好中国', 100, 100, 100)
ctx.strokeStyle = '#0f0'
// 镂空文本
ctx.strokeText('你好世界', 100, 300)
画布
// 获取画布
let c = document.querySelector('canvas')
let ctx = c.getContext('2d')
// 修改笔头宽度
ctx.lineWidth = 20
// 画线之前要开启路径
ctx.beginPath()
// 移动笔头
ctx.moveTo(100, 50)
// 绘制直线路径
ctx.lineTo(200, 50)
ctx.lineTo(200, 300)
// ctx.lineTo(100, 50)
// 闭合路径
ctx.closePath()
// 根据路径绘图
// 绘制镂空线
ctx.stroke()
// 绘制填充图形
// ctx.fill()
ctx.beginPath()
ctx.moveTo(250, 250)
// 绘制弧形
// 第一个和第二个参数: 圆心坐标
// 第三个参数: 圆半径
// 第四个和第五个参数: 起始弧度和结束弧度
// 0 度代表水平向右
// 正方向为顺时针
ctx.arc(250, 250, 250, Math.PI / 180 * 30, Math.PI)
ctx.closePath()
ctx.stroke()
// ctx.fill()
绘制图片
// 获取画布
let c = document.querySelector('canvas')
let ctx = c.getContext('2d')
// 绘制图片,只能绘制html页面中的图片<img>标签,且必须是加载完成的图片
// 获取图片源
const img = document.querySelector('img')
img.addEventListener('load', () => {
// 图片加载完成后才能绘制图片
// 语法:
// void ctx.drawImage(image, dx, dy);
// void ctx.drawImage(image, dx, dy, dWidth, dHeight);
// void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
// 解释:
// image:img标签
// dx,dy: 绘制图片的坐标位置
// dWidth, dHeight: 绘制图片的宽度和高度
// sx, sy: 图片内部的坐标,用于截取图片
// sWidth, sHeight: 截取图片的宽高
// 绘制完整图片
// ctx.drawImage(img, 100, 50)
// ctx.drawImage(img, 100, 50, 200, 100)
// 绘制部分图片
ctx.drawImage(img, 70, 130, 250, 100, 100, 50, 250, 100)
})
canvas像素级颜色操作
// 灰度公式:g = r*0.299 + g*0.587 + b*0.114
// 灰度公式所获得的 g 值,赋值给每个像素点的 rgb 值,这样图像就变成了灰白图
// 计算 255 一半的值
let half = 255 * 0.5
// 黑白图
btn1.addEventListener('click', () => {
// 获取图像的像素信息
let id = ctx1.getImageData(0, 0, 361, 245)
console.log(id);
// id.data 每个像素点的信息,是一个数组
// 数组中每4个成员是一个像素的信息,代表 rgba 的参数值
for (let i = 0; i < id.data.length; i += 4) {
// 获取rgb值
let r = id.data[i]
let g = id.data[i + 1]
let b = id.data[i + 2]
// 计算灰度
let gray = r * 0.299 + g * 0.587 + b * 0.114
if (gray < half) {
// 由灰度可知,该像素更趋近于黑色
id.data[i] = 0
id.data[i + 1] = 0
id.data[i + 2] = 0
} else {
id.data[i] = 255
id.data[i + 1] = 255
id.data[i + 2] = 255
}
}
// 设置图像
ctx2.putImageData(id, 0, 0)
})
// 反转色
btn2.addEventListener('click', () => {
// 获取图像的像素信息
let id = ctx1.getImageData(0, 0, 361, 245)
console.log(id);
for (let i = 0; i < id.data.length; i += 4) {
// 获取rgb值
let r = id.data[i]
let g = id.data[i + 1]
let b = id.data[i + 2]
// 求 rgb 颜色值 相对于 255 的补值
id.data[i] = 255 - r
id.data[i + 1] = 255 - g
id.data[i + 2] = 255 - b
}
ctx2.putImageData(id, 0, 0)
})
// 灰度图
btn3.addEventListener('click', () => {
// 读取图片信息
let id = ctx1.getImageData(0, 0, 361, 245)
for (let i = 0; i < id.data.length; i += 4) {
// 获取rgb值
let r = id.data[i]
let g = id.data[i + 1]
let b = id.data[i + 2]
// 计算灰度
let gray = r * 0.299 + g * 0.587 + b * 0.114
// 赋值灰度
id.data[i] = gray
id.data[i + 1] = gray
id.data[i + 2] = gray
}
// 将 imageData 绘制到 ctx2 上
ctx2.putImageData(id, 0, 0)
动画函数requestAnimationFrame
// 动画目标: 将一个 50 x 50 的方块,以每秒 100px 的速度 向右移动
// requestAnimationFrame 请求动画的下一帧
// 参数是一帧之后的回调函数
requestAnimationFrame(render)
// 上一次动画时长
let lastTime = 0
// 上一帧到下一帧的间隔时间
let deltaTime = 0
let box = {
position: { x: 0, y: 0 },
width: 50,
height: 50,
// 速度: 每秒移动 100px
v: 100
}
// time 动画的播放总时长
function render(time) {
// 执行每一帧的逻辑
// 计算上一帧到这一帧的时间间隔
deltaTime = time - lastTime
lastTime = time
console.log(deltaTime);
// 速度 * deltaTime = 每帧的速度
box.position.x += deltaTime * 0.001 * box.v
// 画图
// 清空画布
ctx.clearRect(0, 0, 500, 500)
ctx.fillRect(box.position.x, box.position.y, box.width, box.height)
// 循环递归请求下一帧
requestAnimationFrame(render)
四·多媒体标签、swiper和animate.css
多媒体标签
// 可以通过音频类型 Audio 来播放音效
let aud = new Audio('./audio/a4.mp3')
// 关于自动播放
// 若直接播放媒体资源,将获得一个异常,告诉你浏览器不允许在用户未经允许的请款下自动播放
// video.play()
// setTimeout(() => {
// video.play()
// }, 5000)
// document.addEventListener('click', () => {
// // 由于不能直接自动播放,所以需要一个事件触发播放
// video.play()
// })
playBtn.addEventListener('click', () => {
// 播放
video.play()
// 获取媒体的总时间
totalTime.innerHTML = video.duration
})
pauseBtn.addEventListener('click', () => {
// 暂停
video.pause()
})
setInterval(() => {
// video.currentTime 当前媒体播放的进度时间
currentTime.innerHTML = video.currentTime
}, 1000)
goTo.addEventListener('click', () => {
// 跳转播放时间
video.currentTime = Number(inp.value)
})
// 音量加减
// 取值范围是0~1
vUp.addEventListener('click', () => {
video.volume = Math.min(1, video.volume + 0.1)
})
vDown.addEventListener('click', () => {
video.volume = Math.max(0, video.volume - 0.1)
})
// 静音与恢复
muted.addEventListener('click', () => {
video.muted = !video.muted
})
swiper布局
<!-- 滚动屏的父元素 -->
<div class="swiper-wrapper">
<!-- 滑块 -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
<!-- 分页工具 -->
<div class="swiper-pagination"></div>
<!-- 导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- 滚动条 -->
<div class="swiper-scrollbar"></div>
swiper初始化配置
// 初始化创建 swiper 对象
// 第一个参数:代表swiper容器的选择器
// 第二个参数:初始化配置项,是一个json对象
// 配置项参考地址:https://swiperjs.com/swiper-api#parameters
const swiper = new Swiper('.swiper', {
// 滚动方向
// 带选项:
// horizontal:横向; vertical:纵向
direction: 'vertical',
// 是否循环
loop: false,
// 特效
effect: 'fade',
// 动画播放时长
speed: 3000
swiper事件
// 通过on方法绑定事件
swiper.on('click', handler)
// 滚动到底部事件
swiper.on('reachEnd', swiper => {
console.log('到达底部');
})
// 解绑事件
swiper.off('click', handler)
// 滑块动画播放结束事件
swiper.on('slideChangeTransitionEnd', swiper => {
console.log('滑块动画播放结束事件');
})
swiper模块
// swiper 模块就是swiper提供的一些小工具,例如:滚动条,导航按钮等
const swiper = new Swiper('.swiper', {
effect: 'cube',
// 导航
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
// 禁用时的样式
disabledClass: 'disabled-style',
hideOnClick: true
},
// 立方体特效的具体配置
cubeEffect: {
// shadow: false, // 去掉阴影
shadowScale: 1, // 阴影大小
shadowOffset: 100
},
// 键盘控制组件
keyboard: {
enabled: true,
onlyInViewport: false,
},
// 分页工具
pagination: {
el: '.swiper-pagination',
bulletActiveClass: 'active-bullet'
},
// 自动播放
autoplay: {
delay: 3000
}
代码控制swiper
// 给 swiper 添加 滑动元素
swiper.addSlide(1, `<div class="swiper-slide">hello world</div>`)
// 添加滑块到末尾
swiper.appendSlide(`<div class="swiper-slide">append Child</div>`)
// 删除slide
swiper.removeSlide(2)
swiper.on('slideChangeTransitionEnd', (_swiper) => {
console.log(_swiper.activeIndex);
})
document.querySelector('.slide-next').addEventListener('click', () => {
// 滑动到下一个
// 第一个参数: 动画播放时长
// 第二个参数: 是否触发动画播放事件
swiper.slideNext(3000, false)
})
document.querySelector('.slide-prev').addEventListener('click', () => {
// 滑动到上一个
// 第一个参数: 动画播放时长
// 第二个参数: 是否触发动画播放事件
swiper.slidePrev(2000, true)
})
document.querySelector('.slide-over').addEventListener('click', () => {
// 滑动到指定位置
// 第一个参数: 指定slide的索引
// 第二个参数: 动画播放时长
// 第三个参数: 是否触发动画播放事件
swiper.slideTo(3, 5000, false)
})
五·微信小程序
1.微信小程序基础
小程序项目结构
components: 小程序的自定义组件
images: 图片文件夹
pages: 存放页面文件的文件夹
index: 页面文件夹
index.js: 页面的js代码
index.json: 页面的配置
index.wxml: html模板文件
index.wxss: 页面的样式文件
utiles: 辅助用的js代码放的文件夹
app.js: 微信小程序的程序入口(程序入口:开始执行代码的地方)
app.json: 小程序应用程序的全局配置文件
app.wxss: 小程序的全局样式(.wxss文件是小程序的样式文件)
project.config.json: 小程序项目的配置
sitemap.json: 用于微信搜索小程序的配置文件
常用标签
<!-- page 标签相当于 html 中的 body -->
<page></page>
<!-- view 标签相当于 html 中的 div -->
<view></view>
<!-- text 相当于 html 中的 span -->
<text></text>
<!-- image 相当于 html 中的 img -->
<image></image>
<!-- block 是一个自身不会显示的标签 -->
<block></block>
单位rem和rpx
## rem
rem 是 html 中的长度单位,代表相对根节点(html)上字体的大小
## rpx
rpx 是 微信wxml中的长度单位,rpx 真实大小的计算是参考的 750px 的屏幕宽度进行的
1rpx 的物理大小 = 750px 宽度屏幕上 1px 的大小
### 总结
若希望某个元素再不同的机型下能够等比例缩放,则请使用 rpx 作为单位
若希望某个元素的大小再不同机型下保持不变,则请使用 px 作为单位
px的尺寸 = rpx下的尺寸 * (当前机型的屏幕宽 / 750)
rpx的尺寸 = px的尺寸 / (当前机型的屏幕宽 / 750)
认识页面对象模型page
Page({
data: {
// 数据
},
onLoad: {
// 加载完成事件
}
})
模板语法
## 循环渲染
作用:可以将数组数据循环显示到页面中
语法:
<!-- wx: 开头的写在标签头部的东西 称为指令 -->
<!-- array: 来自js data中的数组 -->
<!-- 使用 wx:for 一定要加上 wx:key,wx:key的值是array对象中的不可重复的属性 -->
<view wx:for="{{array}}" wx:key="id">
<!-- index: 是 wx:for 中隐式声明的变量,代表循环遍历array时的当前索引 -->
<!-- item: 是 wx:for 中隐式声明的变量,代表循环遍历array时的当前数组成员 -->
{{index}}: {{item}}
</view>
## 条件渲染
可以根据条件判断,选择性的渲染页面
语法:
<view wx:for="{{table}}" wx:key="name">
<text>{{index}}: 姓名 = {{item.name}}; 年龄 = {{item.age}}; 性别 = </text>
<!-- wx:if 指令的值为布尔表达式,为true是渲染该节点,否则不渲染 -->
<text wx:if="{{item.sex==='male'}}">男</text>
<!-- wx:if 可以和 wx:elif、wx:else 连用 -->
<text wx:elif="{{item.sex==='female'}}">女</text>
<text wx:else>其他</text>
</view>
小程序配置
## 全局配置
app.json 文件中的配置是全局配置 影响所有页面
- entryPagePath 小程序启动页的路径
- pages 页面的路径列表
- window 全局窗口的配置
- tabBar 底部选项卡
- debug 开启调试模式
## 页面配置
全局配置下,window中的所有内容,每个页面自身也可以配置
- disableScroll 禁止用户上下滚动页面
- usingComponents 使用组件
2.小程序应用开发
js代码中的赋值与读值
Page({
read() {
console.log('read')
// 函数中的 this 代表当前页面对象模型
console.log(this)
// 谁用this.data读取页面属性
console.log(this.data.table)
}
})
```
给页面属性赋值的方法:
```js
Page({
write() {
// 使用this.setData函数进行赋值,参数是个json对象,需要修改哪个属性,就给该对象添加哪个属性
this.setData({title: '天龙八部'})
}
})
commonjs模块导入导出语
## 导入导出
导出:一个js模块中的代码想要借给另一个模块使用 则需要使用导出语法
导入:将其他js模块的内容借给自己模块使用,则需要用到导入语法
## 语法
导出:
```js
// 给 module.exports 进行赋值,赋值的内容就是导出的内容,可以是任意内容
module.exports = something
```
导入:
```js
// 使用 require 进行导入,path是要导入模块的路径
let something = require(path)
```
阿里iconfont的使用
安装流程:
1. 选择图标,加入自己的项目
2. 下载自己项目
3. 解压下载的zip文件
4. 引入解压文件中的 iconfont.css 文件
使用方法:
1. 使用 span 标签,给标签 class 加入 iconfont
2. 在自己的项目中选择一个图标的 class
3. 在 span 标签中加入所选 class 即可
> 注意:iconfont图标被当作字符使用,所以调节大小时,使用 font-size 属性
## 在微信小程序中使用iconfont
1. 在 iconfont 网站的项目中点击 `项目设置` 设置字体类型为 `Base64` 然后下载项目
2. 将 iconfont.css 改名为 iconfont.wxss
3. 将 iconfont.wxss 放入小程序项目目录下
4. 在小程序的 app.wxss 第一行代码加入 @import '...' (此处是iconfont.wxss文件路径)
页面底部选项卡
在 app.json 中 增加 tabBar 配置就能添加选项卡
```json
{
"tabBar": {
"selectedColor": "#444", // 选中的按钮的文本颜色
"list": [ // 按钮列表
{
"pagePath": "pages/read/read", // 跳转的页面路径
"text": "领读", // 按钮的文字描述
"iconPath": "image/tab_icon1.png", // 未选中时的图标路径
"selectedIconPath": "image/tab_icon1_active.png" // 选中时的图标路径
} ] },}
```
> 注意:要显示选项卡,按钮列表中,必须要有一个配置的 pagePath 属性值,是小程序的入口页面
> 注意:底部选项卡指定的页面不能是分包里的页面
导航与页面间传参
语法:
```html
<!-- url:要跳转到的页面路径 -->
<!-- 若要传递参数,可以在url后面增加 ?key=value 的参数 -->
<navigator url="path"></navigator>
```
语法:
```js
function(){
wx.navigateTo({
// path: 要跳转的路径
// key=value: 要传递的参数
url: 'path?key=value'
})
}
// wx.navigateTo 跳转到某页 会新增堆栈
// wx.redirectTo 重定向到某页 不会新增堆栈
// wx.navigateBack 返回
```
> 参数的获取可以在另一个页面的 onLoad 声明周期函数中 options 变量中存放着参数
获取页面元素
## 方法:
步骤如下:
获取查询器:
let query = wx.createSelectorQuery()
使用查询器 查找节点
query.select(selector) 或者 query.selectAll(selector)
let nodeRef = query.select(selector) // nodeRef 大致可以理解为是页面元素
获取元素属性:
```js
// fields 接收两个参数,
// 第一个参数:查询属性的配置
// 第二个参数:查询结束的回调
nodeRef.fields({
dataset: true, // 自定义属性,也就是标签上 data- 开头的属性
size: true, // 元素的宽高
rect: true, // 元素的位置 top left right bottom
properties: ['url'], // 元素的固有属性,不能查询 id class style 属性和绑定的事件属性
computedStyle: ['backgroundColor', 'fontSize'] // 查询样式
}, (res)=>{
// 该 res 就是查询的结果
console.log(res)
})
```
当调用完 fields 后 ,一定要执行 exec,例如:
```js
query.exec()
```
## 查询组件
小程序组件类似html标签,可以使用css选择器进行查询
```js
// this 是当前页面对象模型
// 通过 this.selectComponent 查询当前页中对应css选择器的组件
const checkbox = this.selectComponent('.checkbox')
```
自定义属性data
```html
<!-- 此处的data-id就是一个自定义属性 -->
<text data-id="0">hello world</text>
```
除了使用 wx.createSelectorQuery 获取页面属性,来获取 data- 开头的自定义属性以外,还可以通过事件获取按钮上的自定义属性,例如:
```html
<button data-id="0" bindtap="remove">删除</button>
```
remove 函数,如下:
```js
function remove(event) {
// 通过事件对象event的target.dataset获取自定以属性
console.log(event.target.dataset)
}
```
三·云开发
1.数据的crud
修改数据
// 初始化sdk
AV.init({
appId: "94Ddp1dFbb1BTQsKcunCQYFk-gzGzoHsz",
appKey: "te8OSHbMAvaunzdFGzzTvvvC",
serverURL: "https://94ddp1df.lc-cn-n1-shared.com"
})
// 通过保存操作来修改数据
// 创建一行数据
// 第一个参数:数据来源的表名
// 第二个参数:表中的ObjectId值,用于指示要修改哪条数据
let stu = AV.Object.createWithoutData('Student', '605863124bcfb013cb35e9e9')
// 修改想要更新的字段
stu.set('name', '李四')
stu.set('sex', 'female')
stu.set('age', 24)
// 修改update时间戳
stu.set('updateTime', Date.now())
// 保存
stu.save().then(res => {
console.log(res)
}).catch(reason => {
console.error(reason)
})
删除数据
// 文档: https://leancloud.cn/docs/leanstorage_guide-js.html#hash664090316
// 初始化sdk
AV.init({
appId: "94Ddp1dFbb1BTQsKcunCQYFk-gzGzoHsz",
appKey: "te8OSHbMAvaunzdFGzzTvvvC",
serverURL: "https://94ddp1df.lc-cn-n1-shared.com"
})
// 使用 createWithoutData 创建一行数据
// 第一个参数:表名
// 第二个参数:指定表下的id值
let stu = AV.Object.createWithoutData('Student', '60596249eec6e5629f95531f')
// 调用destroy函数,销毁该行数据
let result = stu.destroy()
result.then(res => {
console.log(res)
}).catch(reason => {
console.error(reason)
})
查询数据
// 初始化sdk
AV.init({
appId: "94Ddp1dFbb1BTQsKcunCQYFk-gzGzoHsz",
appKey: "te8OSHbMAvaunzdFGzzTvvvC",
// server服务器地址,来自于 设置->应用keys 中的"REST API 服务器地址"
serverURL: "https://94ddp1df.lc-cn-n1-shared.com"
})
// 按照id查询
// 创建查询对象,参数为表名称
let query = new AV.Query('Student')
添加查询条件
equalTo是相等判断
第一个参数:要查询的表中的字段名
第二个参数:要查询的对应字段值
query.equalTo('objectId', '605863124bcfb013cb35e9e9')
// 调用 query.find 函数进行查询
let result = query.find()
console.log(result) // result 是promise对象,所以可以调用then和catch函数
result.then(res => {
// 在then函数中拿到查询结果
// res是个数组,结果存放在数组的项的 attrbuites 中
console.log(res)
}).catch(reason => {
console.error(reason)
})
// 模糊查询
query = new AV.Query('Student')
调用 contains 函数查询指定字段中包含某段文本的数据
第一个参数:字段名称
第二个参数:所包含的内容
query.contains('name', '三')
query.find().then(res => {
console.log(res)
}).catch(reason => {
console.error(reason)
})
方法二:通过正则表达式进行匹配
let regex = /^[\s\S]*三[\s\S]*$/
// 通过 query。matches 函数,让指定字段去匹配正则表达式,查询结果会返回匹配成功的数据
query.matches('name', regex)
query.find().then(res => {
console.log(res)
}).catch(reason => {
console.error(reason)
})
条件查询
大于 greaterThan
大于等于
query.greaterThanOrEqualTo('age', 16)
// 小于 lessThan
// 小于等于
query.lessThanOrEqualTo('age', 27)
不等于
query.notEqualTo('name', '张三')
query.find().then(res => {
console.log(res)
}).catch(reason => {
console.error(reason)
})
列表查询
列表查询若要分批次查询,需要在每行数据记录时间戳,createTime 和 updateTime,分别代表创建数据的时间,和修改数据的时间
let btn1 = document.querySelector('.btn1')
btn1.addEventListener('click', () => {
findNext()
})
// 列表查询,一定要记录最后一条数据的时间戳
let lastTime
// 列表查询函数
function findNext() {
let _query = new AV.Query('Student')
if (lastTime)
_query.lessThan('updateTime', lastTime)
// 可以通过limit函数限制数据库一次查询的数量
_query.limit(3)
// 排序
按 createdAt 升序排列
query.ascending('createdAt');
// 按照指定字段进行降序排列
// 参数是进行降序排列的字段名称
_query.descending('updateTime')
_query.find().then(res => {
console.log(res)
// 跟新lastTime
lastTime = res[res.length - 1].attributes.updateTime
}).catch(reason => {
console.error(reason)
})
}
分页查询
分页查询有以下几个必要参数
查询的当前页
let page = 1
// 每页查询的记录数
let size = 3
// 限制查询出来的数据量
query.limit(size)
// 跳过前面页码中的数据
// 参数是需要跳过的记录数
query.skip((page - 1) * size)
query.find().then(res => {
console.log(res)
}).catch(reason => {
console.error(reason)
})
// 分页查询函数
// kw: 代表姓名的模糊匹配
function page(page, size, kw) {
console.log(kw)
query = new AV.Query('Student')
// 增加查询条件
if (kw && kw.trim() !== '') {
// let regex = new RegExp('^[\\s\\S]*' + kw + '[\\s\\S]*$')
// query.matches('name', regex)
query.contains('name', kw)
}
// 限制查询出来的数据量
query.limit(size)
// 跳过前面页码中的数据
// 参数是需要跳过的记录数
query.skip((page - 1) * size)
query.descending('updateTime')
query.find().then(res => {
console.log(res)
}).catch(reason => {
console.error(reason)
})
// 查询满足条件的总记录数
query.count().then(count => {
console.log('student表中,满足条件的记录有:' + count + '条')
// 计算总页数
let totalPage = Math.ceil(count / size)
console.log('总共' + totalPage + '页')
})
}
添加数据
// 通过 AV.Object.extends() 函数创建类型(该类型对应数据库中的表)
// 其中函数参数,就是表名
const Student = AV.Object.extend('Student')
// 创建类型的实例(该实例对应数据库中的一行数据)
let student = new Student()
// 设置字段(字段指的是数据库中的列名)
student.set('name', '张三')
student.set('sex', 'male')
student.set('age', 16)
// 创建新数据时记录时间戳
let now = Date.now()
student.set('createTime', now)
student.set('updateTime', now)
// 保存对象
let result = student.save() // save函数将返回一个promise对象
console.log(result)
// 调用then函数,传入一个回调函数作为参数
// 当save执行成功后,将调用参数中的回调函数
result.then((res) => {
console.log(res)
}).catch((reason) => { // 函数在save失败调用catch函数中的回调函数
console.error(reason)
})