前端学习笔记

VS快捷键

CTRL+B 打开文件目录

CTRL+~ 打开终端(我的快捷键冲突,无法使用)

CTRL+Q 打开顶部中间的功能选择栏

CTRL++/- 放大/缩小VS页面

Markdown基础语法

1.文本

注:加粗的符号 “__” 按 SHIFT+" ‘)’与’+‘中间的键 "

Style语法示例键盘快捷键
加粗** ** 或 __ __xxxCommand+B (Mac) 或 Ctrl+B (Windows/Linux)
斜体* * 或 _ _xxxCommand+I (Mac) 或 Ctrl+I (Windows/Linux)
粗体和嵌入的斜体** ** 和 _ _xxx
删除线~~ ~~xxx
全部粗体和斜体******xxx
下标 H2O
上标 π*r2
下划线xxxCTRL+U
Style语法示例键盘快捷键 / 备注
脚注[^标记]:注脚内容123[^1]: abc
标题##123语句前+ # ,几个#就是几级标题,最大一级,最小六级
表情:表情单词😲
  • 列表项 //文本前加(* )
    • 子项 //文本前加(- )

2.链接

需求语法示例备注
链接百度[ ]内输入文字,( )内输入网址
图片[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i06UlzWg-1691948413413)()]链接格式前加 ! 就是图片格式,( )内填图片地址
引用文本> 文本
引用代码类型 代码用```框柱的地方填写代码

3.表格

|列名|列名|列名|
|左对齐|居中|右对齐|	//效果
|:-|:-:|-:|			  //语法
|内容|内容|内容|
左对齐居中右对齐
内容内容内容
- [ ] 待办事项
  • 待办事项

快捷键

li>$*9li标签下生成数字1~9的标签

HTML

HTML5基本结构

//页面的声明
<!DOCTYPE html>
//页面的区域
<html>
//页面的头部(用来描述网页的基本信息)
<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>网页</title>
</head>
//页面的主体
<body>
    Hello HTML5!
</body>
</html>

中文乱码问题

中文乱码原理:网页文件编码方式与浏览器的解析方式不同,就会导致中文乱码问题

<head>
    <meta charset="UTF-8">
    <title>HTML5</title>
</head>

注释

注释的内容不会渲染到页面上,可以通过查看源码进行查看

<!-- 注释内容 -->

文档标签

1.属性名和标签之间要有空格
2.属性和属性之间要有空格
3.属性只能在开始标签中

<html lang="en">
  <html lang="en">	开始标签
	lang="en"		标签属性	属性名称="属性值"
	lang	属性名称	
	en		属性值

空白符

空格,换行,制表符都是空白符,网页会自动合并多个空白符为一个空格

换行符


<body>
    Hello <br/> HTML5!
</body>

标题、段落、水平线

标题共有六级,分别为:h1h2h3h4h5h6,标题自带样式:1.加粗 2.上下外边距

h1字号最大,h6字号最小,h4(四级标题)与普通文字大小一样

p标签自带样式:上下外边距

<body>
    <h1>文章标题</h1>
    <h2>副标题</h2>
    <hr/>
    <p>第一段...</p>
    <p>第二段...</p>
</body>

插入资源

资源路径
<img src="https://www.yaconit.com/images/logo.png" alt="">
<!-- /代表网站的根目录 -->
<img src="/public/images/logo.png" alt="">
<!-- /	网站根目录 -->
 <!-- ./	代表当前文件所在的目录 -->
 <!-- ../	跳出当前文件所在的目录,进入父级目录 -->
<img src="../public/images/logo.png" alt="">
<img src="http://127.0.0.1:3000/public/images/logo.png" alt="">
插入图像

简单图像:src: 图片地址,可以时本地地址,也可以是网络地址

<body>
    <h1>文章标题</h1>
    <h2>副标题</h2>
    <p>第一段文本...</p>
    <p>第二段文本...</p>
    <img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"/>
</body>

图片缺失提示 alt:图片的文本替换信息,一般用于图片资源不能加载时显示

<img src="..." alt="图片缺失"/>

图像尺寸

尺寸为正整数,单位为px,width:宽 height:高

<img src="..." alt="..." width="100" height="100"/>

图像尺寸相对于父级元素尺寸的百分比

<img src="..." alt="..." width="50%"/>

鼠标悬浮时提示文本:title

<img src="..." alt="..." title="这张图片是Logo"/>

图文混排样式排版

img{
	vertical-align: middle;			//文本居中(图片旁的文本悬在中间)
}

图片格式

分为矢量图位图

矢量图效果(缩放不模糊,图像是由数学公式计算而来的)
SVG(可缩放矢量图形)可缩放矢量图形是基于可扩展标记语言(标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式。它由万维网联盟制定,是一个开放标准。
位图(常用类型)效果(放大后会模糊,图像由像素点组成)
JPG体积小,有损压缩
PNG透明,无损压缩
GIF动图,色彩少
WEBP网络图片
插入列表
有序列表

默认序号为升序 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cyOtB5mv-1691948413415)(E:/视频图像/image-20230220152454720.png)]

<body>
    <ol>
        <li>咖啡</li>
        <li>牛奶</li>
        <li>茶</li>
    </ol>
</body>

将序号降序:reversed

<ol reversed> ... </ol>

修改标号类型

type 属性的可选值为:1、A、a、I、i

<ol type="A"> ... </ol>

指定序号的起始值

start 只能为整数值

<ol start="5"> ... </ol>
<ol type="A" start="5"> ... </ol>
无序列表

默认的标号为实心圆 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uSlSwjFd-1691948413416)(E:/视频图像/image-20230220152533911.png)]

<body>
    <ul>
        <li>咖啡</li>
        <li>茶</li>
        <li>牛奶</li>
    </ul>
</body>

修改标号类型

type 属性的可选值为:circle、disc、square

<ol type="disc"> ... </ol>
定义列表

dt 用于定义项目

dd 用于描述项目

dt和dd组成了一条完整的列表项,dt表示列表项目,dd是对dt的一种解释说明

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-csdjIBil-1691948413416)(E:/视频图像/image-20230220152746585.png)]

<body>
    <h4>计算机的组成部分</h4>
    <dl>
        <dt>计算机</dt>
        <dd>用来计算的仪器 ... ...</dd>
        <dt>显示器</dt>
        <dd>以视觉方式显示信息的装置 ... ...</dd>
    </dl>
</body>
插入表格

绘制二行四列表格

:表格范围

<body>
    <table>
        <tr>
            <td>cell-1-1</td>
            <td>cell-1-2</td>
            <td>cell-1-3</td>
            <td>cell-1-4</td>
        </tr>
        <tr>
            <td>cell-2-1</td>
            <td>cell-2-2</td>
            <td>cell-2-3</td>
            <td>cell-2-4</td>
        </tr>
    </table>
</body>

带边框的表格

border 的值为正整数,单位为像素

<table border="1"> ... </table>

调整单元格的内边距

cellpadding 的值为正整数,单位为像素

<table border="1" cellpadding="10"> ... </table>

调整单元格间的距离

cellspacing 的值为正整数,单位为像素

<table border="1" cellspacing="10"> ... </table>

调整外边框的可视部分

frame描述
void不显示外侧边框。
above显示上部的外侧边框。
below显示下部的外侧边框。
hsides显示上部和下部的外侧边框。
vsides显示左边和右边的外侧边框。
lhs显示左边的外侧边框。
rhs显示右边的外侧边框。
box在所有四个边上显示外侧边框。
border在所有四个边上显示外侧边框。
<table border="0" cellspacing="10" frame="above"> ... </table>

调整内边框的可视部分

rules描述
none没有线条。
groups位于行组和列组之间的线条。
rows位于行之间的线条。
cols位于列之间的线条。
all位于行和列之间的线条。
<table border="1" cellpadding="10" frame="void" rules="all"> ... </table>

调整表格整体的宽和高

width 的值可以是百分比或者正整数,单位为px

height 的值只能为正整数,单位为px

<table border="1" width="400" height="400"> ... </table>
<table border="1" width="50%"> ... </table>

指定列头

列头自带样式:加粗,居中
<body>
    <table border="1" width="400">
        <tr>
            <th>th-1</th>
            <th>th-2</th>
            <th>th-3</th>
            <th>th-4</th>
        </tr>
        <tr>
            <td>cell-1-1</td>
            <td>cell-1-2</td>
            <td>cell-1-3</td>
            <td>cell-1-4</td>
        </tr>
       
    </table>
</body>

将表格的内容进行分组

thead 表示表格的头部

tbody 表示表格的主体

tfoot 表示表格的脚步

<body>
    <table border="1" width="400">
        <thead>
            <tr>
                <th>th-1</th>
                <th>th-2</th>
                <th>th-3</th>
                <th>th-4</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>cell-1-1</td>
                <td>cell-1-2</td>
                <td>cell-1-3</td>
                <td>cell-1-4</td>
            </tr>
            <tr>
                <td>cell-2-1</td>
                <td>cell-2-2</td>
                <td>cell-2-3</td>
                <td>cell-2-4</td>
            </tr>
            <tr>
                <td>cell-3-1</td>
                <td>cell-3-2</td>
                <td>cell-3-3</td>
                <td>cell-3-4</td>
            </tr>
            <tr>
                <td>cell-4-1</td>
                <td>cell-4-2</td>
                <td>cell-4-3</td>
                <td>cell-4-4</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td>foot-1</td>
                <td>foot-2</td>
                <td>foot-3</td>
                <td>foot-4</td>
            </tr>
        </tfoot>
    </table>
</body>

带标题的表格

标题默认在表格顶部 align="top"

<body>
    <table border="1" width="400">
        <caption>购物清单</caption>
        ...
    </table>
</body>

可以使用 将标题移至表格的底部

<body>
    <table border="1" width="400">
    <caption style="caption-side:bottom;">购物清单</caption>
       // <caption align="bottom">购物清单</caption>	//已废弃
        ...
    </table>
</body>

设置一行数据的排版方式

text-align:说明
right水平方向,居右对其
left水平方向,居左对其
center水平方向,居中对齐
justify水平方向,两端对齐
valign说明
top垂直方向,顶部对齐
middle垂直方向,居中对齐
bottom垂直方向,底部对齐
baseline垂直方向,基线对齐
<table border="1" width="100%" height="300">
    <tr align="center" valign="top"> ... </tr>
</table>

设置单元格的排版方式

alignvalign的值,参考行数据的排版方式

<tr>
    <td align="center" valign="center"> ... </td>
</tr>

合并单元格

水平合并,也可以称为列合并,合并原则是:左边的单元格合并掉右边的单元格

colspan的值为合并单元格的数量,只能为正整数

<body>
    <table border="1" width="100%" height="300">
        <tr align="center">
            <td colspan="2">1-1</td>
            <td>1-3</td>
        </tr>
        <tr align="center">
            <td>2-1</td>
            <td>2-2</td>
            <td>2-3</td>
        </tr>
    </table>
</body>

rowspan:垂直合并,也可以称为行合并,合并原则是:上面的单元格合并掉下面的单元格

<body>
    <table border="1" width="100%" height="300">
        <tr align="center">
            <td rowspan="2">1-1</td>
            <td>1-2</td>
            <td>1-3</td>
        </tr>
        <tr align="center">
            <td>2-2</td>
            <td>2-3</td>
        </tr>
    </table>
</body>
插入音频

插入音频

audio 内的文本可以省略。当老的浏览器不支持 audio 标签时便显示此文本进行提示

默认情况下,不显示音频控件

src 为音频路径,仅支持以下音频格式:

音频格式MIME类型
*.oggaudio/ogg
*.mp3audio/mpeg
<body>
    <audio src="https://www.w3school.com.cn/i/horse.ogg">
        您的浏览器不支持 audio 标签。
    </audio>
</body>

显示音频控件——controls

<audio src="..." controls> ... </audio>

自动播放(无效果)——autoplay

<audio src="..." autoplay="autoplay"> ... </audio>

循环播放——loop

<audio src="..." autoplay="autoplay" loop> ... </audio>

静音模式——muted

<audio src="..." controls muted> ... </audio>

多源引入音频

为了提高兼容性和稳定性,我们可以使用 source 标签来加载音频文件

如果当前浏览器支持第一个 source 引入的音频文件则播放,如果不支持则尝试播放下一个 source 引入的音频文件

<body>
    <audio controls>
        <source src="https://www.w3school.com.cn/i/horse.ogg" type="audio/ogg" />
        <source src="https://www.w3school.com.cn/i/horse.mp3" type="audio/mpeg" />
        您的浏览器不支持 audio 标签。
    </audio>
</body>
插入视频
video`的用法和`audio`的用法类似,具体用法请参考`audio

支持的视频格式如下:

视频格式MIME类型
*.oggvideo/ogg
*.mp4video/mp4
*.webmvideo/webm
<body>
    <video src="https://www.w3school.com.cn/i/movie.ogg" controls autoplay loop muted>
        您的浏览器不支持 video 标签。
    </video>
</body>

调整视频控件的尺寸

尺寸值为正整数,单位为px

<video src="..." controls width="500" height="500"> ... </video>

显示预览图

<video src="..." controls poster="https://www.yaconit.com/public/images/logo.png"> ... </video>

视频预加载设置

preload(预加载)说明
auto(默认)当页面加载后载入整个视频
metadata(推荐)当页面加载后只载入元数据
none当页面加载后不载入视频
<video src="..." controls preload="metadata"> ... </video>

预格式化

标签选中的部分会诚实的显示空白符,不会合并空白符(空格,回车等)

<pre>
    咏鹅

    鹅鹅鹅,
    曲项向天歌,
    白毛浮绿水,
    红掌拨清波。
</pre>

超链接

超链接是超文本链接的简称,意思是可以超出文本的限制进行链接,作用是实现页面与页面之间的跳转

跳转到指定页面

点击此连接,就会从当前页面跳转至 a.html 页面

<a href="a.html">a.html</a>

设置新页面打开的位置

在当前窗口下打开,会覆盖掉当前页面

<a href="..." target="_self">...</a>

在新窗口下打开,会打开一个新窗口或选项卡

<a href="..." target="_blank">...</a>

在指定的内联框架中打开,target 的值为内联框架的 name 属性值

<a href="" target="itop">...</a>

空连接

点击链接,不会有产生任何跳转

<a href="javascript:void(0)">...</a>

锚点和锚链接(用于同一页面上下跳转,href往name跳转)

可以在网页的某个位置设置一个锚点,然后通过锚链接跳转到锚点所在的位置

锚点是只有 name 属性的超链接

锚链接是href 属性包含 # 的超链接

<a href="">刷新页面</a>		//填空白时,点击刷新当前页面

单页跳转

<body>
    <a href="#t1">附表一</a>
    <a href="#t2">附表二</a>
    <a href="#t3">附表三</a>
    <a name="t1"></a>
    <table border="1" width="100%" height="1000">
        <caption>附表一</caption>
    </table>
    <a name="t2"></a>
    <table border="1" width="100%" height="1000">
        <caption>附表二</caption>
    </table>
    <a name="t3"></a>
    <table border="1" width="100%" height="1000">
        <caption>附表三</caption>
    </table>
</body>

跨页跳转

中间填写目标页面的路径,后接#与对应的描点名

<!-- nav.html -->
<body>
    <a href="a.html#t1">附表一</a>
</body>

<!-- a.html -->
<body>
    <a name="t1"></a>
    <table border="1" width="100%" height="1000">
        <caption>附表一</caption>
    </table>
  </body>

功能性链接

下载文件(点击文字会下载href后路径中写的资源)

<a href="/public/images/logo.png" download="">图片</a>

发送邮件

<a href="mailto:邮箱地址">...</a>

拨打电话,在手机端有效

<a href="tel:电话号码">...</a>

执行javascript脚本

<a href="javascript:js脚本">...</a>

文本标签

样式标签

样式标签都有特殊的样式,但他们没有具体的语义

<b>粗体文本</b>
<i>斜体文本</i>
<big>大号文本</big>		!!!已废弃
<small>小号文本</small>
<sup>上标文本</sup>
<sub>下标文本</sub>
<mark>有记号的文本</mark>
<tt>等宽字体</tt>


r是右的英文首字母,l是左的英文首字母
rtl是right to left(从右向左)的简写
<bdo dir="rtl">文字从右向左显示</bdo>
ltr是left to right(从左向右)的简写
<bdo dir="ltr">文字从左向右显示</bdo>

语义化标签

语义化标签也许没有特殊的样式,但他们都表示了某种具体的含义

强调文本

<em>强调文本</em>						//倾斜
<strong>语气更为强烈的强调文本</strong>	//加粗

被插入和删除的文本

del 被删除的文本

ins 被插入的文本,一般用来更正被del的文本

我今年<del>20</del><ins>18</ins>岁了

联系地址

与地址相关的都可以用

包裹,自带样式:倾斜

<body>
    <h3>联系方式:</h3>
    <address>
        <p>地址:**省**市**区**路**号</p>
        <p>电话:12300000000</p>
        <p>邮箱:12345@**.com</p>
    </address>
</body>

引用

引用某个文献,比如书记或杂志的标题

<body>
    <h1>文章标题</h1>
    <p>文字正文</p>
    <cite>——本文摘录自《读者》</cite>
</body>

引用一行内容

毛爷爷说过:<q>所有反动派都是纸老虎</q>

引用大段内容

<body>
    <p>以下文章摘自《读者》:</p>
    <blockquote>
        <p>来自《读者》的大段文摘...</p>
    </blockquote>
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LOclHtZ9-1691948413417)(E:/视频图像/image-20230222155748989.png)]

**键盘按键

请使用<kbd>CTRL</kbd>+<kbd>C</kbd>进行复制

代码块

单行代码块

Java输出语句<code>System.out.print("Hello World");</code>

多行代码一般配合 pre 使用

<body>
    <h3>Java代码块:</h3>
    <pre>
        <code>
            public class HelloWorld{
                public static void main(String[] args){
                    System.out.print("Hello World");
                }
            }
        </code>
    </pre>
</body>

计算机程序输出

<samp>Hello World</samp>

变量定义

一般用于需要用户输入的部分

一个简单的表达式: <var>x</var> = <var>y</var> + 2

缩写文本(鼠标移至文本上会显示全称)

<abbr title="Hyper Text Markup Language">HTML</abbr>

日期时间

<p>我们在每天早上 <time>9:00</time> 开始营业。</p>
<p>我在 <time datetime="2008-02-14">情人节</time> 有个约会。</p>

marquee(文字滚动)标签

用于显示一串来回滚动的文本,图片也行

marquee简介

  • 标签,是成对出现的标签,首标签和尾标签之间的内容就是滚动内容。

  • 标签的属性主要有behavior、bgcolor、direction、width、height、hspace、vspace、loop、scrollamount、scrolldelay等,它们都是可选的。

behavior属性

  • behavior属性的参数值为alternate、scroll、slide中的一个,分别表示文字来回滚动、单方向循环滚动、只滚动一次.

注意!!!!

  • 如果在标签中同时出现了direction和behavior属性,那么scroll和slide的滚动方向将依照direction属性中参数的设置。

bgcolor属性

  • 文字滚动范围的背景颜色,参数值是16进制(形式:#AABBCC或#AA5566等)或预定义的颜色名字(如red、yellow、blue等)。

direction属性

  • 文字滚动的方向,属性的参数值有down、left、right、up共四个单一可选值,分别代表滚动方向向下、向左、向右、向上。

width和height属性

  • width和height属性的作用决定滚动文字在页面中的矩形范围大小。
  • width属性用以规定矩形的宽度,height属性规定矩形的高度。
  • 这两个属性的参数值可以是数字或者百分数,数字表示矩形所占的(宽或高)像素点数,百分数表示矩形所占浏览器窗口的(宽或高)百分比。

hspace和vspace属性

  • 这两个属性决定滚动矩形区域距周围的空白区域.

loop属性

  • loop属性决定滚动文字的滚动次数,缺省是无限循环。参数值可以是任意的正整数,如果设置参数值为-1或infinite时将无限循环。

scrollamount和scrolldelay属性

  • 这两个属性决定文字滚动的速度(scrollamount)和延时(scrolldelay),参数值都是正整数。

align属性

  • 这个属性决定滚动文字位于距形内边框的上下左右位置。

注意

  • 您也可以将和之间的内容替换为图像或其它对象等功能。

各个属性参数

  • direction 表示滚动的方向,值可以是left,right,up,down,默认为left
  • behavior 表示滚动的方式,值可以是scroll(连续滚动)slide(滑动一次)alternate(来回滚动)
  • loop 表示循环的次数,值是正整数,默认为无限循环
  • scrollamount 表示运动速度,值是正整数,默认为6
  • scrolldelay 表示停顿时间,值是正整数,默认为0,单位是毫秒
  • align 表示元素的垂直对齐方式,值可以是top,middle,bottom,默认为middle
  • bgcolor 表示运动区域的背景色,值是16进制的RGB颜色,默认为白色
  • height、width 表示运动区域的高度和宽度,值是正整数(单位是像素)或百分数,默认width=100% height为标签内元素的高度。
  • hspace、vspace 表示元素到区域边界的水平距离和垂直距离,值是正整数,单位是像素。
  • οnmοuseοver=this.stop() οnmοuseοut=this.start() 表示当鼠标以上区域的时候滚动停止,当鼠标移开的时候又继续滚动。

实体符号

常用符号

实体说明写法
空格&nbsp;
©版权符号(©)&copy;
&与符号(&)&amp;
< 小于号(<)&lt;
>大于号(>)&gt;
"双引号(")&quot;

更多符号

https://www.w3school.com.cn/tags/html_ref_symbols.html

分区标签

通用分区

块级元素:

  • 无论内部的内容多少,总是独占一行
  • 在没有设置高度的情况下,高度为内容的高度
  • 带边距的块级元素
    • h1~h6
  • 不带边距的块级元素

块级分区: div

​ 表示一个独立的模块,模块之间没有关系
​ 使用div包裹的区块没有具体意义;
​ 独占一行,无边距;

//使用 `div` 对页面的某些标签进行包裹,配合CSS进行页面布局
<body>
    <div>
        ...
    </div>
</body>

行内分区: span

将块中的某一句话或某一些行内的元素独立出来,从而进行样式操作(没有具体意义)

通过 span 包裹行内的某些文本,配合CSS进行样式调整

<body>
    <p>
        <span> ... </span>
    </p>
</body>

页面分区

头部,主体,脚部都独占一行,无边距

头部

一般指整个页面或某个section的头部区域

<header> ... </header>

主体

一般指页面的主体部分

<main> ...</main>

脚部

一般指整个页面或某个section的尾部区域

<footer> ... </footer>

节段分区

所谓的节段标签,就是将一个HTML页面通过语义进行区域划分,使得整个HTML页面更具逻辑性。

body 定义了主节段,基于主节段,可以通过sectionarticleasidenav 来定义各个子节段。

文章内容节段:article

<body>
    <article>
        <h1>文章内容</h1>
        <p>正文内容...</p>
    </article>
</body>

可以为文章正文添加节段,更好的区分文章的每一个小节的范围

<body>
    <article>
        <h1>文章内容</h1>
        <section>
            <h2>第一节</h2>
            <p>正文内容...</p>
        </section>
        <section>
            <h2>第二节</h2>
            <p>正文内容...</p>
        </section>
    </article>
</body>

侧边栏:aside

一般的文章页都有与文章内容不相干的侧边栏等区块,可以使用aside进行划分

<body>
    <article>
        ...
    </article>
    <aside>
        <h3>热门文章:</h3>
        <ul>
            <li>文章标题1</li>
            <li>文章标题2</li>
        </ul>
    </aside>
</body>

页面分区

导航:nav

nav一般用于导航,可以用于页面导航,也可以用于某篇文章的大纲导航

<body>
    <nav>
        <a href="...">导航1</a>
        <a href="...">导航2</a>
        <a href="...">导航3</a>
    </nav>
    <section>
        模块一
    </section>
    <section>
        模块二
    </section>
    <footer>
        页面底部
    </footer>
</body>

:section

1.与文章相关 2.独立区块 3.当找不到合适的标签时,使用该标签

功能分区

添加页面样式

<head>
    <style> ... </style>
</head>

添加JavaScript脚本

src:1.外部脚本的路径 2.引入外部脚本时,标签内部不能再写任何代码 3.引入外部脚本时,不能将标签改为自闭合标签,必须保留结束标签

<body>
    <script> ... </script>
</body>

模板(要配合JavaScript使用,模板中的代码不会被浏览器解析和渲染)

<body>
    <template> ... </template>
</body>

内联框架

可以将其他页面嵌入到当前页面中显示,一般用于后台页面布局或者广告显示

src 为默认打开的网页网址

<iframe src="http://www.yaconit.com"/>

调整内联框架的尺寸

尺寸的值为整数,单位为px

<iframe width="300" height="500" />

iframe 取名( name ),和超链接的target属性配合使用

<body>
    <a href="http://www.yaconit.com/" target="site">YaconIT</a>
    <a href="http://www.baidu.com/" target="site">百度</a>
    <br/>
    <iframe name="site" width="100%" height="700"/>
</body>

表单标签

表单域

form 标签规定了表单的范围,里面包裹了各种表单元素

action 属性为表单的提交地址,表单的内容都将提交到 action 所指向的地址

method 属性为表单提交的方式,一般情况下使用 post 方式,但也可以选择使用 get 方式

<form action="login.php" method="post">
    <div>
        <label for="account">账号:</label>
        <input type="text" id="account" name="account"/>
    </div>
    <div>
        <label for="password">密码:</label>
        <input type="password" id="password" name="password"/>
    </div>
    <div>
        <button type="submit">登陆</button>
    </div>
</form>

附件上传

如果需要文件上传,那么表单的提交类型一定要为post

enctype属性规定了发送到服务器之前应该如何对表单数据进行编码,默认编码方式为 application/x-www-form-urlencoded。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为“+”号,特殊符号转为 “ASCII HEX”值)。但是,在文件上传时,此属性的值必须为 multipart/form-data,就是不对字符进行编码。

<form action="update.php" method="post" enctype="multipart/form-data">
    <div>
        <label for="file">文件:</label>
        <input type="file" id="file" name="file" />
    </div>
    <div>
        <button type="submit">上传</button>
    </div>
</form>

表单元素

输入框

通用属性说明
type定义了单行文本输入框的类型
name定义了表单元素的名称,提交表单时,作为数据的标识
value定义了表单元素的默认值,提交表单时,作为数据的值

输入框点击时没有边框

input:focus{border:none;outline: none;}
//	  聚焦时	边框		轮廓

输入文本

<input type="text" name="account" value="ZhangSan"/>

如果为文本输入框,type 属性可以省略

<input name="..." value="..."/>

输入密码

<input type="password" />

输入邮箱

<input type="email" />

输入网址

<input type="url" />

输入电话

<input type="tel" />

搜索框

本质上就是 text 输入框,但在语义上有搜索的功能

<input type="search" />

输入数字

<input type="number" />

设置默认值

<input type="number" value="10" />

设置最大值、最小值

<input type="number" max="100" min="1" />

设置步长

<input type="number" min="0" step="10" />

滑动条:type=“range”

<input type="range" value="50" min="1" max="100" step="1" />

输入时间日期

输入日期 日期选择器—— type=“date”

<input type="date" value="2020-09-09"/>

输入时间 时间选择器—— type=“time”

<input type="time" value="09:00" />

输入日期时间 本地日期选择器—— type=“datetime-local”

<input type="datetime-local" value="2018-06-12T19:30" />

输入某年某月 月份选择器—— type=“month”

<input type="month" value="2018-05" />

输入某年的第几周 周选择器—— type=“week”

<input type="week" value="2018-W18" />

颜色输入框 颜色选择器—— type=“color”

<input type="color" value="#FF0000" />

正则表达式

/^		正则表达式开头
$/		正则表达式结尾

\w 字母数字下划线任意一个

【】 这个范围内的任意一个数( 【a-zA-Z】 )

{2,3} 2个字符~3个字符数 {2,} 代表2次或2次以上,不加“,”代表只有2次

\d 数字,等价于0~9

\s 任何空白字符

\S 任何非空格的空白符号{ }

.	除了换行符(回车)以外任意一个符号,需要输入“ . ”的时候写成“ \. ” 
+	前面一个符号重复1次或多次

里面填的数字是次数

文本域

普通文本域

文本域没有value属性,value值就是标签内包含的内容

<textarea name="context">...</textarea>

设置文本域的尺寸

rows 为行数

cols 为列数

<textarea rows="5" cols="20">...</textarea>

设置文本域的换行行为

默认情况下,文本域中的文本在表单提交时是不换行的。

如果希望换行,则配置 wrap 属性为 hard,并且同时配置 cols 属性

<textarea wrap="hard" cols="20">...</textarea>

设置文本域的最大字数

maxlength 属性规定文本区域的最大长度(以字符计)。

<textarea maxlength="50">...</textarea>

选择框

单选按钮

默认情况下为非选中状态

<input type="radio" />

默认选中状态

<input type="radio" checked />

同组单选按钮

要将多个单选按钮设置到同组,只需把所有的单选框的name属性的值设置为一样即可

<input type="radio" name="sex" value="男"/> 男
<input type="radio" name="sex" value="女"/> 女

复选框

默认情况下,复选框是未选中状态

<input type="checkbox" />

默认选中状态

<input type="checkbox" checked />

同组复选框

<h4>请选择权限:</h4>
<input type="checkbox" name="permissions" value="1"/> 读
<input type="checkbox" name="permissions" value="2"/> 写
<input type="checkbox" name="permissions" value="3"/> 执行

文件域

文件域有value属性,但不能给其赋予默认值,文件域的默认值由用户选择的文件路径决定,如果用户没有选择文件,则该值为空字符串,如果用户选择了多个文件,则该值表示第一个已选文件的路径

默认情况下,用户只能选择一个文件

<input type="file" />

让用户可以选择多个文件

<input type="file" multiple />

限制用户选择的文件类型

<input type="file" accept=".gif,.jpg,.png" />

下拉列表框

将一组数据以列表的形式展示,让用户进行选择

select 元素规定了列表的范围,它只有name属性,没有value属性

option 元素为列表的每一个可选项,它包含 value 属性

selectoption 组成了完整的下拉列表框

默认情况情况下,下拉列表框为单选模式

<select name="subject">
    <option value="1">语文</option>
    <option value="2">数学</option>
    <option value="3">生物</option>
</select>

多选模式

<select name="..." multiple>
    ...
</select>

设置可见选项的数目,默认只显示一个

<select name="..." size="5">
    ...
</select>

设置默认被选中的项

<select name="subject">
    <option value="1">语文</option>
    <option value="2" selected>数学</option>
    <option value="3">生物</option>
</select>

禁止某个选项

<select name="subject">
    <option value="1">语文</option>
    <option value="2" disabled>数学</option>
    <option value="3">生物</option>
</select>

对选项进行分组

<select name="subject">
    <optgroup label="理科">
        <option value="1">物理</option>
        <option value="2">化学</option>
    </optgroup>
    <optgroup label="文科">
        <option value="3">历史</option>
        <option value="4">地理</option>
    </optgroup>
</select>

禁止选中某个分组

<select name="subject">
    <optgroup label="理科">
        ...
    </optgroup>
    <optgroup label="文科" disabled>
        ...
    </optgroup>
</select>

按钮

普通按钮

此类按钮需要配合JavaScript进行使用,否则不会由任何作用

<button>按钮</button>
<input type="button" value="按钮"/>

提交按钮

此类按钮可以对表单进行数据提交

<button type="submit">按钮</button>
<input type="submit" value="提交"/>

图片按钮

以图片的形式显示按钮,需要指定图片源,点击此按钮可以提交表单数据

<input type="image" src="https://www.yaconit.com/public/images/logo.png" />

重置按钮

会将表单的数据重置为初始状态

<input type="reset" value="重置" />

隐藏域

不会在页面中显示,但是,可以进行表单数据的传递

使用隐藏域时,必须要设置 namevalue 属性,否则隐藏域将失去意义

<input type="hidden" name="id" value="1" />

标签

用于对表单元素进行说明

<div>
    <label for="pwd">密码</label>
    <input type="password" id="pwd" />
</div>

字段域

用于对表单元素进行区块划分

fieldset 为字段域的界限

legend 为字段域的文本说明

<form action="..." method="...">
    <fieldset>
        <legend>基本信息</legend>
        <div>
            <label for="name">姓名:</label>
            <input type="text" id="name" name="name" />
        </div>
        <div>
            <label for="sex">性别:</label>
            <input type="radio" name="sex" value="0" /> 男
            <input type="radio" name="sex" value="1" /> 女
        </div>
    </fieldset>
    <fieldset>
        <legend>详细信息</legend>
        <div>
            <label for="phone">电话:</label>
            <input type="tel" id="phone" name="phone" />
        </div>
        <div>
            <label for="addr">住址:</label>
            <input type="text" name="addr" />
        </div>
    </fieldset>
</form>

禁用某个字段域

<form action="..." method="...">
    <fieldset>
        ...
    </fieldset>
    <fieldset disabled>
        ...
    </fieldset>
</form>

特殊模式

禁用模式

用户不能填写数据,也不会被表单提交

<input disabled />
<select disabled>
    ...
</select>
<textarea disabled>...</textarea>

只读模式

用户不能填写数据,但可以被表单提交

<input readonly />

必填模式

用户必须填写数据,或者元素包含默认值

<input required />

占位提示符

当元素没有任何数据的时候,就会显示占位提示符中的文本,一旦用户填写了数据或者元素有默认值,则不显示

占位提示符只在 输入框 和 文本域 元素中有效,其他元素无效

<input placeholder="请填写..." />

模式匹配

用户输入的值必须满足指定的模式

只能在单行文本输入框中使用模式匹配

<input pattern="[A-Za-z]+" />

网页配置

编码设置

<head>
    <meta charset="utf-8">
</head>

视口设置

content属性可选值说明
width一个正整数或者字符串 device-width视口宽度,单位为px
height一个正整数或者字符串 device-height视口高度,单位为px
initial-scale一个0.010.0之间的正数定义设备宽度与视口大小之间的缩放比率
maximum-scale一个0.010.0之间的正数定义缩放的最大值;它必须大于或等于minimum-scale的值,不然会导不确定的行为发生。
minimum-scale一个0.010.0之间的正数定义缩放的最小值;它必须小于或等于maximum-scale的值,不然会导致不确定的行为发生。
user-scalable一个布尔值(yes 或者no如果设置为 no,用户将不能放大或缩小网页。默认值为 yes
<head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
</head>

网页信息设置

内容简介

<head>
    <meta name="description" content="博主从业十余年,现任国内知名软件培训学校讲师!博主致力于分享软件开发技术,技术面包含WEB全栈开发、Java全栈开发、Python全栈开发、PHP全栈开发教程,以及MySql、redis、Oracle等数据库教程,Linux服务器操作教程等等">
</head>

关键词

<head>
    <meta name="keywords" content="软件开发教程,WEB前端开发教程,Java全栈开发教程,WEB全栈开发教程,Python教程,PHP全栈开发教程">
</head>

作者信息

<head>
    <meta name="author" content="www.yaconit.com">
</head>

修订信息

<head>
    <meta name="revised" content="Yacon,2020/9/6"/>
</head>

编辑工具信息

<head>
    <meta name="generator" content="Visual Studio Code 1.48.2">
</head>

页面跳转

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="Refresh" content="5;url=http://www.yaconit.com">
</head>

<body>
    <p>对不起,您访问的页面暂时不存在,5秒后,我们将为您跳转到首页!</p>
</body>
</html>

默认链接配置

给所有的链接设置默认的target属性

<html>
    <head>
       <base target="_blank" />
    </head>
    <body>
        <a href="http://www.yaconit.com/index.html">首页</a>
        <a href="http://www.yaconit.com/index.html">资讯</a>
    </body>
</html>

给所有的链接添加前缀

<html>
    <head>
        <base href="http://www.yaconit.com" />
    </head>
    <body>
        <img src="/public/images/logo.png" />
    </body>
</html>

CSS

例:在语句前加矩形,后加圆形

<style>
	h3{
		display: flex;
		align-items: center;
		gap: 4px;
	}
	h3::before{
		content:"";
		width: 10px;
		height: 20px;
		background:#87edff;
	}
	h3::after{
		content:
		width: 10px;
		height: 10px;
		background:#fe75e9;
		border-radius: 50%;
	}

例:多行居中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hEco0OCa-1691948413417)(E:/视频图像/image-20230302172718994.png)]

例:用户名,密码两端对齐

<form action="">
	<div>
		<label for="">用户名</label>
		<input type= "text" / >
	</div>
	<div>
		<label for=""'>密码</label>
		<input type= "text" />
	</div>
< /form>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PypkVToL-1691948413418)(E:/视频图像/image-20230302173019005.png)]

例:插入图片后,图片下方有一条缝隙,解决方法:将图片变成块级元素

img{display: block;}

盒子模型

块级

宽:width
高:heigth
水平排版:text-align:  靠左	left
					 居中		center
					 靠右		right

border-radius: 50%; //把矩形的角变成圆角,写法:1. 150px 2. 50% 3.写4个10px,分别控制4个角

引入样式

优先级:!important > 行内样式 > 内部样式 > 外部样式

在任意等级样式表中填 !important ,当前样式表优先级变为最高

行内样式

<div style="color:red;">...</div>

内部样式

<style>
  * {
    color: red;
  }
</style>

引入外部样式

<link rel="stylesheet" href="style.css" />

导入外部样式

<style>
  @import "./style.css";
</style>

选择器

基础选择器

全部选择器

选择所有元素

* {
  ...;
}

标签选择器

选择指定的所有标签元素

div {
  ...;
}

类选择器

选择包含 class 属性值的所有元素

.class {
  ...;
}

ID 选择器

选择包含 id 属性值的所有选择器

id 的值在同一个网页中应该是唯一的

#id {
  ...;
}

复合选择器

复合选择器由多个基础选择器组成的选择器为复合选择器
交集选择器"."一般情况下,由标签选择器和类选择器构成;多个选择器直接写在一起,即组成一个交集选择器li.red{ }
并级选择器 “,”多个选择器并列写在一起,并且用“,”进行隔开dt,.abc{ }
后代选择器 " "只要在父级内部的子级,无论嵌套多少层都能选中父级 子级(加空格)
父子选择器 “>”必须是父级的直接子级才能选中父级>子级
兄弟选择器 “~”只要与选择器同级的并且在选择器后面的元素都可以被选中选择器1~选择器2
相邻兄弟选择器 “+”只有与选择器相邻的且在选择器后面的一个元素可以被选中选择器1+选择器2

交集选择器

同时满足两个以上条件的选择器

指定某个元素,并且包含某个样式类

<body>
  <style>
    p.red {
      color: red;
    }
  </style>
  <p class="red">...</p>
</body>

同时包含两个样式类,样式类中间不能有空格

<body>
  <style>
    .red.bold {
      color: red;
    }
  </style>
  <p class="red bold">...</p>
</body>

并集选择器

多个元素设置相同的样式

<body>
  <style>
    h1,
    h2 {
      color: red;
    }
  </style>
  <h1>...</h1>
  <h2>...</h2>
</body>

后代选择器

选择所有的子元素,包含孙子级

<body>
  <style>
    ul li {
      color: red;
    }
  </style>
  <ul>
    <li>...</li>
    <!-- 可以选中 -->
    <ol>
      <li>...</li>
      <!-- 可以选中 -->
    </ol>
  </ul>
</body>

父子选择器

选择所有直接子元素,不包含孙子级

<body>
  <style>
    ul > li {
      color: red;
    }
  </style>
  <ul>
    <li>...</li>
    <!-- 可以选中 -->
    <ol>
      <li>...</li>
      <!-- 不能选中 -->
    </ol>
  </ul>
</body>

相邻兄弟选择器

选择后面紧邻的兄弟元素

<body>
  <style>
    dt + dd {
      color: red;
    }
  </style>
  <dl>
    <dd>...</dd>
    <!-- 不能选中 -->
    <dt>...</dt>
    <dd>...</dd>
    <!-- 可以选中 -->
    <dd>...</dd>
    <!-- 不能选中 -->
  </dl>
</body>

兄弟选择器

选择所有后面的兄弟元素

<body>
  <style>
    dt ~ dd {
      color: red;
    }
  </style>
  <dl>
    <dd>...</dd>
    <!-- 不能选中 -->
    <dt>...</dt>
    <dd>...</dd>
    <!-- 可以选中 -->
    <dd>...</dd>
    <!-- 可以选中 -->
  </dl>
</body>

属性选择器

属性选择器使用元素中的属性作为选择条件
包含某个属性[属性名]
包含某个属性且以某值开头[属性名^=‘值’]
包含某个属性且以包含某值[属性名*=‘值’]
包含某个属性且以某值结尾[属性名$=‘值’]
包含某个属性且值为具体值[属性名=‘值’]

包含属性

选择所有包含指定属性的元素

<body>
  <style>
    [name] {
      color: red;
    }
  </style>
  <input name="" />
</body>

包含属性且值为固定值

选择所有包含指定属性,且属性值等于指定值的元素

<body>
  <style>
    [type="text"] {
      color: red;
    }
  </style>
  <input type="text" />
</body>

包含属性且值以指定字符串开头

选择所有包含指定属性,且属性值以指定字符串开头的元素

<body>
  <style>
    [href^="#"] {
      color: red;
    }
  </style>
  <a href="#css指南">...</a>
</body>

包含属性且值包含指定的字符串 选择所有包含指定属性,且属性值包含指定的字符串的元素

<body>
  <style>
    [href*="#"] {
      color: red;
    }
  </style>
  <a href="css.html#css指南">...</a>
</body>

包含属性且值以指定字符串结尾 选择所有包含指定属性,且属性值以指定字符串结尾的元素

<body>
  <style>
    [href$=".com"] {
      color: red;
    }
  </style>
  <a href="mailto:123456@mail.com">...</a>
</body>

伪类选择器

用于超链接

选择所有未被访问的链接

a:link {
  color: red;
}

选择所有已被访问的链接

a:visited {
  color: red;
}

选择非指定的元素

:not

鼠标按下但未释放

:active {
  color: red;
}

鼠标悬浮

:hover {
  color: red;
}

插入文本元素

在元素内容前插入文本元素

<body>
  <style>
    p:before {
      content: "Hello,";
    }
  </style>
  <p>HTML!</p>
</body>

在元素内容后插入内容

<body>
    <style>
        p:after { content: ',HTML!';  }
    </style>
    <p>Hello</p>
</body>

用于表单元素

获取焦点

<body>
  <style>
    :focus {
      outline-color: red;
    }
  </style>
  <form>
    <input type="text" />
    <input type="text" />
    <input type="text" />
  </form>
</body>

启用的元素

<body>
  <style>
    :enabled {
      border-color: red;
    }
  </style>
  <form>
    <input type="text" disabled />
    <input type="text" />
    <input type="text" disabled />
  </form>
</body>

禁用的元素

<body>
  <style>
    :disabled {
      border-color: red;
    }
  </style>
  <form>
    <input type="text" disabled />
    <input type="text" />
    <input type="text" disabled />
  </form>
</body>

选中的元素,只作用于复选框和单选框

<body>
    <style>
        :checked{margin-right:20px;}
    </style>
    <form>
        <input type="radio" checked/> 男
        <input type="radio"/> 女
        <br/>
        <input type="checkbox" checked/> JAVA
        <input type="checkbox"/> HTML
    </form>
</body>

不包含指定条件

<body>
    <style>
        :not(:checked){margin-right:20px;}
    </style>
    <form>
        <input type="radio" checked/> 男
        <input type="radio"/> 女
        <br/>
        <input type="checkbox" checked/> JAVA
        <input type="checkbox"/> HTML
    </form>
</body>

子元素

根据位置,选择第一个子元素

<body>
  <style>
    dl :first-child {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <!-- 可以选中 -->
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <dd>显示用户输入的工具</dd>
  </dl>
</body>
<body>
  <style>
    dl dd:first-child {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <!-- 不能选中,不是 dd 元素 -->
    <dd>用户输入的工具</dd>
    <!-- 不能选中,不是 dl 下的第一个子元素 -->
    <dt>显示器</dt>
    <dd>显示用户输入的工具</dd>
  </dl>
</body>

根据位置,选择最后一个子元素

<body>
  <style>
    dl :last-child {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <dd>显示用户输入的工具</dd>
    <!-- 可以选中 -->
  </dl>
</body>
<body>
  <style>
    dl dt:last-child {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <!-- 不能选中,不是 dl 下的最后一个子元素 -->
    <dd>显示用户输入的工具</dd>
    <!-- 不能选中,不是 dt 元素 -->
  </dl>
</body>

根据类型,选择第一个子元素

<body>
  <style>
    dl :first-of-type {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <!-- 可以选中,dl 下第一个 dt 元素 -->
    <dd>用户输入的工具</dd>
    <!-- 可以选中,dl 下第一个 dd 元素 -->
    <dt>显示器</dt>
    <dd>显示用户输入的工具</dd>
  </dl>
</body>
<body>
  <style>
    dl dd:first-of-type {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <!-- 不能选中,因为该元素不是 dd 元素 -->
    <dd>用户输入的工具</dd>
    <!-- 可以选中,dl 下的第一个 dd 元素 -->
    <dt>显示器</dt>
    <dd>显示用户输入的工具</dd>
  </dl>
</body>

根据类型,选择最后一个元素

<body>
  <style>
    dl :last-of-type {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <!-- 可以选中,dl 下最后一个 dt 元素 -->
    <dd>显示用户输入的工具</dd>
    <!-- 可以选中,dl 下最后一个 dd 元素 -->
  </dl>
</body>
<body>
  <style>
    dl dt:last-of-type {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <!-- 可以选中,dl 下最后一个 dt 元素 -->
    <dd>显示用户输入的工具</dd>
    <!-- 不能选中,因为该元素不是 dt 元素 -->
  </dl>
</body>

根据数量,选择唯一的子元素

<body>
  <style>
    dl :only-child {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <!-- 可以选中,dl 中唯一的元素 -->
  </dl>
</body>
<body>
  <style>
    dl dt:only-child {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <!-- 不能选中,不是 dl 中的唯一元素 -->
    <dd>用户输入的工具</dd>
  </dl>
</body>

根据类型,选择唯一的子元素

<body>
  <style>
    dl :only-of-type {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <!-- 可以选中,dl 中唯一的 dt 元素 -->
    <dd>用户输入的工具</dd>
    <!-- 不能选中,dl 中有多个 dd 元素 -->
    <dd>可以输入任何文字</dd>
    <!-- 不能选中,dl 中有多个 dd 元素 -->
  </dl>
</body>

根据位置,选择指定位置的元素

<body>
  <style>
    dl :nth-child(2) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <!-- 可以选中,dl 中位置为 2 的子元素 -->
    <dt>显示器</dt>
    <dd>显示用户输入的工具</dd>
  </dl>
</body>
<body>
  <style>
    dl dt:nth-child(2) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <!-- 不能选中,不是 dt 元素 -->
    <dt>显示器</dt>
    <dd>显示用户输入的工具</dd>
    <!-- 不能选中,不是 dl 中位置为 2 的子元素 -->
  </dl>
</body>
<body>
  <style>
    dl :nth-child(odd) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <!-- 可以选中,因为位置为奇数 -->
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <!-- 可以选中,因为位置为奇数 -->
    <dd>显示用户输入的工具</dd>
  </dl>
</body>
<body>
  <style>
    dl :nth-child(even) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <!-- 可以选中,因为位置为偶数 -->
    <dt>显示器</dt>
    <dd>显示用户输入的工具</dd>
    <!-- 可以选中,因为位置为偶数 -->
  </dl>
</body>

根据类型,选择指定位置的元素

<body>
  <style>
    dl :nth-of-type(2) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <!-- 可以选中,因为是第2个dt -->
    <dd>显示用户输入的工具</dd>
    <!-- 可以选中,因为是第2个dd -->
  </dl>
</body>
<body>
  <style>
    dl dt:nth-of-type(2) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <!-- 可以选中,因为是第2个dt -->
    <dd>显示用户输入的工具</dd>
    <!-- 不能选中,因为不是 dt 元素 -->
  </dl>
</body>
<body>
  <style>
    dl :nth-of-type(odd) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <!-- 可以选中,因为是第1个dt,1为奇数 -->
    <dd>用户输入的工具</dd>
    <!-- 可以选中,因为是第1个dd,1为奇数 -->
    <dt>显示器</dt>
    <dd>显示用户输入的工具</dd>
  </dl>
</body>
<body>
  <style>
    dl :nth-of-type(even) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <!-- 可以选中,因为是第2个dt,2为偶数 -->
    <dd>显示用户输入的工具</dd>
    <!-- 可以选中,因为是第2个dd,2为偶数 -->
  </dl>
</body>

根据位置,选择指定倒数位置的元素

<body>
  <style>
    dl :nth-last-child(2) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <!-- 可以选中,倒数第2个元素 -->
    <dd>显示用户输入的工具</dd>
  </dl>
</body>
<body>
  <style>
    dl dd:nth-last-child(2) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <dd>用户输入的工具</dd>
    <dt>显示器</dt>
    <!-- 不能选中,因为该元素不是 dd 元素 -->
    <dd>显示用户输入的工具</dd>
  </dl>
</body>

根据类型,选择指定倒数位置的元素

<body>
  <style>
    dl :nth-last-of-type(2) {
      color: red;
    }
  </style>
  <dl>
    <dt>键盘</dt>
    <!-- 可以选中 -->
    <dd>用户输入的工具</dd>
    <!-- 可以选中 -->
    <dt>显示器</dt>
    <dd>显示用户输入的工具</dd>
  </dl>
</body>
<body>
    <style>
        dl dd:nth-last-of-type(2){color:red;}
    </style>
    <dl>
        <dt>键盘</dt><!-- 不能选中,因为该元素不是 dd 元素 -->
        <dd>用户输入的工具</dd><!-- 可以选中 -->
        <dt>显示器</dt>
        <dd>显示用户输入的工具</dd>
    </dl>
</body>

位置伪类

元素位置
第一个元素:first-child
第n个元素(n为整数):nth-child(n)
最后一个元素:last-child
隔行控制样式(n前的数字控制数字倍数行数的样式)所有元素 :nth-child(1n)
奇数行 :nth-child(2n+1) :nth-child(2n-1)
偶数行 :nth-child(2n)
第5行开始使用样式:nth-child(n+5)
第5行及前面元素开始使用样式:nth-child(-n+5)
从后向前数第n个元素:nth-last-child(n)
类型位置
同类型第一个元素:first-of-type
同类型第n个元素(n为整数):nth-of-type(n)
同类型最后一个元素:last-of-type
隔行控制样式(n前的数字控制数字倍数行数的样式)同类型所有元素
:nth-of-type(1n)
同类型奇数行
:nth-of-type(2n+1)
:nth-of-type(2n-1)
同类型同类型偶数行
:nth-of-type(2n)
同类型第5行开始使用样式:nth-of-type(n+5)
同类型第5行及前面元素开始使用样式:nth-of-type(-n+5)
同类型中位置从后向前数第n个元素:nth-last-of-type(n)

伪元素选择器

伪元素犹如在HTML中新建一个元素,实际这个元素不存在
::first-line首行
::first-letter首字符
::selection用户选择
::before在元素的前面插入一个子元素。一定有content属性
::after在元素的后面插入一个子元素。一定有content属性

选择首字母

<body>
  <style>
    p::first-letter {
      color: red;
    }
  </style>
  <p>Hello,HTML</p>
</body>

选择首行

<body>
  <style>
    p::first-line {
      color: red;
    }
  </style>
  <p>
    Hello,HTML!<br />
    Hello,HTML!<br />
    Hello,HTML!<br />
  </p>
</body>

选择用户选取的部分

<body>
  <style>
    p::selection {
      color: red;
    }
  </style>
  <p>
    Hello,HTML!<br />
    Hello,HTML!<br />
    Hello,HTML!<br />
  </p>
</body>

禁止用户选择

<body>
  <style>
    p::selection {
      user-select: none;
    }
  </style>
  <p>
    Hello,HTML!<br />
    Hello,HTML!<br />
    Hello,HTML!<br />
  </p>
</body>

字符样式

cursor:pointer;
手型鼠标(鼠标手)

颜色

颜色名称

<body>
  <style>
    span {
      color: red;
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

十六进制

头两位表示红色,中间两位表示绿色,最后两位表示蓝色,取值范围00 ~ FF

span {
  color: #ff0000;
}
span {
  color: #f00;
}

rgb( r e d , red, red,green,$blue)

取值范围0 - 255

<body>
  <style>
    span {
      color: rgb(255, 0, 0);
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

rgba( r e d , red, red,green, b l u e , blue, blue,alpha)

最后一位为透明度,取值范围0~1

<body>
  <style>
    span {
      color: rgba(255, 0, 0, 0.5);
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

大小

以 px 为单位

<body>
  <style>
    span {
      font-size: 30px;
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

以 em 为单位

1em=父级字体尺寸

2em=2 倍父级尺寸

span {
  font-size: 2em;
}

以 rem 为单位

如果没有为 html 设置字体大小,则使用浏览器默认的字体大小为基准,假设浏览器默认的字体大小为 16px,则 1rem=16px

span {
  font-size: 2rem;
}

如果为 html 设置了字体大小,则以 html 的字体大小为基准,假设 html 的字体大小为 10px,则 1rem=10px

<body>
  <style>
    html {
      font-size: 10px;
    }
    span {
      font-size: 2rem;
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

字体

中文字体和英文字体名称中间有空格的字体需要用引号包裹

设置多个字体时,浏览器会从左至右依次检查哪个字体可用,当检测到可用字体时就直接使用该字体渲染,如果所有字体都不可用,则使用浏览器默认的字体

<body>
  <style>
    span {
      font-family: "华文黑体", "华文行楷";
    }
  </style>
  <div>正常文本<span>对比文本</span>正常文本</div>
</body>

倾斜

font-style说明
normal默认值。标准的字体样式。
italic斜体的字体样式
oblique倾斜的字体样式
inherit从父元素继承
<body>
  <style>
    span {
      font-style: italic;
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

粗细

font-weight说明
normal默认值。定义标准的字符。
bold定义粗体字符。
bolder定义更粗的字符。
lighter定义更细的字符。
100 ~ 900定义由粗到细的字符。400 等同于 normal,而 700 等同于 bold。
inherit从父元素继承
<body>
  <style>
    span {
      font-weight: bold;
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

字体样式缩写

font:倾斜 粗细 大小 字体
<body>
  <style>
    span {
      font: italic bold 30px "华文黑体", "华文行楷";
    }
  </style>
  <div>正常文本<span>对比文本</span>正常文本</div>
</body>

修饰线

text-decoration:位置 风格 颜色;
text-decoration-line说明
none没有修饰线
underline下划线
overline上划线
line-through贯穿线
inherit父级继承
text-decoration-style颜色
solid单实线
double双实线
dotted点划线
dashed虚线
wavy波浪线
<body>
  <style>
    span {
      text-decoration: underline dashed red;
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

分开设置修饰线

<body>
  <style>
    span {
      text-decoration-line: underline;
      text-decoration-color: red;
      text-decoration-style: dashed;
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

没有修饰线

text-decoration: none;

间距

<body>
    <style>
        span{letter-spacing:10px;}
    </style>
    <div>正常文本<span>比对文本</span>正常文本</div>
</body>

阴影

inset——嵌入,使原本在盒子外的阴影在内部显示

text-shadow:inset X轴偏移量 Y轴偏移量 模糊圆角半径 阴影颜色;
text-shadow:X轴偏移量 Y轴偏移量 模糊圆角半径 阴影颜色;
<body>
    <style>
        span{text-shadow: 1px 1px 2px red;}
    </style>
    <div>正常文本<span>比对文本</span>正常文本</div>
</body>

大小写字母转换

text-transform说明
capitalize每个单词的首字母转成大写,其他字母转成小写
uppercase所有字母转成大写形式
lowercase所有字母转成小写形式
none不进行转换
<body>
  <style>
    span {
      text-transform: capitalize;
    }
  </style>
  <div>Hello world <span>Hello world</span> Hello world</div>
</body>

行样式

行高

<body>
  <style>
    div:nth-of-type(2) {
      line-height: 3em;
    }
  </style>
  <div>正常行正常行正常行<br />正常行正常行正常行</div>
  <div>对比行对比行对比行<br />对比行对比行对比行</div>
  <div>正常行正常行正常行<br />正常行正常行正常行</div>
</body>

我们可以使用行高,来实现单行文本在容器中垂直方向居中对齐

<body>
  <style>
    h1 {
      height: 80px;
      line-height: 80px;
      border: 1px solid #000;
    }
  </style>
  <h1>我是一行文本</h1>
</body>

水平对齐方式

只能作用于块级元素,对行内元素无效

text-align说明
left水平居左
center水平居中
right水平居右
justify两端对齐,自动换行时有效
<body>
  <style>
    div {
      text-align: center;
    }
  </style>
  <div>center</div>
</body>

垂直对齐方式

仅对行内元素和单元格有效,或在图文混排时作用于图像上

vertical-align说明
baseline基线对齐,默认值
top顶部对齐
bottom底部对齐
middle居中对齐
10px基线上方 10px

作用于单元格元素

<body>
  <style>
    span {
      display: table-cell;
      height: 50px;
      vertical-align: middle;
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

作用于行内元素

<body>
  <style>
    span {
      vertical-align: 10px;
    }
  </style>
  <div>正常文本<span>比对文本</span>正常文本</div>
</body>

首行缩进

只能作用于块级元素

<body>
  <style>
    div:nth-of-type(2) {
      text-indent: 2em;
    }
  </style>
  <div>正常行正常行正常行<br />正常行正常行正常行</div>
  <div>对比行对比行对比行<br />对比行对比行对比行</div>
  <div>正常行正常行正常行<br />正常行正常行正常行</div>
</body>

空白符处理

white-space说明
normal会合并多个空白符,换行符会被当做空白符
pre-line会合并多个空白符,保留换行符,会删除头尾空白符
pre-wrap不合并空白符,保留换行符,不会删除头尾空白符
nowrap会合并多个空白符,删除所有换行符,会删除头尾空白符
<body>
  <style>
    div:nth-of-type(1) {
      white-space: normal;
    }
    div:nth-of-type(2) {
      white-space: pre-line;
    }
    div:nth-of-type(3) {
      white-space: pre-wrap;
    }
  </style>
  <div>normal normal normal</div>
  <div>pre-line pre-line pre-line</div>
  <div>pre-wrap pre-wrap pre-wrap</div>
</body>

单词间距

仅对英文有效

<body>
    <style>
        div{word-spacing: 10em;}
    </style>
    <div>Hello World!</div>
</body>

单词分割并换行规则

overflow-wrap说明
normal在正常的单词结束处换行
break-word如果行内没有多余的地方容纳该单词到结尾,则那些正常的不能被分割的单词会被强制分割换行
<body>
  <style>
    div {
      width: 10px;
      overflow-wrap: break-word;
    }
  </style>
  <div>Hello World!</div>
</body>

字体溢出处理

overflow:hidden这个属性的作用是隐藏溢出,若aBox的高度小于bBox,溢出的bBox高度会直接隐藏。是隐藏,并不是直接截除了。

text-overflow` 只在块级元素中生效,并且要为块级元素设置 `white-space:nowrap`和`overflow:hidden
p{
	//3句同时使用可以达成溢出效果
	text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w0LP4t9T-1691948413418)(E:/视频图像/image-20230309120438215.png)]

text-overflow说明
clip默认值,溢出部分直接隐藏
ellipsis使用 ‘…’ 来替换溢出部分

单行文本字体溢出处理

<body>
  <style>
    h1 {
      text-overflow: ellipsis;
      white-space: nowrap;
      overflow: hidden;
      width: 300px;
      border: 1px solid #000;
    }
  </style>
  <h1>易非气快、一决,登有承生杨下斯召人年</h1>
</body>

多行文本字体溢出处理,这种方法只适用于移动端和WebKit浏览器

<body>
  <style>
    h1 {
      border: 1px solid #000;
      width: 200px;
      height: 6em;
      line-height: 1.5em;
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 4;
      -webkit-box-orient: vertical;
    }
  </style>
  <h1>
    使不念欲竟才承统人的活,的屯三慧娘,夭作可视别有次的到他文,哥若回胜知的够的的场程君君主在别前是联。
  </h1>
</body>

图片样式

object-fit 属性指定元素的内容应该如何去适应指定容器的高度与宽度。

1.默认,填满容器

object-fit: fill (默认);默认,不保证保持原有的比例,内容拉伸填充整个内容容器。
对象匹配:填充(默认);默认,不保证保持原有的比例,内容拉伸填充整个内容容器.

2.宽度铺满容器,高度自动缩放

object-fit: contain;

3.高度铺满容器,宽度自动缩放,超出部分被剪裁

object-fit: cover;

4.保留原本的长宽,超出部分剪裁,截取部分为正中间

object-fit:none;

5.图片实际宽高小于设置的图片宽高时,显示效果同4,否则效果同2

object-fit:scale-down;

透明度

此属性会影响整个层的透明度,无论是元素本身还是元素内的文本都会被影响

取值范围为 0~1,0 为完全透明,1 为完全不透明

<body>
  <style>
    img {
      opacity: 0.5;
    }
  </style>
  <img src="https://www.yaconit.com/public/images/logo.png" />
</body>

如果只想让元素的背景颜色有透明度,而内部的文本不受影响,需要使用颜色透明度进行控制

<body>
  <style>
    div {
      height: 100px;
      background-image: url(./public/images/logo.png);
    }
    h1 {
      height: 100%;
      background-color: #0000ff50;
    }
  </style>
  <div>
    <h1>
      使不念欲竟才承统人的活,的屯三慧娘,夭作可视别有次的到他文,哥若回胜知的够的的场程君君主在别前是联。
    </h1>
  </div>
</body>

盒子样式

盒子模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4XRlvgUk-1691948413419)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/box-model.png)]

类型

有了整个样式属性后,我们就可以根据需要调整任意盒子的默认类型

display说明
block更改盒子的类型为块级盒子
inline更改盒子的类型为行内盒子
inline-block更改盒子的类型为行内块级盒子
table(父)更改盒子的类型为表格
table-cell(子)更改盒子的类型为单元格
flex更改盒子的类型为伸缩容器
grid更改盒子的类型为网格容器
none隐藏盒子
<body>
    <style>
        div {
            display: inline;
        }
    </style>
    <div>我是DIV</div>
    <div>我是DIV</div>
    <div>我是DIV</div>
</body>
<body>
  <style>
    span {
      display: block;
    }
  </style>
  <span>我是span</span>
  <span>我是span</span>
  <span>我是span</span>
</body>

边距

外边距

元素边框以外的距离

设置四边外边距

<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      border: 1px solid red;
      margin: 20px;
    }
  </style>
  <div></div>
  <div></div>
</body>

设置上下、左右外边距

margin: 10px 20px;

设置上、左右、下外边距

margin: 10px 20px 30px;

设置上、右、下、左外边距

margin: 10px 20px 30px 40px;

设置上外边距

margin-top: 10px;

设置右外边距

margin-right: 10px;

设置下外边距

margin-bottom: 10px;

设置左外边距

margin-left: 10px;

内边距

元素边框与内容之间的距离

设置四边内边距

padding: 10px;

设置上下、左右内边距

padding: 10px 20px;

设置上、左右、下内边距

padding: 10px 20px 30px;

设置上、右、下、左内边距

padding: 10px 20px 30px 40px;

设置上内边距

padding-top: 10px;

设置右内边距

padding-right: 10px;

设置下内边距

padding-bottom: 10px;

设置左内边距

padding-left: 10px;

尺寸

宽度计算——calc的效率低(必须给弹性项加width:100%;)

用百分比设置宽高时,如需一点点增减像素,可用calc包裹(减号两边必须加空格)

width:calc(25% - 10px/2)

调整弹性容器中弹性项的列数(弹性项名可以用 * 代替)

弹性容器名>弹性项名{flex-basis: calc((100% - 弹性项间距*(弹性项数-1))/弹性项数)}

将各种列数的计算代码写在样式表,需要调几列就将 “弹性容器名-列数” 写成弹性容器类名

//2列
div-2>弹性项名{flex-basis: calc((100% - 弹性项间距 * 1) / 2)}
//3列
div-3>弹性项名{flex-basis: calc((100% - 弹性项间距 * 2) / 3)}

设置盒子的尺寸

只能作用于块级盒子

width 盒子的宽度

height 盒子的高度

<body>
  <style>
    div {
      width: 100px;
      height: 300px;
      background-color: red;
    }
  </style>
  <div>100x300</div>
</body>

设置盒子的最小尺寸

当盒子的尺寸比最小尺寸小时,则最小尺寸生效

当盒子的尺寸比最小尺寸大时,则盒子的尺寸生效

<body>
  <style>
    div {
      width: 50px;
      height: 150px;
      min-width: 100px;
      min-height: 300px;
      background-color: red;
    }
  </style>
  <div>100x300</div>
</body>

设置最大尺寸

当盒子的尺寸大于最大尺寸时,最大尺寸生效

当盒子的尺寸小于最大尺寸时,盒子的尺寸生效

<body>
  <style>
    div {
      width: 100px;
      height: 300px;
      max-width: 50px;
      max-height: 150px;
      background-color: red;
    }
  </style>
  <div>50x150</div>
</body>

盒子空间的计算

盒子空间的计算方式有两种:box-sizing:border-boxbox-sizing:content-box

box-sizing:border-box 时,widthheight表示边框以内(包括边框)的尺寸

盒子的宽度空间 = width + margin-left + margin-right
盒子的高度空间 = height + margin-top + margin-bottom

box-sizing:content-box时,widthheight表示内容的尺寸

盒子的宽度空间 = width + margin-left + margin-right + border-left-width + border-right-width + padding-left + padding-right
盒子的高度空间 = height + margin-top + margin-bottom + border-top-width + border-bottom-width + padding-top + padding-bottom

溢出

当盒子内容超出盒子范围时,需要对盒子进行溢出处理

overflow说明
visible默认值。内容不会被修剪,会呈现在元素框之外
hidden内容会被修剪,并且其余内容不可见
scroll内容会被修剪,浏览器会显示滚动条以便查看其余内容
auto由浏览器定夺,如果内容被修剪,就会显示滚动条
inherit继承父级
<body>
  <style>
    div {
      width: 300px;
      height: 300px;
      line-height: 5em;
      overflow: auto;
    }
  </style>
  <div>
    Hello HTML<br />Hello HTML<br />
    Hello HTML<br />Hello HTML<br />
    Hello HTML<br />Hello HTML<br />
  </div>
</body>

边框

可以作用与所有盒子

缩写形式

同时设置四条边

border: 宽度 样式 颜色
border-style说明
dotted圆点
dashed虚线
solid实线
double双实线
groove有雕刻效果的边框
ridge有浮雕效果的边框
inset有陷入效果的边框
outset有突出效果的边框
<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      border: 2px solid red;
    }
  </style>
  <div></div>
</body>

拆分形式

同时设置四条边

<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      border-width: 2px;
      border-style: solid;
      border-color: red;
    }
  </style>
  <div></div>
</body>

设置上下边框和左右边框

border-width: 1px 2px;
border-sytle: solid dotted;
border-color: #f00 #00f;

设置上边框、左右边框和下边框

border-width: 1px 2px 3px;
border-sytle: solid dotted dashed;
border-color: #f00 #00f #0ff;

设置上边框、右边框、下边框和左边框

border-width: 1px 2px 3px 4px;
border-sytle: solid dotted dashed double;
border-color: #f00 #00f #0ff #000;

设置上边框

缩写形式

border-top: 2px solid red;

拆分形式

border-top-width: 1px;
border-top-style: solid;
border-top-color: red;

设置右边框

缩写形式

border-right: 2px solid red;

拆分形式

border-right-width: 1px;
border-right-style: solid;
border-right-color: red;

设置下边框

缩写形式

border-bottom: 2px solid red;

拆分形式

border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: red;

设置左边框

缩写形式

border-left: 2px solid red;

拆分形式

border-left-width: 1px;
border-left-style: solid;
border-left-color: red;

轮廓

默认情况下,轮廓包裹在边框外围

轮廓不能单独设置某条边

轮廓无法进行圆角设置

轮廓不占用盒子空间,边框占用盒子空间,在左布局时,可以使用轮廓进行大框的查看与调试

<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      outline: 2px solid red;
    }
  </style>
  <div></div>
</body>

轮廓偏移

正值表示向外偏移,负值表示向内偏移

<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      outline: 2px solid red;
      outline-offset: 10px;
    }
  </style>
  <div></div>
</body>

圆角

设置四个角

<body>
    <style>
        div {
           width:100px;
           height: 100px;
           border: 2px solid blue;
           border-radius: 10px;
        }
    </style>
    <div></div>
</body>

设置左上右下、 右上左下圆角

border-radius:10px 20px;

设置左上、右上左下、右下圆角

border-radius:10px 20px 30px;

设置左上、右上、右下、左下圆角

border-radius:10px 20px 30px 40px;

设置左上角

border-top-left-radius: 10px;

设置右上角

border-top-right-radius: 10px;

设置左下角

border-bottom-left-radius: 10px;

设置右下角

border-bottom-right-radius: 10px;

阴影

box-shadow: X轴偏移量 Y轴偏移量 阴影模糊半径 模糊扩散半径 阴影颜色 阴影位置;
<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      border: 2px solid blue;
      box-shadow: 1px 1px 2px 1px #f00;
    }
  </style>
  <div></div>
</body>

内阴影

<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      border: 2px solid blue;
      box-shadow: 1px 1px 2px 1px #f00 inset;
    }
  </style>
  <div></div>
</body>

多阴影

<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      border: 2px solid blue;
      box-shadow: 1px 1px 2px 1px #f00 inset, 10px 10px 5px 5px #0005;
    }
  </style>
  <div></div>
</body>

背景

缩写形式

background:背景颜色 图像 平铺方式 定位;
background-repeat说明
repeat沿 X 轴和 Y 轴平铺,图像大小不变,超出部分会被裁剪掉
round沿 X 轴和 Y 轴平铺,图像大小会调整到正好填充的大小
no-repeat不平铺
repeat-x沿 X 轴平铺,图像大小不变,超出部分会被裁剪掉
repeat-y沿 Y 轴平铺,图像大小不变,超出部分会被裁剪掉
background-position说明
center水平方向和垂直方向都居中对齐
top水平方向居中对齐,垂直方向顶部对齐
bottom水平方向居中对齐,垂直方向底部对齐
left水平方向左侧对齐,垂直方向居中对齐
right水平方向右侧对齐,垂直方向居中对齐
left top水平方向左侧对齐,垂直方向顶部对齐
50px水平向左侧偏移 50px,垂直方向居中
-50px水平向右侧偏移 50px,垂直方向居中
10px 10px水平方向偏移 10px,垂直方向偏移 10px
<body>
  <style>
    div {
      width: 300px;
      height: 300px;
      background: red url(https://www.yaconit.com/public/images/logo.png)
        no-repeat left top;
    }
  </style>
  <div></div>
</body>

拆分形式

<body>
  <style>
    div {
      width: 300px;
      height: 300px;
      background-color: red;
      background-image: url(https://www.yaconit.com/public/images/logo.png);
      background-repeat: no-repeat;
      background-position: left top;
    }
  </style>
  <div></div>
</body>

单独设置 x 轴定位

background-position-x: left;

单独设置 y 轴定位

background-position-y: top;

背景图像固定方式

需要配合 overflow:scrolloverflow:auto使用

background-attachment说明
fixed背景固定,不会随着元素内容滚动而滚动
local背景不固定,会随着元素内容滚动而滚动
<body>
  <style>
    div {
      width: 300px;
      height: 300px;
      line-height: 5em;
      overflow: scroll;
      background: red url(https://www.yaconit.com/public/images/logo.png)
        no-repeat left top;
      background-attachment: local;
    }
  </style>
  <div>
    Hello HTML<br />Hello HTML<br />
    Hello HTML<br />Hello HTML<br />
    Hello HTML<br />Hello HTML<br />
  </div>
</body>

背景图像裁剪方式

background-clip说明
border-box背景延伸至边框外沿
padding-box背景延伸至内边距外沿
content-box背景被裁剪至内容区外沿
<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      border: 5px solid rgba(0, 0, 255, 0.2);
      padding: 10px;
      background: transparent url(https://www.yaconit.com/public/images/logo.png)
        no-repeat left top;
      background-clip: content-box;
    }
  </style>
  <div></div>
</body>

背景图像定位区域

background-origin说明
border-box背景图像圆点为 border 的原点
padding-box背景图像圆点为 padding 的原点
content-box背景图像圆点为 content 的原点
<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      border: 5px solid rgba(0, 0, 255, 0.2);
      padding: 10px;
      background: transparent url(https://www.yaconit.com/public/images/logo.png)
        no-repeat left top;
      background-origin: content-box;
    }
  </style>
  <div></div>
</body>

背景图像尺寸

background-size说明
100px宽为 100px,高等比缩放
100px 100px宽为 100px,高为 100px
auto背景图片原有尺寸
cover缩放背景图片以完全覆盖背景区,超出部分裁剪,保证宽或高完全显示
contain缩放背景图片以完全装入背景区,背景区可能会有空白
<body>
  <style>
    div {
      width: 100px;
      height: 100px;
      border: 5px solid rgba(0, 0, 255, 0.2);
      padding: 10px;
      background: transparent url(https://www.yaconit.com/public/images/logo.png)
        no-repeat left top;
      background-size: contain;
    }
  </style>
  <div></div>
</body>

渐变背景

线性渐变

<body>
  <style>
    div {
      height: 100px;
      background: linear-gradient(blue, red);
    }
  </style>
  <div></div>
</body>

调整线性渐变的方向

方向说明
to bottom默认值,从上至下渐变
to top从下至上渐变
to left从右至左渐变
to right从左至右渐变
to left top从右下角至左上角渐变
to left bottom从左下角至右上角渐变
<body>
  <style>
    div {
      height: 100px;
      background: linear-gradient(to right, blue, red);
    }
  </style>
  <div></div>
</body>

径向渐变

<body>
  <style>
    div {
      height: 100px;
      background: radial-gradient(blue, red);
    }
  </style>
  <div></div>
</body>

列表

缩写形式

不一定全部属性都设置,可以只设置列表风格,也可以只设置标记图像或者设置其中的两个

list-style:列表风格 标记图像 标记定位;
list-style-type说明
disc实心圆点 (默认值)
circle空心圆点
square实心方块
decimal十进制阿拉伯数字,从 1 开始
decimal-leading-zero十进制阿拉伯数字,从 01 开始
lower-roman小写罗马数字,从 i 开始
upper-roman大写罗马数字,从 I 开始
lower-greek小写古希腊文,从 α 开始
lower-latin小写英文字母,从 a 开始
upper-latin大写英文字母,从 A 开始
list-style-position说明
outside标记盒在主块盒的外面
inside标记盒是主要块盒中的第一个行内盒,处于元素的内容流之后
<body>
  <style>
    ul {
      list-style: square url(https://www.yaconit.com/public/images/logo.png)
        inside;
    }
  </style>
  <ul>
    <li>list-item</li>
    <li>list-item</li>
    <li>list-item</li>
    <li>list-item</li>
  </ul>
</body>

清空列表所有样式

list-style: none;

单独设置

列表风格

list-style-type: square;

标记位置

list-style-position: inside;

标记图像

list-style-image: url(https://www.yaconit.com/public/images/logo.png);

表格

设置表格外边框样式

border样式可以作用在 tabletd上,但对tr无效

<body>
  <style>
    table {
      border: 1px solid red;
    }
  </style>
  <table>
    <tr>
      <td>cell</td>
      <td>cell</td>
      <td>cell</td>
    </tr>
    <tr>
      <td>cell</td>
      <td>cell</td>
      <td>cell</td>
    </tr>
  </table>
</body>

表格边框合并方式

border-collapse说明
separate不合并,默认值
collapse合并
<body>
  <style>
    table {
      border-collapse: collapse;
    }

    td {
      border: 1px solid red;
    }
  </style>
  <table>
    <tr>
      <td>cell</td>
      <td>cell</td>
      <td>cell</td>
    </tr>
    <tr>
      <td>cell</td>
      <td>cell</td>
      <td>cell</td>
    </tr>
  </table>
</body>

相邻单元格边框之间的距离

当设置了border-collapse: collapse;时无效

<body>
  <style>
    table {
      border-spacing: 10px;
    }

    td {
      border: 1px solid red;
    }
  </style>
  <table>
    <tr>
      <td>cell</td>
      <td>cell</td>
      <td>cell</td>
    </tr>
    <tr>
      <td>cell</td>
      <td>cell</td>
      <td>cell</td>
    </tr>
  </table>
</body>

单独设置水平和垂直间距

border-spacing:水平间距 垂直间距;
border-spacing: 10px 20px;

规定表格标题的位置

只有设置了表格标题时才有效果

caption-side说明
top标题会出现在表格的上方
bottom标题会出现在表格的下方
<body>
  <style>
    table {
      caption-side: top;
    }

    td {
      border: 1px solid red;
    }
  </style>
  <table>
    <caption>
      Caption
    </caption>
    <tr>
      <td>cell</td>
      <td>cell</td>
      <td>cell</td>
    </tr>
    <tr>
      <td>cell</td>
      <td>cell</td>
      <td>cell</td>
    </tr>
  </table>
</body>

是否显示空单元格的边框和背景样式

empty-cells说明
show边框和背景正常渲染。与普通元素一样
hide边框和背景被隐藏
<body>
  <style>
    table {
      empty-cells: hide;
    }

    td {
      border: 1px solid red;
    }
  </style>
  <table>
    <caption>
      Caption
    </caption>
    <tr>
      <td>cell</td>
      <td></td>
      <td>cell</td>
    </tr>
    <tr>
      <td>cell</td>
      <td>cell</td>
      <td>cell</td>
    </tr>
  </table>
</body>

表格的布局算法

table-layout说明
auto自动布局,表格及单元格的宽度取决于包含内容的宽度
fixed固定布局,表格和列的宽度通过表格的宽度来设置,某一列的宽度由首列的宽度决定
<body>
  <style>
    table {
      width: 300px;
      table-layout: fixed;
    }
    td {
      border: 1px solid red;
    }
  </style>
  <table>
    <tr>
      <td>橘子</td>
      <td>香蕉</td>
      <td>火龙果</td>
    </tr>
    <tr>
      <td>天山雪莲</td>
      <td>柚子</td>
      <td>梨</td>
    </tr>
  </table>
</body>

浮动

可以将元素放入浮动流,进入浮动流的元素均水平排列

如果子元素全都在浮动流,那么父级元素所在标准文档流中就没有子元素,所以就会出现塌陷,即高度为 0

float说明
left左浮动
right右浮动
none不浮动
<body>
    <style>
        ul{
            background-color: red;
        }
        li {
            float: left;
            margin: 0 10px
        }
    </style>
    <ul>
        <li>list-item-1</li>
        <li>list-item-2</li>
        <li>list-item-3</li>
    </ul>
</body>

清除浮动

clear说明
left左侧不允许有浮动元素
right右侧不允许有浮动元素
both两侧都不能有浮动元素
<body>
  <style>
    ul {
      background-color: red;
    }
    li {
      float: left;
      margin: 0 10px;
    }
    .clear {
      float: none;
      clear: both;
    }
  </style>
  <ul>
    <li>list-item-1</li>
    <li>list-item-2</li>
    <li>list-item-3</li>
    <li class="clear"></li>
  </ul>
</body>

定位

可以是元素进入定位流,凡是进入定位流的元素,都可以通过 leftrighttopbottom来进行位置的调控

凡是在定位流的元素,都要先去弄清它的原点位置

定位类型

position说明
relative相对定位,原点位置为自身原点位置(只有top和left生效)
absolute(父级也要加)绝对定位,原点位置为最近一个在定位流的父级元素的原点位置,如果没有在定位流的父级元素,则为浏览器可视化窗口的原点位置(盒子的位置以包含它的盒子为基准进行偏移。绝对定位的盒子从标准文档流中脱离,对其后的其他盒子定位没有影响,其他盒子当他不存在)
fixed(悬浮广告)固定定位,原点位置为浏览器可视化窗口的原点位置
sticky(始终置顶的导航栏)粘性定位,原点位置默认为自身原点位置,当页面向上滚动时,会黏贴在页面顶部,具顶部的位置由top决定(不满足top条件时保持文档位置,满足时跟随页面移动)
static没有定位
<body>
  <style>
    body {
      margin: 10px;
    }

    ul {
      background-color: red;
      position: sticky;
      top: 0;
    }
  </style>
  <table height="500"></table>
  <ul>
    <li>list-item-1</li>
    <li>list-item-2</li>
    <li>list-item-3</li>
  </ul>
  <table height="500"></table>
</body>

定位偏移量设置

相对于原点位置的偏移

inset:10%;	
//一次性设置上下左右的偏移量

元素顶部距离上方的偏移量

top: 10px;

元素的底部距离下方的偏移量

bottom: 10px;

元素右侧距离右方的偏移量

right: 10px;

元素左侧距离左方的偏移量

left: 10px;

堆叠顺序

只有在定位流,元素才可以堆叠在一起

当索引值一致时,后面的元素会覆盖前面的元素

索引值越大,元素就越靠前

<body>
  <style>
    li {
      height: 100px;
      width: 100px;
      list-style: none;
      position: absolute;
    }

    li:nth-of-type(1) {
      background-color: rgba(255, 0, 0, 0.7);
      top: 10px;
      left: 10px;
    }

    li:nth-of-type(2) {
      background-color: rgba(0, 255, 0, 0.7);
      top: 20px;
      left: 20px;
      z-index: 1;
    }

    li:nth-of-type(3) {
      background-color: rgba(0, 0, 255, 0.7);
      top: 30px;
      left: 30px;
    }
  </style>
  <ul>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</body>

伸缩容器

伸缩容器也称为弹性盒子,他是一种一维的布局方式,根据主轴和辅助轴的方向,对弹性项进行排列布局

在伸缩容器中的直接子元素被称为弹性项

简写flex:flex-shrink flex-grow flex-basis;

flex: 0 0 1000px; 
这行代码是用来设置弹性布局的,其中flex表示该元素的弹性属性,0 0 1000px分别表示该元素在弹性布局中的三个属性:不会缩小、不会放大、初始宽度为1000像素。

创建伸缩容器

默认的主轴方向为水平方向

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: flex;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
    <div>four</div>
  </div>
</body>

调整主轴方向

flex-direction说明
row(默认)主轴为水平轴,方向为从左至右
row-reverse主轴为水平轴,方向为从右至左
column主轴为垂直轴,方向为从上至下
column-reverse主轴为垂直轴,方向为从下至上
<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: flex;
      flex-direction: column;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
    <div>four</div>
  </div>
</body>

弹性项在主轴的排列

justify-content说明示意图
flex-start从主轴的开始位置排列[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o24Tv5Tx-1691948413420)(E:/视频图像/image-20230313142514256.png)]
flex-end从主轴的结束位置排列[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2xj9CIVE-1691948413420)(E:/视频图像/image-20230313142530833.png)]
center从主轴的中间位置向两边排列[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dAD73NYF-1691948413420)(E:/视频图像/image-20230313142449495.png)]
space-between在主轴方向上两端对齐[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7boQrwsM-1691948413421)(E:/视频图像/image-20230313142556314.png)]
space-around在主轴方向上环绕对齐,第一个元素与最后一个元素距主轴的开始位置和结束位置的距离为子元素间距的一半[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tlvpjzvs-1691948413421)(E:/视频图像/image-20230313142622043.png)]
space-evenly在主轴方向上等距对齐,第一个元素与最后一个元素距主轴的开始位置和结束位置的距离等于子元素间距[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X8xDjO8d-1691948413421)(E:/视频图像/image-20230313142651286.png)]
<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: flex;
      justify-content: space-around;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
    <div>four</div>
  </div>
</body>

弹性项在侧轴的排列

统一设置
设置在父级元素上,作用于所有子弹性项元素

align-items说明示意图
flex-start从侧轴的开始位置排列[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DlhYtjQe-1691948413421)(E:/视频图像/image-20230313145229501.png)]
flex-end从侧轴的结束位置排列[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D6J8mqNK-1691948413422)(E:/视频图像/image-20230313145216327.png)]
center从侧轴的中心位置向两端排列[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xZWfXz8e-1691948413422)(E:/视频图像/image-20230313145243477.png)]
stretch在侧轴方向上填充容器,默认值[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bugf3nLc-1691948413422)(E:/视频图像/image-20230313145305697.png)]
<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: flex;
      align-items: center;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
    <div>four</div>
  </div>
</body>

单独设置
设置在弹性项上,作用于弹性项自身

align-self的值和align-items一致

align-self说明示意图
flex-start从侧轴的开始位置排列[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lLrfNZKn-1691948413422)(E:/视频图像/image-20230313145229501.png)]
flex-end从侧轴的结束位置排列[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V045FndU-1691948413423)(E:/视频图像/image-20230313145216327.png)]
center从侧轴的中心位置向两端排列[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O31COHkm-1691948413423)(E:/视频图像/image-20230313145243477.png)]
stretch在侧轴方向上填充容器,默认值[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4NBEvn5E-1691948413423)(E:/视频图像/image-20230313145305697.png)]
<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: flex;
    }
    .box1 {
      align-self: center;
    }
  </style>
  <div class="wrapper">
    <div class="box1">one</div>
    <div>two</div>
    <div>three</div>
    <div>four</div>
  </div>
</body>

弹性项的溢出处理

flex-wrap说明
nowrap不换行,可能会溢出容器
wrap自动向下换行
wrap-reverse自动向上换行
<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: flex;
      flex-wrap: wrap;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
    <div>four</div>
    <div>five</div>
    <div>six</div>
    <div>eight</div>
    <div>nine</div>
    <div>ten</div>
  </div>
</body>

弹性项的间距

gap(盒子与盒子之间的间距)说明
50px行、列间距均为 50px
50px 10px行间距 50px,列间距 10px
<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: flex;
      flex-wrap: wrap;
      gap: 50px 10px;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
    <div>four</div>
    <div>five</div>
    <div>six</div>
    <div>eight</div>
    <div>nine</div>
    <div>ten</div>
  </div>
</body>

弹性项伸缩

当所有弹性项的增长系数一致时,就会平分容器的空间

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: flex;
    }
    .box1 {
      flex: 1;
    }
    .box2 {
      flex: 1;
    }
    .box3 {
      flex: 1;
    }
    .box4 {
      flex: 1;
    }
  </style>
  <div class="wrapper">
    <div class="box1">one</div>
    <div class="box2">two</div>
    <div class="box3">three</div>
    <div class="box4">four</div>
  </div>
</body>

弹性项的扩张与收缩

弹性项尺寸——flex-basis
如果弹性容器的主轴为水平轴,此时flex-basis表示弹性项的宽
如果弹性容器的主轴为垂直轴,此时flex-basis表示弹性项的高
当所有弹性项尺寸加起来超过父级尺寸时,flex-basis不生效

扩张——flex-grow:数值;

简单理解:占所有弹性项 flex-grow的值之和的份数

数值=0
不扩张(默认值)
数值>0
扩展因子

收缩——flex-shrink:数值;

简单理解:0=不收缩,1=收缩

数值=0
不收缩
数值=1
收缩因子(默认值)

弹性项的初始尺寸

.box1 {
  flex-basis: 200px;
}

弹性项的排序

序号越小越靠近主轴开始位置,序号越大越靠近主轴结束位置

.box1 {
  order: 1;
}

网格容器

网格容器以二维的方式对网格进行排版布局

网格容器内的元素称为网格元素

每一个网格元素都是由轨道创建出来的,轨道可以规定网格元素的数量和尺寸

轨道分为行轨道和列轨道

创建网格容器

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: grid;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
    <div>four</div>
    <div>five</div>
  </div>
</body>

创建显式列轨道

grid-template-columns规定了列轨道的模板,每个值都表示了网格元素的宽度,设置了几个值,在列轨道上就有几个网格元素

1fr表示当前网格元素占 1 份宽度,总宽度由容器宽度决定,总份数为所有网格元素所占的份数和

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr 1fr;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
  </div>
</body>

网格元素的宽度可以使用像素值

grid-template-columns: 50px 80px 60px;

可以让某个网格的宽度自适应

grid-template-columns: 50px auto 60px;

平分网格容器可以使用 rpeat 函数

grid-template-columns: repeat(3, 1fr);

可以设置网格元素的最小和最大宽度

grid-template-columns: minmax(50px, auto) auto 60px;

创建显式行轨道

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: grid;
      grid-template-rows: 1fr 1fr 1fr 1fr;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
  </div>
</body>

隐式轨道的尺寸

设置隐式行轨道的高度

如果显式创建例轨道而没有显式创建行轨道,此时出现隐式的行轨道

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: grid;
      grid-template-columns: minmax(50px, auto) auto 60px;
      grid-auto-rows: 50px;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
  </div>
</body>

设置隐式列轨道的宽度

如果显示创建行轨道而没有显示创建列轨道,此时出现隐式的列轨道

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: grid;
      grid-template-rows: minmax(50px, auto) auto 60px;
      grid-auto-columns: 50px;
    }
  </style>
  <div class="wrapper">
    <div>one</div>
    <div>two</div>
    <div>three</div>
  </div>
</body>

网格元素跨轨道

黑色标注为行轨道线

白色标注为列轨道线

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0aoZMsEv-1691948413424)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/image-20200908235457707.png)]

跨越列轨道线

从第一条列轨道线跨越到第四条列轨道线

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
    }
    .box1 {
      grid-column: 1/4;
    }
  </style>
  <div class="wrapper">
    <div class="box1">one</div>
    <div class="box2">two</div>
    <div class="box3">three</div>
    <div class="box4">six</div>
    <div class="box5">five</div>
  </div>
</body>

从第一条行轨道线跨越到第三条行轨道线

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
    }
    .box1 {
      grid-row: 1/3;
    }
  </style>
  <div class="wrapper">
    <div class="box1">one</div>
    <div class="box2">two</div>
    <div class="box3">three</div>
    <div class="box4">six</div>
    <div class="box5">five</div>
  </div>
</body>

网格元素间距

gap说明
10px行、列间距均为 10px
10px 50px行间距为 10px,列间距为 50px
<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 10px 50px;
    }
  </style>
  <div class="wrapper">
    <div class="box1">one</div>
    <div class="box2">two</div>
    <div class="box3">three</div>
    <div class="box4">six</div>
    <div class="box5">five</div>
  </div>
</body>

网格布局

给子元素定类名,然后在父级布局

//给子元素定类名
.jiuye .neirong .q1{grid-area: q1;}
.jiuye .neirong .q2{grid-area: q2;}
.jiuye .neirong .q3{grid-area: q3;}
.jiuye .neirong .q4{grid-area: q4;}
.jiuye .neirong .q5{grid-area: q5;}
//父级布局
.jiuye .neirong {
  width: 1200px;
  height: 350px;
  gap: 12px;
  display: grid;
  //下面是每个元素的位置
  grid-template-areas:
   "q1 q2 q2 q3"
   "q1 q4 q5 q3";
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-or71mfsR-1691948413424)(E:/视频图像/image-20230320150252611.png)]

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {						//核心
      display: grid;
      grid-template-areas:
        "one one one"
        "two three four"
        "five six six";
    }
    .box1 {
      grid-area: one;
    }
    .box2 {
      grid-area: two;
    }
    .box3 {
      grid-area: three;
    }
    .box4 {
      grid-area: four;
    }
    .box5 {
      grid-area: five;
    }
    .box6 {
      grid-area: six;
    }
  </style>
  <div class="wrapper">
    <div class="box1">one</div>
    <div class="box2">two</div>
    <div class="box3">three</div>
    <div class="box4">four</div>
    <div class="box5">five</div>
    <div class="box6">six</div>
  </div>
</body>

可以使用.来流出空白区域

grid-template-areas:
  ". one ."
  "two three four"
  "five six six";

网络元素堆叠

z-index的相同时,后面的网格元素覆盖前面的网格元素

z-index的值越大,越靠上

<body>
  <style>
    .wrapper {
      width: 300px;
      height: 300px;
      background-color: #ddd;
    }
    .wrapper > div {
      text-align: center;
      padding: 5px;
    }
    .wrapper > div:nth-child(even) {
      background-color: #f0f;
    }
    .wrapper > div:nth-child(odd) {
      background-color: #0ff;
    }
    .wrapper {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
    }
    .box1 {
      grid-column: 1/4;
      grid-row: 1/3;
      z-index: 1;
    }
    .box2 {
      grid-column: 1/3;
      grid-row: 2/4;
    }
  </style>
  <div class="wrapper">
    <div class="box1">one</div>
    <div class="box2">two</div>
  </div>
</body>

变形

transform(只作用于块级)说明
rotate旋转
scale缩放
translate位移
skew斜切
rotate(45deg) skew(20deg)旋转 斜切
.b2{
        /* 控制动画几秒播放完 */
        transition: all 2s linear;
}
body:hover .b2{
        /* 斜切 */
        transform: skew(90deg,90deg);
        /* 放大/缩小(必须大于0,小于1是缩小) */
        transform:scale(0.5);
        /* 旋转 */
        transform: rotate(1080deg);
        /* 位移 */
        transform: translate(50px,60px);
}
body:hover .b3{
		/* 同时使用四种变形 */
        transform: skew(90deg,90deg) scale(0.1) 
        rotate(1080deg) translate(50px,60px);
      }

旋转

rotate说明
45deg顺时针旋转 45°
-45deg逆时针旋转 45°
<body>
  <style>
    body {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    div {
      width: 200px;
      height: 200px;
      position: absolute;
    }
    .box1 {
      background-color: #ccc;
    }
    .box2 {
      background-color: rgba(255, 0, 255, 0.5);
      transition: transform 1s;
    }
    .box2:hover {
      transform: rotate(45deg);
    }
  </style>

  <div class="box1"></div>
  <div class="box2 rotate"></div>
</body>

缩放

scale说明
0.5缩小 0.5 倍,原尺寸 x0.5
1不缩放
2放大 2 倍,原尺寸 x2
0.5 2x 轴缩小 0.5 倍 y 轴放大 2 倍
<body>
  <style>
    body {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    div {
      width: 200px;
      height: 200px;
      position: absolute;
    }
    .box1 {
      background-color: #ccc;
    }
    .box2 {
      background-color: rgba(255, 0, 255, 0.5);
      transition: transform 1s;
    }
    .box2:hover {
      transform: scale(2);
    }
  </style>

  <div class="box1"></div>
  <div class="box2 rotate"></div>
</body>

位移

translate说明
50px延 x 轴向右偏移 50px
-50px延 x 轴向左偏移 50px
50px,30px延 x 轴向右偏移 50px,延 y 轴向下偏移 30px
50px,-30px延 x 轴向右偏移 50px,延 y 轴向上偏移 30px
<body>
    <style>
        body{height: 100vh;display: flex;justify-content: center;align-items: center;}
        div{width: 200px;height: 200px;position: absolute;}
        .box1{background-color: #ccc;}
        .box2{background-color: rgba(255,0,255,0.5);transition: transform 1s;}
        .box2:hover{
            transform: translate(50px);
        }
    </style>

    <div class="box1"></div>
    <div class="box2 rotate"></div>
</body>

只调整 x 轴的偏移量

transform: translateX(50px);

只调整 y 轴的偏移量

transform: translateY(50px);

斜切

skew说明
10deg延 x 轴斜切 10°(可以理解为 x 轴逆向旋转了 10°)
10deg,20deg延 x 轴斜切 10°,延 y 轴斜切 20°,(可以理解为 x 轴逆向旋转了 10°,y 轴顺向旋转了 20°)
-10dge延 x 轴斜切-10°
<body>
  <style>
    body {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    div {
      width: 200px;
      height: 200px;
      position: absolute;
    }
    .box1 {
      background-color: #ccc;
    }
    .box2 {
      background-color: rgba(255, 0, 255, 0.5);
      transition: transform 1s;
    }
    .box2:hover {
      transform: skew(10deg, 20deg);
    }
  </style>

  <div class="box1"></div>
  <div class="box2"></div>
</body>

原点设置(变形的锚点)

transform-origin说明
center原点在元素中心,默认值
top left原点在元素左上角
bottom left原点在元素左下角
top right原点在元素右上角
bottom right原点在元素右下角
50px 50px原点在元素 50px,50px 的位置
<body>
  <style>
    body {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    div {
      width: 200px;
      height: 200px;
      position: absolute;
    }
    .box1 {
      background-color: #ccc;
    }
    .box2 {
      background-color: rgba(255, 0, 255, 0.5);
      transition: transform 1s;
      transform-origin: left top;
    }
    .box2:hover {
      transform: rotate(45deg);
    }
  </style>

  <div class="box1"></div>
  <div class="box2"></div>
</body>

动画

过度动画

元素从一种状态过渡到另一种状态

过度动画需要使用:hover:active 或者 JavaScript 进行触发

transition:属性名 过度时间;`
`transition:属性名 过度时间 延迟时间;`
`transition:属性名 过度时间 过度函数 延迟时间;`
`transition:属性名1 过度时间, 属性名2 过度时间;
过度函数图示说明
linear[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5MBQz0v4-1691948413424)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/cubic-bezier,linear.png)]恒速
ease[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yupqqe1M-1691948413424)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/cubic-bezier,ease.png)]开始和结束速度快,中间速度慢慢
ease-in[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3wf5UuMC-1691948413425)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/cubic-bezier,ease-in.png)]开始缓慢,逐渐加速
ease-in-out[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-diGuQLmO-1691948413425)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/cubic-bezier,ease-in-out.png)]开始逐渐加速,最后逐渐减速
ease-out[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k5cPAM3W-1691948413425)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/cubic-bezer,ease-out.png)]快速开始,缓慢结束
step-start[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-um85qCkM-1691948413425)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/stepsstart.png)]立即跳到结束位置
step-end[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2SDJMEzq-1691948413426)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/stepsend.png)]保持初始状态

进入和离开都会有动画效果

<body>
  <style>
    body {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    div {
      width: 200px;
      height: 200px;
      position: absolute;
    }
    .box1 {
      background-color: red;
      transition: background-color 3s;
    }
    .box1:hover {
      background-color: blue;
    }
  </style>

  <div class="box1"></div>
</body>

如果只有进入时产生动画效果,则将transition 放入最终状态

.box2:hover {
  transition: background-color 3s;
  background-color: blue;
}

所有样式的变化都进行动画——all

transition: all 3s;

自定义动画

定义:@keyframes 动画名{}

animation:动画名称 动画时间;
animation:动画名称 动画时间 过度函数 延迟时间;
animation:动画名称 动画时间 过度函数 延迟时间 播放次数 动画方向 填充模式;
播放次数说明
数值具体的次数,例如:1 为播放 1 次,0.5 为播放一半
infinite无限循环播放
动画方向说明
normal默认值,每次都从头开始播放动画
alternate第一次正向播放动画,第二次反向播放动画,以此类推
reverse每次都反向播放动画
alternate-reverse第一次反向播放动画,第二次正向播放动画,以此类推
填充模式说明
forwards应用最后一帧的样式
backwards应用第一帧的样式
both正向播放停留在最后一帧,反向播放停留在第一帧

所有的过渡动画都可以被自定义动画替代

<body>
    <style>
        body{height: 100vh;display: flex;justify-content: center;align-items: center;}
        div{width: 200px;height: 200px;position: absolute;}
        .box1{background-color: red;}
        .box1:hover{animation: changeColor 3s;}
        @keyframes changeColor{
            form {
                background-color: red;
            }
            to {
                background-color: blue;
            }
        }
    </style>

    <div class="box1"></div>
</body>

如果动画开始样式和元素的初始样式相同,则可以省略form元素

<body>
  <style>
    body {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    div {
      width: 200px;
      height: 200px;
      position: absolute;
    }
    .box1 {
      background-color: red;
    }
    .box1:hover {
      animation: changeColor 3s;
    }
    @keyframes changeColor {
      to {
        background-color: blue;
      }
    }
  </style>

  <div class="box1"></div>
</body>

我们也可以调控动画在过程中的状态变化

<body>
  <style>
    body {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    div {
      width: 200px;
      height: 200px;
      position: absolute;
    }
    .box1 {
      background-color: red;
    }
    .box1:hover {
      animation: changeColor 5s;
    }
    @keyframes changeColor {
      45% {
        background-color: green;
      }
      70% {
        background-color: yellow;
      }
      100% {
        background-color: blue;
      }
    }
  </style>

  <div class="box1"></div>
</body>

滤镜

滤镜一般作用于图像

高斯模糊

blur()

值越大,模糊度就越高,默认值为0px

<body>
  <style>
    img:last-child {
      filter: blur(5px);
    }
  </style>
  <div>
    <img src="/public/images/dp.png" alt="原图像" />
    <img src="/public/images/dp.png" alt="高斯模糊" />
  </div>
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dbNWA4MJ-1691948413426)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/image-20210115102029697.png)]

明度

brightness()

值等于0% 为全黑图像,值等于100% 图像无变化,值大于 100% 图像明度提高

<body>
  <style>
    img:nth-child(2) {
      filter: brightness(0%);
    }
    img:nth-child(3) {
      filter: brightness(50%);
    }
    img:nth-child(4) {
      filter: brightness(100%);
    }
    img:nth-child(5) {
      filter: brightness(200%);
    }
  </style>
  <div>
    <img src="/public/images/dp.png" alt="原图像" />
    <img src="/public/images/dp.png" alt="0%" />
    <img src="/public/images/dp.png" alt="50%" />
    <img src="/public/images/dp.png" alt="100%" />
    <img src="/public/images/dp.png" alt="200%" />
  </div>
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cadPOBEn-1691948413426)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/image-20210115102649927.png)]

对比度

contrast()

值等于 0% 为全灰图像,值等于 100% 图像无变化,值大于 100% 图像对比度提高

<body>
  <style>
    img:nth-child(2) {
      filter: contrast(0%);
    }
    img:nth-child(3) {
      filter: contrast(50%);
    }
    img:nth-child(4) {
      filter: contrast(100%);
    }
    img:nth-child(5) {
      filter: contrast(200%);
    }
  </style>
  <div>
    <img src="/public/images/dp.png" alt="原图像" />
    <img src="/public/images/dp.png" alt="0%" />
    <img src="/public/images/dp.png" alt="50%" />
    <img src="/public/images/dp.png" alt="100%" />
    <img src="/public/images/dp.png" alt="200%" />
  </div>
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L0TjAFaX-1691948413426)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/image-20210115103424213.png)]

灰度

grayscale()

值等于 0% 图像无变化,值等于 100% 图像完全转为灰度图像

<body>
  <style>
    img:nth-child(2) {
      filter: grayscale(0%);
    }
    img:nth-child(3) {
      filter: grayscale(50%);
    }
    img:nth-child(4) {
      filter: grayscale(100%);
    }
  </style>
  <div>
    <img src="/public/images/dp.png" alt="原图像" />
    <img src="/public/images/dp.png" alt="0%" />
    <img src="/public/images/dp.png" alt="50%" />
    <img src="/public/images/dp.png" alt="100%" />
  </div>
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d3jYwDXl-1691948413427)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/image-20210115104500995.png)]

色相旋转

hue-rotate()

值为色环角度值。值为 0deg 图像无变化,默认值为 0deg,值如果大于 360deg 相当于又绕了一圈

<body>
  <style>
    img:nth-child(2) {
      filter: hue-rotate(0deg);
    }
    img:nth-child(3) {
      filter: hue-rotate(90deg);
    }
    img:nth-child(4) {
      filter: hue-rotate(180deg);
    }
    img:nth-child(5) {
      filter: hue-rotate(360deg);
    }
  </style>
  <div>
    <img src="/public/images/dp.png" alt="原图像" />
    <img src="/public/images/dp.png" alt="0deg" />
    <img src="/public/images/dp.png" alt="90deg" />
    <img src="/public/images/dp.png" alt="180deg" />
    <img src="/public/images/dp.png" alt="360deg" />
  </div>
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zfqzyj27-1691948413427)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/image-20210115104843540.png)]

反色

invert()

值为 0% 图像无变化,值为 100% 图像颜色完全相反,值为 0%~100% 图像的效果为值得线性乘数

<body>
  <style>
    img:nth-child(2) {
      filter: invert(0%);
    }
    img:nth-child(3) {
      filter: invert(50%);
    }
    img:nth-child(4) {
      filter: invert(100%);
    }
  </style>
  <div>
    <img src="/public/images/dp.png" alt="原图像" />
    <img src="/public/images/dp.png" alt="0%" />
    <img src="/public/images/dp.png" alt="50%" />
    <img src="/public/images/dp.png" alt="100%" />
  </div>
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CI294jXt-1691948413427)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/image-20210115105324189.png)]

饱和度

saturate()

值为 0 图像完全不饱和,值为 100% 图像无变化,值大于 100% 图像饱和度更高

<body>
  <style>
    img:nth-child(2) {
      filter: saturate(0%);
    }
    img:nth-child(3) {
      filter: saturate(50%);
    }
    img:nth-child(4) {
      filter: saturate(100%);
    }
    img:nth-child(5) {
      filter: saturate(200%);
    }
  </style>
  <div>
    <img src="/public/images/dp.png" alt="原图像" />
    <img src="/public/images/dp.png" alt="0%" />
    <img src="/public/images/dp.png" alt="50%" />
    <img src="/public/images/dp.png" alt="100%" />
    <img src="/public/images/dp.png" alt="200%" />
  </div>
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lii6K8T3-1691948413427)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/image-20210115105618741.png)]

深褐色

sepia()

值为 0% 图像无变化,值为 100% 图像完全时深褐色,值为 0%~100% 图像的效果为值得线性乘数

<body>
  <style>
    img:nth-child(2) {
      filter: sepia(0%);
    }
    img:nth-child(3) {
      filter: sepia(50%);
    }
    img:nth-child(4) {
      filter: sepia(100%);
    }
  </style>
  <div>
    <img src="/public/images/dp.png" alt="原图像" />
    <img src="/public/images/dp.png" alt="0%" />
    <img src="/public/images/dp.png" alt="50%" />
    <img src="/public/images/dp.png" alt="100%" />
  </div>
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j4is26JV-1691948413428)(https://www.yaconit.com/md/yaconit/web-front-end/css/resources/image-20210115110023354.png)]

媒体查询

媒体类型

媒体类型说明
all适用于所有设备。
print适用于在打印预览模式下在屏幕上查看的分页材料和文档。
screen主要用于屏幕。
speech主要用于语音合成器。

媒体特性

媒体特性说明示例
aspect-ratio视窗(viewport)的宽高比@media (aspect-ratio: 8/5) {}
min-aspect-ratio视窗(viewport)的最小宽高比@media (min-aspect-ratio: 3/2) {}
max-aspect-ratio视窗(viewport)的最大宽高比@media (max-aspect-ratio: 1/1) {}
height视窗(viewport)的高度@media (height: 360px) {}
min-height视窗(viewport)的最小高度@media (min-height: 25rem) {}
max-height视窗(viewport)的最大高度@media (max-height: 40rem) {}
orientation视窗(viewport)的旋转方向@media (orientation: landscape) {} @media (orientation: portrait) {}
width视窗(viewport)的宽度,包括纵向滚动条的宽度@media (width: 360px) {}
min-width视窗(viewport)的最小宽度,包括纵向滚动条的宽度@media (min-width: 35rem) {}
max-width视窗(viewport)的最大宽度,包括纵向滚动条的宽度@media (max-width: 50rem) {}
orientation说明
landscapeviewport 处于纵向,即高度大于等于宽度。
portraitviewport 处于横向,即宽度大于高度。

逻辑操作符

逻辑操作符说明示例
and用于将多个媒体查询规则组合成单条媒体查询,当每个查询规则都为真时则该条媒体查询为真,它还用于将媒体功能与媒体类型结合在一起。@media screen and print{}
not用于否定媒体查询,如果不满足这个条件则返回 true,否则返回 false。如果出现在以逗号分隔的查询列表中,它将仅否定应用了该查询的特定查询。如果使用 not 运算符,则还必须指定媒体类型。@media not screen{}
only仅在整个查询匹配时才用于应用样式,并且对于防止较早的浏览器应用所选样式很有用。@media only screen{}
,逗号用于将多个媒体查询合并为一个规则。@media screen, print {}

less与scss

Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展

Less 和 CSS 非常像,因此很容易学习。而且 Less 仅对 CSS 语言增加了少许方便的扩展

Less文件需要经过Less预处理器编译成为CSS

Sass和Less都属于CSS预处理器,其基本思想是,用一种专门的编程语言,进行 Web 页面样式设计,再通过编译器转化为正常的 CSS 文件,以供项目使用”。

不同之处:

  1. 编译环境不一样 Less是基于JavaScript,是在客户端处理的。Sass是基于Ruby的,是在服务器端处理的。

  2. 变量符不一样,Less是@,而Scss是$。

  3. 输出设置,Less没有输出设置,Sass提供4中输出选项:nested, compact, compressed 和 expanded。

  4. Sass支持条件语句,可以使用if{}else{},for{}循环等等。而Less不支持。

  5. 引用外部CSS文件 css@import引用的外部文件如果不想编译时多生成同名的.css文件,命名必须以_开头, 文件名如果以下划线_开头的话,Sass会认为该文件是一个引用文件,不会将其编译为同名css文件.

  6. Sass和Less的工具库不同 Sass有工具库Compass, Less有UI组件库Bootstrap.

JavaScript概述

JavaScript是运行在浏览器中的一种脚本语言,它主要用于与HTML页面进行交互

JavaScript的组成部分

名称说明
ECMAScript(ES6)JavaScript的标准,定义了JavaScript的核心内容
BOMBrowser Objcet Model,浏览器对象模型,用于操纵浏览器对象
DOMDocument Object Model,文档对象模型,用于操纵HTML文档对象

引入JavaScript

嵌入式

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body>
        <input type="button" value="提交" onclick="alert(this.value)"/>
    </body>
</html>

内部引入

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body>
        <!-- HTML代码块 -->

        <script>
            // JavaScript代码块
        </script>
    </body>
</html>    

外部文件引入

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="utf-8"/>
        <script src="js文件路径"></script>
    </head>
    <body>
        <!-- HTML代码块 -->

        <script src="js文件路径"></script>
    </body>
</html>    

增删改查

//ball作为资源
资源:           /api/ball
    新增资源            POST    /api/ball {参数}
    删除资源            DELETE  /api/ball/资源唯一标识
    修改资源            PUT     /api/ball/资源唯一标识{参数}
    读取资源
        读取单一资源    GET    /api/ball/资源唯一标识
        读取资源列表    GET    /api/ball


请求方法(不是全部,常用的):
    GET         ==> 浏览器访问
    POST        ==> 表单提交一般用POST请求
    PUT
    DELETE

只要需要提供大量数据的操作,都可以使用POST请求
一般情况下,后端怎么设计的接口,我们前端就怎么进行调用

例:

轮播图

//轮播图
var index = 2;
function change() {
    // <img src="/public/image/lunbo1.jpg"></img>
    var path = "/public/image/lunbo" + index + ".jpg";
    $(".lunbotu").html("<img src=" + path + "></img>");
    index++;
    if (index >= 6) {
        index = 1;
    }
}
//启动定时器
var time;
function startTime() {
    //setInterval:一个实现定时调用的函数
    time = setInterval("change()", 3000);
}
//停止定时
function stopTime() {
    //clearInterval:解除定时器
    clearInterval(time);
}
//页面加载完毕
$(function () {
    var path = "/public/image/lunbo1.jpg";
    $(".lunbotu").html("<img src=" + path + "></img>");
    startTime();
})
//鼠标悬停时停止
$(".lunbotu").mousemove(function () {
    stopTime();
}).mouseout(function () {
    startTime();
})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JrHd3JVZ-1691948413428)(E:/视频图像/image-20230411170127138.png)]

轮播图加圆和文字

//轮播图
var index = 2;
function lunbotu() {
    //图
    var path = "/public/image/lunbo" + index + ".jpg";
    $(".zixun-left-img").html(`<img src= ${path} class="animate__animated animate__pulse"></img>`);
    //字
    if (index == 1) {
        path2 = "宝马M2雷霆版——毫不犹豫的"
    } else if (index == 2) {
        path2 = "高性价比中型车——捷克姆拉达"
    } else if (index == 3) {
        path2 = "多少钱能让Jeep情怀落地?"
    } else if (index == 4) { path2 = "BMW五系不再遥不可及" }
    $(".zixun-wenzi").html(`<a href="">${path2}</a>`);
    //圆变色
    path3 = `.zixun-xuanze${index}`;
    $(path3).css("background-color", "#fff");
    if (index - 1 > 0) {
        path3 = `.zixun-xuanze${index - 1}`;
        $(path3).css("background-color", "#696B6B");
    } else { $(".zixun-xuanze4").css("background-color", "#696B6B"); }
    index++;
    if (index >= 5) {
        index = 1;
    }
}

线程

  1. 在js中,只有单线程,没有多线程
  2. 当js中有一段代码出现错误或者执行时间很长时,会导致整个页面的渲染停滞
//主线程
console.log("主线程A");
        //代理兼容
        if (window.Worker) {
            //创建了一个子线程
            let workA = new Worker("/js/modules/a.js");
            //主线程监听子线程是否发送消息过来
            workA.onmessage=(e)=>{
                console.log(e.data);
            }
        }
//
//	a.js
//子线程向主线程发送消息
postMessage("A子线程已完成")

ECMAScript(ES6)

ECMAScript(ES6)——JavaScript的标准

控制台输出

单引号和双引号表示一个字符串 数据类型

​ 普通消息输出——目测与日志无区别

console.info("消息信息");
输出日志

日志输出是后期调试JS代码的主要方式

console.log("日志信息")
console.log("日志","信息")
输出错误信息
console.error("错误信息")
console.error("错误","信息")
计算代码块执行时间

括号内的参数名必须一致(包括大小写),

开始计时`和`结束计时`中的标签也保持一致,`开始计时`不会输出任何数据,`结束计时`时会输出运行时间`tag: 2.11ms
console.time('tag'); // 开始计时

// ... 要检测的代码块

console.timeEnd('tag'); // 结束计时

页面输出

在网页上输出

document.write()

以标签形式在页面输出

//在.div中添加一个p标签,内容为 path2 的值
$(".div").html(`<p>${path2}</p>`)

注释

单行注释
// 注释内容
多行注释
/*
 注释内容
*/

CSS注释 /* 123 */

HTML注释 <!-- 123 -->

JS注释 // 123

变量

临时替换变量名:age:a,后续调用a,age将无法使用

变量的命名规范

  • 有意义
  • 不能是关键词(保留词)
  • 变量名是由英文字母数字下划线和**$**组成
  • 变量名不能由数字开头
  • 变量名如果是由多个单词组成,可以用_来分割单词,或者用小驼峰命名法(第一个单词首字母不大写,例:myName)来分割
  • 变量名的首字母要小写

代码块(变量的作用域 ==> 变量可使用的范围)

varlet声明后会有一个初始值,值为——undefined,意思是未定义

声明变量——var

var声明的变量可以在全局使用

var可以先使用,后声明。但是没有值,只是不会报错

var可以被重复声明,后声明的覆盖前面的变量值

var 变量名;
var uname
var 变量1,变量2,...
var uname,sex
var 变量名 = 初始值
var uname = '张三'
声明区块变量——let

let区块变量只在离它最近的代码块有效

let必须先声明,初始化后才能使用

let不能重复被声明

let 变量名
let uname = '张三'
声明常量——const

常量声明时必须有初始值,不能二次修改

常量名一般全大写,如果由多个单词组成,用**_**分割

const 常量名 = 常量值
const PI = 3.14
调用变量
var`和`let`声明的变量,均有初始值`undefined
let uname
console.log(uname) // undefined
let uname = '张三'
console.log(uname) // 张三

当使用一个没有声明的变量时,会报错

console.log(sex) // 报错

var声明的变量,可以先使用后声明

console.log(sex) // undefined
var sex = 20

let声明的变量,必须先声明后使用

console.log(sex) // 报错
let sex = 20

在代码块中,使用var声明的变量可以在代码块的外部使用

{
    var sex = 20
}
{
    console.log(sex) // 20
}

在代码块中,使用let声明的变量只能在声明变量的代码块中使用

{
    let sex = 20
}
{
    console.log(sex) // 报错
}

使用const声明的常量不能被二次赋值

const PI = 3.14
PI = 3.1415 // 报错

数据类型

基本数据类型

字符串——string

任何类型的值与字符串相加,结果一定是字符串

'" 或 ` 包裹的字符,均为字符串

