网站seo优化建议,怎样设计静态网站页面,河南网站排名优化价格,西安网站制作!-- HTML --
HTML是超文本标记语言
1、html常用标签
块级标签 独占一行 可以设置宽度#xff0c;高度#xff0c;margin,padding 宽度默认所在容器的宽度
标签作用table定义表格h1 ~ h6定义标题hr定义一条水平线p定义段落li标签定义列表项目ul定义无序列表ol定…!-- HTML --
HTML是超文本标记语言
1、html常用标签
块级标签 独占一行 可以设置宽度高度margin,padding 宽度默认所在容器的宽度
标签作用table定义表格h1 ~ h6定义标题hr定义一条水平线p定义段落li标签定义列表项目ul定义无序列表ol定义有序列表div定义文档中的分区或节form创建 HTML 表单
table标签
table border1 cellpadding0 cellspacing0 width500 height249thead trth序号/ththname/th/tr/theadtbodytrtd1/tdtd枫枫/td/trtrtd2/tdtd张三/td/tr/tbody
/table
!--align属性名属性值为left center right规定表格相对周围元素的对齐方式--
!--border属性名属性值1或,规定表格是否有边框默认为表示没有边框--
!--cellpadding属性名属性值像素值,单元格内容和边框之间的空白默认为1--
!--cellspacing属性名属性值像素值,单元格和单元格之间的距离默认为2--
!--width属性名属性值像素值或百分比,规定表格的宽度--
!--height属性名属性值像素值或百分比,规定表格的高度--
列表标签
有缩进 有序标签可以通过type属性设置
!-- 可以选择:i A 1 a I --
ol typeIli有序/lili标签/li/ol
form标签
form action/xxx methodget nameform1!-- action提交地址 method提交方式--input namenameinput value提交 typesubmit/input typesubmit提交/forminput value重置 typereset/
/form
属性描述accept-charset规定在被提交表单中使用的字符集默认页面字符集action规定向何处提交表单的地址URL提交页面autocomplete规定浏览器应该自动完成表单默认开启enctype规定被提交数据的编码默认url-encodedmethod规定在提交表单时所用的 HTTP 方法默认GETname规定识别表单的名称对于 DOM 使用document.forms.namenovalidate规定浏览器不验证表单target规定 action 属性中地址的目标默认_self
行内标签 与其他行内元素并排 设置宽高无效 默认的宽度就是文本内容的宽度 水平方向的 padding 和 margin 属性可以使用。 只能容纳文本级元素和内联元素
标签作用a标签定义超链接span组合文档中的行内元素br定义换行b定义字体缩写label标签表单标签input textarea selectimg图片
a标签
a href target_blank新标签页打开/a
a href download下载/a
a href downloada1.png会用a1.png作为名字进行下载/a
target _blank 表示在新标签页中打开目标网页 _self 表示在当前标签页中打开目标网页
download用于下载
input标签
type属性值表现形式对应代码text单行输入文本input typetext /password密码输入框 date日期输入框 checkbox复选框input typecheckbox namesg1 valuepg苹果radio单选框input typeradio namesg valuepg苹果submit提交按钮 reset重置按钮 button普通按钮 hidden隐藏输入框 file文本选择框
属性说明 name表单提交时的 键注意和id的区别 value表单提交时对应项的值 typebutton, reset, submit时为按钮上显示的文本内容 typetext,password,hidden时为输入框的初始值 typecheckbox, radio, file为输入相关联的值 checkedradio和checkbox默认被选中的项 readonlytext和password设置只读 disabled禁用所有input均适用
label标签中的for属性会和input中的id关联
label foruser用户名/label
input typetext placeholder请输入 valuezard namename
input placeholder请输入用户名 iduser
input typepasswordlabel forfile选择文件/label
input idfile styledispaly: none typefile
select(下拉)标签
select nameuseroption value1枫枫/optionoption value2张三/optionoption value3王五/option
/select
可设置 multiple 表示可多选
img标签
img src图片的路径 alt图片未加载成功时的提示 title鼠标悬浮时提示信息 width宽 height高(宽高两个属性只用一个会自动等比缩放)
span和div
span是行内标签中的默认标签
div是块级标签中的默认标签
方便去通过css设置样式
2、相对路径与绝对路径
文件的相对路径和绝对路径
相对路径
img src./avatar.png alt
img srcavatar.png alt绝对路径
img srcG:\IT\前端项目\qianduan_study\html\avatar.png alt
web中相对路径和绝对路径
相对路径
form actionxxxinput typesubmit value提交
/form绝对路径
form action/xxxinput typesubmit value提交
/form
// 相对路径
http://localhost:63342/qianduan_study/html/4.%E7%9B%B8%E5%AF%B9%E8%B7%AF%E5%BE%84%E5%92%8C%E7%BB%9D%E5%AF%B9%E8%B7%AF%E5%BE%84.html
提交 地址 变成了
http://localhost:63342/qianduan_study/html/xxx?
// 绝对路径
http://localhost:63342/qianduan_study/html/4.%E7%9B%B8%E5%AF%B9%E8%B7%AF%E5%BE%84%E5%92%8C%E7%BB%9D%E5%AF%B9%E8%B7%AF%E5%BE%84.html
提交 地址 变成了
http://localhost:63342/xxx? !-- css --
css引入方式 外部引入 link relstylesheet hrefindex.css 内部样式 行内样式
层叠样式表 优先级权重最重要 同级后面的会覆盖前面的
1、css选择器
id选择器
特点id是唯一的不能重复
div idbox/div
#box{}
类选择器
div classbox/div
.box{}
标签选择器
div idbox/div
div{}
属性选择器 []
div idbox /div
a hrefhttps://www.baidu.com/a
div[idbox]{}
a[href]{}
a[hrefhttps://www.baidu.com]{}
通用选择器
给网页元素做一些通用的样式margin:0和padding:0用来清除自带网页的内外间距。
*{margin: 0;padding: 0;
}
并集选择器 ,
#box,#xxx{}
交集选择器
div idbox classxxx/div
#box.xxx{}
后代选择器
div idboxdiv classsubdiv classs1/div/div
/div
.box .s1 {}
子选择器
div idboxdiv classsubdiv classs1/div/div
/div
.box.sub.s1{}
相邻兄弟选择器 -
兄弟只能从上往下选
div classs1/div
div classs2/div
div classs3/div
.s1.s2{}
普通兄弟选择器 ~
div classs1/div
div classs2/div
div classs3/div
.s1~.s3{}
伪类选择器 hover nth-child() styleul li:nth-child(2){color: red;}/* 参数edd是奇数行even是偶数行还可以写表达式2n1 */
/style
ulli1/lili2/li
/ul first-child last-child
否定伪类选择器 :not() style.notdiv:not(.n){font-size:30px;}
/style
div classnotdiv classn123/divdiv123/div
/div
伪元素选择器 before after !-- 加的伪元素不能被选中 --
style.mys::after{content: ;width: 20px;height: 20px;background: blue;display: block; /*inline-block*/}.mys::before{content: 之前;}
/style
div classmys这是微元素
/div
优先级
!important 内联选择器 ID选择器 类选择器 属性选择器 伪类 元素选择器 通配符选择器 继承选择器
/* !important 可以更改内联样式 */
.li{color: green!important;
}
2、css盒模型
*盒子宽度模式
*{box-sizing: border-box; /* 盒子的宽度模式content-box */
}
*display none不显示 block块盒上下的margin会合并 inline行盒设置之后width、height变成无效 inline-block行内块设置后和inline一样不过可设置宽高 flex布局 grid布局
padding
padding-left: 20px;
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
/*四个就是 上 右 下 左;三个就是 上 左右 下;两个就是 上下 左右 */
padding: 20 10 30 40;
margin
基本设置同padding类似
但是margin有auto属性 学flex的时候再说
块盒上下的margin会合并
border
border-width
border-style
/* solid实线;dashed虚线;dotted点线;double双实线 */
border-color
border-left-color: blue;border: 10px solid red;
border-radius: 5px; /* 圆角上右下左 */
border-radius: 50%; /* 圆形 */
设置三角形
只需要给盒子的宽度设置为零然后设置某一个边的宽度和颜色即可
.box{width: 0;height: 0;border-width: 20px;border-style: solid;border-bottom-color: aqua;border-right-color: aquamarine;border-top-color: antiquewhite;border-left-color: blueviolet; /* 需要什么样的三角形就让其他的三角形颜色是透明的 transparent; 透明色 */
} outline 设置
轮廓线属性和border类似 不占用盒子的宽度 只能设置整个的没有单个方向的
3、css定位
值描述absolute生成绝对定位的元素相对于 static 定位以外的第一个父元素进行定位。元素的位置通过 left, top, right 以及 bottom 属性进行规定fixed生成固定定位的元素相对于浏览器窗口进行定位。元素的位置通过 left, top, right以及 bottom属性进行规定relative生成相对定位的元素相对于其正常位置进行定位。因此left:20 会向元素的 LEFT 位置添加 20 像素static默认值。没有定位元素出现在正常的流中忽略 top, bottom, left, right 或者 z-index 声明sticky粘性定位。根据用户的滚动位置进行定位
相对定位 relative 相对元素之前的位置 之前的位置还在文档流中
style.box{display: inline-block;width: 100px;height: 100px;background: aquamarine;position: relative;left: 100px;top: 100px;}.sub{width: 40px;height: 40px;background: red;position: relative;left: 70px;top: 60px;}
/style
body相对定位相对定位 div classboxdiv classsub/div/div 相对定位相对定位相对定位
/body
绝对定位 absolute 脱离文档流 找父级非static的元素进行偏移找不到就层层往上直到body
style.box{display: inline-block;width: 100px;height: 100px;background: aquamarine;position: absolute;right: 100px;top: 100px;}.sub{width: 40px;height: 40px;background: red;position: absolute;left: 70px;top: 60px;}
/style
body相对定位相对定位 div classboxdiv classsub/div1234/div 相对定位相对定位相对定位
/body
固定定位 fixed 脱离文档流 以浏览器为参照
style.box{display: inline-block;width: 100%;height: 60px;background: rgba(0,0,0, 0.5);position: fixed;top: 0;left: 0;}body{height: 2000px;}
/style
body相对定位相对定位 div classbox/div相对定位相对定位相对定位
/body
粘性定位 sticky
粘性定位的元素是依赖于用户的滚动它的行为就像 position:relative; 而当页面滚动超出目标区域时它的表现就像 position:fixed;它会固定在目标位置元素定位表现为在跨越特定阈值前为相对定位之后为固定定位 占据原来的位置 以浏览器为参考
style.d1{height: 40px;width: 40px;background: #b81cc9;position: sticky;top: 100px;}
/style
bodydiv classd1/div
/body
z-index
图层概念 只能在定位元素上生效 父子关系z-index不生效
.c1{position: relative;width: 100px;height: 100px;background-color: blueviolet;top: 50px;z-index: 1;
}
.c2{position: relative;width: 100px;height: 100px;background-color: #2be274;left: 50px;
}
4、css背景设置
背景图片
.bg {width: 100%;height: 200px;background-image: url(https://profile-avatar.csdnimg.cn/392dc034291241239877635a77987f39_m0_65534674.jpg!1);background-size: 50px; /* cover占满、contain保证图片一定在盒子里面 */
}
背景尺寸
background-size: contain; /* 保证图片一定在盒子里面 */
background-size: cover; /* 占满 */
background-size: 100% 50%; /* 背景图像宽度为元素宽度高度为元素高度的一半 */
background-size: 300px auto; /* 背景图像宽度固定为300px高度自动调整 */
背景平铺
background-repeat: no-repeat /*不平铺*/
background-repeat: repeat-x /*横向平铺*/
background-repeat: repeat-y /*纵向平铺*/
background-repeat: repeat /*双向平铺默认*/
图片位置
background-position: left bottom; /* 左上右上右下中心 */
background-position: 10px 20px; /* 从左上角开始算 */
雪碧图
把多个小图片合到一个大图片里面然后通过css图片定位方式把图片显示出来 哔哩哔哩
.bg {width: 40px;height: 40px;background-image: url(https://image.fengfengzhidao.com/rj_0731/20240618113057.png);background-position: -10px -266px;background-repeat: no-repeat;
}
渐变
好看的渐变色网站
线性渐变
body{width: 100%;height: 100hv;margin: 0;background-image: linear-gradient(to top, #a18cd1 0%, #fbc2eb 100%);
}
表示方位
to top /* 从下往上进行渐变 */
to bottom /* 从上往下进行渐变 */
to right /* 从左往右进行渐变 */
to left /* 从右往左进行渐变 */
to top left /* 从右下向左上进行渐变(top和left可以交换位置下同) */
to top right /* 从左下向右上进行渐变 */
to bottom left /* 从右上向左下进行渐变 */
to bottom right /* 从左上向右下进行渐变 */
60peg /* 使用角度表示, 90deg等同于to right */
径向渐变
.radial{width: 300px;height: 300px;background-image: radial-gradient(#a18cd1 0%, #fbc2eb 100%);
}
/* 圆形 */
background-image: radial-gradient(circle, red, blue);
/* 椭圆形 */
background-image: radial-gradient(ellipse, red, blue);
/* 重复 */
background-image: repeating-radial-gradient(red, yellow 10%, green 20%); 边框渐变
.border{width: 300px;height: 300px;border: 20px solid;border-image: linear-gradient(to bottom right, yellow, green) 1 1 1 1; /* 内向偏移量 上右下左1110左边没边框 */
}
文字渐变
display: inline-block; /* 宽度变成文字宽度 */
font-size: 30px;
background-image: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
5、css文字设置
字体样式
font-style 可继承
font-style: italic /* 显示一个斜体的字体样式 */
font-style: oblique /* 显示一个倾斜的字体样式 */
font-style: normal /* 默认值, 正常字体 */
text-decoration 文本的划线 可继承
text-decoration: none /* 不画线并删除任何现有的装饰 */
text-decoration: underline /* 下划线 */
text-decoration: line-through /* 中划线 */
text-decoration: overline /* 上划线 */
/* 也可以设置宽度和颜色 */
text-decoration: underline 10px coral;
font-weight 可继承
font-weight:bold;
text-indent 文本缩进 可继承
/* 首行缩进2字符 */
text-indent: 2rem;
text-transform 大小写控制 可继承
text-transform: capitalize /* 首字母大写 */
text-transform: uppercase /* 大写 */
text-transform: lowercase /* 小写 */
text-transform: none /* 正常 */
间距
line-height 行间距 可继承
/*1.5倍行距*/
line-height: 1.5rem;
letter-spacing 字符间距 可继承
letter-spacing: 2rem;
word-spacing 单词间距 可继承
word-spacing: 1rem;
空白处理
white-space 可继承
white-space: nowrap; /* 强制在一行中显示 会出现横向滚动条 */
white-space: pre /* 换行和空格保留 */
white-space: normal /* 自动换行 */
超出显示省略号
单行超出显示省略号
/*不换行*/
white-space: nowrap;
/*溢出隐藏*/
overflow: hidden;
/*显示省略号*/
text-overflow: ellipsis;
多行超出显示省略号
/*溢出隐藏*/
overflow: hidden;
/*显示省略号*/
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
/*设置显示文本的行数*/
-webkit-line-clamp: 4;
文本对齐
text-align 水平对齐 可继承 对行内元素无效行内块需要设置宽度
text-align: left /* 左对齐 */
text-align: center /* 居中对齐 */
text-align: right /* 右对齐 */
vertical-align 垂直对齐 对行内元素或者行内块元素有效
vertical-align: bottom
/* sub设置文本为下标super设置文本为上标 top与顶端对齐 text-bottom与低端对齐 */
经常用于设置图片或者表单(行内块元素和文字垂直对齐 div classlinespan这是文字/spanimg width100 srchttps://img0.baidu.com/it/u2426072799,1960439289fm253app120sizew931n0fJPEGfmtauto?sec1718816400t94b5bbee4836daa4206bfecc6c0baf4b altspan这是文字/span
/div vertical-align: bottom; 字体设置
font-family 可继承
/* 可以设置多个字体第一个没有就找后面的 */
font-family: 宋体, 方正舒体;
导入字体
用 font-face 导入
font-face {src: url(./ZiXiaoHunLiLiangCuHeiTi(ShangYongXuShouQuan)-2.ttf);font-family: xxx;
}
.line {font-family: xxx;
}
6、css变换与动画
变换 transform
使用变换之后这个原来的位置还在文档流里
只作用于块和行内块可以多个属性共存
平移 translate
transform: translate(x, y);
旋转 rotate
transform: rotate(60deg);
缩放 scale
transform: scale(1.2);
/* 缩放可以破除浏览器12px最小字体大小的限制 */
锚点
主要这对于缩放和旋转
transform-origin: left top;
过渡
transition属性包括以下几个子属性 transition-property指定要过渡的CSS属性名称可以使用通配符 all 表示所有属性都要过渡 transition-duration指定过渡的持续时间单位可以是秒s或毫秒ms transition-timing-function指定过渡的时间函数用于控制过渡的速度曲线常见的值有 ease、linear、ease-in、ease-out、ease-in-out 等 transition-delay指定过渡的延迟时间即过渡开始前等待的时间单位可以是秒s或毫秒ms
.line{display: inline-block;transition: transform 1s; /* all 1s; */transform-origin: right top;
}
.line:hover{transform: scale(1.2);
}
动画
创建动画序列需要使用 animation 属性或其子属性该属性允许配置动画时间、时长以及其他动画细节但该属性不能配置动画的实际表现动画的实际表现是由 keyframes 规则实现
属性描述animation-name指定由 keyframes 描述的关键帧名称animation-duration设置动画一个周期的时长animation-delay设置延时animation-direction设置动画在每次运行完后是反向运行还是重新回到开始位置重复运行animation-iteration-count设置动画重复次数 可以指定 infinite 无限次重复动画animation-play-state允许暂停和恢复动画animation-timing-function设置动画速度 即通过建立加速度曲线设置动画在关键帧之间是如何变化animation-fill-mode规定元素在不播放动画时的样式在开始前、结束后或两者同时 /*
div classtagsdiv classbox/div
/div
*/
.tags {position: relative;width: 400px;height: 400px;background: rosybrown;
}
.box {position: absolute;width: 20px;height: 20px;background: blue;animation-name: move_box; /* 指定由keyframes描述的关键帧名称 */animation-duration: 5s; /* 执行一次动画的时长 */animation-iteration-count: infinite; /* 循环播放 */
}
.tags:hover .box{animation-play-state: paused; /* 允许暂停和恢复动画 */
}
keyframes move_box {0% {left: 0;top: 0;}25% {left: calc(100% - 20px);top: 0;}50% {left: calc(100% - 20px);top: calc(100% - 20px);}75% {left: 0;top: calc(100% - 20px);}100% {left: 0;top: 0;}
}
/* div classbox/div */
keyframes box_move {0% {transfrom: translate(0, 0);}100% {transfrom: translate(1000px, 0);}
}
.box{width: 40px;height: 40px;background-color: #800e0e;animation-name: move_box; /* 指定由keyframes描述的关键帧名称 */animation-duration: 5s; /* 执行一次动画的时长 */animation-iteration-count: infinite; /* 循环播放 */
}
7、css中的flex布局
Flexbox 布局也叫 Flex 布局弹性盒子布局
它决定了元素如何在页面上排列使它们能在不同的屏幕尺寸和设备下可预测地展现出来更简便、完整、响应式地实现各种页面布局
它的主要思想是使父元素能够调整子元素的宽度、高度、排列方式从而更好的适应可用的布局空间 采用 Flex 布局的元素称为 Flex 容器flex container简称容器
它的所有 子元素自动成为容器成员称为 Flex 项目flex item简称项目
容器属性
flex-direction 主轴方向
决定主轴的方向即项目的排列方向
属性值含义row默认值主轴为水平方向水平布局起点在左端从左向右排列row-reverse主轴为水平方向水平布局起点在右端从右向左排列column主轴为垂直方向垂直布局起点在上沿从上往下排列column-reverse主轴为垂直方向垂直布局起点在下沿从下往上排列
justify-content 对齐方式
定义了项目在主轴上的对齐方式
属性值含义flex-start默认值左对齐flex-end右对齐center居中space-between两端对齐项目之间的间隔都相等space-around每个项目两侧的间隔相等。所以项目之间的间隔比项目与边框的间隔大一倍space-evenly均匀排列每个元素
align-items 交叉轴对齐方式
定义项目在交叉轴的对齐方式
属性值含义flex-start交叉轴的起点对齐flex-end交叉轴的终点对齐center交叉轴的中点对齐baseline项目的第一行文字的基线对齐stretch默认值 如果项目未设置高度或设为auto将占满整个容器的高度
flex-wrap 换行
默认情况下项目都排在一条线又称轴线上。flex-wrap属性定义如果一条轴线排不下如何换行
属性值含义nowrap默认值表示不换行wrap换行wrap-reverse换行第一行在下方
flex-flow
flex-flow 属性是 flex-direction 和 flex-wrap 主轴方向和换行的复合属性
flex-flow: row wrap;
align-content
属性和align-items交叉轴对齐方式一样但是多了space-的设置
align-content适用于多行情况
项目属性
order 排序
order属性用来定义项目的排列顺序。数值越小排列越靠前默认为 0
style.flex1{margin-top: 20px;width: 400px;background-color: #f6bcbe;display: flex;}.flex1 .item{order: 10;}
/style
div classflex1div classitem1/divdiv classitem2/divdiv classitem3/divdiv classitem styleorder: 14/div
/div
flex-grow 放大比例
flex-grow属性定义项目的放大比例默认为 0 即如果存在剩余空间也不放大
style.flex1{margin-top: 20px;width: 400px;background-color: #f6bcbe;display: flex;}.flex1 .item{margin: 1px;}
/style
div classflex1div classitem1/divdiv classitem2/divdiv classitem3/divdiv classitem styleflex-grow: 24/div!-- 按剩余空间大小侵占 --
/div
flex-shrink
flex-shrink属性定义了项目的缩小比例默认为 1 即如果空间不足该项目将缩小
style.flex1{margin-top: 20px;background-color: #f6bcbe;display: flex;}.flex1 .item{width: 100px;margin: 1px;}
/style
div classflex1div classitem styleflex-shrink: 01/div !-- 缩小到一定程度就不缩小了 --div classitem2/divdiv classitem3/divdiv classitem styleflex-grow: 24/div!-- 按剩余空间大小侵占 --
/div
flex-basis 设置宽 如果 flex-basis 的值不是 autowidth 属性会被忽略 flex-basis属性定义了在分配多余空间之前项目占据的主轴空间main size。浏览器根据这个属性计算主轴是否有多余空间。它的默认值为auto即项目的本来大小
它的初始值是 auto此时浏览器会检查元素是否设置了 width 属性值
如果有则使用 width 的值作为 flex-basis 的值
如果没有则用元素内容自身的大小
如果 flex-basis 的值不是 autowidth 属性会被忽略
flex
flex属性是flex-grow, flex-shrink 和 flex-basis的简写默认值为0 1 auto。后两个属性可选
.item {flex:0 1 auto;
}
.item {flex-grow: 0;flex-shrink: 1;flex-basis: auto;
}
align-self
align-self属性允许单个项目有与其他项目不一样的对齐方式可覆盖align-items属性。默认值为auto表示继承父元素的align-items属性如果没有父元素则等同于stretch
style.flex1{margin-top: 20px;background-color: #f6bcbe;display: flex;}.flex1 .item{width: 100px;margin: 1px;}
/style
div classflex1div classitem styleflex-shrink: 01/div !-- 缩小到一定程度就不缩小了 --div classitem stylealign-self: center2/divdiv classitem3/divdiv classitem styleflex-grow: 24/div!-- 按剩余空间大小侵占 --
/div
flex与margin auto
之前埋了一个关子在学习margin的时候。它有一个auto属性需要到flex才能用到
style.flex1{margin-top: 20px;width: 400px;background-color: #f6bcbe;display: flex;/* justify-content: space-between; */}.flex1 .item:nth-child(2){margin: 0 auto;}
/style
div classflex1div classitem1/div div classitem2/divdiv classitem3/div
/div
8、css中的grid布局
Flex 布局是轴线布局只能指定“项目”针对轴线的位置可以看作是一维布局
Grid 布局则是将容器划分成“行”和“列”产生单元格然后指定项目所在的单元格可以看作是二维布局。Grid 布局远比 Flex 布局强大
一般情况下在处理某一行的元素的布局时使用flex布局在处理多行的元素布局时使用grid布局
grid解决 如果使用flex要实现类似这样的布局是很麻烦的
需要去算盒子的宽度和中间的间隔
stylebody {margin: 0;}.flex {background-color: #f0eeee;width: 600px;display: flex;flex-wrap: wrap;/* justify-content: space-between; */}.flex .item{width: 135px;height: 40px;background-color: #3be598;margin-bottom: 20px;}.flex .item:nth-child(4n1),.flex .item:nth-child(4n2),.flex .item:nth-child(4n3){margin-right: 20px;/* margin-right: auto; */}
/style
/head
bodydiv classflexdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/div/div
/body
如果不用flex会更复杂但是也是可以实现的
注意空白折叠
stylebody {margin: 0;}.box {background-color: #f0eeee;width: 600px;margin-top: 20px;}.box .item{width: 135px;height: 40px;background-color: #3be598;display: inline-block;margin-bottom: 20px;}.box .item:nth-child(4n1),.box .item:nth-child(4n2),.box .item:nth-child(4n3){margin-right: 15.2px;/* margin-right: calc((100%-1200px)/3); */}
/style
/head
bodydiv classboxdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/div/div
/body
但是如果使用grid将会超级简单
stylebody {margin: 0;}.grid {background-color: #f0eeee;width: 600px;margin-top: 20px;display: grid;grid-template-columns: repeat(4, 1fr);/* grid-row-gap: 20px; */row-gap: 20px;column-gap: 20px;}.grid .item{width: 100%;height: 40px;background-color: #3be598;}
/style
/head
bodydiv classgriddiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/divdiv classitem/div/div
/body
grid容器属性
grid-template-columns 划分列数
固定宽度
grid-template-columns: 40px 40px;
百分比
grid-template-columns: 40% 60%;
比例
grid-template-columns: 1fr 2fr;
重复
grid-template-columns: repeat(5, 1fr); /*5列每列等宽*/
自动计算列
grid-template-columns: repeat(auto-fill, 600px); /*每列固定600px自动算多少列*/
grid-template-columns: repeat(auto-fit, 600px); /*每列固定600px自动算多少列*/
auto
grid-template-columns: 100px auto 100px;
grid-template-rows 划分行数
行列间距
grid-template-columns: repeat(3,1fr);
/*grid-template-rows: repeat(3,1fr);*/
row-gap: 20px;
column-gap: 20px; gap是row-gap和column-gap是简写
容器对齐方式
justify-content 水平对齐方式
justify-content: center; /* 属性和之前一样 */
align-content 垂直对齐方式
align-content: center;
place-content 是align-content属性和justify-content属性的合并简写形式
place-content: end end;
单元格对齐方式
justify-items
align-items
place-items
是align-items属性和justify-items属性的合并简写形式。
justify-items: end;
align-items: end; 项目内单元格对齐方式
用法和justify-items类似但是是在项目属性上写的
div classitem styleplace-self: end end1/div grid项目属性
合并单元格
.item-8{grid-column-start: 2;grid-column-end: 4;
} .item-5{grid-column-start: 2;grid-column-end: 4;grid-row-start: 2;grid-row-end: 4;
}
可简写为
grid-row: 2/4;
grid-column: 2/4; 9、css栅格化
css栅格化
UI组件库的基石整个css布局的核心知识
.row {display: flex;height: 100px;
}
.col {height: 100%;
}
.col-1 {flex: 0 0 10%;
}
.col-2 {flex: 0 0 20%;
}
.col-3 {flex: 0 0 30%;
}
.col-4 {flex: 0 0 40%;
}
.col-5 {flex: 0 0 50%;
}
.col-6 {flex: 0 0 60%;
}
.col-7 {flex: 0 0 70%;
}
.col-8 {flex: 0 0 80%;
}
.col-9 {flex: 0 0 90%;
}
.col-10 {flex: 0 0 100%;
}
Bootstrap 比较早使用css栅格化的ui组件库 它可以单独使用不挑前端框架
官方文档
link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/bootstrap4.6.2/dist/css/bootstrap.min.css integritysha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HIN crossoriginanonymous
!-- 建议下载下来 --
https://cdn.jsdelivr.net/npm/bootstrap4.6.2/dist/css/bootstrap.min.css
10、css实战布局
枫枫博客后台布局 !DOCTYPE html
html langzh-CN
headmeta charsetUTF-8title博客后台框架/titlestyle* {box-sizing: border-box;}body {margin: 0;}.admin {display: flex;}.admin aside {width: 240px;height: 100vh;background-color: white;border-right: 1px solid #f0eeee;}.admin aside .logo {height: 90px;border-bottom: 1px solid #f0eeee;}.admin main {width: calc(100% - 240px);height: 100vh;background-color: white;}.admin main .head {height: 60px;}.admin main .tabs {height: 30px;border-top: 1px solid #f0eeee;border-bottom: 1px solid #f0eeee; /* 下划边框线 */}.admin main .container {height: calc(100vh - 90px);overflow-y: auto; /* 控制滚动条出现的样式 */background-color: #f0eeee;padding: 20px;}.default_main {width: 100%;height: 100%;background-color: white;border-radius: 5px;}/style
/head
body
div classadminasidediv classlogo/divdiv classmenu/div/asidemaindiv classhead/divdiv classtabs/divdiv classcontainerdiv classdefault_main/div/div/main
/div
/body
/html
枫枫博客前台布局 !DOCTYPE html
html langzh-CN
headmeta charsetUTF-8title博客前台/titlestylebody {margin: 0;}* {box-sizing: border-box;}a {color: #333;text-decoration: none;}.blog {}.blog .nav {width: 100%;height: 60px;background-color: rgba(255, 255, 255, 0.8);position: fixed;top: 0;display: flex;justify-content: center;z-index: 100;}.blog .nav .container {align-items: center;}.blog .nav .left {width: 10%;}.blog .nav .left div:nth-child(1) {font-size: 22px;}.blog .nav .left div:nth-child(2) {font-size: 12px;}.blog .nav .center {width: 70%;}.blog .nav .center a {margin-left: 20px;}.blog .nav .right {width: 20%;text-align: right;}.blog .banner {height: 600px;position: relative;}.blog .banner img {width: 100%;height: 100%;object-fit: cover; /* 自适应 */}.blog .banner .slogan {position: absolute;left: 50%;top: 50%;color: white;transform: translate(-50%, -50%); /* 偏移50% */}.blog .banner .slogan div {text-align: center;}.blog .banner .slogan div:nth-child(1) {font-size: 26px;}.blog .banner .slogan div:nth-child(2) {font-size: 18px;margin-top: 10px;}.container {width: 1200px;display: flex;}.blog main {background-color: #f0eeee;display: flex;justify-content: center;padding: 20px 0;}.blog main .container .left {width: calc(100% - 300px - 20px);margin-right: 20px;}.blog main .container .right {width: 300px;}.blog main .news {margin-bottom: 20px;}.blog main .tags {margin-bottom: 20px;}.blog .footer{height: 50px;background-color: white;justify-content: center;align-items: center;display: flex;}.card {background-color: white;border-radius: 5px;}.card .head {padding: 20px 20px 10px 20px;border-bottom: 1px solid #f0eeee;}.card .head .title {font-size: 18px;font-weight: 600;}.card .body{padding: 10px 20px 20px 20px;}/style
/head
body
div classblogdiv classnavdiv classcontainerdiv classleftdiv枫枫知道/divdivFFENGZHIDAO/div/divdiv classcentera href首页/aa href搜索/aa href聊天室/a/divdiv classrighta href登录/a/div/div/divdiv classbannerimg srchttp://image.fengfengzhidao.com/gvb_1009/20231123092743__1123-e.png altdiv classslogandiv枫枫知道个人博客九代/divdiv我的九代博客/div/div/divmaindiv classcontainerdiv classleftdiv classcard newsdiv classheaddiv classtitle今日热搜/div/divdiv classbody/div/divdiv classcard articlediv classheaddiv classtitle文章列表/div/divdiv classbody/div/div/divdiv classrightdiv classcard tagsdiv classheaddiv classtitle标签云/div/divdiv classbody/div/divdiv classcard user_infodiv classheaddiv classtitle个人信息/div/divdiv classbody/div/div/div/div/maindiv classfooter建站日期2023-02-15网站已运行: 493天15时32分45秒/div
/div
/body
/html
!-- JavaScript -- 前端所使用的编程语言 弱类型动态语言
1、使用js的三种方式 行内 button οnclickalert(你点到我了)点我/button 外部引入 script srcindex.js/script 内嵌 可以在任何地方引入 !DOCTYPE html
html langzh-CNheadmeta charsetUTF-8title引入js/titlescriptconsole.log(hello world head里面)/script/headbodyscriptconsole.log(hello world body里面)/script/bodyscriptconsole.log(hello world body外面)/script
/html
scriptconsole.log(hello world html的外面)
/script
2、变量与基本数据类型
变量声明
var 函数作用域 作用域提升 console.log(name)
{var name xiaojin
} 全局变量可以被挂载到window上
let 块级作用域 暂时性死区
const 常量声明就需要初始化 通常用于声明数组和对象
和
是值判断不会去判断类型
是值和类型一起判断
console.log(12 12) // true
console.log(12 12) // false
基本数据类型
八种基本数据类型
Number、String、Boolean、Null、undefined、object、symbol、bigInt
number
const a 123
const a1 Number(123)
console.log(a, typeof a)
console.log(a1, typeof a1)
const a2 0b110 // 6
console.log(a2)
const a3 0o11 // 9
console.log(a3)
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
const a4 0xa1 // 10 * 16 1 161
console.log(a4) // 最终打印都是十进制
保留小数 toFixed
const a5 3.14159265354
console.log(a5)
console.log(a5.toFixed(2)) // 3.14
console.log(a5.toFixed(0)) // 3
转整数 Number.parseInt()
console.log(Number.parseInt(3.14)) // 3
console.log(Number.parseInt(5)) // 5
console.log(Number.parseInt(5.256)) // 5
是否为整数Number.isInteger()
console.log(Number.isInteger(1)) // true
console.log(Number.isInteger(1.2)) // false
console.log(Number.isInteger(1.2)) // false
console.log(Number.isInteger(1)) // false
console.log(Number.isInteger(-3)) // true
取整
console.log(Math.round(3.5)) // 四舍五入 4
console.log(Math.round(3.4)) // 四舍五入 3
console.log(Math.ceil(1.0000001)) // 向上取整 2
console.log(Math.ceil(1.9)) // 向上取整 2
console.log(Math.floor(1.9)) // 向下取整 1
console.log(Math.floor(1.001)) // 向下取整 1
string
字符串
const s1 ffzd
console.log(s1, typeof s1)
const s2 String(枫枫)
console.log(s2, typeof s2)console.log(s1[0]) // f
console.log(s1[2]) // z
indexOf() 根据字符找编号
const s1 ffzd
console.log(s1.indexOf(z)) // 2
console.log(s1.indexOf(1)) // -1
// 如果有多个字符匹配返回最开始那个字符的编号
console.log(s1.indexOf(zd)) // 2
split() 按照特点的分隔符切割字符串
const s3 枫枫,zhangsan,lisi
const a s3.split(,)
console.log(a[0], a[1])
slice() 切片返回值也是一个字符串
const s4 枫枫,zhangsan,lisi
console.log(s4.slice(3, 11)) // 前闭后开 zhangsan
includes() 包含判断是否有子串包含
const s5 枫枫,zhangsan,lisi
console.log(s5.includes(lisi)) // true
console.log(s5.indexOf(lisi) ! -1) // true
trim() 去空格
const s6 我的名字是枫枫
console.log(s6)
console.log(s6.trim())
boolean false、0、、null、undefined、NaN 转为 布尔值 为 false 其他所有值 转为布尔值 为 true
const b1 true
const b2 false
console.log(Boolean(0))
console.log(Boolean()) // 空字符串 false
console.log(Boolean( )) // 空格字符串 true
console.log(Boolean(null))
console.log(Boolean(undefined))
console.log(Boolean(false))
console.log(Boolean(NaN))
object
增删改查
const lyf {name: lyf,age: 18
}
const lyf1 {name: lyf,age: 18
}
console.log(lyf, typeof lyf)
console.log(lyf1, typeof lyf1)console.log(lyf.name)
console.log(lyf[name])lyf.addr 湖南
lyf[xxx] yyy
console.log(lyf)lyf.age 19
console.log(lyf)delete lyf.addr
delete lyf[xxx]
console.log(lyf)const name fengfeng
const obj {[name]:
}
console.log(obj)
null
null表示一个空值或没有对象值。它是一个表示空对象指针的特殊关键字
null的用法 作为函数的参数表示该函数的参数不是对象 作为对象原型链的终点
undefined
undefined的用法 变量被声明了但没有赋值时就等于undefined 调用函数时应该提供的参数没有提供该参数等于undefined 对象没有赋值的属性该属性的值为undefined 函数没有返回值时默认返回undefined
为啥要用null和undefined
symbol 唯一值
js对象属性名都是字符串这容易造成属性名冲突的问题
const name Symbol(name)
const age Symbol(age)
const symObj {[name]: 张三,[age]: 14,
}
symObj[name] 枫枫 // 不会替换那个name
console.log(symObj)
console.log(symObj[name])
bigInt
可以安全地存储和操作大整数即使这个数已经超出了Number类型能够表示的安全整数范围。
在 JavaScript 中普通的数字Number 类型只能安全地表示 -9007199254740991即 -(2^53 - 1)到 9007199254740991即 2^53 - 1之间的整数。超出这个范围的整数在表示时可能会失去精度。因此BigInt解决了之前Number整数溢出的问题。
const b1 BigInt(123)
console.log(typeof b1, b1)
console.log(b1 BigInt(10086)) // 必须都是bigint才行
const b2 12345678910n // bigint类型
console.log(typeof b2, b2)
3、数组与数组方法
数组
数组创建
const a1 [fengfeng, zhangsan, lisi]
console.log(a1[0]) // 获取数组的第一个元素
console.log(a1.length) // 获取数组的长度数组中元素的个数
console.log(a1[a1.length - 1]) // 获取数组的最后一个元素
const a2 Array(fengfeng, zhangsan, lisi)
console.log(a2)
遍历数组
for i
for (let i 0; i a1.length; i) {console.log(i, a1[i])
}
for of
遍历数组最常用方法
for (const value of a2) {console.log(value)
}
判断一个对象是不是数组
typeof(数组) 得到的结果是object。因为数组本质就是对象
Array.isArray()
console.log(Array.isArray(a1)) // true
console.log(Array.isArray(1)) // false
instanceof
console.log(a1 instanceof Array) // true
数组方法
push()、pop()方法
push() 数组末端添加一个或多个元素返回添加之后数组的长度
const a1 [fengfeng, zhangsan, lisi]
a1.push(王五)
const l a1.push(z1, z2)
console.log(l, a1)
pop() 移除数组末端的元素并返回
const a2 [fengfeng, zhangsan, lisi]
const item a2.pop()
console.log(item, a2)
shift()、unshift()方法
shift() 从数组最左端移出元素并返回移出的元素
const a3 [fengfeng, zhangsan, lisi]
const fi a3.shift()
console.log(fi, a3)
unshift() 在数组的开头插入新元素并返回数组的新长度
const a4 [fengfeng, zhangsan, lisi]
const l1 a4.unshift(小红)
console.log(l1, a4)
join()方法
将数组内所有元素按join()内的参数为分割添加到字符串中
const a5 [fengfeng, zhangsan, lisi]const s a5.join(,)
console.log(s) // fengfeng,zhangsan,lisi
console.log(a5.join()) // 默认就是,
console.log(a5.join(|)) // fengfeng|zhangsan|lisi
sort()方法 默认升序
const a6 [4, 2, 1, 5]
console.log(a6.sort()) // 升序
可以通过reverse()反转得到降序
const a6 [4, 2, 1, 5]
console.log(a6.sort()) // 升序
console.log(a6.reverse()) // 反转
高级用法 (后一个元素当前元素)
return 正值和0不变 return 负值就交换
const a6 [0, 2, 1, 5]a6.sort(function (a, b){console.log(a, b)return b-a
})
console.log(a6)
a-b 升序后一个比当前元素大 b-a 降序 当前元素比后一个大
splice()方法
用于删除数组中的元素并且返回被删除的数组
const a7 [fengfeng, zhangsan, lisi]
const a8 a7.splice(1, 1) // (索引, 要删除的个数)
console.log(a8) // 被删除的数组 [zhangsan]
console.log(a7) // 原位删除 [fengfeng,lisi] 以下是ES6新增的数组方法
forEach() 循环 中途不能退出
const a1 [fengfeng, zhangsan, lisi]
a1.forEach(function (value, index, array){console.log(value, index, array)
})
map() 迭代
迭代每一个元素去进行操作
const a2 a1.map(function (value, index, array){return value qq.com
})
console.log(a2) // [fengfengqq.com, zhangsanqq.com, lisiqq.com] 不会原位修改
filter() 过滤
const a3 a1.filter(function (value, index, array){if (value zhangsan){return true}
})
console.log(a3) // [zhangsan]
every()方法、some()方法
every判断数组中是不是 每一个 都满足条件
some判断数组中 其中一个 满足条件
const a4 [5, 1, 0, -1, 2]
console.log(a4.every(function (value){if (value 0){return true}
})) // falseconsole.log(a4.some(function (value){if (value 0){return true}
})) // true
find()方法
获取数组中满足条件的数据如果有 就是满足条件的第一个数据如果没有就是undefined
const a5 [5, 1, 0, -1, 2]
const item a5.find(function (value, index, obj){if (value 5){return true}
})
console.log(item) // 5 找不到就是undefined
const index a5.findIndex(function (value, index, obj){if (value 5){return true}
})
console.log(index) // 0 找不到就是-1
4、流程控制
逻辑运算符
流程控制的关键掌管进退的神
一般用于编写复合逻辑
与
const name fengfeng
const age 12
console.log(age 18 name.startsWith(f))
或
const name fengfeng
const age 12
console.log(age 18 || name.startsWith(f))
非 !
console.log(!(age 18) )
逻辑短路 如果前面的条件是false那就不会去判断后面的条件了
||如果前端的条件是true那就不会去判断后面的条件了
如何验证
function t(){console.log(t)return true
}console.log(-10 t()) // 不会执行t
console.log(10 || t()) // 不会执行t
判断语句
if语句
单分支
const name fengfeng
if (name fengfeng) {console.log(去度假)
}// 如果代码语句只有一行可以省略{}
if (name fengfeng)console.log(去度假)
console.log(不管什么我都会执行)
双分支
if (name fengfeng){console.log(fengfeng去度假)
}else {console.log(fengfeng继续搬砖)
}
多分支
const scope 90
if (scope 90) {console.log(A)
} else if (scope 80) {console.log(B)
} else if (scope 60) {console.log(C)
} else {console.log(D)
}
分支嵌套
if (scope 80){if (scope 90){console.log(A)}else {console.log(B)}
}else {if (scope 60){console.log(C)}else {console.log(D)}
}
分支优化
function get_scope(scope){if (scope 90){console.log(A)return;}if (scope 80){console.log(B)return;}if (scope 60){console.log(C)return;}console.log(D)}
switch语句 注意 执行case 里面的语句时如果没有break则继续执行下一个case里面的语句 const day 7switch (day) {case 1:console.log(周一)breakcase 2:console.log(周二)breakcase 3:console.log(周三)breakcase 4:console.log(周四)breakcase 5:console.log(周五)breakcase 6:console.log(周六)breakcase 7:console.log(周天)breakdefault:console.log(错误)
}
循环语句
传统for循环
let sum 0
for (let i 1; i 100; i) {sum i
}
console.log(sum)
for in循环 遍历对象
for...in循环可以用来遍历对象的可枚举属性列表包括原型链上的属性
const obj {name:枫枫,age: 21
}
for (const objKey in obj) {console.log(objKey)
}
for of循环 遍历数组
用于遍历数组
const array [枫枫, 张三]
for (const item of array) {console.log(item)
}
while循环
let i 1
let r 0
while (i 100){// 循环体r ii
}
console.log(r)
do while循环
先执行一次循环体再进行条件判断
let o 1
let r 0
do {r oo
}while (o 100)
console.log(r)
continue
例如吃5个包子吃到第3个发现里面有半个虫子这个包子就不吃了继续吃下一个。
for (let j 1; j 10; j) {if (j 3){console.log(吃到第${j}个包子发现虫子这个包子我不吃了)continue}console.log(吃到第${j}个包子)
}
break
跳出整个循环
例如吃5个包子吃到第3个发现里面有半个虫子这盘都不吃了。
for (let j 1; j 10; j) {if (j 3){console.log(吃到第${j}个包子发现虫子我都不吃了)break}console.log(吃到第${j}个包子)
}
5、js函数
函数是一种可重复使用的代码块
函数是一种非常重要和常用的语言特性可以用于封装代码、抽象功能、提高代码的可读性和可维护性等
例如经常使用的 console.log函数它的功能就是将变量打印到控制台上我们只需要调用这个函数即可而log函数考虑的就很多了
函数声明和调用 function声明
function hello() {console.log(hello)
}
hello() 匿名函数
const say function (){console.log(say)
}
say() 箭头函数
const eat (){console.log(eat)
}
eat() 立即执行函数
(function (){console.log(立即执行)
})()
函数参数 声明是形参调用是实参 function add(a, b){ // a,b是形参return a b
}
console.log(add(1,2)) // 1,2是实参
默认参数 如果对应的参数没有被赋值那么对应的参数就是undefined function getName(namefeng){// if (name undefined){// return feng// }// name name || fengreturn name
}
参数列表
形参和实参的传递是一一对应的剩余的被参数列表接收
// function sum(a, ...list) {}
function sum(...list) {let res 0for (const item of list) {res item}return res
}
console.log(sum(2, 3))
console.log(sum(2, 3, 2, 3, 45))
arguments
完整的参数列表是一个类数组
function sum1() {let res 0for (const item of arguments) {res item}return res
}
console.log(sum1(2, 3))
console.log(sum1(2, 3, 2, 3, 45))
函数返回值 没有显式return等于return undefined
function set(){
}
console.log(set()) // undefined
函数作为变量
函数自身也可以作为参数放入对象、数组中
function getName(){return fengfeng
}const lis [1,sss, getName]
console.log(lis[2]())
如果函数在对象中此时它就叫方法
const obj {name: fengfeng,eat: function (){return ${this.name}在吃饭},say: (){// 箭头函数中不能用thisconsole.log(在说话)},study(){console.log(${this.name}在学习)}
}
console.log(obj.name)
console.log(obj.eat())
obj.say()
obj.study()
递归函数
在函数中调用自身 一定要设置退出条件 示例展开所有的数组变成一维数组
const list [你好, 吃饭了吗,[好,[[abc]]]]
写法1
const a1 []
function oneArray(array){for (const arrayElement of array) {if (arrayElement instanceof Array){oneArray(arrayElement)continue}a1.push(arrayElement)}
}
oneArray(list)
console.log(a1)
写法2
function oneArray1(array){const a2 []function oneArray(array){for (const arrayElement of array) {if (arrayElement instanceof Array){oneArray(arrayElement)continue}a2.push(arrayElement)}}oneArray(array)return a2
}
console.log(oneArray1(list))
有非常多的方法
function oneArray2(array){const a3 []for (const arrayElement of array) {if (arrayElement instanceof Array){a3.push(...oneArray2(arrayElement))continue}a3.push(arrayElement)}return a3
}console.log(oneArray2(list))
this问题
this指向 函数外window 函数内函数中的this指向谁取决于这个函数是怎么调用的 箭头函数没有this或者this是window
this指向修改
function.call()
function.call(this指向谁, 函数参数1,参数2...)
// 调用函数并修改函数中的this指向
function.apply()
function.apply(this指向谁, [参数1, 参数2...])
// 调用函数并修改函数中的this指向
function.bind()
function.bind(指向,参数1,参数2,...)
// 绑定this指向 箭头函数的this不能修改 function get() {console.log(get, this, arguments)
}
const set (){console.log(set, this)
}
const obj {name: fengfeng,get: get,set: set,
}
get()
obj.get()
set()
obj.set()
// 改变this
get.call(obj, 1,2,3)
get.apply(obj, [1,2,3])
get.bind(obj, 1,2,3)(4,5,6)
// 箭头函数的this指向不能修改
6、js的对象
创建对象
字面量
const obj {name: 枫枫
}
new一个对象
const o2 new Object({})
原型对象
function People(name, age){this.name namethis.age age
}
People.prototype.eat function (){console.log(${this.name}在吃饭)
}
const o2 new People(枫枫, 21)
console.log(o2)
o2.eat()
create方法
继承
// 其中的name和age属性 是在原型上
const o3 Object.create({name: 枫枫, age: 21})
console.log(o3)
console.log(o3.name)
o3.name lisi
// 给自己加了一个name属性
console.log(o3.name)
// 如果自己有这个属性就用自己的没有就去原型上去找
属性操作
查询通过点或者方括号获取
console.log(o3.name)
console.log(o3[name])
删除属性 delete只能删除自身的继承来的不能删
delete o3.name // 只能删自己身上的属性
delete o3.age
// 原型上的name和age还在
检测属性
属性名 in object 可以自己检测继承来的属性
const o3 Object.create({name: 枫枫, age: 21, eat: function (){}})
o3.addr 长沙市
console.log(age in o3) // true
console.log(addr in o3) // true
console.log(eat in o3) // true 方法就是特殊的属性
object.hasOwnPreperty(属性名) 检测自身的属性
const o3 Object.create({name: 枫枫, age: 21, eat: function (){}})
o3.addr 长沙市
console.log(o3.hasOwnProperty(addr)) // true
console.log(o3.hasOwnProperty(age)) // false
属性枚举
for-in继承自身的属性
const o3 Object.create({name: 枫枫, age: 21, eat: function (){}})
o3.addr 长沙市
for (const o3Key in o3) {console.log(o3Key)
}
Object.keys() 自己的属性
const o3 Object.create({name: 枫枫, age: 21, eat: function (){}})
o3.addr 长沙市
console.log(Object.keys(o3)) // [addr]
Object常用的API
Object.assign() 浅拷贝
Object.assign(target, ...sources)
// 参数target 目标参数sources源对象 返回值目标对象 如果目标对象中的属性具有相同的键则属性将被源对象中的属性覆盖 Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象 assign其实是浅拷贝而不是深拷贝。也就是说如果源对象某个属性的值是对象那么目标对象拷贝得到的是这个对象的引用。同名属性会替换
const obj {name: 王五, addr: 长沙}
const source {name: 枫枫,info: {age: 21},likes: []
}
Object.assign(obj, source)
source.info.age 22 // 最终会影响到 obj里面的age
source.name zhangsan // 外层的不会影响
source.likes.push(篮球) // 最终会影响到 obj里面的likes
console.log(obj)
Object.keys()
一个表示给定对象的所有可枚举属性的字符串数组
const o3 Object.create({name: 枫枫, age: 21, eat: function (){}})
o3.addr 长沙市
console.log(Object.keys(o3)) // [addr]
Object.defineProperty()定义对象属性
Object.defineProperty(obj, name, {value: 101, // 属性的值writable: true, // 是否允许修改enumerable: true, // 是否允许枚举configurable: true, // 是否允许删除
});
Object.getOwnPropertyNames()
Object.getOwnPropertyNames() 返回一个数组该数组对元素是对象自身拥有的枚举或不可枚举属性名称字符串。
const o1 {name: 枫枫}Object.defineProperty(o1, age, {value: 21,writable: true, // 是否可修改enumerable: false, // 是否可枚举configurable: true, // 是否可删除
})
console.log(Object.keys, Object.keys(o1)) // 获取可枚举的属性列表
console.log(Object.getOwnPropertyNames, Object.getOwnPropertyNames(o1)) // 获取属性列表
// delete o1.age
原型与原型链
原型在JavaScript是一个很重要的概念它是面向对象可以继承的基础
原型链是原型的查找机制是一条寻址链。其实原型上的方法或属性查找都是按照一定的顺序沿着原型链进行查找的。如果查找到最后仍然没有找到这个原型和方法那么就真的没有了
原型链的尽头是null
给构造函数添加原型
// Object.prototype.字段名
const obj {}
console.log(obj)
const o1 new Object({})
Object.prototype.name 枫枫
console.log(o1)
修改现有对象的原型
找这个现有对象的父级的构造函数
比如{}的原型是Object的实例
const obj {}
Object.prototype.toString function (){return 这是对象的toString方法
}
console.log(obj )
console.log(obj.toString())
Object.create()设置原型方法
const o2 Object.create({eat(){console.log(吃饭)}
})
console.log(o2)
使用proto属性
可以通过设置对象的 __proto__ 属性来改变其原型
const o2 Object.create({eat(){console.log(吃饭)}
})
o2.__proto__.study function (){console.log(在学习)
}
console.log(o2)
new的过程 创建一个新的对象 把该对象的__proto__属性设置为构造函数的prototype属性即完成原型链 执行构造函数中的代码构造函数中的this指向该对象(obj) 返回该对象obj
function People(name){this.name name
}function _new(fn, ...args){// 1. 创建一个新的对象const o {}// 2. 把该对象的__proto__属性设置为构造函数的prototype属性即完成原型链o.__proto__ fn.prototype// 3. 执行构造函数中的代码构造函数中的this指向该对象(obj)fn.apply(o, args)// 4. 返回对象return o
}
const o3 new People(枫枫)
console.log(o3)
const o4 _new(People, 枫枫)
console.log(o4)
7、js时间库
在JavaScript中时间戳timestamp是一种表示特定时刻距离某个固定时间点的毫秒数。通常这个固定时间点是指 1970年1月1日00:00:00UTC 即Unix纪元
时间戳
获取当前时间戳
console.log(new Date().getTime()) // 获取毫秒级时间戳 13位
将时间戳转换为时间对象
console.log(new Date(1719414979389))
日期对象
格式化日期对象
const date new Date()
console.log(date.getFullYear())
console.log(date.getMonth() 1) // 月是从0开始的
console.log(date.getDate())
console.log(date.getHours())
console.log(date.getMinutes())
console.log(date.getSeconds())
把时间变成 2024-06-26 15:04:05这样的格式
可以使用字符串的padStart() 方法把格式变成两位不够的用第二个参数补
function parseDate(dateString){let dateif (dateString){date new Date(dateString)}else {date new Date()}const y date.getFullYear().toString()const M (date.getMonth() 1).toString().padStart(2, 0)const d date.getDate().toString().padStart(2, 0)const h date.getHours().toString().padStart(2, 0)const m date.getMinutes().toString().padStart(2, 0)const s date.getSeconds().toString().padStart(2, 0)return ${y}-${M}-${d} ${h}:${m}:${s}
}console.log(parseDate(2022-12-12 15:04:05))
console.log(parseDate())
字符串转换为时间对象
new Date(2022-12-12 15:04:05)
日期计算
在一个日期上加减一个时间
调用setXXX方法重新设置一个时间
const d1 new Date()
console.log(parseDate(d1))
// 七天前
d1.setDate(d1.getDate() - 7)
// 5小时后
d1.setHours(d1.getHours() 5)
console.log(parseDate(d1))
一个未来的时间距离现在还剩多久 时间戳相减
得到一个毫秒的时间然后算出秒数、分钟、小时、天
function timeUntil(timeStr) {const now new Date();const then new Date(timeStr);const diff then - now;// 如果给定时间已经过去返回过去的时间 if (diff 0) {return 时间已经过去;}// 将毫秒转换为秒const seconds Math.floor(diff / 1000); // 向下取整const minutes Math.floor(seconds / 60);const hours Math.floor(minutes / 60);const days Math.floor(hours / 24);if (days 0) {return ${days} 天 ${hours % 24} 小时 ${minutes % 60} 分钟 ${seconds % 60} 秒;} else if (hours 0) {return ${hours} 小时 ${minutes % 60} 分钟 ${seconds % 60} 秒;} else if (minutes 0) {return ${minutes} 分钟 ${seconds % 60} 秒;} else {return ${seconds} 秒;}
}
一个过去的时间距离现在过了多久
也是算时间的差值直接除以大的年大于0就直接返回以此类推
function getDateDiff(dateTimeStamp) {// 时间字符串转时间戳const timestamp new Date(dateTimeStamp).getTime();const minute 1000 * 60;const hour minute * 60;const day hour * 24;const month day * 30;const year day * 365;const now new Date().getTime();const diffValue now - timestamp;let result;if (diffValue 0) {return;}const yearC diffValue / year;const monthC diffValue / month;const weekC diffValue / (7 * day);const dayC diffValue / day;const hourC diffValue / hour;const minC diffValue / minute;if (yearC 1) {result parseInt(yearC) 年前;} else if (monthC 1) {result parseInt(monthC) 月前;} else if (weekC 1) {result parseInt(weekC) 周前;} else if (dayC 1) {result parseInt(dayC) 天前;} else if (hourC 1) {result parseInt(hourC) 小时前;} else if (minC 1) {result parseInt(minC) 分钟前;} elseresult 刚刚;return result;
}
8、正则表达式
正则表达式Regular Expression在代码中常简写为regex、regexp或RE使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。搜索模式可用于文本搜索和文本替换 各个编程语言中都支持正则表达式 正则表达式的用途有很多比如 表单输入验证 搜索和替换 过滤大量文本文件如日志中的信息 读取配置文件 网页抓取 处理具有一致语法的文本文件例如 CSV
在线正则表达式
/[ab012]/g
字符集合
使用“[]” 里面属于||的关系
/[az012]/g // []中是||的关系 字符范围
使用“-”
/[a-z]/g
/[\u4e00-\u9fa5]/g // 匹配中文 数量字符
{m,n}
最少匹配m个最多匹配n个
/[\u4e00-\u9fa5]{2,3}/g // 匹配中文
/* {m,n} 最少匹配m个最多匹配n个 */ 匹配前面一个表达式一次或者多次相当于{1,}。
/a[bc]a/g // 相当于{1,} *匹配前面一个表达式0次或者多次相当于{0,}。
/a[bc]*a/g // 相当于{0,} ?单独使用匹配前面一个表达式零次或者一次相当于{0,1}
/https?:\/\//g // 相当于{0,1} 贪婪模式
正则会尽可能的匹配多的字符
/a[ab]*a/g // 贪婪模式,正则会尽可能的匹配多的字符 非贪婪模式
尽可能匹配少的
/a[ab]?a/g // 非贪婪模式,尽可能匹配少的
元字符
元字符说明\d匹配数字 [0-9]\D匹配非数字\w匹配数字、字母、下划线\W匹配非数字、字母、下划线\s匹配任意的空白字符\S匹配任意的非空白符.匹配除换行符之外的任意字符
特殊字符
特殊字符说明.匹配除了换行符之外的任何单个字符\转义字符|逻辑或操作符[^]取非匹配未包含的任意字符 [^0-9]
位置匹配
位置字符说明\b匹配一个单词边界也就是指单词和空格间的位置 \s空格也可\B匹配非单词边界^匹配开头在多行匹配中匹配行开头$匹配结尾在多行匹配中匹配行结尾 分组
使用小括号
捕获分组
/\d{4}-(\d{2})-d{2}-(\d{2}):\d{2}:\d{2}/g
月:$1 小时:$2 无捕获分组
有些时候使用小括号只是希望把它当做一个整体不希望分组
/(\d\.){3}\d/g
$1
/?:(\d\.){3}\d/g
$1 修饰符
修饰符说明g表示全局匹配即在整个字符串中搜索所有匹配项而不仅仅是第一个匹配项 //gi表示在匹配时忽略大小写 //gim表示多行模式在这种模式下正则表达式可以同时匹配每一行的内容而不仅仅是整个字符串 /^python/gimu表示在匹配时进行完全递归这样可以处理一些较为复杂和嵌套的情况s在默认情况下.元字符匹配除了换行符之外的任意字符。但是在设置了s修饰符后.元字符也会匹配换行符 /a.*?(.*?)\/a/gims
m模式
主要影响^和$符合的行为 s模式
点号可以匹配换行 js中的正则表达式
定义正则表达式
const re /1\d{10}/g
const re1 new RegExp(1\d{10}, g)
字符串的正则方法
通过字符串调用的方法
search() 被匹配的最开始索引
没有匹配到就返回-1
const re /1\d{10}/g
const s 我的手机号是 15254586535
console.log(s.search(re)) // 7最开始匹配到的索引
match() 正则匹配
console.log(s.match(re))
replace()正则替换
console.log(大傻春你要干什么你是大傻叉吗.replace(傻, *))
console.log(大傻春你要干什么你是大傻叉吗.replaceAll(傻, *))
console.log(大傻春你要干什么你是大傻叉吗.replace(/[傻叉]/g, *))
使用分组替换
const r /(1\d{10}).*?([\w-]\w\.\w)/g
const str my phone is : 15252523256, my email is: 525416qq.com
concole.log(str.replace(r, 我的手机号, $1, 邮箱: $2))
正则表达式函数
const r /(1\d{10}).*?([\w-]\w\.\w)/g
const str my phone is : 15252523256, my email is: 525416qq.com
concole.log(str.replace(r, function(data, g1, g2){// (data, ...args) console.log(data, args)console.log(data, args)return 我的手机号, ${g1}, 邮箱: ${g2}
})
concole.log(str.replace(r, function(data, g1, g2){const tel Number(g1)1return 我的手机号, ${tel.toString()}, 邮箱: ${g2}
})
正则方法
通过正则对象调用的方法
test() 是否匹配
console.log(/abc/.test(abcd)) // true
console.log(/abc/.test(abd)) // false
execl() 方法
可以使用分组第一个参数就是正则表达式匹配的内容
后面的参数就是分组匹配的内容
const r /(1\d{10})/g
console.log(r.exec(my phone is: 15252523256))
console.log(res[1]) // 第一个分组
具名分组
const r /(?phone1\d{10}).*?(?email[\w-]\w\.\w)/g
res r.exec(my phone is : 15252523256, my email is: 525416qq.com))
console.log(res.groups.phone)
9、class
在过去JavaScript 是一门基于原型的面向对象编程语言没有 Class 和模块化的概念。这导致了代码的组织结构混乱难以维护和扩展
类和对象
我们生活中有很多的车小车汽车自行车火车摩托车电动车
他们都是属于“车”这么一类
具体的一辆你在2024年买的一辆四个轮子的小车这就叫对象
class定义
class Animal{nameageclass1constructor(name, age) { // 传参this.name namethis.age ageclass1 碳基生物}eat(){console.log(${this.name}在吃饭)}
}
const cat new Animal(加菲猫, 5)
console.log(cat)
cat.eat()
其中的constructor属于构造方法name、age属于对象属性eat属于对象方法
其中的eat方法是在原型上的
*继承
使用class之后就能很方便的使用继承功能
使用 extends 继承父类super() 用于实例化继承的类
class Animal{nameconstructor(name) {this.name name}eat(){console.log(${this.name}在吃饭)}
}
// 猫继承动物的属性或方法
class Cat extends Animal{colorconstructor(name, color) {super(name);this.color color}running(){console.log(猫在行走)}
}
const cat new Cat(加菲猫, 白色)
console.log(cat)
静态属性和方法
只能由类去调用
// 只能由类去调用
class Animal{static name 动物static eat(){console.log(在吃饭)}
}Animal.eat()
console.log(Animal.name)
10、js模块化
模块化是指将一个复杂的程序依据一定的规则规范封装成几个块文件并进行组合在一起
最早我们开发将所有的代码写在一个js文件中随着需求越来越复杂代码量越来越大如果仍然把所有代码写在一个js文件中那么代码耦合度过高不方便后期维护也不方便程序员找到某一个功能点的代码
模块化将一个复杂的js文件按共同或类似的逻辑拆分成多个js文件拆封的文件内部数据是私有的只是向外部暴露一些接口方法与其他模块通信不仅方便找到某一块功能点的代码也可以达到复用的效果
ES6实现模块化
重点是引入js的地方必须要有一个 typemodule
script srcmodule/index.js typemodule/script
然后子模块可以使用 export 将成员抛出
父模块使用 import 将子模块的成员导入 导入的时候把js文件的后缀写完 export 具体成员
// ./module/m1.js
export function add(x, y){return xy
}
export const name 枫枫
export const obj {name: fengfeng
}
script typemoduleimport {add, name, obj} from ./module/m1.js;
/script
export default
export default {obj: {name: 张三},add, // add: add,
}
script typemoduleimport m1 from ./module/m1.js;import {add, name, obj} from ./module/m1.js;
/script
立即执行函数实现模块化
除了可以用使用对象进行成员隔离
还可以使用立即执行函数创造一个封闭的代码空间
const m1 (function (){function add(a, b){return ab}return {add: add,}
}())const m2 (function (){function add(){return this is m2 add}return {add: add,}
}())console.log(m1.add(1,2))
console.log(m2.add())
模块化实现 IIFE就是匿名函数自执行的方式(闭包)
!-- 向window对象上添加全局属性也有的把这种方法叫做添加命名空间 --
!-- 目的就是向外暴露方法(接口),方法很好,但是多个模块之间有相互依赖关系就不好办了 --
script typetext/javascript(function(win){function aFn(){// ...}function bFn(){// ...}// 向外暴露方法es6的写法win.myMethod {aFn, bFn}})(window)
/script IIFE模式增强向入口中传入依赖的模块
!-- 假设依赖jq,这种方式引入的js文件、模块,必须有一定的先后顺序,否则报错undefined --
script typetext/javascript(function(win){function aFn(){$(body).css(...)}function bFn(){// ...}// 向外暴露方法es6的写法win.myMethod {aFn, bFn}})(window,jQuery);
/script
模块化的好处
!-- 在面试时背下来就好 -- 避免命名冲突减少命名空间污染 更好的分离按需加载 更高的复用性、高可维护性
引入多个script后会出现的问题
引入多个script之后会不可避免的出现请求的交叉 请求过多 依赖会乱掉依赖模糊 难以维护各种调用交织在一起
这也就促使真正上的模块化的出现就是后来的common.js,AMD,es6,CMD // sum.js
function sum(a,b){
return ab
}
scrtpt src./sum.js/scrtpt !-- 全局污染 --
scrtpt src./sum.js typemodule/scrtpt
导出
// sum.js
function sum(a,b){
return ab
}
export default sum; /* 不会污染全局 */
// main.js
import sum from ./sum.js;
console.log(sum);
scrtpt src./main.js typemodule/scrtpt 官方包管理 npmdd
社区包管理 yarn pnpm cnpm
npm i jquery
npm i jquery1 // 安装版本1
npm uninstall jquery
11、BOM浏览器对象模型
BOMBrowser Object Model浏览器对象模型 BOM的核心就是window对象 window是浏览器内置的一个对象里面包含着操作浏览器的方法
History 浏览器记录
history.back上一页相当于浏览器上的返回按钮
history.forword下一页相当于浏览器上的前进按钮
history.go(n) n为正时向前n页n为负时后退n页
button οnclickforword()前进/button
button οnclickback()后退/button
button οnclickgo(1)前进1页/button
button οnclickgo(-1)后退1页/button
scriptfunction forword(){history.forward()}function back(){history.back()}function go(n){history.go(n)}
/script
Location 浏览器地址
以http://do.com:3000/xx/yy?nameff为例除了源地址其他属性可以重新赋值
属性值说明location.portocolhttp:页面使用的协议通常是http:或https:location.hostnamedo.com服务器域名location.port3000请求的端口号location.hostdo.com:3000服务器名及端口号location.originhttp://do.com:3000url的源地址只读location.href完整的url地址等价于window.locationlocation.pathname/(这里指的是3000后面的/)url中的路径和文件名不会返回hash和search后面的内容只有当打开的页面是一个文件时才会生效location.search?nameff查询参数
location.reload() 刷新页面
location.replace() 替换页面 不会保留当前页面的历史记录因此用户无法通过浏览器的后退按钮返回到之前的页面
对话框
alert 提示框
console.log(alert(这是一个提示信息))
confirm 询问框
console.log(confirm(确定要删除吗)) // 阻塞代码
可以获取到用户点击的确定和取消的操作确定就是true取消就是false
prompt 输入框
console.log(prompt(今天晚上吃什么, 西北风)) // 阻塞代码
定时器
setTimeout 倒计时多少时间以后执行函数 语法setTimeout(要执行的函数多少时间以后执行) 单位是毫秒返回值是当前这个定时器是页面中的第几个定时器 可以使用clearTimeout关闭定时器
function handler(){console.log(handler)
}
setTimeout(handler, 3000)
const timer setTimeout(handler, 3000) // 页面中的第几个定时器
console.log(timer)
clearTimeout(timer) // 关闭定时器
setInterval 每隔多少时间执行一次函数 语法setInterval(要执行的函数间隔多少时间) 只要不关闭会一直执行 可以使用clearInterval关闭定时器
let count 0;
const timer1 setInterval((){if (count 3){clearInterval(timer1)return}console.log(new Date().toLocaleString())count
}, 1000) // 间隔执行第一个参数是函数第二个是间隔时间
console.log(timer1)
防抖和节流
用户点击按钮的时候点太快了点了两下那么这个函数就会被执行两次
debounce、throttle
防抖
在事件被触发n秒后执行回调如果在这n秒内事件又被触发则重新计时
类似于回城被打断就要重新开始重新计时
button οnclicknewHandler(hello)1/button
scriptfunction handler(name){console.log(被点击了, name)}function debounce(fn, delay) { // 函数,防抖时间let timer null;return function() {clearTimeout(timer); // 之前如果有计时器要清除timer setTimeout(() {fn.apply(this, arguments);}, delay);}}
/script
const newHandler debounce(handler, 300)
节流
在规定的单位时间内只能有一次触发事件的回调函数执行如果在同一时间内被触发多次只会生效一次
类似于技能CDCD没好你用不了技能
节流的逻辑要稍微复杂一点首先事件触发之后是要立即执行的后续再触发时间则要看看是不是在设定的时间阈值内在的话就不执行不在就立即执行
button οnclickthrottleHandler(hello)1/button
script
function throttle(fn, delay) {let timer null;let startTime Date.now(); // new Date().getTime()return function () {// 判断现在的时间const curTime Date.now();// 节流时间-两个时间的时间戳const remaining delay - (curTime - startTime);// 清除定时器clearTimeout(timer);// 已经超过时间差了直接执行if (remaining 0) {fn.apply(this, arguments);startTime Date.now();} else {// 还没到时间差设置一个定时器去执行timer setTimeout(() {fn.apply(this, arguments);startTime Date.now();}, remaining);}};
}
/script
const throttleHandler throttle(handler, 300)
window界面属性
屏幕窗口视口
console.log(视口, window.innerWidth, window.innerHeight)
console.log(窗口, window.outerWidth, window.outerHeight)
console.log(屏幕, window.screen.width, window.screen.height) 滚动相关
文档向右或者向下滚动的距离
scrollX scrollY 只针对body的滚动条才有效 定位scrollTo绝对scrollBy相对
// 滚动到页面左上角
window.scrollTo(0,0)
// 滚动到页面左边100像素和顶部200像素的位置
window.scrollTo(100,200)// 当前视口向下滚动100像素
window.scrollBy(0,100)
// 当前视口向右滚动40像素
window.scrollBy(40,0)
平滑滚动
// 平滑滚动
window.scrollTo({top: 1200, behavior: smooth})
Navigator浏览器信息
属性描述navigator.userAgent获取浏览器的整体信息navigator.appName获取浏览器名称navigator.appVersion获取浏览器的版本号navigator.platform获取当前计算机的操作系统
12、DOM文档对象模型
DOM是“Document Object Model”的首字母缩写即文档对象模型。用来描绘一个层次化的节点树允许开发人员获取、添加、移除和修改页面的某一部分元素
获取元素
通过id获取
const dom document.getElementById(box1)
console.log(dom)
通过css选择器获取
// console.log(document.getElementsByClassName(name))用的很少
console.log(document.querySelector(.name))
console.log(document.querySelector(#name))
console.log(document.querySelectorAll(.name))
Element元素对象
元素tag 标签名
dom.tagName // 获取标签名
属性
// 属性操作
const a document.getElementById(a)
// 获取属性
console.log(a.getAttribute(href))
// 设置、修改属性
a.setAttribute(href, https://www.fengfengzhidao.com)
// 删除属性
a.removeAttribute(xxx)
dataset 标签属性
可以以对象的形式获取、设置标签属性
div idbox data-name枫枫 !-- 必须带上data- --这是一个盒子
/div
scriptconst dom document.getElementById(box)// 获取console.log(dom.dataset.name)console.log(dom.dataset[name])console.log(dom.dataset)// 设置dom.dataset.addr 长沙市// 删除delete dom.dataset.name// 可以使用自定义属性的方式console.log(dom.getAttribute(data-addr))
/script
classList class名
以数组的形式获取、操作标签的class
div classbox /div
scriptconst box document.querySelector(.box)console.log(box.classList)// 添加标签类名box.classList.add(head)// 是否包含console.log(box.classList.contains(head))// 有就删除没有就创建box.classList.toggle(footer)box.classList.toggle(footer)// 删除box.classList.remove(head)// 替换box.classList.replace(box, box1)
/script
outerHTML、innerHTML、innerText
div idboxa hrefhtt://www.fengfengzhidao.com点我/aspan你好/span
/div
scriptconst box document.getElementById(box)console.log(box.innerText)console.log(box.innerHTML)console.log(box.outerHTML)
// box.innerText axxx/a
// box.innerHTML divspan234/span/div
// box.outerHTML axxx/a
/script
style 样式
设置或读取css样式
如果通过 style 属性去获取样式则只能获取行内样式不能获取其他地方的样式 对于 - 相连的css属性名要么使用 [] 来调用属性要么转换成小驼峰命名的方式 div classname stylefont-size: 20px; background-color: #800e0e; color: white枫枫知道/div
scriptconst dom document.querySelector(.name)// 获取样式console.log(dom.style.fontSize)console.log(dom.style.backgroundColor)console.log(dom.style.color)console.log(dom.style.textAlign) // 只能获取行内的其他地方的获取不到// 设置样式dom.style.fontSize 30pxdom.style.padding 30px
/script
可以通过 getComputedStyle 可以获取到的元素的计算之后的样式信息
console.log(getComputedStyle(dom).textAlign) // 获取计算后的style样式
节点操作
节点的操作主要就是增删改查
创建节点
document.createElement
// 创建节点
const dom document.createElement(a)
dom.setAttribute(href, https://www.fengfengzhidao.com)
dom.innerText 枫枫知道
插入子节点
给一个已知的节点去插入一个新的节点
appendChild在父节点的最后一个子节点后插入一个节点
append在父节点的最后一个子节点后插入多个不同的节点
insertBefore在父节点的子节点之前插入节点,第二个参数为null就是append
// 插入子节点
const box document.getElementById(box)
// box.appendChild(dom)
// box.append(dom)// 在任意位置之前插入
// box.insertBefore(dom, null) // 在末尾插入
// box.insertBefore(dom, box.children[1]) // 在第二个元素前插入
// box.insertBefore(dom, document.querySelector(.d2))
添加兄弟节点
after 在后面插入
before 在前面插入
const d1 document.querySelector(.d1)
// d1.before(dom) // 在d1的前面插入
d1.after(dom) // 在d1的后面插入
删除节点
node.removeChild() 从DOM中删除一个子节点。返回删除的节点
node.remove() 删除自身没有返回值
const d2 document.querySelector(.d2)
console.log(d2.removeChild(d2.querySelector(.dd2))) // 删除子节点并返回被删除的子节点d2.remove() // 删除自己
父子节点
const d2 document.querySelector(.d2)
console.log(d2.children) // 获取它的子节点列表
console.log(d2.parentNode) // 获取它的父亲节点
事件
JS事件就是用户或浏览器本身的某种行为一般是用户对页面的一些动作引起的
例如单击某个链接或按钮、在文本框中输入文本、按下键盘上的某个按键、移动鼠标等等
当事件发生时您可以使用 JavaScript 中的事件处理程序也可称为事件监听器来检测并执行某些特定的程序。
一般情况下事件的名称都是以单词on开头的例如点击事件 onclick、页面加载事件 onload 等
事件有三种绑定方式分别是
在标签上绑定事件
input placeholder用户名 οninputinput(event)
button点我/button
scriptfunction input(e){console.log(e.target.value)}
/script
在dom中绑定事件
const btn document.querySelector(.btn)
btn.onclick function (e){console.log(e.target) // 获取被点击的dom对象
}
添加事件监听
function click(e){console.log(e.target)
}
btn.addEventListener(click, click)// btn.addEventListener(click, function (e){
// console.log(2, e.target)
// })// 移除事件
const removeEvent document.querySelector(.remove_event)
removeEvent.onclick function (){btn.removeEventListener(click, click)
}
需要记住的一些事件
load 加载完成
resize 窗口大小变化
scroll 滚动事件blur 失去焦点
focus 获得焦点click 用户单击鼠标左键或按下回车键触发
dbclick 用户双击鼠标左键触发。
mousedown 在用户按下了任意鼠标按钮时触发
mouseenter 在鼠标光标从元素外部首次移动到元素范围内时触发。此事件不冒泡
mouseleave 元素上方的光标移动到元素范围之外时触发。不冒泡
mousemove 光标在元素的内部不断的移动时触发
mouseover 鼠标指针位于一个元素外部然后用户将首次移动到另一个元素边界之内时触发
mouseout 用户将光标从一个元素上方移动到另一个元素时触发
mouseup 在用户释放鼠标按钮时触发keydown 当用户按下键盘上的任意键时触发。按住不放会重复触发
keypress 当用户按下键盘上的字符键时触发。按住不放会重复触发
keyup 当用户释放键盘上的键时触发
textInput 这是唯一的文本事件用意是将文本显示给用户之前更容易拦截文本
事件描述onchangeHTML 元素改变onclick用户点击 HTML 元素onmouseover鼠标指针移动到指定的元素上时发生onmouseout用户从一个 HTML 元素上移开鼠标时发生onkeydown用户按下键盘按键onload浏览器已完成页面的加载
事件冒泡
当一个事件被触发时它首先在最内层的元素也称为目标元素或事件源上发生
然后这个事件会向上冒泡依次触发其父元素上的同一类型事件一直冒泡到最外层元素通常是document对象
这种冒泡机制允许我们在父元素上设置事件处理器以便在子元素的事件发生时执行特定的操作
style.p2{display: flex;justify-content: center;align-items: center;}
/style
div classp1div classp2div classp3我是p3/div/div
/div
scriptconst p1 document.querySelector(.p1)const p2 document.querySelector(.p2)const p3 document.querySelector(.p3)p3.onclick function (e){console.log(p3, e.target)}p2.onclick function (e){console.log(p2, e.target)// event.stopPropagation() // 阻止冒泡}p1.onclick function (e){console.log(p1, e.target)}
/script
阻止冒泡
event.stopPropagation()
阻止事件的默认行为
常规情况下点击a标签会自动跳转至页面这是事件的默认行为若不想要这个效果即可使用阻止事件的默认行为即可实现
a hrefbaidu.com百度/a
scriptconst a document.querySelector(a)a.onclick function(e){console.log(e.target)e.preventDefault() // 阻止事件的默认行为}
/script
很多网站都有点击外部链接会有安全提示
const a document.querySelector(a)
a.onclick function (e){const ok confirm(你确定要访问 ${e.target.getAttribute(href)}吗)if (!ok){e.preventDefault() // 取消标签的默认行为}
}
事件委托
事件委托又叫事件代理。事件委托就是利用事件冒泡只指定一个事件处理程序就可以管理某一类型的所有事件
比如说有100个子节点像实现点击子节点执行某个函数给100个子节点去绑定事件明显不划算就可以通过事件委托来实现
div classboxdiv classs s1s1/divdiv classs s2s2/divdiv classs s3s3/divdiv classs s4s4/divdiv classs s5s5/div
/div
scriptconst box document.querySelector(.box)box.onclick function (e){console.log(e.target)}
/script
事件循环
JavaScript事件循环是一种机制用于处理异步事件和回调函数。它是JavaScript运行时环境的一部分负责管理事件队列和调用栈
事件循环的基本原理是事件循环的核心是一个事件队列所有的事件都被放入这个队列中然后按照顺序依次执行。如果队列为空JavaScript会等待新的任务加入队列。当JavaScript代码执行时所有同步任务都会被立即执行而异步任务则会被放入事件队列中
当所有同步任务执行完毕后事件循环会从事件队列中取出一个任务并将其放入调用栈中执行。当该任务执行完毕后事件循环会再次从事件队列中取出下一个任务并重复这个过程
// 什么是异步任务
console.log(1)
setTimeout(() {console.log(3)
}, 0)
console.log(2)
// 顺序 1 2 3
// 当同步任务执行完之后才会从任务队列中执行异步任务
宏任务和微任务
异步任务也分宏任务和微任务
宏任务包括setTimeout、setInterval、I/O操作等
微任务包括Promise、MutationObserver等
当事件循环从事件队列中取出一个任务时它会先执行所有微任务然后再执行一个宏任务。这个过程会一直重复直到事件队列中的所有任务都被执行完毕
console.log(1);
setTimeout(function() { console.log(2); Promise.resolve().then(function() { console.log(3); });
}, 0); Promise.resolve().then(function() { console.log(4);
});
console.log(5);
// 输出结果为 1 5 4 2 3
执行顺序 执行第一个console.log输出1。 执行setTimeout将其回调函数放入宏任务队列中。 执行Promise.resolve().then将其回调函数放入微任务队列中。 执行第二个console.log输出5。 当前任务执行结束执行微任务队列中的所有任务输出4。 执行宏任务队列中的第一个任务即setTimeout的回调函数输出2。 执行Promise.resolve().then的回调函数输出3。
需要注意的是微任务和宏任务的执行顺序是固定的即先执行所有微任务再执行宏任务。因此如果在一个宏任务中产生了新的微任务那么这些微任务会在下一个宏任务执行之前执行。
console.log(1); setTimeout(function() { console.log(2); Promise.resolve().then(function() { console.log(3); });
}, 0); Promise.resolve().then(function() { console.log(4); setTimeout(function() { console.log(5); }, 0);
}); console.log(6); // 输出结果为1 6 4 2 3 5
执行顺序 执行第一个console.log输出1。 执行setTimeout将其回调函数放入宏任务队列中。 执行Promise.resolve().then将其回调函数放入微任务队列中。 执行第三个console.log输出6。 当前任务执行结束执行微任务队列中的所有任务输出4。 执行宏任务队列中的第一个任务即setTimeout的回调函数输出2。 执行Promise.resolve().then的回调函数将setTimeout的回调函数放入宏任务队列中。 当前任务执行结束执行微任务队列中的所有任务输出3。 执行宏任务队列中的第一个任务即setTimeout的回调函数输出5
!-- --
es6
解构赋值
// 一般用常量const声明需要改的时候在改成变量let
const [a, b, c] [1, 2, 3]
const str abc${a}
const { username, age:userAge, ...otherInfo } {username: 杨小槿,age: 18,gender: male,category: user
}
console.log(username, userAge, otherInfo)
数组和对象的扩展
const arr1 [1, 2, 3]
const arr2 [4, 5, 6]
const arr3 [...arr1, ...arr2, 10]
const obj1 {a:1
}
const obj2 {b:2,...obj1
}
// 数组方法 Array.from() arguments打印实参
function fn(){console.log(arguments)arguments.push(1)
}
fn(1,2,3,4)
// ------------
function fn(){Array.from(arguments).forEach(function(item){console.log(item)})
}
fn(1,2,3,4)
// 对象方法 Object.assign()
const objA {name: 杨小槿,age: 18
}
const objB Object.assign({}, objA) // Object.assign({},objA,objB,objC)
objB.namea
console.log(objA,objB)
Class
class A{constructor (name, age) {this.name namethis.age age}introduce(){console.log(我的名字是${this.name},年龄${this.age})}
}
const a1 new A(杨小槿, 18)
a1.introduce()class B extends A {constructor (name, age, gender) {super(name, age)this.gender gender}sayHello(){console.log(泥蒿this.name)}
}
const b1 new B(小李, 19, 女)
b1.introduce()
b1.sayHello()
箭头函数
const getSum1 function(n){return n3
}
const getSum1 n n 3
console.log(getSum1(10))
const getSum2 (n1, n2) n1 n2
const getSum3 (n1, n2, ...other) console.log(n1, n2, other)
getSum3(10, 20, 100, 200, 300)const getSum1 n {return n 3
}
异步处理
promise解决异步写法中的嵌套问题
const p1 new Promise((resolve, reject){resolve(任务成功得到的数据)//reject()
})
p1.then(data {console.log(data)
})
const p1 new Promise((resolve, reject){// resolve(任务成功得到的数据)reject(任务失败得到的数据)
})
p1.then(data {console.log(data)return new Promise((resolve, reject){// resolve(任务成功得到的数据)reject(任务失败得到的数据)
})
})
.catch(err {console,log(err)
})
// Async await
function asyncTask(){return new Promise((resolve, reject){const isSuccess trueif (isSuccess){resolve(任务二的成功处理结果)} else {reject(任务二的失败处理结果)}})
}async function main(){console.log(任务一)cost data await asyncTask()console.log(data)console.log(任务三)
}
main()
// Proxy代理对象
const obj {name:杨小槿, age:18}
const container document.getElementById(container)
container.textContent obj.name
obj.name abc
......