console.log(typeof('张三')) // string
console.log(typeof("张三")) // string
console.log(typeof(`张三`)) // string

`` : 模板字符串,支持换行,可以使用${变量名}

字符串的使用

//单引号和双引号使用方法一致
let abc1=
"大家好,我叫"+name+",我是"+sex+",我今年"+age+"岁了。"
// ` 包裹的字符串可以让字符串换行,显示时也有换行的效果
//使用${}调用变量
let abc2=`大家好,我叫${name},我是${sex},
		我今年${age}岁了。`

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YetzAND4-1691948413428)(E:/视频图像/image-20230328143405659.png)]

数值——number

数字不需要用引号括起来,如果括起来,就变成了字符串

NaN ==> not a number(不是一个数值)

Infinity ==> 无限大

console.log(typeof( ))——用来检查括号内的值是什么数据类型

  • 任何数值类型与数值类型进行算数运算,结果一定是数值类型
  • 任何数值类型与NaN进行算术运算,得到的结果一定是NaN
  • 任何数值类型与无限大进行算术运算,得到的结果一定是无限大。除了与0进行运算时,得到的是NaN
var age=12;
Infinity` 当被除数为 `0`是,则会出现 `Infinity
console.log(typeof(20)) // number
console.log(typeof(3.14)) // number
console.log(typeof(Infinity)) // number
布尔——boolean

布尔的本质是数值类型(整数)

true 的值为 1,也代表

false 的值为 0,也代表

console.log(typeof(true)) // boolean
console.log(typeof(false)) // boolean
var age=12;			var a = 123;
var b=age>a;		console.log(b);
//得到 b 的值为 false
未定义的类型——undefined

变量声明后没有被初始化,此时的变量值为 undefined

console.log(typeof(undefined)) // undefined
对象类型——object

1.{ } 2.null——空对象 3.[ ]——数组

对象类型赋值,为地址传值,相互之间受影响。解决方法是展开对象

只有给对象赋值为 null 时,对象才为 null

null表示 没有指向任何对象的对象 ,空对象

console.log(typeof (null)) // object
var v = []
console.log(typeof (v)) // object
var v = new Object()
console.log(typeof (v)) // object
var v = {}
console.log(typeof (v)) // object
let student = {
      name : "张三",
      age : 20,
      sex : "男性",
    }
console.log(student);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lyvpRLgs-1691948413429)(E:/视频图像/image-20230328153444777.png)]

console.log(student.name);
console.log(student.age);
console.log(student.sex);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P051D24a-1691948413429)(E:/视频图像/image-20230328154825506.png)]

函数——function
function f (){}
console.log(typeof (f)) // function
var f = function(){}
console.log(typeof (f)) // function

数据类型转换

  • 隐式数据类型转换:非用户主动进行转换的过程(自动类型转换)
  • 显式数据类型转换:用户主动进行转换的过程(强制类型转换)

隐式转换

与字符串相加时,数字会被转成字符串

字符串与数值类型进行> <比较时,字符串自动转为数值类型

布尔类型与数值类型进行运算时,布尔类型自动转为数值类型

一般情况下,变量的类型会根据值的变化而变化

var x = 10
console.log(typeof(x)) // number

x = '张三'
console.log(typeof(x)) // string

当字符串与数字进行运算时,数字会被转成字符串

var x = 10
var y = '张三的年龄:' + x
console.log(y) // 张三的年龄:10
字符串转为数字

将任何类型的值转为数值类型(如果是数字加字符的字符串,只提取最前面的数字,遇到非数字就停止截取)

let abc="123";
abc=Number(abc);
//将字符串转变为数值(整数)类型
abc=parseInt(abc);
//将字符串转变为数值(浮点数)类型
abc=parseFloat(abc);

将字符串转为整数——parseInt

var x = '3.14'
console.log(parseInt(x)+1) // 4
var x = '3.14是圆周率'
console.log(parseInt(x)+1) // 4
var x = '圆周率是3.14'
console.log(parseInt(x)+1) // NaN
var x = '3'
console.log((+x)+1) // 4

将字符串转为浮点数——parseFloat

var x = '3'
console.log(parseFloat(x)+1) // 4
var x = '3.14'
console.log(parseFloat(x)+1) // 4.140000000000001
var x = '3.14是圆周率'
console.log(parseFloat(x)+1) // 4.140000000000001
var x = '3.14'
console.log((+x)+1) // 4.140000000000001
var x = '3.14是圆周率'
console.log((+x)+1) // NaN

任意类型转字符串

Boolean类型转字符串

let x = true
console.log(x.toString())

数值类型转字符串

let x = 10
console.log(x.toString())

判断是否为数值类型

console.log(isNaN('a')) // true
console.log(isNaN(false)) // false
console.log(isNaN(10)) // false
console.log(isNaN('10')) // false

页面弹窗

弹出对话框让用户输入字符串作为变量值

let age =window.prompt("请输入数字");

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TWXH8UrV-1691948413429)(E:/视频图像/image-20230328172556178.png)]

运算符

符号含义符号含义
+>大于
-<小于
*==数值是否等于
/!=不等于
%百分比===值和类型是否都一样
**次方&&
||

赋值运算符

赋值

x = y

加法赋值

x += y // x = x + y

减法赋值

x -= y // x = x - y

乘法赋值

x *= y // x = x * y

除法赋值

x /= y // x = x / y

求余赋值

x %=y // x = x % y

求幂赋值

x **= y // x = x ** y

算数运算符

加法

x + y

减法

x - y

乘法

x * y

除法

x / y

次方

y个x相乘

x ** y

自增

哪怕在其他式子内,自增长后的数值也保留

x++ // x = x + 1

++x 与 x++ 在单独写的时候数值结果一致;

z=x++;时,先对z进行赋值,再让x自增长;z=++x;时,z等于自增长后的x

console.info时也一样,输出x++时先输出x,再让x自增

注意优先级!

	let x=10;
    let y=x++ + ++x;
    let z=++y + y++;
console.log("x",x,"y",y,"z",z);
//"x",12,"y",24,"z",46

自减

x-- // x = x - 1

比较运算符

值等于

只判断值,不判断类型

x == y

全等于

即判断值,也判断类型

x === y

值不等于

只判断值,不判断类型

x != y

不全等于

即判断值,也判断类型

x !== y

大于

x > y

小于

x < y

大于等于

x >= y

小于等于

x <= y

逻辑运算符

逻辑运算的结果只有两个:truefalse

逻辑与

一假则假

x && y

逻辑或

一真则真

x || y

逻辑非

非真即假

!x

三元运算符

一元运算符与二元运算符

  • 操作数 运算符 操作数 ==> 表达式

  • 只有一个操作数的叫一元运算符

  • ++ – +(正) -(负)

  • 有两个操作数的运算符叫二元运算符

    三元运算符

x ? y : z
//布尔表达式,如果真=y,假=z

不同类型之间的加法运算

数值与数值相加

number + number = number

var x = 1
var y  = 2
console.log(x + y) // 3

数值与布尔相加

number + boolean = number

true == 1` `false == 0
var x = true
var y = 1
console.log(x + y) // 2

数值与字符串相加

number + string = string

var x = 10
var y = 'Hello'
console.log(x + y) // 10Hello

布尔与字符串相加

boolean + string = string

var x = true
var x = 'Hello'
console.log(x + y) // trueHello

运算符优先级

() > 一元运算符 > 二元运算符 > 三元运算符
() > 算术运算符 > 比较运算符 > 逻辑运算符 > 赋值运算符
++` 和 `--` > `*`、`/` 和 `%` > `+` 和 `-
!` > `&&` > `||`

语句块

创建语句块

{
    console.log('Hello Js')
}

在语句块内声明的 let 变量,只能在语句块内使用

{let x = 1;}
console.log(x); // b is not defined

在语句块内声明的 var 变量,在语句块外也可以使用

{var x = 1;}
console.log(x); // 1

在语句块内可以使用在语句块外声明的变量

let x = 1, y = 2;
{console.log(x,y)} // 1 2

如果语句块内外创建相同名称的 var 变量,语句库内的变量会覆盖语句块外的变量

var x = 1;
{var x = 2;}
console.log(x); // 2

如果语句块内外创建相同名称的 let 变量,语句库内的变量和语句块外的变量互不影响

let x = 1;
{
  let x = 2;
  console.log(x); // 2
}
console.log(x); // 1

程序流程:

  • 1.业务流 ===> 指导方针
  • 2.数据流 ===> 业务流实现
  • 3.现金流===> 数据流引导

控制流

判断分支

if

假值:'' 0 false undefined null NaN

为了防止逻辑错误,可以把值放在前,变量放在后面if(1==age)

let money = 500

if(money >= 1000){
    console.log('买别墅');
}else if(money >= 500){
    console.log('买洋房')
}else if(money >= 100){
    console.log('买楼房');
}else{
    console.log('存着,租房住');
}
switch

switch 一般用于等值判断,但只能做全等判断(===)

如果default不是在最后面,就必须加上break;

break;只能用于switch和循环结构,用来跳出当前代码块

let role = '企业老板'

switch(role){
    case '企业老板':
        console.log('删除权限');
        console.log('修改权限');
        console.log('查询权限');
        break;
    case '部门经理':
        console.log('修改权限');
        console.log('查询权限');
        break;
    case '普通员工':
        console.log('查询权限');
        break;
    default:
        console.log('无权访问');
}

switch 漏勺效应

let role = '企业老板'

switch(role){
    case '企业老板':
        console.log('删除权限');
    case '部门经理':
        console.log('修改权限');
    case '普通员工':
        console.log('查询权限');
        break;
    default:
        console.log('无权访问');
}

循环迭代

循环

  • 循环 = 循环条件 + 循环体
  • 循环条件控制循环的执行
  • 循环体是循环要执行的部分
  • 在循环体中一定要改变循环的迭代数据

迭代

  • 可迭代的量
  • 迭代 ==> 由一组值组成的量
  • 什么时候用数组?需要存储同一“业务类型”的多个数据(成绩数组,姓名数组。)
//迭代初始值
let z = 0
//循环条件
for (let i = 0; i <= 100; i++) {
//循环体
     if (i % 2 == 0) {
          z += i;
     }
//条件迭代
     i++
	}
}
for

固定次数循环

先判断,后执行,判断失败就不执行

for(let i = 1; i <= 10; i++){
    console.log(i)
}
while

非固定次数的循环

先判断,后执行,判断失败就不执行

一般用来做死循环

let i = 0
while(i <= 10){
    console.log(i)
    i++
}
do…while

先执行循环,再进行判断

至少执行一次的循环

一般用来做死循环

let i = 0
do{
    console.log(i)
    i++
}while(i <= 10);
for…in

循环显示数组的一种简写方式

如果需要在代码块里使用索引(下标)的情况使用

let x = ['a','b','c','d']
for (i in x) {
    console.log(x[i])		//含义是输出数组x的第i个
}
for…of

循环显示数组的一种简写方式

如果想直接获取数组元素时使用

let x = ['a','b','c','d']
for (i of x) {				//i被赋值为数组x的第i个的值
    console.log(i)
}
  • 普通for可以控制迭代步数,for...in for...of不行,只能一步一步地向下迭代

  • 想遍历整个数组时,可以考虑使用for...in for...of

  • 不想遍历整个数组或有特殊条件时,要用普通for

break

跳出循环

强制退出整个循环,后续循环不再执行

跳出当前循环

for (x = 1; x <= 5; x++) {
    for (y = 1; y <= 100; y++) {
        console.log('x=', x, 'y=', y)
        if (y == 2) {
            break // 仅仅跳出内层循环,无法跳出外层循环
        }
    }
}

跳出到指定位置,退出循环

out:
for (x = 1; x <= 5; x++) {
    for (y = 1; y <= 100; y++) {
        console.log('x=', x, 'y=', y)
        if (y == 2) {
            break out // 直接跳转到 out 位置,跳过循环继续执行
        }
    }
}
continue

继续循环

强制退出本次循环,继续后续循环

for (x = 1; x <= 10; x++) {
    if (x % 2 == 0) {
        continue // 直接跳转到 'x++' 继续执行
    }
    console.log('x=', x)
}

跳转到指定位置下第一个循环的x++处,继续循环

into:
for (x = 1; x <= 5; x++) {
    for (y = 1; y <= 100; y++) {
        console.log('x=', x, 'y=', y)
        if (y == 2) {
            continue into // 跳转到 into 位置,继续进入循环
        }
    }
}

异常处理

throw

throw 异常类型(“异常消息”)——异常类型(查看MDN)是固定的,不要自定义

主动抛出异常,并自定义抛出信息,后续代码不继续执行

var x = 10
var y = 0
if(y == 0){
    throw '被除数不能为 0'
}
try…catch…finally

尝试捕获异常,如果出现异常则进行异常处理finally块无论是否出现异常都会被执行

try{						//尝试检测代码中的错误
    console.log(x)
}catch(e){					//捕获try检测的错误,并尝试处理
    console.log(e)			 //try报错,catch才会执行
}finally{					//无论try有没有检测到错误,finally都执行
    console.log('finally')
}

函数

函数:代码封装,提高代码的复用性

  • 函数的返回值一定是函数的最后一个被执行的语句
  • 函数体内可以使用函数体外定义的变量
  • 函数体内定义的变量只能在函数体内使用,函数体外无法使用
  • 函数体内定义了函数体外相同名字的变量时,函数体外的变量的作用域无法进入到函数体内
  • 函数的形参相当于在函数体内定义了一个变量
  • 带默认值的变量要放在可变变量之前,不带默认值变量的后面

函数分类

  • 函数分类一.
    • 具名函数
    • 匿名函数
  • 函数分类二.

    • 无参无返回值函数

      function(){}
      ()=>{}
      
    • 无参有返回值函数

      function(){return "";}
      ()=>{return "";}
      
    • 带参无返回值函数

      function(abc){}
      (abc)=>{}
      
    • 带参有返回值函数

      function(abc){return "";}
      (abc)=>{return "";}
      
  • 函数分类三.
    • 1.普通函数
    • 2.箭头函数
    • 3.回调函数
    • 4.立即执行函数
    • 5.递归函数
    • 6.闭包函数
    • 7.构造函数

无参函数

无参无返回值

定义

//第一种写法,使用function定义函数
function fun(){
    console.log('Hello fun')
}
//第二种写法,使用 => 定义函数
const fun = ()=>{
	console.log("Hello fun =>")
}

调用

fun()

无参有返回值

定义

function fun(){
    return "Hello Js"
}

调用

let result = fun()
console.log(result)

带参函数

当执行一个函数需要额外条件时,需要添加形式参数;不需要时不加形参

带有固定数量的参数

function fun(形参列表){函数体} //形式参数,列表形式

实参的数量要与形参的数量保持一致,并且具有一对一的对应赋值关系

如果实参比形参多,则多出的实参被抛弃

如果实参比形参少,则没有被赋值的形参值为undefined

function(x,y,z){}
(x,y,z)=>{}

定义

function fun(num1, num2){
    console.log(num1 + num2)
}

调用

上面定义的fun(num1, num2)参数值调用下面的fun(1,2),输出结果变成console.log(1 + 2)

fun(1, 2)

带有默认值的参数

定义

function fun(msg, name='js'){
    console.log(msg, name)
}

调用

fun('Hello')
fun('Hello', 'JavaScript')

带有不固定数量的参数

实参的数量要与形参的数量保持一致,并且具有一对一的对应赋值关系

函数中只能有一个可变参数,这个参数必须放在形参列表的最后

如果实参比形参多,实参会一对一按顺序先赋值给非可变形参,剩余的实参会赋值给可变形参,可变形参用数组的方式记录剩下的所有实参

如果实参比形参少,则没有被赋值的非可变形参的值undefined,可变形参的值为空数组【】

非固定参数函数

function(x,y,...z){}
(x,y,...z)=>{}

参数带默认值

function(x,y=10){}
(x,y=10)=>{}

定义

function fun(num1,num2,...args) {
    let z = 0;
    for(let i of args){
        z += i
    }
    return num1+num2+z
}

调用

let result = fun(1, 1, 2, 3, 4)
console.log(result);

匿名函数

可以用一个变量来接收匿名函数

let fun = function(){
    console.log('Hello Js')
}

调用

fun()

可以直接使用匿名函数

setTimeout(function(){
  console.log(1)
},1000)

立即执行函数

该函数在被浏览器加载时就会被调用执行

(function(){
  函数体
})()

箭头函数

当箭头函数只有一句话并且是return时,可以简写

const abc= name=> `${name}值`;
(形参列表)=>{
	函数体
	return 返回值;
}

无参箭头函数

定义

let fun = ()=>{
    console.log(1)
}

调用

fun()

有单个参数的箭头函数

如果只有一个参数的话,小括号可以省略

定义

let fun = msg=>{
    console.log(msg)
}

调用

fun('Hello Js')

有多个参数的箭头函数

调用

let fun = (x, y)=>{
    console.log(x + y)
}

调用

fun(1, 2)

方法体内只有return语句

定义

let x = v => v + 10

调用

let y = x(1)
console.log(y)

回调函数

匿名函数作为参数传入 fun,在 fun 函数内被调用

回调函数调用

function fun(x,y,cb){
    let z = x + y
    cb(z)
}
function 回调函数(){}
function 普通函数(回调函数){}
普通函数(回调函数);
function huidiao(fun){
      console.log("f1()","1")
      fun()
    }
function f2(){
      console.log("f2()",2)
    }
    huidiao(f2)
//用户输入
//callback ==> 回调函数
    function huidiao(callback){
      const value=prompt("请输入一个数据");
      //执行回调函数
      callback(value)
    }
//计算
    function calc(value){
      value=Number(value)
      console.log(value+10)
    }
//输出
    function print(value){
      console.log(value)
    }
//调用
    huidiao(calc,print)

函数入参

fun(1,2,function(res){
    console.log(res)    
})

递归函数

一个函数在函数体内调用自己,这种模式我们成为递归函数

可以理解为是一个特殊的循环结构

必须要有退出条件,否则是死循环,退出机制的实现需要使用return

function 普通函数(形参){
	普通函数(形参);
	return 返回值;
}

定义函数,并在内部调用

let nums = [1, 2, 3, 4, 5]

function fun(i, y=0) {
    if (i == nums.length) {
        return y
    }
    y += nums[i]
    return fun(++i, y)
}

外部调用

let z = fun(0)
console.log(z)

闭包函数

使用

function 普通函数(){
	function 内部函数(){
		内部函数函数体
	}
	内部函数();
}
function bibao(sex) {
      let name = "张三"
      function names(age) {
        console.log(`${name},${sex},${age}`)
      }
      return names;
    }
    const bibaoa = bibao("男")
    let age = 20
    bibaoa(age)

function bibao(x) {
      return function (y) {
        return x+y
      }
    }
    let bi2 = bibao(1);
    let num = bi2(2);
    console.log(num);

function bibao() {
      let age;
      const setAge= function (y) {
        age=y>0? y : 0;
        console.log(age);
      }
      return setAge;
    }
let setAge = bibao();
setAge(-20);
//或者
function bibao() {
      let age
      const setAge= function (y) {
        age=y>0? y : 0
        console.log(age)
      }
      return setAge(50)=bibao();
    }

构造函数

不能加返回值

使用

function 构造函数(形参){
	函数体
	//无返回值
}
const 对象名 =new 构造函数(形参);

函数调用注意事项

如果方法调用和方法声明在同一个<script>块中,则可以先调用后声明

<script>
    console.log(fun(1,2));

    function fun(i,j){
        return i+j;
    }
</script>

如果方法调用和方法声明不在同一个<script>块中,则必须要先声明后调用

<script>
    function fun(i,j){
        return i+j;
    }
</script>
<script>
    console.log(fun(1,2));
</script>

如果尝试接收一个无返回值的函数,则得到的返回值为undefined

<script>
    function fun(x){
        console.log(x);
    }

    var r = fun(10);
    console.log(r);
</script>

解构

解构数组

将数组中的元素一一对应的赋值给左边的变量

let [x,y,z] = [1,2,3]
console.log(x,y,z) // 1 2 3

如果想忽略某个值,则直接保留 , 即可

let [x, ,z] = [1,2,3]
console.log(x,z) // 1 3

也可将多余的数据赋值给一个变量

let [x,y,...z] = [1,2,3,4,5]
console.log(x,y,z) // 1 2 [3, 4, 5]

解构对象

变量名要与对象属性名保持一致

let {name,age} = {name:'张三',age:20}
console.log(name,age) // 张三 20

默认值

let {name,age,sex='男'} = {name:'张三',age:20}
console.log(name,age,sex) // 张三 10 男

展开语法

展开数组

let x = [1,2,3,4]
console.log(...x) // 1 2 3 4

数组拷贝

let x = [1,2,3,4]
let y = [...x,5,6,7]
console.log(y) // [1, 2, 3, 4, 5, 6, 7]

函数调用

function calc(x,y,z){
    console.log(x + y + z)
}
let p = [1,2,3]
calc(...p) // 6

展开对象

对象展开后只能用于创建另一个对象

合并2个数组:

let x = {name:'张三',age:20};
let y = {sex:'男'};
let z=[...x,...y];
console.log(z) // [name: "张三", age: 20, sex: "男"]

合并后,如果同一个变量有多个值,则值为最后写的变量值

let a = {age:20;}
let b = {age:15;}
let abc = {...a, ...b}
console.log(abc)	//age=15

合并数组后,去掉重复——...new Set

let a = [1, 2, 3]
let b = [3, 4, 5]
let abc = [...new Set([...a, ...b])]
console.log(abc)	//[1,2,3,4,5]

对象

在javascript中,万物皆对象,所有的对象都继承于顶级对象Object

创建对象

1. 字面量对象 
const obj = {}
2. 构造函数
function Obj(){}

const obj = new Obj();
3. Object
const boj = new Object();
4. Class
class Obj{}

const obj = new Obj();

继承

1. 原型继承
function Person(){}
function Child(){}
Child.prototype = new Person();
2. 通更改this实现继承
function Person(){}
function Child(){
  Person.call(this)
}
function Person(){}
function Child(){
  Person.apply(this)
}
3. 通过 extends 实现继承
class Person{}
class Child extends Person{}

字面量对象

一次只能创建一个对象

定义直接,使用方便,不能复用。往往用于配置数据

let person = {
    name:'张三',
    age:20
}
console.log(person.name,person.age)
///
const 对象名={
	属性名:属性值,
	方法名:function(){}
}
const 对象名={
	属性名:属性值,
	方法名(){}
}
let obj={
    say(){
        //this指向当前字面量对象
        console.log(this);
    }
}
obj.say()			//输出:{say:}

构造函数

可以构建多个对象,但是每次构建对象时,都会拷贝构造函数里面的所有成员

可以复用,内存消耗大。

可以将方法提取到原型中,来解决内存消耗大的问题

function 构造函数={
	this.属性名=属性值;
	this.方法名=function(){};
}
const 对象名=new 构造函数();

无参构造函数

function Person(){
    this.name = '张三'
    this.age = 20
    this.say = function(){
        console.log(`我叫${this.name},今年${this.age}岁了`)
    }
}
let p = new Person()
p.say()

带参构造函数

function stu(names,age){
    this.names=names;
    this.age=age;
    this.say=function(){
        console.log(`${names}今年${age}岁`);
    }
}
let stu1=new stu("张三","18")
let stu2=new stu("李四","8")
stu1.say()
stu2.say()

对象继承

call,apply:两个函数都能改变父类this的指向

call——函数名.call(this,name,age);

apply——函数名.apply(this,[name,age]);

//父级构造函数
function Person(name,age){
    this.name = name
    this.age = age
    this.say = function(){
        console.log(`我叫${this.name},今年${this.age}岁了`)
    }
}
//子级构造函数
function Employee(name,age){
    Person.call(this,name,age)		//如果call(null,name,age)
}

let e = new Employee('张三',20)
e.say()							//则这里用window.say()调用

基于object

const 对象名=new object();
对象名.属性名=属性值;
对象名.方法名=function(){}

原型

在javascript中,每个对象都有一个原型,每个原型也有原型,最顶端的原型为null,null没有原型

使用原型可以构建多个对象,每个对象都拥有独立的属性,但方法会被所有对象共享

使用原型创建的对象,无法在构建对象时对属性进行初始化

  • 每一个函数和对象都有原型属性
  • 获取函数的原型对象
    • 函数名.prototype
    • 获取对象的原型对象
    • proto(不能直接获取)
    • object.getPrototypeOf(对象名)
function Person() { }
Person.prototype.name = '张三'
Person.prototype.age = 20
Person.prototype.say = function () {
    console.log(`我叫${this.name},今年${this.age}岁了`)
}

let p = new Person()
p.say()

构造函数加原型

构造函数可以为属性进行初始化,原型可以是每个对象都共享方法

function Person(name,age) {
    this.name = name
    this.age = age
}
Person.prototype.say = function () {
    console.log(`我叫${this.name},今年${this.age}岁了`)
}
let p = new Person('张三','李四')
p.say()

1.构造函数的原型和这个构造函数生成的对象的原型一致

function 构造函数(){};
const 对象名=new 构造函数();
构造函数.prototype==对象._proto_

2.对象的构造函数和对象的原型的构造函数一致

对象.constructor==对象._proto_.constructor

3.构造函数的原型的构造函数和这个构造函数生成的对象的构造函数一致

构造函数.prototpye.constructor==对象.constructor

工厂模式

无需直接定义或new出一个新对象,对象都有工厂函数产生

function 工厂函数(形参列表){
	const 对象名=new object();
	对象名.属性名=属性值;
	对象名.方法名=function(){}
	return 对象名;
}
const 对象名=工厂函数(实参列表)
function gongchang(names,age){
    let stu=new Object();
    stu.names=names
    stu.age=age
    stu.say=function(){
        console.log(`${this.names}今年${this.age}岁了`)
    }
    return stu;
}
let zs=gongchang("张三",20)
zs.say()

原型链

原型链解决了对象间的继承问题,每个对象都可以作为另一个对象的原型

function Person(name,age) {
    this.name = name
    this.age = age
}
Person.prototype.say = function () {
    console.log(`我叫${this.name},今年${this.age}岁了`)
}


function Employee(name,age){
    Person.call(this,name,age)
}
Employee.prototype = new Person()

let e = new Employee('张三',20)
e.say()

实例所属

判断实例是否属于某个构造函数

function Person() { }

function Employee() { }
Employee.prototype = new Person()

let e = new Employee()

console.log(e instanceof Employee) // true
console.log(e instanceof Person) // true

判断实例是否来自于某个构造函数

function Person() { }

function Employee() { }
Employee.prototype = new Person()

let e = new Employee()

console.log(e.constructor == Employee) // false
console.log(e.constructor == Person) // true

可变属性

对象初始化时,可变属性的名称为变量的值。当对象生成后,在改变变量的值,对象的属性名不会再跟着改变。

let name = 'key'
let obj = {
    [name]: '张三'
}
console.log(obj) // {key: "张三"}
let stu={
            name:"张三",
            uname:"李四",
        }
        let key='name'
        console.log(stu[key]);	//动态变量名用[]包裹
let stu={
            name:"张三",
            uname:"李四",
        }
        //key是变量,value是值
        function setStu(key,value){
            stu[key]=value;			//value赋值给key
        }
        function getStu(key){
            return stu[key];		//获取stu的变量名的值
        }
        let skey="sex"
        let svalue="女"
        setStu(skey,svalue)			//将 sex:女 插入stu
        let key=prompt("输入")
        console.log(getStu(key))	//显示stu的变量的值
        console.log(stu);

JavaScript中的类与java的不同,只是语法相近而已,底层还是基于原型实现的(为了学java的人能适应前端js)

js没有类的概念,这个class引用了高级面向对象语言的语法,本质还是原型

function stu(){}===class stu{} 两者效果一样

this只能在构造函数里或方法里使用,类里必须加constructor()才能用

静态和非静态:

  1. 静态方法里调用非静态的成员,可以使用this
  2. 静态方法里调用静态成员,可以使用this或类名
  3. 非静态方法里调用非静态成员。使用this
  4. 非静态方法里调用静态成员,使用 类名
  5. 静态方法中,不能调用私有成员

私有和共有:

  1. 私有属性要在类中先声明,然后在构造函数中赋值
  2. 私有成员要用#开头
  3. 私有成员只能在类内部使用,类外不可用

多态

在不同的类中,相同名称的方法,所实现的功能不同,这种形式称之为多态

重写(重载)

子类中存在与父类相同的方法,这种形式称之为方法的重写(重载);

对象调用时,使用子级的方法(覆盖父级的方法)

super——表示父类

  1. 在子类的构造函数中调用父类的函数,使用super(),这句话一定是子类构造函数体的第一句话
  2. 在子类中调用父类的成员,可以使用super.成员的方式
  3. 在子类中super不能调用父类的私有成员,子类也不会继承父类的私有成员

创建类

class Person{ 
    // ...
}
let p = new Person()

构造方法

class stu{
   constructor(){			//没有这个就不能用this
       this.name="张三"
    }
}
console.log(new stu());		//输出stu的值

无参构造

class Person{
    constructor(){			
        this.name = '张三'
        this.age = 20
    }
}
let p = new Person()
console.log(p.name,p.age) // 张三 20

有参构造

class Person{
    constructor(name,age){
        this.name = name
        this.age = age
    }
}
let p = new Person('张三',20)
console.log(p.name,p.age) // 张三 20

带默认值的有参构造

class Person{
    constructor(name,age){
        this.name = name || '匿名'
        this.age = age || 0
    }
}
let p = new Person()
console.log(p.name,p.age) // 匿名 0

实例方法

class Person{
    constructor(name,age){
        this.name = name || '匿名'
        this.age = age || 0
    }
    say(){
        console.log(`我叫${this.name},今年${this.age}岁了!`)
    }
}
let p = new Person('张三',20)
p.say() // 我叫张三,今年20岁了!

静态方法

静态方法只能由类直接调用,实例对象无法调用

静态方法中不能调用实例成员

class Person{
    static say(name,age){
        console.log(`我叫${name},今年${age}岁了!`)
    }
}
Person.say('张三',20) // 我叫张三,今年20岁了!
class Person{
            constructor(name){
                this.name=name
            }
            say(){
                console.log(this.name);
            }
        }
//老师类
        class Teacher extends Person{
            //静态属性
            static school="十中"
            //静态方法
            static fun(){
                console.log(this.name);
                console.log("静态方法",this.school);
            }
            teacher(){
                console.log("非静态方法");
                console.log(Teacher.school);
            }
        }
        const tea=new Teacher("张三")
        tea.teacher()

类的继承

extends==> 继承,也是扩展

class Person{
    constructor(name,age){
        this.name = name || '匿名'
        this.age = age || 0
    }
    say(){
        console.log(`我叫${this.name},今年${this.age}岁了!`)
    }
}

class Employee extends Person{}

let e = new Employee('张三',20)
e.say() // 我叫张三,今年20岁了!

调用父级的构造方法

class Person{
    constructor(name,age){
        this.name = name || '匿名'
        this.age = age || 0
    }
    say(){
        console.log(`我叫${this.name},今年${this.age}岁了!`)
    }
}

class Employee extends Person{
    constructor(name,age,sex){
        super(name,age)
        this.sex = sex || '未知'
    }
}

let e = new Employee('张三',20,'男')
e.say()

调用父级的方法

class Person{
    constructor(name,age){
        this.name = name || '匿名'
        this.age = age || 0
    }
    say(){
        console.log(`我叫${this.name},今年${this.age}岁了!`)
    }
}

class Employee extends Person{
    constructor(name,age,sex){
        super(name,age)
        this.sex = sex || '未知'
    }
    say(){
        super.say()
        console.log(`我是${this.sex}孩子`)
    }
}

let e = new Employee('张三',20,'男')
e.say()

模块

模块可以是一个js脚本,也可以由多个js脚本组成

  • 模块内的成员只能在模块内使用,模块外不可用
  • 如果让模块外可用,要把成员导入

创建模块

// modules/index.js
let uname = '张三'
function say(){
    console.log('Hello!!')
}

导出模块成员

单独导出

// modules/person.js
export let uname = '张三'
export function say(){
    console.log('Hello!!')
}

统一导出

// modules/person.js
let uname = '张三'
function say(){
    console.log('Hello!!')
}
export{uname,say}

导入模块

<!-- index.html -->
<script type="module">
    import {uname,say} from './person.js'
    console.log(uname)
    say()
</script>

定义别名

导出时定义别名

// modules/person.js
let uname = '张三'
function say(){
    console.log('Hello!!')2
}
export{uname as u,say as s}
<!-- index.html -->
<script type="module">
    import {u,s} from './person.js'
    console.log(u)
    s()
</script>

导入时定义别名

// modules/person.js
let uname = '张三'
function say(){
    console.log('Hello!!')
}
export{uname,say}
<!-- index.html -->
<script type="module">
    import {uname as u,say as s} from './person.js'
    console.log(u)
    s()
</script>

默认导出

default——默认,加在export后面

// modules/person.js
let uname = '张三'
function say(){
    console.log('Hello!!')
}
export default{uname,say}
<!-- index.html -->
<script type="module">
    import person from './person.js'
    console.log(person.uname)
    person.say()
</script>

本地数据存储

sessionStorage——会话存储空间

localStorage——本地存储空间

**注:**往本地里存储数据不能存truefalse,会被转成字符串。

        //写入数据
        sessionStorage.setItem("name","张三")
        localStorage.setItem("name","李四")
        sessionStorage.setItem("age",20)
        localStorage.setItem("age",20)
        //读数据
        let zs=sessionStorage.getItem("name");
        let ls=localStorage.getItem("name");
        let zs_age=sessionStorage.getItem("age");
        let ls_age=localStorage.getItem("age");

        console.log(zs,ls);
        console.log(zs_age,ls_age);
        //查看数据类型
        console.log(zs_age,typeof zs_age);
        console.log(ls_age,typeof ls_age);
        //删除数据
        sessionStorage.removeItem("name");
        localStorage.removeItem("name");
        //清空数据
        sessionStorage.clear();
        localStorage.clear();

本地永久存储

关闭浏览器,数据不会丢失

存储或修改数据

localStorage.setItem('name','张三')    

获取数据

console.log(localStorage.getItem('name'))

删除数据

localStorage.removeItem('name')

清空数据

localStorage.clear()

获取本地存储条目数

console.log(localStorage.length) // 1

本地临时存储

关闭浏览器,数据就会被清空

存储或修改数据

sessionStorage.setItem('name','张三')

获取数据

console.log(sessionStorage.getItem('name'))

删除数据

sessionStorage.removeItem('name')

清空数据

sessionStorage.clear()

获取本地存储条目数

console.log(sessionStorage.length) // 1

异步处理

  1. 在js中有两种代码,一种叫同步代码,一种叫异步代码
  2. 同步代码在执行时,会严格按照控制流语句的顺序进行代码执行
  3. 在既有同步也有异步的情况下,同步代码一定会优先执行,等所有同步代码全部执行完毕后,异步代码才会被统一执行
//同步
console.log("A");

//同步
function fun(c){
    //异步
    setTimeout(()=>{
        console.log("B");
        c()
     },2000)
}

//同步
fun(()=>{console.log("C");})
//目的:原本该输出“ACB”,现在b内回调c,导致输出结果为“ABC”

Promise

用于表示一个异步操作的最终完成 (或失败), 及其结果值.

function f(flag){
    return new Promise(function(resolve,reject){
        if(flag){
            resolve('成功')
        }else{X
            reject('失败')
        }
    })
}

x = true
f(x).then(function(res){
    console.log(res) // x == true : 成功
}).catch(function(res){
    console.log(res) // x == false : 失败
})

Proxy——代理

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

  • handler (en-US)

    包含捕捉器(trap)的占位符对象,可译为处理器对象。

  • traps

    提供属性访问的方法。这类似于操作系统中捕获器的概念。

  • target

    被 Proxy 代理虚拟化的对象。它常被作为代理的存储后端。根据目标验证关于对象不可扩展性或不可配置属性的不变量(保持不变的语义)。

    //目标对象
    let zs={
        name:"张三",
        money:1000,
        sex:1,
    }
    //代理对象,代理对象代理目标对象
    let p=new Proxy(zs,{
    //目标对象读取属性时,代理对象的行为
        get:(target,property)=>{
            console.log(`正在读取目标对象的${property}属性`);
            return target[property];
        },
        //目标对象修改属性时,代理对象的行为
        set:(target,property,value)=>{
    //target是对象,property是需要修改属性的属性名,value是属性值
            console.log(`正在修改目标对象的${property}属性,值为${value}`);
            target[property]=value;
            console.log(target);
        }
    })
    //通过代理对象修改目标对象的属性,会触发代理对象的set行为
    p.name="李四";
    p.money=-555;
    //通过代理对象读取目标对象的属性,会触发代理对象的get行为
    p.name;
    p.money;
    

语法

const p = new Proxy(target, handler)

Copy to Clipboard

参数

  • target

    要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

  • handler

    一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

方法

handler 对象的方法

handler 对象是一个容纳一批特定属性的占位符对象。它包含有 Proxy 的各个捕获器(trap)。

所有的捕捉器是可选的。如果没有定义某个捕捉器,那么就会保留源对象的默认行为。

ES6内置对象

数组

创建数组

创建空数组
var arr = new Array()
var arr = []
创建并指定长度
var arr = new Array(2)
var arr = [,,]
创建并实例化
var arr = Array('a','b',3,4)
var arr = ['a','b',3,4]

数组元素

通过下标来访问数组元素,元素的下标从 0 开始

数组下标 = 数组长度 - 1
修改或新增数组元素
var arr = new Array(2)
arr[0] = 'a'
arr[1] = 'b'
arr[2] = 'c'
arr[3] = 'd'
调用数组元素
var arr = ['a','b',3,4]
console.log(arr[0],arr[1])
删除数组元素
var arr = ['a','b',3,4]
delete arr[2]
console.log(arr)
数组长度
var arr = ['a','b','c','d']
console.log(arr.length)

数组方法

数组合并

方法1:x.concat(y)

方法2:[...x,...y]

var x = [1,2,3]
var y = ['a','b','c']
var z = x.concat(y)
console.log(z) // [1, 2, 3, "a", "b", "c"]
数组转字符串

x.join(y) y是分隔符,x是数组名

var x = [1,2,3]
var y = '-'
var z = x.join(y)
console.log(z) // 1-2-3
插入元素

在数组末尾添加一个或多个元素——push

var x = [1,2,3]
x.push('a','b')
console.log(x) // [1, 2, 3, "a", "b"]

在数组开头添加一个或多个元素——unshift

var x = [1,2,3]
x.unshift('a','b')
console.log(x) // [ "a", "b", 1, 2, 3]
移除元素

移除数组的最后一个元素——pop

var x = [1,2,3]
x.pop()
console.log(x) // [1, 2]

移除数组的第一个元素——shift

var x = [1,2,3]
x.shift()
console.log(x) // [2, 3]
数组切片

取值范围是下标左侧

slice(start, end)

第一个参数为 起始索引 (起始下标),第二个参数为 结束索引 (结束下标)

var x = [1,2,3,4,5,6]
var y = x.slice(2,4)
console.log(y) // [3, 4]
数组替换(数组分割)

会改变原数组

x.splice(start)

数组分割

a=[1,2,3,4,5];	
b=a.splice(1,2);	//b为数组,值为a删去的部分	
  console.log(a);	//[1,4,5]
  console.log(b);	//[2,3]

删除下标为3之后的所有元素

var x = ['a','b','c','d','e','f']
x.splice(3)
console.log(x) // ["a", "b", "c"]
x.splice(start,size)

删除下标为2之后的3个元素 这个时候splice(2,3)2是下标,3是数量

var x = ['a','b','c','d','e','f']
x.splice(2,3)
console.log(x) // ["a", "b", "f"]
x.splice(start,size,v1,v2,...)

删除指定范围的元素,并用新元素替换

var x = ['a','b','c','d','e','f']
x.splice(2,3,'x','y','z')
console.log(x) // ["a", "b", "x", "y", "z", "f"]
翻转数组

reverse()

var x = [3,1,6,7,2,4,5]
x.reverse()
console.log(x) // [5, 4, 2, 7, 6, 1, 3]
升序排序

sort()

var x = [3, 1, 6, 7, 2, 4, 5]
x.sort()
console.log(x) // [1, 2, 3, 4, 5, 6, 7]

按数组某一属性排序

let a = [
    { name: "张三", age: 20 },
    { name: "李四", age: 18 },
    { name: "王五", age: 29 },
]
a.sort((a,b)=>a.age-b.age)
a.forEach((value, index) => {
    console.log(value);
});

降序排列

原理:如果b大于a,则b在前,否则a在前

x.sort((a,b) => b - a )		//换成a-b就是正序排列
查找元素
indexOf(searchEle)

从下标为0的元素开始搜索,如果找到返回所在的下标,如果没找到,返回 -1

var x = ['b','a','e','d','a','f']
var z = x.indexOf('a')
console.log(z) // 1
indexOf(searchEle,fromIndex)

从下标为2的元素开始搜索

var x = ['b','a','e','d','a','f']
var z = x.indexOf('a',2)
console.log(z) // 4
lastIndexOf(searchEle)

从最后一个元素向前搜索

var x = ['b','a','e','d','a','f']
var z = x.lastIndexOf('a')
console.log(z) // 4

查询数组中某一个元素的值的下标

        let a = [
            { name: "张三", age: 20 },
            { name: "李四", age: 18 },
            { name: "王五", age: 29 },
        ]
        //查询这个元素的下标
        let i=a.findIndex(value=>value.name=="王五");
        console.log(i);		//2
        //查询这个元素所在的数组
        let i=a.find(value=>value.name=="王五");
        console.log(i);		//{ name: "王五", age: 29 }
遍历数组
let a=[9,2,3,4,5,1]
a.forEach((value,index) => {
 console.log(value);
});
基于原数组创建新数组
map(callback(element,index))
var x = ['b','a','e','d','a','f']
var y = x.map(function(e,i){
    return e.toUpperCase()
})
console.log(y) // ["B", "A", "E", "D", "A", "F"]

修改数组的值

let a = [
    { name: "张三", age: 20 },
    { name: "李四", age: 18 },
    { name: "王五", age: 29 },
]
//给所有人的年龄+1
a.map((value) => ++value.age)
a.forEach((value, index) => {
    console.log(value);
});
数组过滤

filter()

filter(element,index)
var x = [1,7,4,2,9,8,3,5,6]
var y = x.filter(function(e,i){
    return e > 5
})
console.log(y) // [7, 9, 8, 6]
///
let a = [
    { name: "张三", age: 20 },
    { name: "李四", age: 18 },
    { name: "王五", age: 29 },
]
let b=a.filter((value)=>value.age>=20)	//只显示age>=20的内容
b.forEach((value, index) => {
    console.log(value);
});
判断是否为数组
var x = []
console.log(Array.isArray(x)) // true

数组去重

let abc1=[1,5,2,8,2,5,2,9,8]	//声明一个数组
let abc=new Set([...abc1]);		//将数组转为集合,集合自动去重
let abc2=[...abc];				//将集合转为数组
console.log(abc2);				//获得一个没有重复的数组

数组函数

资料网站:

https://mp.weixin.qq.com/s?__biz=MjM5MDA2MTI1MA==&mid=2649118986&idx=1&sn=a20751891391d24879e145357ac205a0&chksm=be587ea7892ff7b10d3f169b6032bfdb79a7186570489943083fdd033d2ec133a70d4f64d5aa&scene=27


数组类型是object,用=赋值时,赋值的是地址

let a=[1,2,3]
let b=a;		//a的数据地址赋值给了b,a和b共用一组数据
b[0]=2			//如果是 b=2 ,则 a=[1,2,3],b=2
console.log(a[0],b[0])		//2,2	a和b==[2,2,3]

用解构跟展开可以破解该问题

let a=[1,2,3]
function add(b){
    b.push(4);		//数组添加一个元素,值为 4
    return b;
}
let newB=add([...a])
console.log(a,newB)		//a[1, 2, 3],newB[1, 2, 3, 4]

集合

集合里面的值都是唯一的,不可重复

创建集合

创建空集合
let x = new Set()
console.log(x) // Set(0) {}
创建并初始化
let x = new Set([1,2,3,4])
console.log(x) // Set(4) {1, 2, 3, 4}

集合属性

查看集合长度
let x = new Set([1,2,3,4])
console.log(x.size) // 4

集合方法

添加元素
let x = new Set()
x.add(1)
x.add(2)
console.log(x) // Set(2) {1, 2}
删除元素
let x = new Set(['a','b','c','d'])
x.delete('b')
console.log(x) // Set(3) {"a", "c", "d"}
清空集合
let x = new Set(['a','b','c','d'])
x.clear()
console.log(x) // Set(0) {}
查找元素
let x = new Set(['a','b','c','d'])
console.log(x.has('c')) // true
遍历集合
let x = new Set(['a','b','c','d'])
x.forEach(function(e){
    console.log(e)
})
//或者
x.forEach(value=>{
    console.log(value);
})
//或者
for(let i of x){
    console.log(i);
}

Map

键值对结构,键不可重复,值可以重复

创建Map

创建空Map
let x = new Map()
console.log(x) // Map(0) {}
创建并初始化
let x = new Map([
    ['name','张三'],
    ['age',20]
])
console.log(x) // Map(2) {"name" => ”张三“, "age" => 20}

Map属性

获取长度
let x = new Map([['name', '张三'], ['age', 20]])
console.log(x.size) // 2

Map方法

添加或修改元素
let x = new Map([['name', '张三'], ['age', 20]])
x.set('sex', '男')
console.log(x) // Map(3) {"name" => ”张三“, "age" => 20, "sex" => "男"}
获取元素的值
let x = new Map([['name', '张三'], ['age', 20]])
console.log(x.get('name')) // 张三
删除元素
let x = new Map([['name', '张三'], ['age', 20]])
x.delete('name')
console.log(x) // Map(2) {"age" => 20}
清空Map
let x = new Map([['name', '张三'], ['age', 20]])
x.clear()
console.log(x) // Map(0) {}
遍历Map
let x = new Map([['name', '张三'], ['age', 20]])
x.forEach(function(v,k){
    console.log(k,v)
})
查询Key是否存在
let x = new Map([['name', '张三'], ['age', 20]])
console.log(x.has('name')) // true
获取所有的键
let x = new Map([['name', '张三'], ['age', 20]])
console.log(x.keys()) // MapIterator {"name", "age"}
获取所有的值
let x = new Map([['name', '张三'], ['age', 20]])
console.log(x.values()) // MapIterator {"张三", 20}

字符串

创建字符串

字面量字符串

双引号形式

console.log("This is string")

单引号形式

console.log('This is string')

模板字符串

console.log(`This is string`)
字符串对象
let x = new String('This is string')
console.log(x) // String {"This is string"}
字符串换行

使用 + 拼接

console.log('This is'+
            'string') // This is string

使用 \ 拼接

console.log('This is \
string') // This is string

保留字符串的双引号

let a=123;
console.log("aaa  \"a\" bbb");	//输出结果:a    "a"   b
本来双引号代表字符串的边界,用\后取消该效果

使用模板字符串

console.log(`This is 
string`) // This is 
         // string
解析变量

只有在模板字符串中,可以解析变量

let name = '张三'
let sex = 20
let x = `${name}今年${sex}岁了`
console.log(x) // 张三今年20岁了

字符串属性

字符串长度
let x = 'This is string'
console.log(x.length) // 14

字符串方法

提取指定字符
x.charAt(index)
let x = 'This is string'
console.log(x.charAt(2)) // i
x[index]
let x = 'This is string'
console.log(x[2]) // i
字符串拼接
//x.concat(y)
let x = 'This is '
let y = 'string'
let z = x.concat(y)
console.log(z) // This is string

//x + y
let x = 'This is '
let y = 'string'
let z = x + y
console.log(z) // This is string
字符串验证

判断是否以某个字符串结尾

x.endsWith(y)
let x = 'This is string'
let y = 'ing'
let z = x.endsWith(y)
console.log(z) // true

判断是否以某个字符串开头

x.startsWith(y)
let x = 'This is string'
let y = 'This'
let z = x.startsWith(y)
console.log(z) // true

判断是否包含某个字符串

x.includes(y)
let x = 'This is string'
let y = 'str'
let z = x.includes(y)
console.log(z) // true
查找字符串

查找某个字符串的位置,查到了返回索引,没查到返回-1

x.indexOf(y)
let x = 'This is string'
let y = 'is'
let z = x.indexOf(y)
console.log(z) // 2

使用则匹配,返回匹配后的结果数组

x.match(y)
let x = '12345@163.com'
let y = /\d+/g
let z = x.match(y)
console.log(z) // ["12345", "163"]

使用正则或字符串搜索,返回索引,如果没搜索到,返回-1

x.search(y)
let x = '12345@163.com'
let y = '163'
console.log(x.search(y)) // 6
字符串查找并替换
let x = '12345@163.com'
let y = '163'
let z = 'qq'
console.log(x.replace(y,z)) //12345@qq.com
字符串切片
x.slice(start,end)
let x = '12345@163.com'
console.log(x.slice(2,5)) // 345

x.substring(start,end)
let x = '12345@163.com'
console.log(x.substring(2,5)) // 345
分割字符串
let x = '12345@163.com'
console.log(x.split('@')) // ["12345", "163.com"]
英文字母大小写转换

转成小写

x.toLocaleLowerCase()
let x = 'This Is String'
console.log(x.toLocaleLowerCase()) // this is string
x.toLowerCase()
let x = 'This Is String'
console.log(x.toLowerCase()) // this is string

转成大写

x.toLocaleUpperCase()
let x = 'This Is String'
console.log(x.toLocaleUpperCase()) // THIS IS STRING
x.toUpperCase()
let x = 'This Is String'
console.log(x.toUpperCase()) // THIS IS STRING
去除首尾空格
let x = '   This Is String   '
console.log(x.trim()) // This Is String
//字符串
        let a = "  123  456  ";
        console.log(a);
//去掉两端的空格
        console.log(a.trim());			//"123  456"
//去掉开始位置的空格
        console.log(a.trimStart());		//"123  456  "
//去掉左边的空格
        console.log(a.trimLeft());		//"123  456  "
//去掉结束位置的空格
        console.log(a.trimEnd());		//" 123  456"
//去掉右边的空格
        console.log(a.trimRight());		//" 123  456"
任何类型的数据转成字符串
x.toString()
let x = 100
let y = x.toString()
console.log(typeof y) // string
String(x)
let x = 100
let y = String(x)
console.log(typeof y) // string

数字

创建数字

字面量数字

类型为number

let x = 10
console.log(x) // 10
数字对象

类型为Object

let x = new Number(10)
console.log(x) // Number {10}

数字方法

判断是否为非数字

如果是数字返回 false,不是数字返回 true

console.log(Number.isNaN('a')) // true
console.log(isNaN(10)) // false
判断是否为整数

判断是否为整数类型,前提条件必须是number类型

如果用数字封装new Number(),类型为Object,所以变量判断不是整数

console.log(Number.isInteger(10)) // true
console.log(Number.isInteger(10.0)) // true
console.log(Number.isInteger(3.14)) // false
转为浮点数
Number.parseFloat(x)
let x = '50'        
let y = Number.parseFloat(x)
console.log(typeof y) // number
parseFloat(x)
let x = '50'        
let y = parseFloat(x)
console.log(typeof y) // number
转为整数
Number.parseInt(x)
let x = '50'        
let y = Number.parseInt(x)
console.log(typeof y) // number
parseInt(x)
let x = '50'        
let y = parseInt(x)
console.log(typeof y) // number

数学

数学属性

圆周率

VS内只有48位的值

console.log(Math.PI) // 3.141592653589793

数学方法

绝对值
console.log(Math.abs(-10)) // 10
向上取整
console.log(Math.ceil(12.01)) // 13
向下取整
console.log(Math.floor(12.99)) // 12
返回最大值
console.log(Math.max(5,2,6,9,1,7)) // 9
返回最小值
console.log(Math.min(5,2,6,9,1,7)) // 1
产生0~1的随机数

产生的随机数可以为 0, 但不能为 1

console.log(Math.random()) // 0.544536372532334

获取指定范围的随机数

Math.random() * (max - min) + min
console.log(Math.ceil(Math.random()*(9999-1000)+1000));
四舍五入
console.log(Math.round(12.5)) // 13
console.log(Math.round(12.4)) // 12
返回一个数的整数部分
console.log(Math.trunc(12.9)) // 12
返回指定的小数位

保留指定的小数位

得到的结果是一个字符串

console.log(Math.PI.toFixed(2))

日期时间

创建日期对象

创建当前时间的日期对象
new Date()
let x = new Date()
console.log(x) // Sat Sep 19 2020 17:02:43 GMT+0800 (中国标准时间)
创建指定日期的时间对象
new Date('yyyy-MM-ddThh:mm:ss')
let x = new Date('1900-10-01T12:20:03')
console.log(x) // Mon Oct 01 1900 12:20:03 GMT+0805 (中国标准时间)
new Date(year,monthIndex,day,hours,minutes,seconds)

monthIndex 表示月份的整数值,从 0(1月)到 11(12月)

let x = new Date(2000,10,1,13,20,5)
console.log(x) // Wed Nov 01 2000 13:20:05 GMT+0800 (中国标准时间)

日期时间方法

获取时间戳

返回自 1970-1-1 00:00:00 UTC(世界标准时间)至今所经过的毫秒数

console.log(Date.now()) // 1600506934200

解析一个表示日期的字符串,并返回从 1970-1-1 00:00:00 所经过的毫秒数。

console.log(Date.parse('2020-10-10T11:11:05')) // 1602299465000
Date.UTC(year,monthIndex,day,hours,minutes,seconds)
console.log(Date.UTC(2020, 10, 10, 11, 11, 3)) // 1605006663000
获取年份
let x = new Date('2020-09-19T17:22:10')
console.log(x.getFullYear()) // 2020
获取月份

0表示一月,1表示二月,2表示三月,以此类推

let x = new Date('2020-09-19T17:22:10')
console.log(x.getMonth()) // 8
获取当月的第几天
let x = new Date('2020-09-19T17:22:10')
console.log(x.getDate()) // 19
获取小时数
let x = new Date('2020-09-19T17:22:10')
console.log(x.getHours()) // 17
获取分钟数
let x = new Date('2020-09-19T17:22:10')
console.log(x.getMinutes()) // 22
获取秒数
let x = new Date('2020-09-19T17:22:10')
console.log(x.getSeconds()) // 10
获取毫秒数
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.getMilliseconds()) // 123
获取周几

0表示周日,1表示周一,2 表示周二,以此类推

let x = new Date('2020-09-19T17:22:10')
console.log(x.getDay()) // 6
获取时间戳

返回从1970-1-1 00:00:00 UTC(协调世界时)到该日期经过的毫秒数

let x = new Date('2020-09-19T17:22:10.123')
console.log(x.getTime()) // 1600507330123
将时间转成字符串
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.toDateString()) // Sat Sep 19 2020
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.toLocaleString()) // 2020/9/19 下午5:22:10
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.toLocaleDateString()) // 2020/9/19
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.toLocaleTimeString()) // 下午5:22:10

页面获取并显示当前时间

<h1 id="time"></h1>

<script>
    function num(num) {
       return num < 10 ? `0${num}` : num;
    }

    setInterval(() => {
       let date = new Date();
       let month = date.getMonth() + 1;
       let day = date.getDate();
       let hours = date.getHours();
       let minutes = date.getMinutes();
       let seconds = date.getSeconds();
       let week = date.getDay();
       let weekZh = ["日", "一", "二", "三", "四", "五", "六"];

       let time=`${date.getFullYear()}年${num(month)}月${num(day)}日 星期${weekZh[week]}
       ${num(hours)}:${num(minutes)}:${num(seconds)}`;
     document.getElementById("time").innerText=time;
     },1000)
</script>

JSON

创建JSON

let x = { "name": "张三", "age": 20 }
console.log(x) // {name: "张三", sex: 20}

JSON方法

将JSON转为字符串
let x = { "name": "张三", "age": 20 }
console.log(JSON.stringify(x)) // {"name":"张三","sex":20}
将字符串转为JSON
let x = '{"name":"张三","age":20}'
console.log(JSON.parse(x)) // {name: "张三", sex: 20}

JSON对象与字面量对象的区别

JSON对象的属性和字符串类型的值均需要用 " 包裹

字面量对象的属性可以不用引号包裹,也可以使用 '" 包裹

字面量对象字符串类型的值可以使用 '" 包裹

正则表达式

创建正则表达式

/pattern/flags
let x = /ab+c/i
new RegExp(pattern,flags)
let x = new RegExp('ab+c','i')
let x = new RegExp(/ab+c/,'i')

正则表达式的标记

标记说明
g全局匹配
i忽略大小写
m多行匹配

正则表达式方法

匹配搜索

在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null

let x = '12345@163.com'
let y = new RegExp(/\d+/)
console.log(y.exec(x)) // ["12345", index: 0, input: "12345@163.com", groups: undefined]
匹配校验

执行一个检索,用来查看正则表达式与指定的字符串是否匹配,如果匹配返回true,否则返回false

let x = '12345@163.com'
let y = new RegExp(/\d+/)
console.log(y.test(x)) // true

正则表达式符号

符号说明
/…/代表一个模式的开始和结束
^匹配字符串的开始
$匹配字符串的结束
s任何空白字符
S任何非空白字符
d匹配一个数字字符,等价于[0-9]
D除了数字之外的任何字符,等价于[^0-9]
w匹配一个数字、下划线或字母字符,等价于[A-Za-z0-9_]
W任何非单字字符,等价于[^a-zA-z0-9_]
.除了换行符之外的任意字符
()对数据进行分组
[]在范围内,例如:[357]只能取3或5或7,[3-7]3到7范围内的一个值
[^]不在范围内
{n}匹配前一项n次
{n,}匹配前一项n次,或者多次
{n,m}匹配前一项至少n次,但是不能超过m次
*匹配前一项0次或多次,等价于{0,}
+匹配前一项1次或多次,等价于{1,}
?匹配前一项0次或1次,也就是说前一项是可选的,等价于{0,1}
``

验证是否为手机号

//是否为(135)|(189)|(159)|(175)开头,后面是否为8个数字
let reg=/^((135)|(189)|(159)|(175))\d{8}$/;
let no=17512345678;			//需要验证的手机号
console.log(reg.test(no));	//判断手机号是否符合正则表达式

BOM

窗口操作

绑定事件

onclick鼠标点击时触发事件

新开窗口

<body>
    <button onclick="window.open()">打开新窗口</button>
</body>

关闭当前窗口

<body>
    <button onclick="window.close()">关闭当前窗口</button>
</body>

打印当前文档

window.print()

弹窗

警告框

alert("Hello")

选择框

点击确定,返回true

点击取消,返回false

let choose = window.confirm('请选择')
console.log(choose)

提示输入框

点击确定,返回用户输入的内容

点击取消,返回null

let choose = window.prompt('请输入')
console.log(choose)

页面地址

解析地址

获取完整路径

console.log(location.href) // http://127.0.0.1:5500/demo/index.html?uname=zs&upass=123#login

获取域名和端口

console.log(location.host) // 127.0.0.1:5500

获取域名

console.log(location.hostname) // 127.0.0.1

获取端口

console.log(location.port)  // 5500

获取协议

console.log(location.protocol)  // http:

获取路径

console.log(location.pathname) // /demo/index.html

获取查询字符串

console.log(location.search) // ?uname=zs&upass=123

获取锚路径

console.log(location.hash) // #login

重新加载

location.reload()

跳转页面

打开一个页面

window.open("https://www.yaconit.com/")

会产生历史记录

window.localtion.href = 'https://www.yaconit.com/'
localtion = 'https://www.yaconit.com/'
location.assign('https://www.yaconit.com/')

不会产生历史记录

localtion.replace('https://www.yaconit.com/')

历史记录

后退

history.back()

前进

history.forward()

跳转

正整数表示前进几个记录 负整数表示后退几个记录

history.go(-1)

DOM

DOM文档

从js提交给html页面数据

    <dl>
        <dt>姓名:</dt>
        <dd id="name"></dd>
        <dt>性别:</dt>
        <dd id="sex"></dd>
        <dt>年龄:</dt>
        <dd id="age"></dd>
    </dl>

    <script>
        let stu = {
            name: "张三",
            sex: 1,
            age: 18,
        }
        //通过ID获取标签
        let nameDD = document.getElementById("name");
        let sexDD = document.getElementById("sex");
        let ageDD = document.getElementById("age");
        //设置标签中的文本内容
        stu.sex = 2;	//修改
        //向html返回数据
        nameDD.innerText = stu.name;
        sexDD.innerText = stu.sex;
        ageDD.innerText = stu.age;
    </script>

页面

页面属性

获取来源页面的URL

console.log(document.referrer)

获取当前文档的字符集

console.log(document.characterSet) // UTF-8

获取当前文档的标题

console.log(document.title)

获取整个html数据

console.log(document);

获取页面中这个ID的那一行

 console.log(document.getElementById(prop));

获取页面中这个ID的那一行的文本内容

console.log(document.getElementById(prop).innerText);

页面状态

判断当前页面是否隐藏

console.log(document.hidden) // false

获取当前页面的状态

状态(布尔类型)说明
visible页面可见
hidden页面隐藏
prerender页面正在渲染
console.log(document.visibilityState)

检测用户是否在看页面

//定时器,每秒检测一次
setInterval(()=>{
    //判断页面是可见还是隐藏
     if (document.hidden) {
         //如果隐藏,就更改页面标题
          document.title = "页面崩溃"
      }else{
           document.title = "DOM"
      }
},1000)

获取当前文档的加载状态

状态说明
loading正在加载
interactive文档已被解析,但诸如图片、样式和框架之类的子元素仍在加载
complete加载完成
console.log(document.readyState) // loading

节点

Node => 节点 Element => 元素 Attribute => 属性 style=>样式 Event=>事件

Element 是 Node 的子类

创建节点

创建标签

document.createElement('nodeName')
let a = document.createElement('a')
console.log(a) // <a></a>

创建属性

document.createAttribute('attrName')
attr.textContent = 'attrValue'
let href = document.createAttribute('href')
href.textContent = 'http://localhost'
console.log(href) // href = "http://localhost"

创建文本

document.createTextNode('text')
let text = document.createTextNode('超链接')
console.log(text) // "超链接"

创建注释

let comm = document.createComment('这是注释')
console.log(comm) // <!--这是注释-->

获取节点

获取当前文档的html元素

let html = document.documentElement

获取当前文档的body元素

let body = document.body

获取当前文档中的head元素

let head = document.head

获取当前文档中所有的表单元素

let forms = document.forms

获取当前文档中所有的img元素

let images = document.images

获取当前文档中所有的a元素

let links = document.links

根据标签名获取元素列表

<body>
    <div></div>
    <script>
        let elements = document.getElementsByTagName('div')
        console.log(elements) // HTMLCollection [div]
    </script>
</body>

根据ID获取元素

<body>
    <div id="box1"></div>
    <script>
        let element = document.getElementById('box1')
        console.log(element) // <div id="box1"></div>
    </script>
</body>

根据类名获取元素列表

<body>
    <div class="active">Test</div>
    <script>
        let elements = document.getElementsByClassName('active')
        console.log(elements) // HTMLCollection [div.active]
    </script>
</body>

根据name获取元素列表

<body>
    <input name="uname"/>
    <script>
        let elements = document.getElementsByName('uname')
        console.log(elements) // NodeList [input]
    </script>
</body>

使用CSS选择获取第一个匹配的元素

<body>
    <input name="uname"/>
    <script>
        let element = document.querySelector('[name="uname"]')
        console.log(element) // <input name="uname"/>
    </script>
</body>

使用CSS选择器获取所有匹配的元素

<body>
    <input name="uname"/>
    <script>
        let elements = document.querySelectorAll('[name="uname"]')
        console.log(elements) // NodeList [input]
    </script>
</body>

获取所有子元素

获取所有子节点

<body>
    <ul id="ul">
        <li>li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        console.log(ul.childNodes) // NodeList(9) [text, li, text, li, text, li, text, li, text]
    </script>
</body>

获取所有子标签

console.log(ul.children) // HTMLCollection(4) [li, li, li, li]

获取第一个子元素

获取第一个子节点

<body>
    <ul id="ul">
        <li>li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        console.log(ul.firstChild) // #text
    </script>
</body>

获取第一个子标签

console.log(ul.firstElementChild) // <li>li-1</li>

获取最后一个子元素

获取最后一个子节点

<body>
    <ul id="ul">
        <li>li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        console.log(ul.lastChild) // #text
    </script>
</body>

获取最后一个子标签

console.log(ul.lastElementChild) // <li>li-4</li>

获取上一个元素

获取上一个节点

<body>
    <ul>
        <li>li-1</li>
        <li id="li2">li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let li2 = document.getElementById('li2')
        console.log(li2.previousSibling) // #text
    </script>
</body>

获取上一个标签

console.log(li2.previousElementSibling) // <li>li-1</li>

获取下一个元素

获取下一个节点

<body>
    <ul>
        <li id="li1">li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let li1 = document.getElementById('li1')
        console.log(li1.nextSibling) // #text
    </script>
</body>

获取下一个标签

console.log(li1.nextElementSibling) // <li>li-2</li>

获取父级节点

获取父级节点

<body>
    <ul>
        <li id="li1">li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let li1 = document.getElementById('li1')
        console.log(li1.parentNode) // <ul>...</ul>
    </script>
</body>

获取父级元素

console.log(li1.parentElement) // <ul>...</ul>

获取最近的一个在定位流中的父级元素,如果没有在定位流中的父级元素,则返回body

console.log(li1.offsetParent) // body

节点数据

获取节点名称

<body>
    <ul>
        <li id="li1">li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let li1 = document.getElementById('li1')
        console.log(li1.nodeName) // LI
    </script>
</body>
console.log(li1.tagName) // LI

获取节点类型

类型说明
1标签节点
2属性节点
3文本节点
8注释节点
<body>
    <ul>
        <li id="li1">li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let li1 = document.getElementById('li1')
        console.log(li1.nodeType) // 1
    </script>
</body>

获取当前节点的值

只对TEXTComment节点有效,其余节点均返回null

<body>
    <ul>
        <li id="li1">li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let li1 = document.getElementById('li1')
        console.log(li1.firstChild.nodeValue) // li-1
    </script>
</body>

获取当前节点以及后代节点的文本内容

<body>
    <ul id="ul">
        <li>li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        console.log(ul.textContent)
    </script>
</body>

获取或设置当前节点的HTML结构

获取结构

<body>
    <ul id="ul">
        <li>li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        console.log(ul.outerHTML)
    </script>
</body>

设置结构

ul.outerHTML = "<ul><li>list-item</li></ul>"

获取或设置当前节点内部的HTML结构

获取内部结构

<body>
    <ul id="ul">
        <li>li-1</li>
        <li>li-2</li>
        <li>li-3</li>
        <li>li-4</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        console.log(ul.innerHTML)
    </script>
</body>

设置内部结构

ul.innerHTML = "<li>list-item</li>"

获取或设置当前元素内部的文本,包含后代元素的文本

获取内部的文本

<body>
    <div id='wrapper'>
        <div>Hello</div>
    </div>
    <script>
        let wrapper = document.getElementById('wrapper')
        console.log(wrapper.innerText) // Hello
    </script>
</body>

设置内部的文本

wrapper.innerText = 'Hello HTML'

盒子数据

尺寸说明图示
clientWidth clientHeight获取视口的宽和高,不包括边框[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C7EOenss-1691948413431)(https://www.yaconit.com/md/yaconit/web-front-end/javascript/resources/client.png)]
offsetWidth offsetHeight获取视口的宽和高,包括边框[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZGWFF37X-1691948413431)(https://www.yaconit.com/md/yaconit/web-front-end/javascript/resources/=Dimensions-offset.png)]
clientTop clientLeft获取上边框和左边框的宽度[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LEFCtJyK-1691948413431)(https://www.yaconit.com/md/yaconit/web-front-end/javascript/resources/image-20200920214135167.png)]
offsetTop只读属性,它返回当前元素相对于其 offsetParent 元素的顶部内边距的距离。
offsetLeft只读属性,返回当前元素左上角相对于 HTMLElement.offsetParent 节点的左边界偏移的像素值。
offsetParentHTMLElement.offsetParent 是一个只读属性,返回一个指向最近的(指包含层级上的最近)包含该元素的定位元素或者最近的 table, td, th, body 元素。当元素的 style.display 设置为 “none” 时,offsetParent 返回 nulloffsetParent 很有用,因为 offsetTopoffsetLeft 都是相对于其内边距边界的

获取当前元素相对于 offsetParent 的相对位置

<body>
    <style>
        body{margin:0;}
        #wrapper{width: 500px;height: 500px;border:5px solid red;box-sizing: border-box;position: relative;}
        #innerbox{width: 200px;height: 200px;border:20px solid blue;margin: 50px;padding: 50px;overflow: auto;}
        #content{background-color:aqua;height: 100%;width: 100%;}
    </style>
    <div id="wrapper">
        <div id="innerbox">
            <div id="content"></div>
        </div>
    </div>
    <script>
        let ib = document.getElementById('innerbox')
        console.log(ib.offsetLeft,ib.offsetTop) // 50 50
    </script>
</body>

节点操作

克隆节点

不包含后代元素

<body>
    <ul id="ul">
        <li>li-1</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        let newUl = ul.cloneNode()
    </script>
</body>

包含后代元素

let newUl = ul.cloneNode(true)

复制数据粘贴在其他地方

<ul>
    <li id="a1">123</li>
</ul>
    <input type="button" value="查询" onclick="a1234()">
    <ol></ol>
    
<script>
       function a1234(){
        let oldLi=document.querySelector('#a1')
        let ol=document.querySelector('ol')
//克隆
        let newLi=oldLi.cloneNode(true)
//粘贴
        ol.append(newLi)
       }
</script>

添加子节点

作为最后一个子节点添加到当前节点

<body>
    <ul id="ul">
        <li>li-1</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        let li = document.createElement('li')
        li.innerText = 'list-item'
        ul.appendChild(li)        
    </script>
</body>

作为第一个子节点添加到当前节点

ul.prepend(li)

在当前节点下增加一个子节点,并使该子节点位于参考节点的前面。

<body>
    <ul id="ul">
        <li id="li">li-1</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        let li = document.getElementById('li')
        let newLi = document.createElement('li')
        newLi.innerText = 'list-item'
        ul.insertBefore(newLi,li)     
    </script>
</body>

移除节点

移除当前节点下的指定子节点

<body>
    <ul id="ul">
        <li id="li1">li-1</li>
        <li id="li2">li-2</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        let li1 = document.getElementById('li1')
        ul.removeChild(li1) 
    </script>
</body>

替换节点

用一个新节点替换掉当前节点下的指定子节点

<body>
    <ul id="ul">
        <li id="li">li-1</li>
    </ul>
    <script>
        let ul = document.getElementById('ul')
        let li = document.getElementById('li')
        let newLi = document.createElement('li')
        newLi.innerText = 'new list item'
        ul.replaceChild(newLi,li) 
    </script>
</body>

获取或设置节点的隐藏状态

获取节点的隐藏状态

console.log(ul.hidden)

隐藏节点

ul.hidden = true

设置当前节点的焦点

获取焦点

<body>
    <input type="text" id='sex' name='sex'>
    <script>
        let input = document.getElementById('sex')
        input.focus()
    </script>
</body>

失去焦点

input.blur()

点击当前元素

<body>
    <button id="btn" onclick="alert('我被点击了')">按钮</button>
    <script>
        let btn = document.getElementById('btn')
        btn.click()
    </script>
</body>

创建按钮

//创建按钮
        let buttonhei=document.createElement("button")
//设置标签内文本
        buttonhei.innerText="夜间模式"
//绑定事件
        buttonhei.onclick=hei;
//追加至body中
        document.body.append(buttonhei);
//事件
        function hei() {
		//修改页面背景颜色
            document.body.style.backgroundColor = 'black'
        }

创建图片

//创建图片元素
        let img=document.createElement('img');
//创建src属性对象
        //设置图片路径
        let src=document.createAttribute('src')
        src.textContent='/0412f51e-102401fpp8.jpg'
        //设置图片宽度
        let width=document.createAttribute('width')
        width.textContent='300px'
//将src和width属性添加到img中
        img.attributes.setNamedItem(src)
        img.attributes.setNamedItem(width)
//获取body
        let body=document.body;
//将img添加到body中
        body.append(img)

创建文本

//创建标题元素
        let h1=document.createElement('h1')
//创建文本节点
        let text=document.createTextNode("标题")
//将文本节点添加到h1元素中
        h1.append(text);
        document.body.append(h1)

在审查元素中给h1添加注释

//创建注释
        let zhushi=document.createComment("这是一级标题")
//在h1前面插入该注释
        document.body.insertBefore(zhushi,h1)

显示一个标签所有父级标签

<div id="div">
        <section>
            <ol>
                <li>
                    <ul>
                        <li id="a1">123</li>
                    </ul>
                </li>
            </ol>
        </section>
    </div>
    
let a12 = document.getElementById('a1')
        function a1234(fuji = []) {
            if (a12.tagName != "BODY") {
                a12 = a12.parentNode;
                fuji.push(a12)
                console.log(a12);
                return a1234(fuji);
            } else {
                console.log(fuji);
                return 
            }
        }

点击时删除改元素

<ul>
    <li onclick="remove(event)">1</li>
    <li onclick="remove(event)">2</li>
    <li onclick="remove(event)">3</li>
    <li onclick="remove(event)">4</li>
</ul>

<script>
   function remove(e){
    //不保留位置,通过属性隐藏
    e.target.hidden=true;
    //不保留位置,通过样式隐藏
    e.target.style.display='none';
    //保留位置,通过样式隐藏
    e.target.style.visibilty='hidden';
    //自己删除自己(新浏览器有效,有兼容性问题)
    e.target.remove();
    //兼容性好
    e.target.parentNode.removeChild(e.target);
   }
</script>

创建一个秒表计时器

//一个精准到0.1s的计时器,点击时触发开始/暂停,第二次点击数据不清零
<button class="time" onclick="time2()">0</button>

const times = document.querySelector(".time")
        let flag = false
        let aaa = 0
        function time2() {
            flag = !flag
            if (flag) {
                abc = setInterval(() => {
                    aaa += 100
                    times.innerHTML = (aaa / 1000)
                }, 100)
            } else {
                clearInterval(abc)
            }
        }

属性

属性查询

获取当前元素的所有属性

<body>
    <input type="text" id='sex' name='sex'>
    <script>
        let input = document.getElementById('sex')
        console.log(input.attributes) // NamedNodeMap {0: type, 1: id, 2: name, type: type, id: id, name: name, length: 3}
    </script>
</body>
console.log(input.getAttributeNames()) //(3) ["type", "id", "name"]

获取指定属性的值

<body>
    <input type="text" id='sex' name='sex'>
    <script>
        let input = document.getElementById('sex')
        console.log(input.getAttribute('type')) // text
    </script>
</body>

判断当前元素是否包含指定的属性

<body>
    <input type="text" id='sex' name='sex'>
    <script>
        let input = document.getElementById('sex')
        console.log(input.hasAttribute('type')) // true
    </script>
</body>

获取元素的自定义属性

<body>
    <input type="text" id='sex' name='sex' data-id='1' data-state='del'>
    <script>
        let input = document.getElementById('sex')
        console.log(input.dataset) // DOMStringMap {id: "1", state: "del"}
    </script>
</body>

删除属性

移除当前元素的指定属性

<body>
    <input type="text" id='sex' name='sex'>
    <script>
        let input = document.getElementById('sex')
        input.removeAttribute('name')
    </script>
</body>

添加或修改属性

添加或修改属性

如果设置一个不存在的属性,则为添加

如果设置一个已存在的属性,则为修改

<body>
    <input type="text" id='sex' name='sex'>
    <script>
        let input = document.getElementById('sex')
        input.setAttribute('value','男')
    </script>
</body>

样式操作

获取或设置当前元素的class值

获取class值

<body>
    <div id="div" class="wrap active"></div>
    <script>
        let div = document.getElementById('div')
        console.log(div.className) // wrap active
    </script>
</body>

设置class值

div.classList = 'strong'

获取当前元素的class列表

<body>
    <div id="div" class="wrap active"></div>
    <script>
        let div = document.getElementById('div')
        console.log(div.classList) // DOMTokenList(2) ["wrap", "active", value: "wrap active"]
    </script>
</body>

追加class

<body>
    <div id="div" class="wrap"></div>
    <script>
        let div = document.getElementById('div')
        div.classList.add('active')
    </script>
</body>

移除class

<body>
    <div id="div" class="wrap active"></div>
    <script>
        let div = document.getElementById('div')
        div.classList.remove('active')
    </script>
</body>

设置样式

字符串形式设置

<body>
    <div id="div"></div>
    <script>
        let div = document.getElementById('div')
        div.style = "height:100vh;background-color:red";
    </script>
</body>

单独设置

div.style.height = '100vh'
div.style.backgroundColor = 'red'

读取样式

读取行内样式

<body>
    <div id="div" style="height: 100vh;background-color: red;"></div>
    <script>
        let div = document.getElementById('div')
        console.log(div.style.backgroundColor) // red
    </script>
</body>

读取非行内样式

window.getComputedStyle(hezi,null).width 获取hezi的宽度,window可以省略

<body>
    <style>
        #div{height: 100vh;background-color: red;}
    </style>
    <div id="div"></div>
    <script>
        let div = document.getElementById('div')
        console.log(window.getComputedStyle(div,null).backgroundColor) // rgb(255, 0, 0)
    </script>
</body>

滚动条

获取或设置滚动条左偏移位置

<body>
    <style>
        body{margin:0;}
        #wrapper{width: 500px;height: 500px;border:5px solid red;box-sizing: border-box;}
        #innerbox{width: 200px;height: 200px;border:20px solid blue;margin: 50px;padding: 50px;overflow: auto;}
        #content{background-color:aqua;height: 200%;width: 200%;}
    </style>
    <div id="wrapper">
        <div id="innerbox">
            <div id="content"></div>
        </div>
    </div>
    <script>
        let ib = document.getElementById('innerbox')
        ib.scrollLeft = 50
    </script>
</body>

获取或设置滚动条上偏移位置

ib.scrollTop = 50

设置滚动条左偏移和上偏移

ib.scroll(50,50)
ib.scrollTo(50,50)

DOM事件

事件 = 目标+事件类型+处理操作

事件操作

绑定事件

在DOM上直接绑定事件

事件处理程序直接写在元素上

<button onclick="console.log('按钮被点击了')">按钮</button>

绑定事件处理函数

<body>
    <button onclick="clickHandle()">按钮</button>
    <script>
        function clickHandle(){
            console.log('按钮被点击了')
        }
    </script>
</body>

通过JS绑定事件

直接使用闭包函数作为事件处理函数

<body>
    <button id="btn">按钮</button>
    <script>
        const btn = document.getElementById('btn')
        btn.addEventListener('click',function(){
            console.log('按钮被点击了')
        })
    </script>
</body>

绑定事件处理函数

<body>
    <button id="btn">按钮</button>
    <script>
        function clickHandle(){
            console.log('按钮被点击了')
        }
        const btn = document.getElementById('btn')
        btn.addEventListener('click',clickHandle)
    </script>
</body>
移除事件
<body>
    <button id="btn">按钮</button>
    <script>
        function clickHandle(){
            console.log('按钮被点击了')
            btn.removeEventListener('click',clickHandle)
        }
        const btn = document.getElementById('btn')
        btn.addEventListener('click',clickHandle)
    </script>
</body>

鼠标事件

鼠标单击事件

鼠标的左键会触发该事件

<body>
    <style>
        body{margin: 0;padding:50px;box-sizing: border-box;}
        #wrapper{height: 300px;width:300px;background-color: #f00;box-sizing: border-box;padding:50px;position: relative;}
        #inner{height: 200px;width:200px;background-color: #00f;}
    </style>
    <div id="wrapper">
        <div id="inner"></div>
    </div>
    <script>
        const wrapper = document.getElementById('wrapper')
        wrapper.addEventListener('click',function(e){
            console.log(e) // MouseEvent {...}
        })
    </script>
</body>
鼠标双击事件

鼠标的左键会触发该事件

wrapper.addEventListener('dblclick',function(e){
    console.log(e) // MouseEvent {...}
})
鼠标按下事件

鼠标的左键中键右键都会触发该事件

wrapper.addEventListener('mousedown',function(e){
    console.log(e) // MouseEvent {...}
})
鼠标弹起事件

鼠标的左键中键右键都会触发该事件

wrapper.addEventListener('mouseup',function(e){
    console.log(e) // MouseEvent {...}
})
鼠标进入事件

进出子元素不触发

wrapper.addEventListener('mouseenter',function(e){
    console.log(e) // MouseEvent {...}
})

进出子元素触发

wrapper.addEventListener('mouseover',function(e){
    console.log(e) // MouseEvent {...}
})
鼠标移出事件

进出子元素不触发

wrapper.addEventListener('mouseleave',function(e){
    console.log(e) // MouseEvent {...}
})

进出子元素触发

wrapper.addEventListener('mouseout',function(e){
    console.log(e) // MouseEvent {...}
})
鼠标移动事件
wrapper.addEventListener('mousemove',function(e){
    console.log(e) // MouseEvent {...}
})
鼠标右键单击

只有单击鼠标右键时才会触发

wrapper.addEventListener('contextmenu',function(e){
    console.log(e) // MouseEvent {...}
})
MouseEvent
属性说明
e.button返回按键索引 0:左键 1:中键 2:右键
e.target返回触发事件的目标元素
e.clientX e.clientY返回点击点的坐标,相对于目标元素
e.screenX e.screenY返回点击点的坐标,相对于屏幕
鼠标滚轮滚动事件

只有鼠标滚轮滚动时触发

<body style="height: 100vh;">
    <script>
        const body = document.body
        body.addEventListener('wheel', function (e) {
            console.log(e) // WheelEvent {...}
        })
    </script>
</body>
WheelEvent
属性说明
e.deltaX e.deltaY返回滚轮的滚动量
e.target返回触发事件的目标元素
文本选择事件

该事件只能绑定到<input><textarea>元素上

<body>
    <textarea id='tx' cols="50" rows="50">
        That was Wintermute, manipulating the lock the way it had manipulated the drone micro and the dripping chassis of a heroin factory. The Sprawl was a square of faint light. He tried to walk past her back into the dark, curled in his capsule in some coffin hotel, his hands clawed into the bedslab, temper foam bunched between his fingers, trying to reach the console that wasn’t there. Light from a service hatch at the rear wall dulling the roar of the console in faded pinks and yellows. Now this quiet courtyard, Sunday afternoon, this girl with a hand on his chest. Still it was a steady pulse of pain midway down his spine. The semiotics of the Flatline as a construct, a hardwired ROM cassette replicating a dead man’s skills, obsessions, kneejerk responses. Images formed and reformed: a flickering montage of the Sprawl’s towers and ragged Fuller domes, dim figures moving toward him in the dark, curled in his sleep, and wake alone in the tunnel’s ceiling. Why bother with the movement of the train, their high heels like polished hooves against the gray metal of the car’s floor. Strata of cigarette smoke rose from the tiers, drifting until it struck currents set up by the blowers and the chassis of a gutted game console.
    </textarea>
    <script>
        const tx = document.getElementById('tx')
        tx.addEventListener('select',function(e){
            console.log(e) // Event {...}
        })
    </script>
</body>

键盘事件

按键被按下事件
<body>
    <input type="text" id="input">
    <script>
        const input = document.getElementById('input')
        input.addEventListener('keydown',function(e){
            console.log(e) // KeyboardEvent {...}
        })
    </script>
</body>

有两种写法

document.documentElement.addEventListener('keydown', (e) => {
            // 返回按键的值:    e.key
            if (e.key == 'w') {
                alert('按下W键');
            }
        })
        
        // 按键被按下事件
        document.documentElement.onkeydown = ((e) => {
            label=document.querySelector("label")
            // 返回按键的值:    e.key
            if (e.key == 'w') {
                alert('按下W键');
            }
        })
按键被弹起事件
input.addEventListener('keyup',function(e){
    console.log(e) // KeyboardEvent {...}
})
KeyboardEvent
属性说明
e.key返回按键的值,例如:a,1,Alt
e.code返回物理按键码,例如:KeyA,Digit1,AltLeft
e.target返回触发事件的目标元素

视图事件

滚动事件
<body>
    <style>
        body{margin: 0;padding:50px;box-sizing: border-box;}
        #wrapper{height: 300px;width:300px;background-color: #f00;box-sizing: border-box;padding:50px;position: relative;overflow: auto;}
        #inner{height: 500px;width:500px;background-color: #00f;}
    </style>
    <div id="wrapper">
        <div id="inner"></div>
    </div>
    <script>
        const wrapper = document.getElementById('wrapper')
        wrapper.addEventListener('scroll',function(e){
            console.log(e) // Event {...}
        })
    </script>
</body>

当滚动条下拉1000px后才显示按钮

    <div class="ding">^</div>	//点击后会回到页面最顶部

    <script>
        //获取ding的DOM
        const ding = document.querySelector('.ding')
        //事件监听
        window.onscroll = (event) => {
            //这里是滚动后才执行,所以初始会显示内容
            //解决方法将下面第二行克隆至事件监听外,先执行一次。或者给目标盒子先加一个hidden,在加载页面时隐藏
            let top = document.documentElement.scrollTop;
            ding.style.display = top >= 1000 ? "block" : "none";
        }
        ding.onclick = (e) => {
            //设置循环定时器
            const aaa=setInterval(()=>{
                //速度
                let speed=100;
                //滚动条向上移动
                document.documentElement.scrollTop -=speed;
                if(document.documentElement.scrollTop<=0){
                    //清除定时器
                    clearInterval(aaa)
                }
                //滚动条每1毫秒运行一次
            },1)
            // zhiding=(document.documentElement.scrollTop = 0)
        }
    </script>
窗口尺寸重置事件

作用于window对象

<body>
    <script>
        window.addEventListener('resize',function(e){
            console.log(e) // Event {...}
        })
    </script>
</body>
页面隐藏事件

只能用来在页面关闭时给提示

当浏览器在显示与会话历史记录不同的页面的过程中隐藏当前页面时,pagehide(页面隐藏) 事件会被发送到一个Window 。例如,当用户单击浏览器的“后退”按钮时,当前页面在显示上一页之前会收到一个pagehide(页面隐藏) 事件。

在此示例中,建立了一个事件处理程序以监视 pagehide (页面隐藏) 事件,并在持久保存页面以进行可能的重用时执行特殊处理。

window.addEventListener("pagehide", event => {
  if (event.persisted) {
    /* the page isn't being discarded, so it can be reused later */
  }
}, false);

这也可以使用 Window 上的 onpagehide 事件处理程序属性来编写:

//离开当前页面时触发,但只触发一次
window.onpagehide = event => {
        location='/buybus.html'
}

拖拽事件

搭建基本的HTML页面

<body>
    <style>
        body{margin: 0;padding:50px;box-sizing: border-box;}
        #wrapper{display: flex;justify-content: space-between;gap:10px;}
        #wrapper ul{flex:1;border:1px solid red;list-style: none;padding: 0;height: 300px;}
        #wrapper ul li{padding: 10px;border:1px solid blue;margin: 5px;text-align: center;}
    </style>
    <div id="wrapper">
        <ul class="target">
            <li>li-1</li>
            <li>li-2</li>
            <li>li-3</li>
            <li>li-4</li>
            <li>li-5</li>
        </ul>
        <ul class="target"></ul>
        <ul class="target"></ul>
    </div>
</body>

设置可拖动的元素

<script>
    // 使 li 可以被拖动
    const lis = document.getElementsByTagName('li')
    for(li of lis){
        li.setAttribute('draggable',true)
    }
</script>

设置拖动的目标区域

<script>
    // 使 li 可以被拖动
    /* ... */

    // 设置 .target 为拖动的目标区域
    const targets = document.getElementsByClassName('target')
    for(target of targets){
        target.addEventListener('dragover',function(e){
            e.preventDefault()
        })
    }
</script>

给可拖动元素绑定开始拖动事件

// 使 li 可以被拖动
const lis = document.getElementsByTagName('li')
for(li of lis){
    li.setAttribute('draggable',true)

    // 开始拖动
    li.addEventListener('dragstart',function(e){
        current = this
    })
}

给目标元素绑定释放事件

// 设置 .target 为拖动的目标区域
const targets = document.getElementsByClassName('target')
for(target of targets){
    /* ... */

    // 释放元素
    target.addEventListener('drop',function(e){
        this.appendChild(current)
    })
}

设置进入目标区域后,目标区域的背景颜色

// 设置 .target 为拖动的目标区域
const targets = document.getElementsByClassName('target')
for(target of targets){
    /* ... */

    // 释放元素
    /* ... */

    // 进入目标区域
    target.addEventListener('dragenter',function(e){
        this.style.backgroundColor = 'rgba(255,0,0,0.3)'
    })
}

设置离开目标区域后,目标区域的背景颜色

// 设置 .target 为拖动的目标区域
const targets = document.getElementsByClassName('target')
for(target of targets){
    /* ... */

    // 释放元素
    /* ... */

    // 进入目标区域
    /* ... */

    // 离开目标区域
    target.addEventListener('dragleave',function(e){
        this.style.backgroundColor = '#fff'
    })
}

设置拖动结束后,目标区域的背景颜色

// 使 li 可以被拖动
const lis = document.getElementsByTagName('li')
for(li of lis){
    li.setAttribute('draggable',true)

    // 开始拖动
    /* ... */

    // 结束拖动
    li.addEventListener('dragend',function(e){
        this.parentNode.style.backgroundColor = '#fff'
    })
}

元素拖动时,在父级消失

// 使 li 可以被拖动
const lis = document.getElementsByTagName('li')
for(li of lis){
    li.setAttribute('draggable',true)

    // 开始拖动
    /* ... */


    // 结束拖动
    /* ... */


    // 正在拖动
    li.addEventListener('drag',function(e){
        this.parentNode.removeChild(this)
    })
}

资源事件

资源加载事件

window触发

<body>
    <script>
        window.addEventListener('load', function(e) {
            console.log(e);
        });
    </script>
</body>

文档加载完成后触发

<body onload="loadHandle(event)">
    <h1>Hello HTML</h1>
    <script>
        function loadHandle(e){
            console.log(e)
        }
    </script>
</body>

图片加载触发

<body>
    <img src="https://www.yaconit.com/public/images/logo.png" onload="loadHandle(event)">
    <script>
        function loadHandle(e){
            console.log(e)
        }
    </script>
</body>

表单事件

表单提交事件
<body>
    <form id="login">
        <div>
            <label for="uname">账号:</label>
            <input type="text" id="uname" name="uname">
        </div>
        <div>
            <label for="upass">密码:</label>
            <input type="password" id="upass" name="upass">
        </div>
        <div>
            <input type="submit" value="登陆"/>
        </div>
    </form>
    <script>
        const loginForm = document.getElementById('login')
        loginForm.addEventListener('submit',function(e){
            console.log(e) // SubmitEvent {...}
            e.preventDefault() // 禁止表单提交
        })
    </script>
</body>
assert 非空判断
assert(name, "请输入类目名称")		//如果值为空,则弹出对话框显示后面的文本
更改事件

<input type="text"><textarea> 在失去焦点时,才会判断是否产生了更改

<select><input type="radio"><input type="checkbox">在每次更改选项时就会触发该事件

<body>
    <form id="login">
        <input type="text" id="uname" name="uname">
    </form>
    <script>
        const uname = document.getElementById('uname')
        uname.addEventListener('change',function(e){
            console.log(e) // Event {...}
        })
    </script>
</body>
输入事件

<input><textarea>在输入时触发该事件

<body>
    <form id="login">
        <input type="text" id="uname" name="uname">
    </form>
    <script>
        const uname = document.getElementById('uname')
        uname.addEventListener('input',function(e){
            console.log(e) // InputEvent {...}
        })
    </script>
</body>
焦点事件

获取焦点事件

<body>
    <input type="text" id="input">
    <script>
        const input = document.getElementById('input')
        input.addEventListener('focus', function (e) {
            console.log(e) // FocusEvent {...}
        })
    </script>
</body>

失去焦点事件

input.addEventListener('blur', function (e) {
    console.log(e) // FocusEvent {...}
})

媒体事件

媒体加载事件

媒体的第一帧已经加载完成

<body>
    <video id="vm" src="https://www.w3school.com.cn/i/movie.ogg" controls>
        您的浏览器不支持 video 标签。
    </video>
    <script>
        const vm = document.getElementById('vm')
        vm.addEventListener('loadeddata',function(e){
            console.log(e) // Event {...}
        })
    </script>
</body>

媒体已经加载完成

vm.addEventListener('suspend',function(e){
    console.log(e) // Event {...}
})
媒体播放事件

媒体开始播放

vm.addEventListener('play',function(e){
    console.log(e) // Event {...}
})

媒体暂停播放,用户主动暂停

vm.addEventListener('pause',function(e){
    console.log(e) // Event {...}
})

媒体暂停播放,由于网络原因,因缺少数据而被迫暂停

vm.addEventListener('waiting',function(e){
    console.log(e) // Event {...}
})

媒体播放结束

vm.addEventListener('ended',function(e){
    console.log(e) // Event {...}
})

按压事件

开始按压
<body style="height: 100vh;">
    <script>
        document.addEventListener('touchstart',function(e){
            console.log(e) // TouchEvent {...}
        })
    </script>
</body>
结束按压
document.addEventListener('touchend',function(e){
    console.log(e) // TouchEvent {...}
})
按压时移动
document.addEventListener('touchmove',function(e){
    console.log(e) // TouchEvent {...}
})

表单数据

创建表单数据对象

<body>
    <form id="login">
        <div>
            <label for="uname">账号:</label>
            <input type="text" id="uname" name="uname" value="张三">
        </div>
        <div>
            <label for="upass">密码:</label>
            <input type="password" id="upass" name="upass" value="123">
        </div>
        <div>
            <input type="submit" value="登陆" />
        </div>
    </form>
    <script>
        const loginForm = document.getElementById('login')
        let fd = new FormData(loginForm)
    </script>
</body>

表单数据对象操作

查询数据

查询指定name的数据,返回单一值

console.log(fd.get('uname')) // 张三

查询指定name的数据,返回数组

console.log(fd.getAll('uname')) // ["张三"]

检查是否有指定的name

console.log(fd.has('uname')) // true

获取所有键值对

for(entry of fd.entries()){
    console.log(entry[0],entry[1])
}

追加数据

fd.append('sex','男')

删除数据

fd.delete('uname')

获取所有的键

for(key of fd.keys()){
    console.log(key)
}

获取所有的值

for(value of fd.values()){
    console.log(value)
}

修改或新增数据

fd.set('uname','李四')

上传文件解析

获取上传文件对象

<body>
    <label for="file">头像:</label>
    <input type="file" name="file" id="file" onchange="changeHandle()"/>
    <script>
        function changeHandle(){
            let fileInput = document.getElementById('file')
            let files = fileInput.files
            console.log(files)
        }
    </script>
</body>

查看文件名称

for(file of files){
    console.log(file.name)
}

查看文件类型

for(file of files){
    console.log(file.type)
}

查看文件大小

单位:字节

for(file of files){
    console.log(file.size)
}

查了文件路径

for(file of files){
    console.log(window.URL.createObjectURL(file))
}

媒体操作

播放媒体

<body>
    <video id="vd" src="https://www.w3school.com.cn/i/movie.ogg">
        您的浏览器不支持 video 标签。
    </video>
    <script>
        let vd = document.getElementById('vd')
        vd.play()
    </script>
</body>

暂停播放媒体

vd.pause()

显示媒体控制器

true显示控制器false不显示控制器

vd.controls = true

媒体自动播放

true自动播放false不自动播放

vd.autoplay = true

设置媒体当前播放时间

单位为秒

vd.currentTime = 2

循环播放

true循环 false不循环

vd.loop = true

静音模式

true静音 false不静音

vd.muted = true

音量调节

1音量最大,0音量最小

vd.volume = 0.3

新建一个音量条

<input type="range" min="0" max="1" step="0.01" id="vol">

<script>
const vol = document.getElementById("vol");
vol.addEventListener("input",e=>{
    vm.volume=e.target.value;
})

新建一个进度条

<input type="range" min="0" max="0" step="1" id="time">
<script>
const time = document.getElementById("time")
time.addEventListener("input",e=>{
     vm.currentTime=e.target.value;
})
//数据加载完毕
        vm.addEventListener("loadeddata",e=>{
            //读取总时长
            time.max=vm.duration;
        })

Bootstrap5.3.0

UI级框架,以实现网页界面为主。实现了常规的页面元素,减少css的编写

官网:https://v4.bootcss.com/

安装

在线使用

<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/js/bootstrap.bundle.min.js" integrity="sha384-/mhDoLbDldZc3qpsJHpLogda//BVZbgYuw6kof4u2FrCedxOtgRZDTHgHUhOCVim" crossorigin="anonymous"></script>

下载

npm i bootstrap@5.3.0-alpha1

调用

<link rel="stylesheet" href="./plugins/node_modules/bootstrap/dist/css/bootstrap.css">

<script src="./plugins/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>

内容分类

js包内

bundle——集束包,包含依赖 js

最下面4个包——完整包,不包含依赖 js

基础使用

row col 作用等同于弹性盒子,使内部的内容自动排列(需要给父级加container,不然布局会乱)

<template>
  <div class=" container">
    <div class="row row-cols-5">
        <!-- row-cols-5与col-3只有一个生效,都写就是内侧的生效 -->
        <!-- row-cols-5与col-3必须在同级写row/col才生效 -->
      <dl v-for="item in 12" :key="item" class="col col-3">
        <dt>
          <img src="public/image/a2.png" alt="">
        </dt>
        <dd>北欧集合棉麻收纳筐</dd>
      </dl>
    </div>
  </div>
</template>

Bootstrap 官方图标库

官网:https://icons.bootcss.com/

下载

npm i bootstrap-icons

调用

<link rel="stylesheet" href="./plugins/node_modules/bootstrap-icons/font/bootstrap-icons.min.css">

VUE3

导入

单独导入

https://unpkg.com/vue@3.3.4/dist/vue.global.js

进入该网址后保存至项目 public/plugins/vue@3.3.4/vue.global.js"

基础使用

基础格式

<!-- 挂载点(一个挂载点绑定一个vue实例,vue实例会解释挂载点中的vue语法) -->
    <div id="app">
        {{msg}}
    </div>

    <script src="/public/plugins/vue@3.3.4/vue.global.js"></script>
    <script>
        const {createApp}=Vue;
        //创建vue实例对象
        createApp({
            //数据模型
            data(){
                return{
                    //声明变量
                    msg:"大楚兴,陈胜王!!!"
                }
            },
        //填写方法
        methods: {
        
        },
        //用来写数据计算
        computed:{
        
        },
        })
        //挂载挂载点(将Vue实例与app挂载点进行绑定)
        //一个实例只能绑定一个挂载点
        .mount("#app")
    </script>

main.js注释

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'

//导入组件(自创组件,原本没有)
import VA from '@/components/VA.vue'
import VB from '@/components/VB.vue'
import VC from '@/components/VC.vue'

//根据组件创建实例
const app = createApp(App)

//注册全局组件(注册上面的自创组件)
app.component('VA',VA)
app.component('VB',VB)
app.component('VC',VC)

//加载中间件(插件)
app.use(createPinia())
app.use(router)

//挂载挂载点
app.mount('#app')

指令

指令作用
v-on :(缩写是@)绑定事件
v-if(v-else):控制元素隐藏/显示(从dom中移除或创建)
v-show:控制元素的display样式隐藏/显示(控制样式)
v-model:双向绑定表单元素
v-bind: (缩写是 :)单向把值赋给属性
v-for:循环展示信息
v-html:显示语句时会使标签生效
v-once:只渲染元素一次。随后的重新渲染,元素及其所有的子节点将被视为静态内容并跳过。(可以优化更新性能)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bi9V7Diu-1691948413432)(ea05c4fbc685f76adfb03a600f69f99.png)]

v-html 显示语句时会使标签生效

<div id="app">			//msg:"<b>大楚兴,陈胜王!!!</b>"
        {{msg}}					//<b>大楚兴,陈胜王!!!</b>
        <p v-html="msg"></p>	//大楚兴,陈胜王!!!	(加粗版)
    </div>

v-bind: 拼接字符串,单向把值赋给属性(缩写是 :)

显示图片
<div id="img">
        <!-- 完整写法 -->
        <img v-bind:src="`${img}/${width}/${height}`">
        <!-- 简略写法 -->
        <img :src="`${img}/${width}`">
    </div>
    
    createApp({
            data(){
                return{
                    img:"https://picsum.photos/id/684",
                    width:200,
                    height:100
                }
            }
        })
        .mount("#img")

动态修改样式: :style="isCollapse ? 'left: 64px' : 'left: 122px;'"

v-on :绑定事件(缩写是@)

v-if(v-else):控制元素隐藏/显示(从dom中移除或创建)

v-show:控制元素的display样式隐藏/显示(控制样式)

v-model:双向绑定表单元素

从父组件传数据到子组件:

  • 给子组件添加属性
  • 父组件给子组件的属性赋值

从子组件传数据到父组件:

  • 给子组件添加自定义事件
  • 父组件监听子组件的自定义事件
//获取input的值进行相加计算
<div id="jisuan">
    <input type="text" v-model.number="x">
    <input type="text" v-model.number="y">
    <p>{{x}}+{{y}}={{z}}</p>
</div>

        createApp({
            data(){
                return{
                    x:0,
                    y:0,
                }
            },
            computed:{
                z(){
                    return this.x+this.y
                }
            }
        }).mount("#jisuan")

v-for:循环展示信息

//如果集合不为空,循环显示集合数据
    <div id="app">
        <ul v-if="user && user.length">
        <template v-for="item in user">
            <li>
                {{item.name}}{{item.age}}
            </li>
        </template>
    </ul>
    <div v-else>暂无数据</div>
    </div>

        createApp({
            data(){
                return{
                    user:[
                        {name:"张三",age:20},
                        {name:"李四",age:27},
                        {name:"王五",age:25},
                    ]
                }
            }
        }).mount("#app")

生命周期函数

钩子函数含义
beforeCreateVue实例进行初始化,此时实例的各个组件还没有完全初始化,因此不能访问data、computed、watch、methods的方法和数据,同时,Vue实例的挂载点也没有进行初始化
createdVue实例初始化完成,此时可以访问data、computed、watch、methods的方法和数据,但是依旧没有进行Vue实例的挂载点初始化
beforeMount将实例绑定到模板并进行渲染,但并不会讲实例挂载到页面上
mounted讲渲染好的模板绑定到页面上,此时,Vue实例已完全创建好
beforeUpdate数据变更时执行,在实例数据更改之前执行自定义逻辑或操作
updated将Vue实例更新完成的数据重新渲染到内存中的虚拟DOM中,再讲虚拟DOM应用到页面上
beforeDestroyVue实例进入销毁阶段,此时实例上的data、methods、过滤器、指令等仍处于可用的状态,还没有真正执行销毁的过程(解除与页面DOM元素的绑定)
detroyed实例被销毁(解除Vue实例与页面DOM元素的绑定,但该Vue实例的对象、数据仍然可以使用)
<body>
    <div id="app">
        <button @click="count++">{{count}}</button>
    </div>
    
<script src="/public/plugins/vue@3.3.4/vue.global.js"></script>
<script>
    Vue.createApp({
        data(){
            return{
                count:0
            }
        },
        //钩子函数
        setup(){
            console.log('setup,不能使用this');
            console.log(this);
        },
        beforeCreate(){
            console.log('创建前,不能使用this');
            console.log(this);
        },
        created(){
            console.log('创建后');
            console.log(this);
        },
        beforeMount(){
            console.log('挂载前');
            console.log(this);
        },
        mounted(){
            console.log('挂载后');
            console.log(this);
        },
        //点击按钮触发
        beforeUpdate(){
            console.log('更新前');
            console.log(this);
        },
        updated(){
            console.log('更新后');
            console.log(this);
        },
        beforeUnmount(){
            console.log('解挂前');
            console.log(this);
        },
        unmounted(){
            console.log('解挂后');
            console.log(this);
        },
    }).mount("#app")
</script>

字符串用法

<div id="sex">
      <p>性别:{{sex?"男":"女"}}</p>						//性别:男
      <p>{{hello.split('').reverse().join('')}}</p>		//!!!好你
      <p>{{`VUE:${hello}`}}</p>							//VUE:你好!!!
    </div>
    
createApp({
        data() {
          return {
            sex: 1,
            hello: "你好!!!",
          };
        },
      }).mount("#sex");

调用写法

<div id="app">
      <p>{{msg}}</p>
    </div>
    
const { createApp } = Vue;
      //创建vue实例对象
      const app2=createApp({
        //数据模型
        data() {
          return {
            //声明变量
            msg: "阿达辛苦了出门啦可",				//初始输出结果
          };
        },
        //钩子函数,自动运行
        mounted(){
            //内部调用(经常使用)
            this.msg="畅销书5"						//更改输出结果
        }
      })
        .mount("#app");
        //外部调用(很少使用)
        app2.$data.msg="123"						//再次更改输出结果

导入组件

在目录的src下新建文件夹components用来存储组件,然后主界面调用组件
//导入组件
import VHello from "./components/VHello.vue";
export default {
  //注册局部属性
  components:{
    VHello
  }
};

//然后在需要放组件的位置填写一个标签名,名字为局部属性的名字
<VHello></VHello>

组件间的数据通信

父向子传数据

1.在子组件中定义属性 2.在父组件中给子组件的属性赋值

//在父级调用的组件标签中填写属性名跟属性值
<Vtitle text="待办事项2"></Vtitle>

//在子组件中接收值
<template>
  <h1>{{ text }}</h1>
</template>

<script>
export default {
    props:["text"],
}
</script>

自定义事件

事件修饰符:

1.prevent:阻止默认事件
2.stop: 阻止事件冒泡
3.once:事件只触发一次
4.capture:使用事件的捕获模式:
5.self:只有event.target是当前操作的元素时才触发事件
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

   <div id="root">
    <button @click.prevent="showInfo">按钮</button>
   </div>
<script type="text/javascript">
    new Vue({
        el:"#root",
        data:{
   },
    methods:{
        showInfo(){
            
        }
    }
})    

————————————————
版权声明:本文为CSDN博主「好·好」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yuandawang/article/details/122213080

【插槽】在组件中插入组件

匿名插槽 ,作用相当于占位符

具名插槽,用来插入特定的组件

//主界面写法
<VAaa>
	<VBbb></VBbb>
<VAaa>
//在组件中需要插入的位置加上插槽 <slot>
<template>
    <span>姓名</span><input type="text" :value="name"><br>
    <slot></slot>
    <span>爱好</span><input type="text" :value="loves"><br>
</template>
<!-- App.vue界面 -->
<template>
  <VList2 :data="list">
    <template #default="{item,index}">
      <div>
        <span>{{ index }}</span>
        <span>{{item.name}}</span>
        <span>{{item.age}}</span>
      </div>
    </template>
  </VList2>
</template>

<script setup>
import { ref } from 'vue'
import VList2 from './components/VList2.vue';

const list = ref([
  { id: 1, name: "水岸东方", age: 15 },
  { id: 2, name: "阿萨德", age: 25 },
  { id: 3, name: "搜不到", age: 19 },
])
</script>

<!-- VList2界面 -->
<template>
    <ul>
        <li v-for="(item, index) in data" :key="index">
            <slot :item="item" :index="index">{{ item }}</slot>
        </li>
    </ul>
</template>

<script setup>
import { defineProps } from 'vue'
const $props = defineProps({
    data: {
        type: Array,
        default: () => { },
    }
})
</script>

$emit · $props

声明式属性,是响应式的:

$emit 自定义事件

$props 自定义属性

<script setup>
import { defineProps, defineEmits } from "vue";
const $emit = defineEmits();
const $props = defineProps({
  modelValue: Number,	//设定属性的类型
});
    
const change = (value) => {
  if ($props.modelValue + value >= 1) {
    $emit("update:modelValue", $props.modelValue + value);
  }
};
</script>
<template>
  <div class="number">
    <button @click="change(-1)">-</button>
    <!-- 接收上面的数据与父组件用v-model双向绑定 -->
    <span>{{ modelValue }}</span>			
    <button @click="change(1)">+</button>
  </div>
</template>

属性穿透

useAttrs 透穿属性,非响应式

依赖注入

<!-- App.vue中定义变量的值 -->
<script setup>
import { ref,provide } from 'vue'
//响应式
const proA=ref("valueA");
//提供数据
provide("proA",proA)
</script>

<!-- 在接收数据的组件中填写 -->
<template>
  <div>{{ proA }}</div>
</template>

<script setup>
import { inject } from 'vue'
const proA = inject("proA")

</script>

路由

实现组件间切换,局部刷新

<RouterLink> 作用等同于

导航栏
<!-- App.vue的内容 -->
<template>
  <RouterLink to="/">页头</RouterLink>
  <div>
    <ul>
      <li><RouterLink :to="{name:'HomeView'}">首页</RouterLink></li>
      <li><RouterLink :to="{name:'Riyong'}">日用家居</RouterLink></li>
      <li><RouterLink :to="{name:'Pinpai'}">品牌介绍</RouterLink></li>
      <li><RouterLink :to="{name:'Lipin'}">礼品定制</RouterLink></li>
      <li><RouterLink :to="{name:'Lianxi'}">联系我们</RouterLink></li>
      <li><RouterLink :to="{name:'Qiye'}">企业采购</RouterLink></li>
    </ul>
  </div>

<!-- 路由组件显示的位置(占位符) -->
  <RouterView />

  <RouterLink to="/about">页脚</RouterLink>
</template>
//index.js 的内容
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "@/views/HomeView.vue";
import Riyong from "@/views/Riyong.vue";
import Qiye from "@/views/Qiye.vue";
import Pinpai from "@/views/Pinpai.vue";
import Lianxi from "@/views/Lianxi.vue";
import Lipin from "@/views/Lipin.vue";

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    //path:路径   name:名称    component:功能组件
    { path: "/HomeView", name: "HomeView", component: HomeView, },
      //将路径改成‘/’后,打开页面时HomeView默认显示
      // { path: "/", name: "HomeView", component: HomeView, },
    { path: "/Riyong", name: "Riyong", component: Riyong, },
    { path: "/Qiye", name: "Qiye", component: Qiye, },
    { path: "/Pinpai", name: "Pinpai", component: Pinpai, },
    { path: "/Lianxi", name: "Lianxi", component: Lianxi, },
    { path: "/Lipin", name: "Lipin", component: Lipin, },
    {
      //懒加载
      path: "/ProductDetail", name: "ProductDetail", component: () => import("@/views/ProductDetail.vue"),
    },
  ],
});

export default router;
事件中跳转
import { useRouter } from 'vue-router'
const $router = useRouter()

//跳转到name为Login的组件
$router.push({ name: 'Login' })

点击按钮时,文本内容更换

<div id="sex1">
      <div>{{msg}}</div>
      <button @click="changeMsg">123</button>
    </div>
    
    const sex=createApp({
        data(){
          return{
            msg:"hello"
          }
        },
        methods:{
          getMsg(){
            return this.msg;
          },
          changeMsg(){
            this.msg="456"
          }
        },
      }).mount("#sex1")

表单提交时,密码显示或隐藏

<template>
    <span>密码</span>
    <input :type="show ? 'text' : 'password'">
    <button @click="show = !show">{{ show ? '显示' : '隐藏' }}</button>
</template>
<script setup>
import { defineProps } from 'vue'
const $props = defineProps({
    //属性名:类型 默认值 false
    // show:Boolean,
    show: {
        type: Boolean,
        default:false,
        //必填 true=必填 false=非必填
        //required:false,
        //默认值
        //default:true,
    },
})
</script>

启动项目自动打开页面

在vite.config.js中写入

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  server: {
    //启动后打开浏览器
    open: true,
    //主机
    host: "127.0.0.1",
    //端口
    port: 5173
  }
})

VUE3新特性

    <div id="img">
      <!-- 完整写法(VUE2使用) -->
      <img :src="img1.src" :width="img1.width" :height="img1.height">
      <!-- 简略写法(VUE3新特性) -->
      <img v-bind="img1" />
    </div>
    
    createApp({
        data() {
          return {
            img1: {
              src: "https://picsum.photos/id/685/200/100",
              width: 200,
              height: 100,
            },
          };
        },
      }).mount("#img");

属性穿透

NGINX

反向代理

优点:轻量级,效率高,免费

使用

在写好的项目终端输入npm run build进行打包,然后将dist文件夹内的文件放入nginx目录下的html中,然后在浏览器输入:http://localhost:81/进入

axios

前端拦截器

作用:补全地址;设置请求头;响应拆解,错误统一处理

微信小程序

基础格式

文件目录:

  • pages 页面存放文件夹
    • index
      • index.js

//块级标签
<view>相当于html中的<div>,所有块级组件都可以看成<view>
//行级标签
<text>相当于span

尺寸单位由px换成写rpx,因为不同手机的屏幕像素不一样。(100px相当于200rpx)

app.json是默认配置,页面内的 .json 文件优先度更高

app.json功能设置

{
    //pages字段 —— 用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。
    //可以进行跳转的页面的地址(自动生成)
    "pages": [
        "pages/index/index",
        "pages/home/home"
    ],
    //window字段 —— 定义小程序所有页面的顶部背景颜色,文字颜色定义等。
    //标题设置
    "window": {
        "backgroundTextStyle": "dark",
        "navigationBarBackgroundColor": "#666678",
        "navigationBarTitleText": "地狱",
        "navigationBarTextStyle": "white",
        "enablePullDownRefresh": true		//是否有下拉刷新功能
    },
    //建立一个页面底部导航栏
    "tabBar": {
        "list": [
            {
                //导航文字
                "text": "首页",
                //跳转路径
                "pagePath": "pages/index/index",
                //图标路径
                "iconPath": "/static/images/tabbar/pointer.png",
                //图标激活时的路径
                "selectedIconPath": "/static/images/tabbar/pointer_active.png"
            }
        ]
    },
    "style": "v2",
    "sitemapLocation": "sitemap.json"
}

版本

分为:1.开发版 2.测试版 3.灰度版 4.正式版

灰度版是在正式版的基础上添加了功能,但没有发布,先给部分人进行测试,如果满意度高就正式上线

数据

在页面上显示数据

//js
  data: {
    person: {
      name: "张三", age: 12
    }
  }
//wxml
<template name="person">
  <view  style="margin-top: 200rpx;">		//样式只有这里生效
    <text>姓名{{name}}</text>
    <text>年龄{{age}}</text>
  </view>
</template>
<template is="person" data="{{...person}}"/>

if判断,符合条件就会显示

//js
sex:1
//wxml
<text wx:if="{{sex==0}}">未知</text>
<text wx:elif="{{sex==1}}"></text>
<text wx:else></text>

只要是变量引用,就一定用{{}}包裹。Number和Boolean类型的字面量,也要用{{}}包裹

使用 wx:for-item 可以指定数组当前元素的变量名,

使用 wx:for-index 可以指定数组当前下标的变量名:

//原本
<view wx:for="{{array}}">
  {{index}}: {{item.message}}
</view>
//改后
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
  {{idx}}: {{itemName.message}}
</view>

接收api接口的数据,并给数据集合添加新元素

onLoad() {
    wx.request({
      url: "http://localhost:8888/api/Product?categoryUUID=973b8ecfea690db3676739170deb7c6c",
      method: "GET",
      success: ({ data }) => {
        let productList = data.data.records.map(item => {
          return { ...item, price: Math.trunc(Math.random() * 100), state: 0 };
            //也可以写成
             // item.price=Math.trunc(Math.random() * 100), item.state= 0 
          	// return item;
        })
        this.setData({
          productList: productList
        })
      },
      fail(e) {
        console.log(e);
      },
    })
  },

封装api接口,接收数据

//组件中创建http.js跟api.js
//http.js
exports.http = {
  request(url, method = "GET", data = {}, header = {}) {
    return new Promise((resolve, reject) => {
      wx.request({
        url, method, data, header,
        success(res){
          resolve(res.data.data)
        },
        fail(error) {
          reject(error)
        },
      })
    })
  },
  get(url, data = {}, header = {}) {
    return this.request(url, "GET", data, header,)
  },
  post(url, data = {}, header = {}) {
    return this.request(url, "POST", data, header,)
  },
  put(url, data = {}, header = {}) {
    return this.request(url, "PUT", data, header,)
  },
  del(url, data = {}, header = {}) {
    return this.request(url, "DELETE", data, header,)
  },
}
//api.js
exports.api={
  product:"http://localhost:8888/api/Product",
  article:"http://localhost:8888/api/Article",
}
//接收数据的页面
const { api } = require("../../common/api")
const { http } = require("../../common/http")
Page({
  /**
   * 生命周期函数--监听页面显示
   */
  async onShow() {
    const { records: productList } = await http.get(api.product)
    this.setData({ productList })
  },
})

本地存储

官方文档
小程序提供了读写本地数据缓存的接口,通过wx.setStorage写数据到缓存,在小程序中几乎所有接口都是异步的,这里存储数据也是一个异步操作,如果希望进行同步存储需要调用wx.setStorageSync。

异步存储
wx.setStorage({

  data: {name:"name",age:4},//需要存储的内容。只支持原生类型、Date、及能够通过JSON.stringify序列化的对象。
 
  key: 'list',//本地缓存中指定的 key

})
同步存储
wx.setStorageSync(‘list1’, {name:“name”,age:5})
读取本地数据
在小程序中可以通过wx.getStorage/wx.getStorageSync将数据存储到本地。

异步操作
wx.getStorage({

  key: 'list',
 
  success(res){
 
    console.log(res);
 
  }
 
})

同步操作
const list = wx.getStorageSync(‘list’)
缓存的限制和隔离
小程序宿主环境会管理不同小程序的数据缓存,不同小程序的本地缓存空间是分开的,每个小程序的缓存空间上限为10MB,如果当前缓存已经达到10MB,再通过wx.setStorage写入缓存会触发fail回调。
小程序的本地缓存不仅仅通过小程序这个维度来隔离空间,考虑到同一个设备可以登录不同微信用户,宿主环境还对不同用户的缓存进行了隔离,避免用户间的数据隐私泄露。
由于本地缓存是存放在当前设备,用户换设备之后无法从另一个设备读取到当前设备数据,因此用户的关键信息不建议只存在本地缓存,应该把数据放到服务器端进行持久化存储。
存储
每次当数据发生变化的时候,我们都需要同步一份到storage中,比如增加、删除、勾选。

获取数据
每次加载到这个页面的时候,都从storage中把数据取出来,进行data数据的初始化。

标签使用

使块级容器内的元素带有滚动效果

实现长按文本选中文本内容的效果

使用小程序原本没有的标签

<rich-text nodes="<h1 style='color:red;'>标题</h1>"/>

页面跳转

分为navigator组件的方式和js的方式实现

//wxml中使用
1.<navigator url = "/pages/details/details">跳转到新页面</navigator>
2.<navigator url = "/pages/details/details" open-type = "redirect">跳转到新页面</navigator>
对应 wx.redirectTo 的功能
3.<navigator url = "/pages/details/details" open-type = "switchTab">跳转到新页面</navigator>
对应 wx.switchTab 的功能
4.<navigator url = "/pages/details/details" open-type = "reLaunch">跳转到新页面</navigator>
对应 wx.reLaunch 的功能
5.<navigator url = "/pages/details/details" open-type = "navigateBack">跳转到新页面</navigator>
对应 wx.navigateBack 的功能

在页面跳转时传输数据

<navigator url="/pages/leimu/leimu?id=1"> 在对应页面的js中用下面代码获取id值

//生命周期函数--监听页面加载
  onLoad(options) {
    console.log(options.id);
  },
//js中使用
1.
wx.navigateTo(有返回键,不可以跳转到tabBar页面)
wx.navigateTo({
	url: '/pages/detail/detail?id=1'
})

2.
wx.switchTab (没有返回键,只能跳转到tabBar页面,不可以携带参数)
wx.switchTab({  
  url: `/pages/detail/detail`,
})

3.
wx.reLaunch(跳转任意页面,没有返回键 ,有首页按钮)
 wx.reLaunch({
  url: '/pages/detail/detail'
  })
  
4.
wx.redirectTo(关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面)
wx.redirectTo({
url: `/pages/detail/detail`,
})

5.
wx.navigateBack(关闭当前页面,返回上一页面或多级页面,data值为1,表示跳转上一页,2表示跳两级)
wx.navigateBack({
   delta:1
})

导入

目的:在主页面显示其他文件的内容

导入模版

//主页面
//模版所在的地址
<import src="./a" />
//is后接模板名,data用来传数据
<template is="hear" data="{{user:'张三'}}"></template>

//模板
//name设置模板名,{{user}}用来接收值
<template name="hear">
  <view>12345{{user}}</view>
</template>

导入文件

//主页面
<include src="./a"></include>

//a.wxml
<view>123</view>

瀑布流

自动排列滚动

属性类型默认值必填说明
typestringaligned 。aligned:每行高度由同一行中最大高度子节点决定;masonry:瀑布流,根据子元素高度自动布局布局方式
cross-axis-countnumber2交叉轴元素数量
max-cross-axis-extentnumber0交叉轴元素最大范围
main-axis-gapnumber0主轴方向间隔
cross-axis-gapnumber0交叉轴方向间隔
paddingArray[0, 0, 0, 0]长度为 4 的数组,按 top、right、bottom、left 顺序指定内边距

弹出窗口

image-20230718012350609
//wxml
<button bind:tap="open">显示</button>
<page-container show="{{state}}" round>
  <view style="height: 50vh;">123</view>
  <button bind:tap="close">x</button>
</page-container>

//js
  data: {
    state: false,
  },
  close() {
    this.setData({
      state: false
    })
  },
  open() {
    this.setData({
      state: true
    })
  },

事件

点击事件: bindtap

catchtap 子级的点击事件,点击时不会触发父级的事件

点击弹出提示

wx.showToast({
  title: '成功',
  icon: 'success',
  duration: 2000
})

什么是事件

  • 事件是视图层到逻辑层的通讯方式。
  • 事件可以将用户的行为反馈到逻辑层进行处理。
  • 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
  • 事件对象可以携带额外信息,如 id, dataset, touches。

事件的使用方式

  • 在组件中绑定一个事件处理函数。

bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。

<view id="tapTest" data-hi="Weixin" bindtap="tapName"> Click me! </view>
  • 在相应的Page定义中写上相应的事件处理函数,参数是event。
Page({
  tapName: function(event) {
    console.log(event)
  }
})
  • 可以看到log出来的信息大致如下:
{
  "type":"tap",
  "timeStamp":895,
  "target": {
    "id": "tapTest",
    "dataset":  {
      "hi":"Weixin"
    }
  },
  "currentTarget":  {
    "id": "tapTest",
    "dataset": {
      "hi":"Weixin"
    }
  },
  "detail": {
    "x":53,
    "y":14
  },
  "touches":[{
    "identifier":0,
    "pageX":53,
    "pageY":14,
    "clientX":53,
    "clientY":14
  }],
  "changedTouches":[{
    "identifier":0,
    "pageX":53,
    "pageY":14,
    "clientX":53,
    "clientY":14
  }]
}

使用WXS函数响应事件

基础库 2.4.4 开始支持,低版本需做兼容处理

从基础库版本2.4.4开始,支持使用WXS函数绑定事件,WXS函数接受2个参数,第一个是event,在原有的event的基础上加了event.instance对象,第二个参数是ownerInstance,和event.instance一样是一个ComponentDescriptor对象。具体使用如下:

  • 在组件中绑定和注册事件处理的WXS函数。
<wxs module="wxs" src="./test.wxs"></wxs>
<view id="tapTest" data-hi="Weixin" bindtap="{{wxs.tapName}}"> Click me! </view>
**注:绑定的WXS函数必须用{{}}括起来**
  • test.wxs文件实现tapName函数
function tapName(event, ownerInstance) {
  console.log('tap Weixin', JSON.stringify(event))
}
module.exports = {
  tapName: tapName
}

ownerInstance包含了一些方法,可以设置组件的样式和class,具体包含的方法以及为什么要用WXS函数响应事件,请点击查看详情

事件详解

事件分类

事件分为冒泡事件和非冒泡事件:

  1. 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
  2. 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。

WXML的冒泡事件列表:

类型触发条件最低版本
touchstart手指触摸动作开始
touchmove手指触摸后移动
touchcancel手指触摸动作被打断,如来电提醒,弹窗
touchend手指触摸动作结束
tap手指触摸后马上离开
longpress手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发1.5.0
longtap手指触摸后,超过350ms再离开(推荐使用longpress事件代替)
transitionend会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart会在一个 WXSS animation 动画开始时触发
animationiteration会在一个 WXSS animation 一次迭代结束时触发
animationend会在一个 WXSS animation 动画完成时触发
touchforcechange在支持 3D Touch 的 iPhone 设备,重按时会触发1.9.90

注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 formsubmit事件,inputinput事件,scroll-viewscroll事件,(详见各个组件)

普通事件绑定

事件绑定的写法类似于组件的属性,如:

<view bindtap="handleTap">
    Click here!
</view>

如果用户点击这个 view ,则页面的 handleTap 会被调用。

事件绑定函数可以是一个数据绑定,如:

<view bindtap="{{ handlerName }}">
    Click here!
</view>

此时,页面的 this.data.handlerName 必须是一个字符串,指定事件处理函数名;如果它是个空字符串,则这个绑定会失效(可以利用这个特性来暂时禁用一些事件)。

自基础库版本 1.5.0 起,在大多数组件和自定义组件中, bind 后可以紧跟一个冒号,其含义不变,如 bind:tap 。基础库版本 2.8.1 起,在所有组件中开始提供这个支持。

绑定并阻止事件冒泡

bind 外,也可以用 catch 来绑定事件。与 bind 不同, catch 会阻止事件向上冒泡。

例如在下边这个例子中,点击 inner view 会先后调用handleTap3handleTap2(因为tap事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),点击 middle view 会触发handleTap2,点击 outer view 会触发handleTap1

<view id="outer" bindtap="handleTap1">
  outer view
  <view id="middle" catchtap="handleTap2">
    middle view
    <view id="inner" bindtap="handleTap3">
      inner view
    </view>
  </view>
</view>
互斥事件绑定

自基础库版本 2.8.2 起,除 bindcatch 外,还可以使用 mut-bind 来绑定事件。一个 mut-bind 触发后,如果事件冒泡到其他节点上,其他节点上的 mut-bind 绑定函数不会被触发,但 bind 绑定函数和 catch 绑定函数依旧会被触发。

换而言之,所有 mut-bind 是“互斥”的,只会有其中一个绑定函数被触发。同时,它完全不影响 bindcatch 的绑定效果。

例如在下边这个例子中,点击 inner view 会先后调用 handleTap3handleTap2 ,点击 middle view 会调用 handleTap2handleTap1

<view id="outer" mut-bind:tap="handleTap1">
  outer view
  <view id="middle" bindtap="handleTap2">
    middle view
    <view id="inner" mut-bind:tap="handleTap3">
      inner view
    </view>
  </view>
</view>
事件的捕获阶段

自基础库版本 1.5.0 起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用capture-bindcapture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。

在下面的代码中,点击 inner view 会先后调用handleTap2handleTap4handleTap3handleTap1

<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">
  outer view
  <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
    inner view
  </view>
</view>

如果将上面代码中的第一个capture-bind改为capture-catch,将只触发handleTap2

<view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2">
  outer view
  <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
    inner view
  </view>
</view>
事件对象

如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。

BaseEvent 基础事件对象属性列表:

属性类型说明基础库版本
typeString事件类型
timeStampInteger事件生成时的时间戳
targetObject触发事件的组件的一些属性值集合
currentTargetObject当前组件的一些属性值集合
markObject事件标记数据2.7.1

CustomEvent 自定义事件对象属性列表(继承 BaseEvent):

属性类型说明
detailObject额外的信息

TouchEvent 触摸事件对象属性列表(继承 BaseEvent):

属性类型说明
touchesArray触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouchesArray触摸事件,当前变化的触摸点信息的数组

特殊事件: canvas 中的触摸事件不可冒泡,所以没有 currentTarget。

type

代表事件的类型。

timeStamp

页面打开到触发事件所经过的毫秒数。

target

触发事件的源组件。

属性类型说明
idString事件源组件的id
datasetObject事件源组件上由data-开头的自定义属性组成的集合

currentTarget

事件绑定的当前组件。

属性类型说明
idString当前组件的id
datasetObject当前组件上由data-开头的自定义属性组成的集合

说明: target 和 currentTarget 可以参考上例中,点击 inner view 时,handleTap3 收到的事件对象 target 和 currentTarget 都是 inner,而 handleTap2 收到的事件对象 target 就是 inner,currentTarget 就是 middle。

dataset

在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。

在 WXML 中,这些自定义数据以 data- 开头,多个单词由连字符 - 连接。这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如:

  • data-element-type ,最终会呈现为 event.currentTarget.dataset.elementType
  • data-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype

示例:

<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>
Page({
  bindViewTap:function(event){
    event.currentTarget.dataset.alphaBeta === 1 // - 会转为驼峰写法
    event.currentTarget.dataset.alphabeta === 2 // 大写会转为小写
  }
})

mark

在基础库版本 2.7.1 以上,可以使用 mark 来识别具体触发事件的 target 节点。此外, mark 还可以用于承载一些自定义数据(类似于 dataset )。

当事件触发时,事件冒泡路径上所有的 mark 会被合并,并返回给事件回调函数。(即使事件不是冒泡事件,也会 mark 。)

代码示例:

在开发者工具中预览效果

<view mark:myMark="last" bindtap="bindViewTap">
  <button mark:anotherMark="leaf" bindtap="bindButtonTap">按钮</button>
</view>

在上述 WXML 中,如果按钮被点击,将触发 bindViewTapbindButtonTap 两个事件,事件携带的 event.mark 将包含 myMarkanotherMark 两项。

Page({
  bindViewTap: function(e) {
    e.mark.myMark === "last" // true
    e.mark.anotherMark === "leaf" // true
  }
})

markdataset 很相似,主要区别在于: mark 会包含从触发事件的节点到根节点上所有的 mark: 属性值;而 dataset 仅包含一个节点的 data- 属性值。

细节注意事项:

  • 如果存在同名的 mark ,父节点的 mark 会被子节点覆盖。
  • 在自定义组件中接收事件时, mark 不包含自定义组件外的节点的 mark
  • 不同于 dataset ,节点的 mark 不会做连字符和大小写转换。
touches

touches 是一个数组,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。

Touch 对象
属性类型说明
identifierNumber触摸点的标识符
pageX, pageYNumber距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
clientX, clientYNumber距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
CanvasTouch 对象
属性类型说明特殊说明
identifierNumber触摸点的标识符
x, yNumber距离 Canvas 左上角的距离,Canvas 的左上角为原点 ,横向为X轴,纵向为Y轴
changedTouches

changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。

detail

自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。

点击事件的detail 带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。

组件

组件样式:

组件的样式具有穿透能力,建议使用class选择器;id选择器在组件内无效,但是可以向上穿透

:host 给整个组件加样式(前面不要加东西)

组件使用

1.在文件夹根目录新建 components 文件夹,在其内部再建一个文件夹,右键点击新建 component组件。

2.在需要调用该组件的页面的json文件中写入组件的路径

  "usingComponents": {
  	//组件名			组件路径
    "my-component":"/components/my-component/my-component"
  }

3.页面传值

<my-component age="{{10}}" name="张三" sex="{{1}}"></my-component>

//组件接收
<view>{{name}}</view>
<view>{{sex}}</view>
<view>{{age}}</view>

4.双向绑定

//组件的js中定义数据
properties: {
    name: {
      type: String,
      value: "qwe",
    },
    sex: {
      type: Number,
      value: 10,
    },
  },
//组件页面
<input type="text" model:value="{{name}}"/>
<input type="text" model:value="{{sex}}"/>
//接收数据的页面
<my-component model:sex="{{sex}}" model:name="{{name}}"></my-component>

虚拟化

为了使书写样式更加方便,解决页面结构与实际结构不一致的问题

文件上传

wx.chooseMedia(Object object) 拍摄或从手机相册中选择图片或视频。 文档

//获取图片
  getimg() {
    //选择头像
    wx.chooseMedia({
      mediaType: ['image'],
      sourceType: ['album', 'camera'],
      success: ({ tempFiles }) => {
        const [{ tempFilePath }] = tempFiles;
        this.setData({
          avatar: tempFilePath,
        })
        //上传头像
        wx.uploadFile({
          filePath:tempFilePath,
          name: 'file',
          url: 'api.upload',
          async success({data}){
            //修改头像
            await http.post(api.user,{avatar:JSON.parse(data).data})
          }
        })
      }
    })
  },

获取用户地址

//json文件
"requiredPrivateInfos": [
    "getLoaction"
  ],
  "permission": {
    "scope.userLocation": {
      "desc": "请求获取您的当前位置"
    }
  }

地图添加

\1. 在小程序的页面文件(.wxml)中添加以下代码:

<view class="map-container">
  <map
    id="myMap"
    longitude="{{longitude}}"
    latitude="{{latitude}}"
    scale="{{scale}}"
    markers="{{markers}}"
    show-location="{{true}}"
    bindmarkertap="markerTap"
    bindcontroltap="controlTap"
    bindregionchange="regionChange"
  ></map>
</view>
  

\2. 在页面的样式文件(.wxss)中添加以下代码:

.map-container {
  margin-top: 30rpx;
  width: 80vw;
  border: 1rpx solid #afafaf;
  margin: auto;
  border-radius: 30rpx;
  background-color: #fff;
  padding: 30rpx;
  margin-bottom: 20rpx;
}

.map-container map {
  width: 100%;
  height: 100%;
}

\3. 在页面的逻辑文件(.js)中添加以下代码:

Page({
  data: {
    longitude: 0, // 地图中心经度
    latitude: 0, // 地图中心纬度
    scale: 16, // 缩放级别
    markers: [] // 地图标记点
  },

  onLoad: function() {
    // 获取用户当前位置
    wx.getLocation({
      type: 'gcj02',
      success: (res) => {
        this.setData({
          longitude: res.longitude,
          latitude: res.latitude
        });
      }
    });
  },

  onReady: function() {
    // 创建地图上的标记点
    const marker = {
      id: 1,
      latitude: 0, // 标记点纬度
      longitude: 0, // 标记点经度
      title: '标记点标题',
      iconPath: '/images/marker.png', // 标记点图标路径
      width: 30, // 标记点图标宽度
      height: 30 // 标记点图标高度
    };

    this.setData({
      markers: [marker]
    });
  },

  markerTap: function(e) {
    console.log('点击了标记点', e);
  },

  controlTap: function(e) {
    console.log('点击了控件', e);
  },

  regionChange: function(e) {
    console.log('视野发生变化', e);
  }
});

请注意,你需要将 longitudelatitude 设置为你希望地图的初始中心位置的经纬度。同时,你还可以根据需要自定义标记点的经纬度、图标等属性。

uni-app

条件编译

条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。

**写法:**以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。

  • #ifdef:if defined 仅在某平台存在
  • #ifndef:if not defined 除了某平台均存在
  • %PLATFORM%:平台名称
条件编译写法说明
#ifdef APP-PLUS 需条件编译的代码 #endif仅出现在 App 平台下的代码
#ifndef H5 需条件编译的代码 #endif除了 H5 平台,其它平台均存在的代码
#ifdef H5 || MP-WEIXIN 需条件编译的代码 #endif在 H5 平台或微信小程序平台存在的代码(这里只有||,不可能出现&&,因为没有交集)

%PLATFORM% 可取值如下:

生效条件
VUE3HBuilderX 3.2.0+ 详情
APP-PLUSApp
APP-PLUS-NVUE或APP-NVUEApp nvue 页面
APP-ANDROIDApp Android 平台 仅限 uts文件
APP-IOSApp iOS 平台 仅限 uts文件
H5H5
MP-WEIXIN微信小程序
MP-ALIPAY支付宝小程序
MP-BA
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值