好久没更新了
@ -186,5 +186,13 @@ overflow-x:auto(滚动条)/ hidden (隐藏) 横向内容溢出的表现
|
||||
|
||||
overflow-y:auto(滚动条)/ hidden (隐藏) 纵向内容溢出的表现
|
||||
|
||||
verticle-align 设置元素的垂直对齐方式
|
||||
属性值:
|
||||
* baseline 默认值,元素放置在父元素的基线上
|
||||
* text-top 元素顶端和父元素字体顶端对齐
|
||||
* text-bottom 元素顶端和父元素字体底部对齐
|
||||
* middle 元素位于父元素的中部
|
||||
...
|
||||
|
||||
|
||||
|
||||
|
@ -115,7 +115,7 @@ css 盒模型包括如下要素
|
||||
width:300px;
|
||||
height:300px;
|
||||
background-color:red;
|
||||
margin-top:20px;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
#inner {
|
||||
|
BIN
csspress/4.flex.assets/image-20210222165013291.png
Normal file
After Width: | Height: | Size: 67 KiB |
@ -7,16 +7,9 @@ flex 意为弹性盒子,用来为盒模型提供最大的灵活性
|
||||
任何一个元素都能被指定为flex 容器
|
||||
|
||||
```
|
||||
/*
|
||||
选中元素为块级元素时
|
||||
*/
|
||||
display:flex
|
||||
display:flex 选中元素为块级元素时
|
||||
|
||||
|
||||
/*
|
||||
选中元素为内联元素时
|
||||
*/
|
||||
display:inline-flex
|
||||
display:inline-flex 选中元素为内联元素时
|
||||
```
|
||||
|
||||
### 基本概念
|
||||
@ -35,13 +28,24 @@ display:inline-flex
|
||||
|
||||
当 flex-direction 的值为column时 主轴为竖直 侧轴为水平
|
||||
|
||||
![image-20210120143705542](E:\web\lessons\课件\csspress\4.flex.assets\image-20210120143705542.png)
|
||||
![image-20210222165013291](\4.flex.assets\image-20210222165013291.png)
|
||||
|
||||
|
||||
|
||||
![image-20210120143705542](\4.flex.assets\image-20210120143705542.png)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 容器的属性
|
||||
|
||||
- flex-direction 声明容器使用的轴是水平的还是垂直的
|
||||
- row 水平
|
||||
- column 垂直
|
||||
- row 水平(起点在左)
|
||||
- column 垂直 (起点在上)
|
||||
- row-reverse 水平(起点在右)
|
||||
- column-reverse 垂直(起点在下)
|
||||
|
||||
- justify-content 声明排列的方式
|
||||
- center 居中
|
||||
- space-around 每个项目两侧的间隔相等 项目到边框有间距
|
||||
@ -53,7 +57,7 @@ display:inline-flex
|
||||
- baseline 第一行文字的基线对齐
|
||||
- stretch 默认占满整个容器的高度
|
||||
|
||||
![image-20210120113341512](E:\web\lessons\课件\csspress\4.flex.assets\image-20210120113341512.png)
|
||||
![image-20210120113341512](\4.flex.assets\image-20210120113341512.png)
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
@ -103,7 +107,7 @@ display:inline-flex
|
||||
|
||||
##### center: 水平居中
|
||||
|
||||
![image-20210120114326831](E:\web\lessons\课件\csspress\4.flex.assets\image-20210120114326831.png)
|
||||
![image-20210120114326831](\4.flex.assets\image-20210120114326831.png)
|
||||
|
||||
```
|
||||
.box{
|
||||
@ -120,7 +124,7 @@ display:inline-flex
|
||||
|
||||
##### space-around 每个项目两侧的间隔相等 项目到边框有间距
|
||||
|
||||
![image-20210120114504619](E:\web\lessons\课件\csspress\4.flex.assets\image-20210120114504619.png)
|
||||
![image-20210120114504619](\csspress\4.flex.assets\image-20210120114504619.png)
|
||||
|
||||
```
|
||||
.box{
|
||||
@ -137,7 +141,7 @@ display:inline-flex
|
||||
|
||||
##### space-between 两端对齐 项目之间的间隔都相等
|
||||
|
||||
![image-20210120114721023](E:\web\lessons\课件\csspress\4.flex.assets\image-20210120114721023.png)
|
||||
![image-20210120114721023](\4.flex.assets\image-20210120114721023.png)
|
||||
|
||||
|
||||
|
||||
|
@ -75,6 +75,50 @@
|
||||
|
||||
通过’%‘单位来实现响应式效果。浏览器高度和宽度发生变化时,通过百分比单位可以使元素的高和宽随着浏览器的变化而变化,从而实现响应式效果
|
||||
|
||||
可以取百分比的属性:
|
||||
* 定位:top, right, bottom, left
|
||||
* 盒模型:width,height, margin,padding
|
||||
* 背景:backgroug-position, backgroud-size
|
||||
* 文本:text-indent
|
||||
* 字体:font-size
|
||||
|
||||
css 百分比都相对于谁?
|
||||
结论:css的布局块都是盒子,然后一个盒子的百分比其实是相对于其包含块的,也就是他的父级元素。
|
||||
* 相对于父级宽度的:
|
||||
* width
|
||||
* max-width
|
||||
* min-width
|
||||
* padding
|
||||
* margin
|
||||
* text-indent
|
||||
* left
|
||||
* right
|
||||
...
|
||||
|
||||
* 相对于父级高度的:
|
||||
* height
|
||||
* max-height
|
||||
* min-height
|
||||
* top
|
||||
* bottom
|
||||
|
||||
* 相对于主轴长度(在flex弹性盒子布局中)
|
||||
* flex-basis
|
||||
|
||||
* 相对于继承字号的
|
||||
* font-size
|
||||
|
||||
* 相对于自身字号的
|
||||
* line-height
|
||||
|
||||
* 相对于自身宽高的
|
||||
* border-radius 等border相关
|
||||
* background-size
|
||||
...
|
||||
|
||||
* 相对于行高的
|
||||
* verticle-align (设置元素垂直对齐方式)
|
||||
|
||||
示例:
|
||||
|
||||
```
|
||||
@ -195,5 +239,8 @@ rem是一个相对单位,1rem等于html元素上字体设置的大小。我们
|
||||
|
||||
2.根据设计稿大小,调整里面的最后两个参数值。
|
||||
|
||||
3.使用1rem=100px转换你的设计稿的像素,例如设计稿上某个块是100px*300px,换算成rem则为1rem*3rem。
|
||||
3.使用1rem=100px转换你的设计稿的像素,例如设计稿上某个块是100px * 300px,换算成rem则为1rem*3rem。
|
||||
|
||||
示例参考demo/rem.html
|
||||
|
||||
|
||||
|
BIN
csspress/css实战(一).assets/image-20210223151126809.png
Normal file
After Width: | Height: | Size: 294 KiB |
BIN
csspress/css实战(一).assets/image-20210223174608465.png
Normal file
After Width: | Height: | Size: 375 KiB |
BIN
csspress/css实战(一).assets/image-20210223180430143.png
Normal file
After Width: | Height: | Size: 373 KiB |
BIN
csspress/css实战(一).assets/image-20210223180523455.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
csspress/css实战(一).assets/image-20210223181949796.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
csspress/css实战(一).assets/image-20210223182049992.png
Normal file
After Width: | Height: | Size: 355 KiB |
BIN
csspress/css实战(一).assets/image-20210223182258454.png
Normal file
After Width: | Height: | Size: 333 KiB |
BIN
csspress/css实战(一).assets/image-20210223182345438.png
Normal file
After Width: | Height: | Size: 270 KiB |
BIN
csspress/css实战(一).assets/image-20210223182428924.png
Normal file
After Width: | Height: | Size: 142 KiB |
BIN
csspress/css实战(一).assets/image-20210223182524394.png
Normal file
After Width: | Height: | Size: 495 KiB |
43
csspress/css实战(一).md
Normal file
@ -0,0 +1,43 @@
|
||||
# css实战阶段一
|
||||
### 苏宁易购
|
||||
|
||||
#### 顶部导航栏:
|
||||
|
||||
![image-20210223180523455](E:\web\lessons\课件\csspress\css实战(一).assets\image-20210223180523455.png)
|
||||
|
||||
|
||||
|
||||
说明: 写完顶部导航条以后需要加上下面的白色下拉框的内容 本阶段可以一直显示
|
||||
|
||||
### 白色的标题搜索栏
|
||||
|
||||
![image-20210223181949796](E:\web\lessons\课件\csspress\css实战(一).assets\image-20210223181949796.png)
|
||||
|
||||
|
||||
|
||||
### 分类
|
||||
|
||||
![image-20210223182049992](E:\web\lessons\课件\csspress\css实战(一).assets\image-20210223182049992.png)
|
||||
|
||||
|
||||
|
||||
### 热卖爆款
|
||||
|
||||
![image-20210223182258454](E:\web\lessons\课件\csspress\css实战(一).assets\image-20210223182258454.png)
|
||||
|
||||
|
||||
### 冰箱洗衣机
|
||||
|
||||
![image-20210223182345438](E:\web\lessons\课件\csspress\css实战(一).assets\image-20210223182345438.png)
|
||||
|
||||
|
||||
|
||||
### 底部导航
|
||||
|
||||
![image-20210223182428924](E:\web\lessons\课件\csspress\css实战(一).assets\image-20210223182428924.png)
|
||||
|
||||
|
||||
|
||||
### 固定的侧边栏
|
||||
|
||||
![image-20210223182524394](E:\web\lessons\课件\csspress\css实战(一).assets\image-20210223182524394.png)
|
52
csspress/demo/absolute.html
Normal file
@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.box1 {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: yellow;
|
||||
margin: 20px;
|
||||
/* position:static */
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
background: red;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box1">
|
||||
<div class="box2"></div>
|
||||
</div>
|
||||
<p>
|
||||
<p> 注:这里红色的div是依据 body定位的,而不是根据父元素黄色的div 定位,</p>
|
||||
<p> 加上position static 后也是根据body 定位,</p>
|
||||
<p>当父元素的Position声明为 absolute 时,红色会依据父级黄色定位,但是会超脱文档流,影响下面的元素</p>
|
||||
|
||||
|
||||
|
||||
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
46
csspress/demo/fixed.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body{
|
||||
overflow: auto;
|
||||
}
|
||||
.box1 {
|
||||
background: yellow;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
/* height: 50px; */
|
||||
}
|
||||
|
||||
.box2 {
|
||||
height: 20px;
|
||||
position: fixed;
|
||||
top: 30px;
|
||||
width: 100%;
|
||||
background: red;
|
||||
}
|
||||
.box3{
|
||||
width: 60px;
|
||||
height: 900px;
|
||||
background: pink;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box1">暖暖</div>
|
||||
<div class="box2"></div>
|
||||
<div class="box3"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,57 +1,107 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
*{
|
||||
margin:0;
|
||||
padding:0;
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.box{
|
||||
|
||||
.box {
|
||||
width: 1000px;
|
||||
height: 500px;
|
||||
background: pink;
|
||||
display:flex;
|
||||
display: flex;
|
||||
/* 通过display:flex来把目标元素设置成flex布局 */
|
||||
flex-direction: row;
|
||||
/* align-items: center; */
|
||||
justify-content: space-between;
|
||||
/* flex-direction 属性决定主轴的方向,值为row的时候水平排列 起点在左 */
|
||||
}
|
||||
.box1{
|
||||
|
||||
.box1 {
|
||||
width: 1000px;
|
||||
height: 500px;
|
||||
background: gold;
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
/*
|
||||
justify-content: space-between;
|
||||
justify-content: space-around;
|
||||
justify-content: space-center;
|
||||
*/
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.left,.left1{
|
||||
|
||||
.left,
|
||||
.left1 {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: red;
|
||||
}
|
||||
.right,.right1{
|
||||
|
||||
.right,
|
||||
.right1 {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: blue;
|
||||
}
|
||||
|
||||
.box3 {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.box4 {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box">
|
||||
<div class="box" style="margin-bottom: 15px;">
|
||||
|
||||
<div class="left"></div>
|
||||
<div class="right"></div>
|
||||
<div>
|
||||
这里是flex-direction:row的状况 即水平排列 起点在左侧
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="left"></div>
|
||||
<div class="left"></div>
|
||||
<div class="left"></div>
|
||||
<div class="left"></div>
|
||||
<div class="left"></div>
|
||||
<div class="left"></div>
|
||||
<div class="right"></div>
|
||||
<div>
|
||||
这里是flex-direction:row的状况 即水平排列 起点在左侧
|
||||
对于溢出的状况,flex-wrap 可以定义是否换行
|
||||
<P>默认属性值为 nowrap 不换行;其他属性还有wrap(换行), wrap-reverse(换行,第二行反向排列)</P>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box1">
|
||||
<div class="left1"></div>
|
||||
|
||||
<div class="right1"></div>
|
||||
<div class="left1"></div>
|
||||
<div>
|
||||
这里是flex-direction:column的状况 即垂直排列 起点在上面
|
||||
</div>
|
||||
</div>
|
||||
<div class="box box3">
|
||||
<div class="left"></div>
|
||||
<div class="right"></div>
|
||||
<div>
|
||||
这里是flex-direction:column的状况 即垂直排列 起点在下面
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="box1 box4">
|
||||
|
||||
<div class="right1"></div>
|
||||
<div class="left1"></div>
|
||||
<div>
|
||||
这里是flex-direction:column-reverse的状况 即垂直排列 起点在下面
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
86
csspress/demo/flex1pailie.html
Normal file
@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
*{
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
.box{
|
||||
width: 1000px;
|
||||
height: 500px;
|
||||
background: pink;
|
||||
|
||||
display:flex;
|
||||
/* 通过display:flex来把目标元素设置成flex布局 */
|
||||
flex-direction: row;
|
||||
/* flex-direction 属性决定主轴的方向,值为row的时候水平排列 起点在左 */
|
||||
|
||||
justify-content: center;
|
||||
}
|
||||
.box1{
|
||||
width: 1000px;
|
||||
height: 500px;
|
||||
background: gold;
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
}
|
||||
.left,.left1{
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: red;
|
||||
}
|
||||
.right,.right1{
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: blue;
|
||||
}
|
||||
.box3{
|
||||
justify-content: space-around;
|
||||
}
|
||||
.box4{
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="margin-bottom: 50px;">
|
||||
注:以下所有实例 基于flex-direction:row的情况,即水平排列 起点在左边
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="left"></div>
|
||||
<div class="right"></div>
|
||||
|
||||
</div>
|
||||
<div style=" margin-bottom: 30px;">
|
||||
上面是 justify-content:center 居中的状况
|
||||
</div>
|
||||
|
||||
<div class="box1">
|
||||
<div class="left"></div>
|
||||
<div class="right"></div>
|
||||
|
||||
</div>
|
||||
<div style=" margin-bottom: 30px;">
|
||||
上面是 justify-content:space-between 居中的状况
|
||||
两端对齐 项目之间的间隔都相等
|
||||
</div>
|
||||
|
||||
<div class="box box3">
|
||||
<div class="left"></div>
|
||||
<div class="right"></div>
|
||||
|
||||
</div>
|
||||
<div style=" margin-bottom: 30px;">
|
||||
上面是 justify-content:space-around 居中的状况
|
||||
每个项目两侧的间隔相等 项目到边框有间距
|
||||
即两端不对齐
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
112
csspress/demo/flexjiaochazhou.html
Normal file
@ -0,0 +1,112 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
*{
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
.box{
|
||||
width: 1000px;
|
||||
height: 500px;
|
||||
background: pink;
|
||||
display:flex;
|
||||
/* 通过display:flex来把目标元素设置成flex布局 */
|
||||
flex-direction: row;
|
||||
/* flex-direction 属性决定主轴的方向,值为row的时候水平排列 起点在左 */
|
||||
|
||||
align-items: center;
|
||||
}
|
||||
.box1{
|
||||
width: 1000px;
|
||||
height: 500px;
|
||||
background: gold;
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
|
||||
}
|
||||
.left,.left1{
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: red;
|
||||
}
|
||||
.right,.right1{
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: blue;
|
||||
}
|
||||
.box3{
|
||||
align-items: flex-end;
|
||||
}
|
||||
.box4{
|
||||
align-items: baseline ;
|
||||
}
|
||||
.box5{
|
||||
align-items: stretch;
|
||||
}
|
||||
.lefta{
|
||||
height:auto
|
||||
}
|
||||
.boxfin{
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="margin-bottom: 50px;">
|
||||
注:以下所有实例 基于flex-direction:row的情况,即水平排列 起点在左边
|
||||
且 主轴为默认
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="left"></div>
|
||||
<div class="right"></div>
|
||||
</div>
|
||||
<div style=" margin-bottom: 30px;">
|
||||
上面是 align-items:center 居中的状况
|
||||
</div>
|
||||
|
||||
<div class="box1">
|
||||
<div class="left"></div>
|
||||
<div class="right"></div>
|
||||
|
||||
</div>
|
||||
<div style=" margin-bottom: 30px;">
|
||||
上面是 align-items: flex-start; 起点在上面
|
||||
</div>
|
||||
|
||||
<div class="box box4">
|
||||
<div class="left"></div>
|
||||
<div class="right"></div>
|
||||
|
||||
</div>
|
||||
<div style=" margin-bottom: 30px;">
|
||||
上面是 align-items:base-line 项目的第一行文字的基线对齐的情况
|
||||
</div>
|
||||
|
||||
<div class="box1 box5">
|
||||
<div class="left lefta"></div>
|
||||
<div class="right lefta"></div>
|
||||
|
||||
</div>
|
||||
<div style=" margin-bottom: 30px;">
|
||||
上面是 align-items:stretch(默认值) 如果项目未设置高度或设为auto,将占满整个容器的高度。
|
||||
</div>
|
||||
|
||||
<div class="box1 boxfin">
|
||||
<div class="left"></div>
|
||||
<div class="right"></div>
|
||||
|
||||
</div>
|
||||
<div class="zong">
|
||||
总结1:flex-direction属性定义的是主轴方向,默认为水平,所以 交叉轴方向默认为垂直;
|
||||
<p>当 flex-direction的值为column的时候,align-items决定的就是垂直方向的排列方式</p>
|
||||
<b>align-items决定的是交叉轴的排列方式 而不一定是单指 垂直的排列方式</b>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
35
csspress/demo/relative.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
div{
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.box1 {
|
||||
background: yellow;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
background: red;
|
||||
position: relative;
|
||||
top: 20px;
|
||||
left: 30px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box1">暖暖</div>
|
||||
<div class="box2"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -38,6 +38,6 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
媒体查询实现自适应
|
||||
</body>
|
||||
</html>
|
@ -1,50 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
document.querySelectorAll
|
||||
</script>
|
||||
<style>
|
||||
*{
|
||||
margin:0px;
|
||||
margin:0;
|
||||
padding: 0;
|
||||
}
|
||||
html , body{
|
||||
width:100% ;
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.box{
|
||||
width: 100%;
|
||||
height: 60%;
|
||||
border: 1px solid black;
|
||||
}
|
||||
.content{
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
width: 30%;
|
||||
height: 30%;
|
||||
background: pink;
|
||||
margin: 30px;
|
||||
}
|
||||
/* @media (max-width: 780px) {
|
||||
.box{
|
||||
width: 600px;
|
||||
}
|
||||
.content{
|
||||
background: skyblue;
|
||||
}
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.box{
|
||||
width: 500px;
|
||||
}
|
||||
.content{
|
||||
background: rgb(135, 235, 202);
|
||||
}
|
||||
} */
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box">
|
||||
<!-- <div class="content"></div> -->
|
||||
</div>
|
||||
百分比实现自适应
|
||||
<div class="box"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
117
csspress/实战/xuechengzaixian.html
Normal file
@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.nav{
|
||||
width: 100%;
|
||||
height: 66px;
|
||||
vertical-align:middle;
|
||||
line-height: 66px;
|
||||
background: #f4f5f7;
|
||||
font-size: 13px;
|
||||
}
|
||||
.main{
|
||||
width: 938px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.left{
|
||||
display: flex;
|
||||
}
|
||||
.logo{
|
||||
width: 132px;
|
||||
height: 29px;
|
||||
background-color: aqua;
|
||||
margin: auto 0;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.menu{
|
||||
list-style: none;
|
||||
display: inline-flex;
|
||||
}
|
||||
.menu li{
|
||||
margin-right: 27px;
|
||||
}
|
||||
.search{
|
||||
width: 180px;
|
||||
height: 28px;
|
||||
border-radius: 4px;
|
||||
outline: none;
|
||||
border: 0px;
|
||||
padding-left: 20px;
|
||||
margin-left: 1px;
|
||||
}
|
||||
.right{
|
||||
display: flex;
|
||||
}
|
||||
.msg{
|
||||
width: 10px;
|
||||
height: 20px;
|
||||
background: black;
|
||||
margin: auto 0;
|
||||
margin-left: 11px;
|
||||
margin-right: 11px;
|
||||
}
|
||||
.photo{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 60%;
|
||||
background: white;
|
||||
margin: auto 0;
|
||||
margin-right: 11px;
|
||||
}
|
||||
.searchbox{
|
||||
background: #00a4ff;
|
||||
height: 32px;
|
||||
margin: auto 0;
|
||||
line-height:29px;
|
||||
margin-right:19px
|
||||
}
|
||||
.searchbox span{
|
||||
|
||||
color: white;
|
||||
padding:5px 19px;
|
||||
|
||||
}
|
||||
.icon{
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="nav">
|
||||
<div class="main">
|
||||
<div class="left">
|
||||
|
||||
<img src="" alt="" class="logo">
|
||||
<ul class="menu">
|
||||
<li>首页</li>
|
||||
<li>课程</li>
|
||||
<li>职业规划</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="searchbox">
|
||||
<input type="text" placeholder="输入关键字" class="search">
|
||||
<span>搜索</span>
|
||||
</div>
|
||||
|
||||
<p>个人中心</p>
|
||||
<div class="msg"></div>
|
||||
<div class="photo"></div>
|
||||
<p>asd</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
9
es6/a.js
Normal file
@ -0,0 +1,9 @@
|
||||
const sqrt = Math.sqrt;
|
||||
function square(x) {
|
||||
return x * x;
|
||||
}
|
||||
function diag(x, y) {
|
||||
return sqrt(square(x) + square(y));
|
||||
}
|
||||
|
||||
export {sqrt, square, diag}
|
78
es6/async.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
// const fs = require('fs');
|
||||
|
||||
// const readFile = function (fileName) {
|
||||
// return new Promise(function (resolve, reject) {
|
||||
// fs.readFile(fileName, function (error, data) {
|
||||
// if (error) return reject(error);
|
||||
// resolve(data);
|
||||
// });
|
||||
// });
|
||||
// };
|
||||
|
||||
// const gen = function* () {
|
||||
// const f1 = yield readFile('/etc/fstab');
|
||||
// const f2 = yield readFile('/etc/shells');
|
||||
// console.log(f1.toString());
|
||||
// console.log(f2.toString());
|
||||
// };
|
||||
// // *是 Generator 的声明
|
||||
|
||||
|
||||
// const gen2 = async function () {
|
||||
// const f1 = await readFile("file1")
|
||||
// const f2 = await readFile("file2")
|
||||
// console.log(f1.toString())
|
||||
// console.log(f2.toString())
|
||||
// }
|
||||
// // async 声明这个函数是 异步函数 只有在被async修饰的函数中,才能使用await 关键字
|
||||
// // await 等待后面的操作完成后才继续执行
|
||||
|
||||
|
||||
// async function getStockPriceByName(name) {
|
||||
// const symbol = await getStockSymbol(name);
|
||||
// const stockPrice = await getStockPrice(symbol);
|
||||
// return stockPrice;
|
||||
// }
|
||||
|
||||
// getStockPriceByName('goog').then(function (result) {
|
||||
// console.log(result);
|
||||
// });
|
||||
|
||||
|
||||
async function testAsync() {
|
||||
return "hello async";
|
||||
}
|
||||
async function t1(){
|
||||
var data = testAsync();
|
||||
console.log(data)
|
||||
}
|
||||
async function t2(){
|
||||
var data = await testAsync();
|
||||
console.log(data)
|
||||
}
|
||||
t1() //没加await修饰的时候 返回的是promise对象
|
||||
t2() // 加了await的时候 返回的是promise对象中的value的值 即 hello async!
|
||||
|
||||
|
||||
|
||||
// var list =await getlist("url");
|
||||
// var uinfo =await getinfo("url");
|
||||
// 。。。
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
68
es6/b.js
Normal file
@ -0,0 +1,68 @@
|
||||
import { square, diag } from './a.js';
|
||||
console.log(square(11)); // 121
|
||||
console.log(diag(4, 3)); // 5
|
||||
|
||||
|
||||
// promise 构造函数接受一个函数作为参数,该函数的两个参数分别是resolve,reject
|
||||
// 成功时调用resolve函数,失败时调用reject函数
|
||||
|
||||
// const promise = new Promise(function(resolve, reject) {
|
||||
// // ... some code
|
||||
|
||||
// if (/* 异步操作成功 */){
|
||||
// resolve(value);
|
||||
// } else {
|
||||
// reject(error);
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
// promise.then(function(value) {
|
||||
// // success
|
||||
// }, function(error) {
|
||||
// // failure
|
||||
// })
|
||||
|
||||
|
||||
let promise = new Promise(function(resolve, reject) {
|
||||
console.log('Promise');
|
||||
resolve();
|
||||
});
|
||||
|
||||
promise.then(function() {
|
||||
console.log('resolved.');
|
||||
});
|
||||
|
||||
console.log('Hi!');
|
||||
|
||||
|
||||
|
||||
const getJSON = function(url) {
|
||||
const promise = new Promise(function(resolve, reject){
|
||||
const handler = function() {
|
||||
if (this.readyState !== 4) {
|
||||
return;
|
||||
}
|
||||
if (this.status === 200) {
|
||||
resolve(this.response);
|
||||
} else {
|
||||
reject(new Error(this.statusText));
|
||||
}
|
||||
};
|
||||
const client = new XMLHttpRequest();
|
||||
client.open("GET", url);
|
||||
client.onreadystatechange = handler;
|
||||
client.responseType = "json";
|
||||
client.setRequestHeader("Accept", "application/json");
|
||||
client.send();
|
||||
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
getJSON("/posts.json").then(function(json) {
|
||||
console.log('Contents: ' + json);
|
||||
}, function(error) {
|
||||
console.error('出错了', error);
|
||||
});
|
125
es6/bianliang.html
Normal file
@ -0,0 +1,125 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
{
|
||||
let a = 1;
|
||||
var b = 2;
|
||||
a = 9;
|
||||
let a = "llp"
|
||||
}
|
||||
// console.log(a)
|
||||
// console.log(b)
|
||||
|
||||
for (var i = 0; i < 5; i++) {
|
||||
console.log(i)
|
||||
}
|
||||
console.log(i) //5
|
||||
|
||||
for (let m = 0; m < 5; m++) {
|
||||
console.log(m, "llk")
|
||||
}
|
||||
// console.log(m)
|
||||
|
||||
|
||||
var a = [];
|
||||
for (var i = 0; i < 10; i++) {
|
||||
a[i] = function () {
|
||||
console.log(i);
|
||||
};
|
||||
}
|
||||
a[6](); // 10
|
||||
|
||||
var a = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
a[i] = function () {
|
||||
console.log(i);
|
||||
};
|
||||
}
|
||||
a[6](); // 10
|
||||
|
||||
|
||||
const c = 10
|
||||
c = 9;
|
||||
|
||||
console.log(d)
|
||||
var d = 7
|
||||
|
||||
|
||||
// let aa = 1;
|
||||
// let bb = 2;
|
||||
// let cc = 3;
|
||||
|
||||
// |
|
||||
|
||||
let [aa, bb, cc] = ["a", "b", "c"] //解构赋值
|
||||
|
||||
|
||||
let [foo, [[bar], baz]] = [1, [[2], 3]];
|
||||
|
||||
// foo 1
|
||||
// bar 2
|
||||
// baz 3
|
||||
|
||||
|
||||
let [, , third] = ["foo", "bar", "baz"];
|
||||
third // "baz"
|
||||
|
||||
|
||||
let [x, , y] = [1, 2, 3];
|
||||
x //1
|
||||
y //3
|
||||
|
||||
|
||||
let [head, ...tail] = [1, 2, 3, 4];
|
||||
head // 1
|
||||
tail // [2,3,4]
|
||||
|
||||
|
||||
|
||||
let [x, y, ...z] = ['a'];
|
||||
x // a
|
||||
y // undefined
|
||||
z // []
|
||||
|
||||
// ...先生成一个数组,把后面所有的元素都塞进去
|
||||
|
||||
|
||||
|
||||
|
||||
let [a, [b], d] = [1, [2, 3], 4];
|
||||
a // 1
|
||||
b // 2
|
||||
d // 4
|
||||
// 不完全解构的时候 左边的变量名只能匹配到第一个值作为他的变量值
|
||||
|
||||
|
||||
|
||||
// 报错
|
||||
// let [foo] = 1;
|
||||
// let [foo] = false;
|
||||
// let [foo] = NaN;
|
||||
// let [foo] = undefined;
|
||||
// let [foo] = null;
|
||||
// let [foo] = {};
|
||||
// 如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错。
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
结论 用Let声明的变量,只在当前代码块中能够访问,
|
||||
用var声明的变量,在代码块内部外部都能访问
|
||||
在同一个代码块中,let 不能重复定义
|
||||
let 不存在var的变量提升
|
||||
|
||||
<p>
|
||||
const 声明的是常量, 定义完成以后值不能被修改 所以在定义的时候需要给他赋初始值
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
89
es6/promise.html
Normal file
@ -0,0 +1,89 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<!-- <script type="module" src="./b.js"></script> -->
|
||||
<script>
|
||||
// 定义一个 promise 对象
|
||||
// var promise = new Promise(function (resolve, reject) {
|
||||
// // resolve 成功状态下调用的函数
|
||||
// // reject 失败状态下调用的函数
|
||||
|
||||
// if (成功) {
|
||||
// resolve()
|
||||
// } else {
|
||||
// reject()
|
||||
// }
|
||||
// })
|
||||
// console.log(promise)
|
||||
|
||||
// // 使用promise 对象
|
||||
// promise.then(function (res) {
|
||||
// console.log(res) //成功返回的值
|
||||
// }).catch(function (err) {
|
||||
// console.log(err) //失败返回的值
|
||||
// })
|
||||
|
||||
|
||||
|
||||
// function timeout(ms) {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// setTimeout(resolve, ms, 'done');
|
||||
// });
|
||||
// }
|
||||
|
||||
// timeout(100).then((value) => {
|
||||
// console.log(value);
|
||||
// });
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const getJSON = function (url) {
|
||||
const promise = new Promise(function (resolve, reject) {
|
||||
const handler = function () {
|
||||
if (this.readyState !== 4) {
|
||||
return;
|
||||
}
|
||||
if (this.status === 200) {
|
||||
resolve(this.response);
|
||||
} else {
|
||||
reject(new Error(this.statusText));
|
||||
}
|
||||
};
|
||||
const client = new XMLHttpRequest();
|
||||
client.open("GET", url);
|
||||
client.onreadystatechange = handler;
|
||||
client.responseType = "json";
|
||||
// client.setRequestHeader("Accept", "application/json");
|
||||
client.send();
|
||||
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
getJSON("/posts.json").then(function (json) {
|
||||
console.log('Contents: ' + json);
|
||||
}).catch(function(err){
|
||||
console.log(err)
|
||||
});
|
||||
|
||||
|
||||
async function s(){
|
||||
var list =await getJSON("url")
|
||||
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
96
es6/setmap.html
Normal file
@ -0,0 +1,96 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
var arr = [1, 1, 2, 2, 3, 3, 3]
|
||||
// console.log(arr)
|
||||
|
||||
let set = new Set(arr)
|
||||
// console.log(set)
|
||||
set[3] = 2
|
||||
// console.log(set)
|
||||
// set 作为数据结构,里面的成员都是唯一的
|
||||
|
||||
let strarr = new Set(["s", "l", "S", "L"])
|
||||
// console.log(strarr) //[s,l,S,L]
|
||||
strarr.delete("s")
|
||||
// console.log(strarr, "new")
|
||||
// console.log(strarr.has("L"))
|
||||
|
||||
for (let i of strarr.keys()) {
|
||||
// console.log(i)
|
||||
} //for in 会失败
|
||||
|
||||
for (let i of strarr.values()) {
|
||||
// console.log(i)
|
||||
}
|
||||
//set实例的键和值都是一样的 所以用keys()/values()的时候 遍历得到的结果是一样的
|
||||
// entries() 返回键+值
|
||||
|
||||
for (let i of strarr.entries()) {
|
||||
// console.log(i)
|
||||
}
|
||||
|
||||
//Array [ "l", "l" ]
|
||||
// Array["S", "S"]
|
||||
// Array["L", "L"]
|
||||
|
||||
|
||||
|
||||
// 向 Set 加入值的时候,不会发生类型转换,所以5和"5"是两个不同的值。相同字母的大小写也是不同的值
|
||||
|
||||
//set 属性
|
||||
// set.prototype.constructor 构造函数
|
||||
// set.prototype.size 返回set实例的值的个数
|
||||
|
||||
|
||||
// set 方法
|
||||
// set.prototype.add(要添加的值) 向set实例中添加一个元素
|
||||
// set.prototype.delete(删除的值) 删除set实例中的一个元素
|
||||
// set.prototype.clear() 清空
|
||||
// set.prototype.has(要判断的值) 判断是否在set实例中 返回的是布尔值
|
||||
|
||||
|
||||
|
||||
// Array.from(set的实例) 将set实例转成数组
|
||||
|
||||
|
||||
// 数组去重
|
||||
// function dedupe(array) {
|
||||
// return Array.from(new Set(array));
|
||||
// }
|
||||
|
||||
// dedupe([1, 1, 2, 3]) // [1, 2, 3]
|
||||
|
||||
|
||||
|
||||
|
||||
// map
|
||||
const map = new Map([
|
||||
['name', '张三'],
|
||||
['title', 'Author']
|
||||
]);
|
||||
console.log(map)
|
||||
|
||||
const m = new Map();
|
||||
const o = { p: 'Hello World' };
|
||||
m.set(o,'content') // m.set(key,value) map实例中能用对象来当键
|
||||
|
||||
//json 方法:
|
||||
// json.stringfy() 对象转成json
|
||||
// json.parse() json转对象
|
||||
|
||||
console.log(m.get(o))
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -12,7 +12,7 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
|
||||
开始之前 需要新建一个 后缀名为.html 的文件,我们后面所说的所有操作,都是在html 文件中进行的
|
||||
|
||||
可以使用的编辑器有很多: 记事本,editplus, notepad++, **vscode** ....这里推荐vscode
|
||||
可以使用的编辑器有很多: 记事本,editplus, notepad++, hbuilder **vscode** ....这里推荐vscode
|
||||
|
||||
### html 基本结构
|
||||
|
||||
@ -30,12 +30,16 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
|
||||
> 在解读上面的代码之前,我们先来看这些由<(左尖括号), 内容 , >(右尖括号) 组成的内容,这些内容叫做标签(tag), 在html中用<> 把他们包裹起来是为了与其他纯文本内容进行区分
|
||||
|
||||
> <!DOCTYPE html> 是Document Type Declaration 的简称,用来声明文档,也就是告诉浏览器当前使用的是哪种HTML
|
||||
> <html></html> 表示页面编写的都是HTML代码,必须成对出现,除了文档生命之外的所有代码都必须写在<html></html>中间
|
||||
> <head></head> 表示页面的头部,页面的标题(title标签),meta元信息定义,文档样式表和脚本等信息 一般写在head 中间
|
||||
> <body></body> 表示页面的身体 页面内容需要写在 body 标签内 --
|
||||
html 元素和标签的区别:
|
||||
> HTML标签是超文本标记语言的最基本单位,而HTML 元素指的是从开始标签(start tag)到结束标签(end tag)的所有代码。
|
||||
|
||||
|
||||
> \<!DOCTYPE html> 是Document Type Declaration 的简称,用来声明文档,也就是告诉浏览器当前使用的是哪种HTML
|
||||
> \<html>\</html> 表示页面编写的都是HTML代码,必须成对出现,除了文档生命之外的所有代码都必须写在\<html>\</html>中间
|
||||
> \<head>\</head> 表示页面的头部,页面的标题(title标签),meta元信息定义,文档样式表和脚本等信息 一般写在head 中间
|
||||
> \<body>\</body> 表示页面的身体 页面内容需要写在 body 标签内 --
|
||||
>
|
||||
> <meta charset="utf-8" /> 设置文档使用utf-8编码集
|
||||
> \<meta charset="utf-8" /> 设置文档使用utf-8编码集
|
||||
|
||||
### 写第一个网页 --hello world
|
||||
|
||||
@ -73,13 +77,10 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
|
||||
![image-20201230114458198](html基础.assets/image-20201230114458198.png)
|
||||
|
||||
元素分类:
|
||||
|
||||
分类方式:
|
||||
|
||||
标签分类:
|
||||
- 有无闭合标签
|
||||
- 单标签
|
||||
- 没有闭合标签,单标签书写形式以 / 结尾 如:<img /> <input /> ...
|
||||
- 没有闭合标签,单标签书写形式以 / 结尾 如:\<img /> \<input /> ...
|
||||
|
||||
- 双标签
|
||||
|
||||
@ -92,8 +93,7 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
<span>这是文本标签 </span>
|
||||
```
|
||||
|
||||
|
||||
|
||||
元素分类:
|
||||
- 块级元素和内联元素
|
||||
|
||||
- 块级标签:在页面中以块的形式展现——相对于其前面的内容他会出现在新的一行,其后面的内容也会被挤到下一行展现。一个块级元素不会被嵌套进内联元素中,但可以嵌套在其他块级元素。
|
||||
@ -137,7 +137,6 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
一个属性需要包含如下内容:
|
||||
|
||||
> 1.一个空格,位于元素名称和属性名称之间
|
||||
>
|
||||
> 2. 属性名称,后面跟着一个等于号(=)
|
||||
> 3. 一个属性值,用“” 包裹
|
||||
|
||||
@ -205,7 +204,7 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
<a href="www.baidu.com'>baidu</a>
|
||||
```
|
||||
|
||||
上面这种写法是错误的!!!!!
|
||||
<p style="color:red">上面这种写法是<b>错误</b>的!!!!!</p>
|
||||
|
||||
|
||||
|
||||
@ -217,20 +216,20 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
|
||||
在html代码中,我们让每一个嵌套的元素以两个空格缩进,
|
||||
|
||||
```
|
||||
原意字符 等价字符引用
|
||||
< <
|
||||
> >
|
||||
'' "
|
||||
' &apos
|
||||
& &
|
||||
```
|
||||
| 原意字符 | 等价字符引用 |
|
||||
|---|---|
|
||||
| (空格)| |
|
||||
|<|<|
|
||||
|>|>|
|
||||
|''|"|
|
||||
|'|&apos|
|
||||
|&|&|
|
||||
|
||||
|
||||
|
||||
### html 注释
|
||||
|
||||
<!-- 注释内容 -->
|
||||
\<!-- 注释内容 -->
|
||||
|
||||
```
|
||||
<p>我在注释外!</p>
|
||||
@ -238,3 +237,32 @@ html(HyperText Markup Language --超文本标记语言),不是一个编
|
||||
<!-- <p>我在注释内!</p> -->
|
||||
```
|
||||
|
||||
阅读上面的文档,完成以下练习:
|
||||
|
||||
1. 写出html基本结构
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2. 写出至少5个单标签和至少8个双标签
|
||||
|
||||
|
||||
|
||||
|
||||
3. 新建一个html文件,页面上展示hello world
|
||||
world加粗
|
||||
完成内网通发截图
|
||||
|
||||
4. 新建一个html文件,页面上展示一篇文章的题目,作者,发布日期,正文内容,阅读量,点赞量,评论量
|
||||
其中,标题单独一行,下面放作者,发布日期,下面放正文内容,最下面放阅读量,点赞量,评论量
|
||||
完成内网通发截图
|
||||
5. 在任务4的基础上 在正文之前插入一个图片作为文章封面
|
||||
完成内网通发截图
|
||||
|
||||
6. 在任务5的基础上,从最上面添加一个输入框和搜索按钮,点击搜索,将输入框中输入的值带入www.baidu.com的地址栏中
|
||||
完成内网通发截图
|
||||
|
||||
7. 用自己的方式调整任务4的html页面的样式
|
||||
完成内网通发截图
|
134
htmlpress/biaoge.md
Normal file
@ -0,0 +1,134 @@
|
||||
# 表格(table)
|
||||
|
||||
表格:由行和列组成的结构化数据集(表格数据)
|
||||
|
||||
### 使用场景
|
||||
|
||||
html表格应用于展示表格数据,而不是用来实现网页布局
|
||||
|
||||
用表格实现网页布局出现的问题:
|
||||
|
||||
1. 表格布局减少了视觉受损的用户的可访问性
|
||||
2. 表格会产生更多的标签,使代码变得更难于编写,维护,调试
|
||||
3. 表格不能自动响应 正确的布局容器(如div ) 他们的默认宽度是父元素的100% 但表格的默认大小是根据其内容而定的。因此 如果要做移动端适配,就需要采取额外的措施来改变表格的样式
|
||||
|
||||
### 新建一个表格
|
||||
|
||||
1. 每个表格的内容都被包含在<table></table> 中 而且这些内容需要写在html结构的body部分
|
||||
2. 在表格中,最小的内容容器是单元格,是通过(td)创建的 这是一列
|
||||
3. 如果想换行,需要把位于同一行的内容包含在 一个tr 标签中 即用<tr></tr> 定义一行
|
||||
|
||||
示例:
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>姓名</td>
|
||||
<td>年龄</td>
|
||||
<td>性别</td>
|
||||
<td>班级</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
效果如下:
|
||||
|
||||
![image-20210105170312759](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210105170312759.png)
|
||||
|
||||
上面的代码中出现的 <table border="1"></table> 中的border 用于给表格加上边框
|
||||
|
||||
|
||||
|
||||
#### 表格表头(th)
|
||||
|
||||
table包裹的 th标签会有加粗的效果 看起来是表格的表头
|
||||
|
||||
把上面表格的顶部四个单元格做成表头效果:
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<th>姓名</th>
|
||||
<th>年龄</th>
|
||||
<th>性别</th>
|
||||
<th>班级</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
![image-20210105172500056](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210105172500056.png)
|
||||
|
||||
|
||||
|
||||
### 允许单元格跨行或列
|
||||
|
||||
|
||||
|
93
htmlpress/html标签详解.md
Normal file
@ -0,0 +1,93 @@
|
||||
# html 主要标签
|
||||
## 文字相关的标签
|
||||
|
||||
### 标题和段落
|
||||
**标题标签(hn)**
|
||||
* h1
|
||||
* h2
|
||||
* h3
|
||||
* h4
|
||||
* h5
|
||||
* h6
|
||||
> h1~h6标用来声明标题,h1定义最大的标题,h6定义最小的标题,注意不要用来改变同一行的文字大小,这种样式需求应使用层叠样式表(css)实现
|
||||
|
||||
实例:
|
||||
<h1>这是h1</h1>
|
||||
<h2>这是h2</h2>
|
||||
<h3>这是h3</h3>
|
||||
<h4>这是h4</h4>
|
||||
<h5>这是h5</h5>
|
||||
<h6>这是h6</h6>
|
||||
|
||||
**段落标签**
|
||||
* p
|
||||
> 在html中,每个段落是通过<p> 标签进行定义的。
|
||||
|
||||
实例:
|
||||
|
||||
```
|
||||
<p>我是一个段落标签</p>
|
||||
```
|
||||
|
||||
阅读下面的代码体会合理的结构层次
|
||||
效果:
|
||||
|
||||
<h1>三国演义</h1>
|
||||
|
||||
<p>罗贯中</p>
|
||||
|
||||
<h2>第一回 宴桃园豪杰三结义 斩黄巾英雄首立功</h2>
|
||||
|
||||
<p>话说天下大势,分久必合,合久必分。周末七国分争,并入于秦。及秦灭之后,楚、汉分争,又并入于汉……</p>
|
||||
|
||||
<h2>第二回 张翼德怒鞭督邮 何国舅谋诛宦竖</h2>
|
||||
|
||||
<p>且说董卓字仲颖,陇西临洮人也,官拜河东太守,自来骄傲。当日怠慢了玄德,张飞性发,便欲杀之……</p>
|
||||
|
||||
<h3>却说张飞</h3>
|
||||
|
||||
<p>却说张飞饮了数杯闷酒,乘马从馆驿前过,见五六十个老人,皆在门前痛哭。飞问其故,众老人答曰:“督邮逼勒县吏,欲害刘公;我等皆来苦告,不得放入,反遭把门人赶打!”……</p>
|
||||
```
|
||||
<h1>三国演义</h1>
|
||||
|
||||
<p>罗贯中</p>
|
||||
|
||||
<h2>第一回 宴桃园豪杰三结义 斩黄巾英雄首立功</h2>
|
||||
|
||||
<p>话说天下大势,分久必合,合久必分。周末七国分争,并入于秦。及秦灭之后,楚、汉分争,又并入于汉……</p>
|
||||
|
||||
<h2>第二回 张翼德怒鞭督邮 何国舅谋诛宦竖</h2>
|
||||
|
||||
<p>且说董卓字仲颖,陇西临洮人也,官拜河东太守,自来骄傲。当日怠慢了玄德,张飞性发,便欲杀之……</p>
|
||||
|
||||
<h3>却说张飞</h3>
|
||||
|
||||
<p>却说张飞饮了数杯闷酒,乘马从馆驿前过,见五六十个老人,皆在门前痛哭。飞问其故,众老人答曰:“督邮逼勒县吏,欲害刘公;我等皆来苦告,不得放入,反遭把门人赶打!”……</p>
|
||||
```
|
||||
|
||||
> 结构层次原则:
|
||||
> 1.您应该最好只对每个页面使用一次\<h1> — 这是顶级标题,所有其他标题位于层次结构中的下方。
|
||||
>2.请确保在层次结构中以正确的顺序使用标题。不要使用\<h3>来表示副标题,后面跟\<h2>来表示副副标题 - 这是没有意义的,会导致奇怪的结果。
|
||||
>3. 在可用的六个标题级别中,您应该只在每页使用不超过三个,除非您认为有必要使用更多。具有许多级别的文档(即,较深的标题层次结构)变得难以操作并且难以导航。在这种情况下,如果可能,建议将内容分散在多个页面上。
|
||||
|
||||
## 列表 list
|
||||
### 无序列表 ul-li
|
||||
<ul>
|
||||
<li>香菱</li>
|
||||
<li>皇女</li>
|
||||
<li>旅行者</li>
|
||||
<li>派蒙</li>
|
||||
</ul>
|
||||
|
||||
```
|
||||
<ul>
|
||||
<li>香菱</li>
|
||||
<li>皇女</li>
|
||||
<li>旅行者</li>
|
||||
<li>派蒙</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
阅读上面的文档,完成以下练习
|
||||
|
||||
1. 新建一个html页面,
|
234
htmlpress/表单.md
Normal file
@ -0,0 +1,234 @@
|
||||
创建我的第一个表单
|
||||
|
||||
* HTML表单是什么?
|
||||
* 设计表单
|
||||
* 主动学习:使用HTML实现我们的表单
|
||||
* 基本表单样式
|
||||
* 向您的web服务器发送表单数据
|
||||
|
||||
本文提供了您第一次创建HTML表单的经验,包括设计一个简单表单,使用正确的HTML元素实现它,通过CSS添加一些非常简单的样式,以及如何将数据发送到服务器。
|
||||
预备知识:
|
||||
|
||||
基本计算机素养和对HTML的基本理解。
|
||||
目标: 为了熟悉HTML表单是什么,它们被用来做什么,如何设计它们,以及简单情况下需要的基本HTML元素。
|
||||
|
||||
HTML表单是什么?
|
||||
HTML表单是用户和web站点或应用程序之间交互的主要内容之一。它们允许用户将数据发送到web站点。大多数情况下,数据被发送到web服务器,但是web页面也可以自己拦截它并使用它。
|
||||
|
||||
HTML表单是由一个或多个小部件组成的。这些小部件可以是文本字段(单行或多行)、选择框、按钮、复选框或单选按钮。大多数情况下,这些小部件与描述其目的的标签配对——正确实现的标签能够清楚地指示视力正常的用户和盲人用户输入表单所需的内容。
|
||||
|
||||
HTML表单和常规HTML文档的主要区别在于,大多数情况下,表单收集的数据被发送到web服务器。在这种情况下,您需要设置一个web服务器来接收和处理数据。如何设置这样的服务器超出了本文的范围,但是如果您想了解更多,请参阅模块后面的发送表单数据。
|
||||
设计表单
|
||||
|
||||
在开始编写代码之前,最好先退一步,花点时间考虑一下您的表单。设计一个快速的模型将帮助您定义您想要询问用户的正确的数据集。从用户体验(UX)的角度来看,要记住:表单越大,失去用户的风险就越大。保持简单,保持专注:只要求必要的数据。在构建站点或应用程序时,设计表单是非常重要的一步。这超出了本文的范围,涵盖了表单的用户体验,但是如果您想深入了解这个主题,您应该阅读下面的文章:
|
||||
|
||||
杂志<Smashing Magazine>中有很好的关于表单用户体验的文章,或许其中最重要的应该是他们的Extensive Guide To Web Form Usability.
|
||||
UXMatters 也是一个非常有思想的资源,从基本的最佳实践到复杂的问题如多页表单,都有很好的建议。
|
||||
|
||||
在本文中,我们将构建一个简单的联系人表单。让我们做一个粗略的草图。
|
||||
|
||||
The form to build, roughly sketch
|
||||
|
||||
我们的表单将包含三个文本字段和一个按钮。我们向用户询问他们的姓名、电子邮件和他们想要发送的信息。点击这个按钮将把他们的数据发送到一个web服务器。
|
||||
主动学习:使用HTML实现我们的表单
|
||||
|
||||
好了,现在我们准备进入HTML代码并对表单进行编码。为了构建我们的联系人表单,我们将使用以下HTML元素:<form>, <label>, <input>, <textarea>, and <button>.
|
||||
|
||||
在进一步讨论之前,先创建一个简单HTML模板的本地副本—您将在这里输入您的表单HTML。
|
||||
<form> 元素
|
||||
|
||||
所有HTML表单都以一个<form>元素开始:
|
||||
|
||||
<form action="/my-handling-form-page" method="post">
|
||||
|
||||
</form>
|
||||
|
||||
这个元素正式定义了一个表单。就像<div>元素或<p>元素,它是一个容器元素,但它也支持一些特定的属性来配置表单的行为方式。它的所有属性都是可选的,但实践中最好至少要设置action属性和method属性。
|
||||
|
||||
action 属性定义了在提交表单时,应该把所收集的数据送给谁(/那个模块)(URL)去处理。.
|
||||
method 属性定义了发送数据的HTTP方法(它可以是“get”或“post”).
|
||||
|
||||
注意:如果您想深入了解这些属性是如何工作的,那么将在发送表单数据文章中详细说明。
|
||||
|
||||
现在,将上面的<form> 元素添加到您的HTML主体中
|
||||
<label>, <input> 和 <textarea> 元素
|
||||
|
||||
我们的联系人表单非常简单,包含三个文本字段,每个字段都有一个标签。该名称的输入字段将是一个基本的单行文本字段,电子邮件的输入字段将是一个只接受电子邮件地址的单行文本字段,而消息的输入字段将是一个基本的多行文本字段。
|
||||
|
||||
就HTML代码而言,我们需要如下的东西来实现这些表单小部件:
|
||||
|
||||
<form action="/my-handling-form-page" method="post">
|
||||
<div>
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name">
|
||||
</div>
|
||||
<div>
|
||||
<label for="mail">E-mail:</label>
|
||||
<input type="email" id="mail">
|
||||
</div>
|
||||
<div>
|
||||
<label for="msg">Message:</label>
|
||||
<textarea id="msg"></textarea>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
更新您的表单代码,使其看起来像上面的代码。
|
||||
|
||||
使用\<div> 元素可以使我们更加方便地构造我们自己的代码,并且更容易样式化(参见本文后面的文章)。注意在所有\<label>元素上使用for属性;它是将标签链接到表单小部件的一种正规方式。这个属性引用对应的小部件的id。这样做有一些好处。最明显的一个好处是允许用户单击标签以激活相应的小部件。如果您想更好地理解这个属性的其他好处,您可以找到如何构造HTML表单的详细信息。
|
||||
|
||||
在 \<input>元素中,最重要的属性是type 属性。这个属性非常重要,因为它定义了\<input>属性的行为方式。它可以从根本上改变元素,所以要注意它。稍后您将在原生表单控件文章中找到更多关于此的内容。
|
||||
|
||||
在我们的简单示例中,我们使用值 text 作为第一个输入——这个属性的默认值。它表示一个基本的单行文本字段,接受任何类型的文本输入。
|
||||
对于第二个输入,我们使用值email,它定义了一个只接受格式正确的电子邮件地址的单行文本字段。这会将一个基本的文本字段转换为一种“智能”字段,该字段将对用户输入的数据进行一些检查。在稍后的表单数据验证文章中,您将了解到更多关于表单验证的信息。
|
||||
|
||||
最后但同样重要的是,要注意\<input> 和\<textarea>\</textarea>的语法。这是HTML的一个奇怪之处。 \<input> 标签是一个空元素,这意味着它不需要关闭标签。相反, \<textarea>不是一个空元素,因此必须使用适当的结束标记来关闭它。这对HTML表单的特定特性有影响:定义默认值的方式。要定义\<input>的默认值,你必须使用value 属性,如下所示:
|
||||
|
||||
```
|
||||
<input type="text" value="by default this element is filled with this text" />
|
||||
|
||||
```
|
||||
|
||||
相反,如果您想定义\<textarea>的默认值,您只需在\<textarea>元素的开始和结束标记之间放置默认值,就像这样:
|
||||
|
||||
<textarea>by default this element is filled with this text</textarea>
|
||||
|
||||
\<button> 元素
|
||||
|
||||
我们的表格已经快准备好了,我们只需要再添加一个按钮,让用户在填写完表单后发送他们的数据。这是通过使用 \<button> 元素完成的。在 \</form>这个结束标签上方添加以下内容:
|
||||
|
||||
```
|
||||
|
||||
<div class="button">
|
||||
<button type="submit">Send your message</button>
|
||||
</div>
|
||||
|
||||
```
|
||||
<div class="button">
|
||||
<button type="submit">Send your message</button>
|
||||
</div>
|
||||
|
||||
您会看到\<button>元素也接受一个 type属性,它接受submit, reset或者 button 三个值中的任一个。
|
||||
|
||||
单击 type 属性定义为 submit 值(也是默认值)的按钮会发送表单的数据到<form>元素的action 属性所定义的网页。
|
||||
单击 type 属性定义为 reset 值的按钮 将所有表单小部件重新设置为它们的默认值。从用户体验的角度来看,这被认为是一种糟糕的做法。
|
||||
单击 type 属性定义为 button 值的按钮……不会发生任何事!这听起来很傻,但是用JavaScript构建定制按钮非常有用。
|
||||
|
||||
注意:您还可以使用相应类型的 <input>元素来生成一个按钮,如 <input type="submit">。<button>元素的主要优点是, <input>元素只允许纯文本作为其标签,而<button>元素允许完整的HTML内容,允许更复杂、更有创意的按钮文本。
|
||||
基本表单样式
|
||||
|
||||
现在您已经完成了表单的HTML代码,尝试保存它并在浏览器中查看它。
|
||||
现在,你会看到它看起来很丑。
|
||||
|
||||
注意: 如果你怀疑你的HTML代码不对,试着把它和我们完成的例子进行比较 —— first-form.html (你也可以观看预览版)。
|
||||
|
||||
如何排布好表单是公认的难点。这超出了本文的讨论范围,所以现在我们只需要让您添加一些CSS来让它看起来很好。
|
||||
|
||||
首先,在您的HTML头部中添加一个 <style>元素。应该是这样的:
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
在样式标签中,添加如下的CSS,如下所示:
|
||||
|
||||
form {
|
||||
/* 居中表单 */
|
||||
margin: 0 auto;
|
||||
width: 400px;
|
||||
/* 显示表单的轮廓 */
|
||||
padding: 1em;
|
||||
border: 1px solid #CCC;
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
form li + li {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
label {
|
||||
/* 确保所有label大小相同并正确对齐 */
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
/* 确保所有文本输入框字体相同
|
||||
textarea默认是等宽字体 */
|
||||
font: 1em sans-serif;
|
||||
|
||||
/* 使所有文本输入框大小相同 */
|
||||
width: 300px;
|
||||
box-sizing: border-box;
|
||||
|
||||
/* 调整文本输入框的边框样式 */
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
input:focus, textarea:focus {
|
||||
/* 给激活的元素一点高亮效果 */
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
textarea {
|
||||
/* 使多行文本输入框和它们的label正确对齐 */
|
||||
vertical-align: top;
|
||||
|
||||
/* 给文本留下足够的空间 */
|
||||
height: 5em;
|
||||
}
|
||||
|
||||
.button {
|
||||
/* 把按钮放到和文本输入框一样的位置 */
|
||||
padding-left: 90px; /* 和label的大小一样 */
|
||||
}
|
||||
|
||||
button {
|
||||
/* 这个外边距的大小与label和文本输入框之间的间距差不多 */
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
现在,它看起来没那么丑了。
|
||||
|
||||
注意: 你可以在GitHub上的这里找到它 first-form-styled.html (也可以在这儿看运行结果).
|
||||
向您的web服务器发送表单数据
|
||||
|
||||
最后一部分,也许是最棘手的部分,是在服务器端处理表单数据。如前所述,大多数时候HTML表单是向用户请求数据并将其发送到web服务器的一种方便的方式。
|
||||
|
||||
<form> 元素将定义如何通过action 属性和 method属性来发送数据的位置和方式。
|
||||
|
||||
但这还不够。我们还需要为我们的数据提供一个名称。这些名字对双方都很重要:在浏览器端,它告诉浏览器给数据各自哪个名称,在服务器端,它允许服务器按名称处理每个数据块。
|
||||
|
||||
要将数据命名为表单,您需要在每个表单小部件上使用 name 属性来收集特定的数据块。让我们再来看看我们的表单代码:
|
||||
|
||||
<form action="/my-handling-form-page" method="post">
|
||||
<div>
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="user_name">
|
||||
</div>
|
||||
<div>
|
||||
<label for="mail">E-mail:</label>
|
||||
<input type="email" id="mail" name="user_email">
|
||||
</div>
|
||||
<div>
|
||||
<label for="msg">Message:</label>
|
||||
<textarea id="msg" name="user_message"></textarea>
|
||||
</div>
|
||||
|
||||
...
|
||||
|
||||
在我们的例子中,表单会发送三个已命名的数据块 "user_name", "user_email", 和 "user_message"。这些数据将用使用HTTP POST 方法,把信息发送到URL为 "/my-handling-form-page"目录下。
|
||||
|
||||
在服务器端,位于URL"/my-handling-form-page" 上的脚本将接收的数据作为HTTP请求中包含的3个键/值项的列表。这个脚本处理这些数据的方式取决于您。每个服务器端语言(PHP、Python、Ruby、Java、c等等)都有自己的机制。深入到这个主题已经超出了本指南的范围,但是如果您想了解更多,我们已经在发送表单数据文章中提供了一些示例。
|
||||
总结
|
||||
|
||||
祝贺您,您已经构建了您的第一个HTML表单。它看起来就像这样:
|
||||
|
||||
然而,这仅仅是开始,现在是时候深入研究了。HTML表单比我们在这里看到的要强大得多,本指南的其他文章将帮助您掌握其余部分。
|
||||
|
305
htmlpress/表单2.md
Normal file
@ -0,0 +1,305 @@
|
||||
Skip to main content
|
||||
Skip to search
|
||||
|
||||
Search MDN
|
||||
Sign in
|
||||
发送表单数据
|
||||
|
||||
学习 Web 开发
|
||||
HTML表单指南
|
||||
发送表单数据
|
||||
|
||||
Select your preferred language
|
||||
Table of contents
|
||||
|
||||
数据都去哪儿了?
|
||||
特殊案例:发送文件
|
||||
常见的安全问题
|
||||
结论
|
||||
相关链接
|
||||
在本单元中
|
||||
|
||||
上一页
|
||||
Overview: Forms
|
||||
下一页
|
||||
|
||||
本文将讨论当用户提交表单时发生了什么——数据去了哪,以及当它到达时该如何处理?我们还研究了与发送表单数据相关的一些安全问题。
|
||||
预备知识:
|
||||
|
||||
基本计算机素养,对HTML的理解,对HTTP 和服务器端编程的基础知识。
|
||||
目标: 了解表单数据提交时发生了什么,包括服务器上如何处理数据的基本概念。
|
||||
数据都去哪儿了?
|
||||
|
||||
在这里,我们将讨论在提交表单时数据会发生什么。
|
||||
客户端/服务器体系结构
|
||||
|
||||
web基于非常基本的客户端/服务器体系结构,可以总结如下:客户端(通常是web浏览器)向服务器发送请求(大多数情况下是Apache、Nginx、IIS、Tomcat等web服务器),使用HTTP 协议。服务器使用相同的协议来回答请求。
|
||||
|
||||
A basic schema of the Web client/server architecture
|
||||
|
||||
在客户端,HTML表单只不过是一种方便的用户友好的方式,可以配置HTTP请求将数据发送到服务器。这使用户能够提供在HTTP请求中传递的信息。
|
||||
|
||||
注意:为了更好地了解客户端—服务器架构是如何工作的,请阅读我们的服务器端网站编程的第一个步骤模块。
|
||||
在客户端:定义如何发送数据
|
||||
|
||||
<form>元素定义了如何发送数据。它的所有属性都是为了让您配置当用户点击提交按钮时发送的请求。两个最重要的属性是action和method。
|
||||
action 属性
|
||||
|
||||
这个属性定义了发送数据要去的位置。它的值必须是一个有效的URL。如果没有提供此属性,则数据将被发送到包含这个表单的页面的URL。
|
||||
|
||||
在这个例子中,数据被发送到一个绝对URL —— http://foo.com:
|
||||
|
||||
<form action="http://foo.com">
|
||||
|
||||
这里,我们使用相对URL——数据被发送到服务器上的不同URL
|
||||
|
||||
<form action="/somewhere_else">
|
||||
|
||||
在没有属性的情况下,像下面一样,<form>数据被发送到表单出现的相同页面上:
|
||||
|
||||
<form>
|
||||
|
||||
许多较老的页面使用下面的符号表示数据应该被发送到包含表单的相同页面;这是必需的,因为直到HTML5action属性都需要该符号。现在,这不再需要了。
|
||||
|
||||
<form action="#">
|
||||
|
||||
注意:可以指定使用HTTPS(安全HTTP)协议的URL。当您这样做时,数据将与请求的其余部分一起加密,即使表单本身是托管在使用HTTP访问的不安全页面上。另一方面,如果表单是在安全页面上托管的,但是您指定了一个不安全的HTTP URL,它带有action属性,所有的浏览器都会在每次尝试发送数据时向用户显示一个安全警告,因为数据不会被加密。
|
||||
method属性
|
||||
|
||||
该属性定义了如何发送数据。HTTP协议提供了几种执行请求的方法;HTML表单数据可以通过许多不同的方法进行数据传输,其中最常见的是GET方法和POST方法。
|
||||
|
||||
为了理解这两种方法之间的区别,让我们回过头来看看HTTP是如何工作的。
|
||||
每当您想要访问Web上的资源时,浏览器都会向URL发送一个请求。
|
||||
HTTP请求由两个部分组成:一个包含关于浏览器功能的全局元数据集的头部,和一个包含服务器处理特定请求所需信息的主体。
|
||||
GET 方法
|
||||
|
||||
GET方法是浏览器使用的方法,请求服务器返回给定的资源:“嘿,服务器,我想要得到这个资源。”在这种情况下,浏览器发送一个空的主体。由于主体是空的,如果使用该方法发送一个表单,那么发送到服务器的数据将被追加到URL。
|
||||
|
||||
考虑下面这个表单:
|
||||
```
|
||||
|
||||
<form action="http://foo.com" method="get">
|
||||
<div>
|
||||
<label for="say">What greeting do you want to say?</label>
|
||||
<input name="say" id="say" value="Hi">
|
||||
</div>
|
||||
<div>
|
||||
<label for="to">Who do you want to say it to?</label>
|
||||
<input name="to" id="to" value="Mom">
|
||||
</div>
|
||||
<div>
|
||||
<button>Send my greetings</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
```
|
||||
|
||||
由于已经使用了GET方法,当你提交表单的时候,您将看到www.foo.com/?say=Hi&to=Mom在浏览器地址栏里。
|
||||
|
||||
数据作为一系列的名称/值对被附加到URL。在URL web地址结束之后,我们得到一个问号(?),后面跟着由一个与符号(&)互相分隔开的名称/值对。在本例中,我们将两个数据传递给服务器。
|
||||
|
||||
say, 它有一个 Hi的值。
|
||||
to, 它有一个 Mom的值。
|
||||
|
||||
HTTP请求如下:
|
||||
|
||||
GET /?say=Hi&to=Mom HTTP/2.0
|
||||
Host: foo.com
|
||||
|
||||
注意:你可以在GitHub 上看到本例子——见 get-method.html (预览版).
|
||||
POST 方法
|
||||
|
||||
POST方法略有不同。这是浏览器在询问响应时使用与服务器通信的方法,该响应考虑了HTTP请求正文中提供的数据:“嘿,服务器,看一下这些数据,然后给我回一个适当的结果。”如果使用该方法发送表单,则将数据追加到HTTP请求的主体中。
|
||||
|
||||
让我们来看一个例子,这是我们在上面的GET部分中所看到的相同的形式,但是使用method属性设置为post。
|
||||
|
||||
<form action="http://foo.com" method="post">
|
||||
<div>
|
||||
<label for="say">What greeting do you want to say?</label>
|
||||
<input name="say" id="say" value="Hi">
|
||||
</div>
|
||||
<div>
|
||||
<label for="to">Who do you want to say it to?</label>
|
||||
<input name="to" id="to" value="Mom">
|
||||
</div>
|
||||
<div>
|
||||
<button>Send my greetings</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
当使用POST方法提交表单时,没有数据会附加到URL,HTTP请求看起来是这样的,而请求主体中包含的数据是这样的:
|
||||
|
||||
POST / HTTP/2.0
|
||||
Host: foo.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 13
|
||||
|
||||
say=Hi&to=Mom
|
||||
|
||||
Content-Length数据头表示主体的大小,Content-Type数据头表示发送到服务器的资源类型。稍后我们将讨论这些标头。
|
||||
|
||||
注意:你可以在 GitHub 上看到本例—— 见 post-method.html (预览版).
|
||||
查看HTTP请求
|
||||
|
||||
HTTP请求永远不会显示给用户(如果您想要看到它们,您需要使用诸如Firefox Network Monitor或Chrome Developer Tools之类的工具)。例如,您的表单数据将显示在Chrome网络选项卡中:
|
||||
|
||||
按下 F12
|
||||
选择 "Network"
|
||||
选择 "All"
|
||||
在 "Name" 标签页选择 "foo.com"
|
||||
选择 "Headers"
|
||||
|
||||
你可以获得表单数据,像下图显示的那样
|
||||
|
||||
唯一显示给用户的是被调用的URL。正如我们上面提到的,使用GET请求用户将在他们的URL栏中看到数据,但是使用POST请求用户将不会看到。这一点很重要,有两个原因:
|
||||
|
||||
如果您需要发送一个密码(或其他敏感数据),永远不要使用GET方法否则数据会在URL栏中显示,这将非常不安全。
|
||||
如果您需要发送大量的数据,那么POST方法是首选的,因为一些浏览器限制了URL的大小。此外,许多服务器限制它们接受的URL的长度。
|
||||
|
||||
在服务器端:检索数据
|
||||
|
||||
无论选择哪种HTTP方法,服务器都会接收一个字符串并解析,以便将数据作为键/值对序列获取。您访问这个序列的方式取决于您使用的开发平台以及您可能使用的任何特定框架。您使用的技术也决定了如何处理密钥副本;通常,最近收到的密钥的值是优先的。
|
||||
例如:原始PHP
|
||||
|
||||
PHP提供了一些全局对象来访问数据。假设您已经使用了POST方法,那么下面的示例将获取数据并将其显示给用户。当然,你对数据的处理取决于你自己。您可以显示它,将它存储到数据库中,通过电子邮件发送它,或者以其他方式处理它。
|
||||
|
||||
```
|
||||
<?php
|
||||
// The global $_POST variable allows you to access the data sent with the POST method by name
|
||||
// To access the data sent with the GET method, you can use $_GET
|
||||
$say = htmlspecialchars($_POST['say']);
|
||||
$to = htmlspecialchars($_POST['to']);
|
||||
|
||||
echo $say, ' ', $to;
|
||||
?>
|
||||
|
||||
```
|
||||
|
||||
这个例子显示了一个带有我们发送的数据的页面。您可以在我们的示例php-example.html中看到这一点——该文件包含与我们之前看到的相同的示例表单,它使用了post的method和php-example.php的action。当提交时,它将表单数据发送到php-example.php,其中包含了上述代码块中所见的php代码。当执行此代码时,浏览器中的输出是Hi Mom。
|
||||
|
||||
注意:当您将本例加载到本地浏览器中时,这个示例将无法工作---浏览器无法解析PHP代码,因此当提交表单时,浏览器只会为您提供下载PHP文件。为了让它生效,您需要通过某种类型的PHP服务器运行这个示例。本地PHP测试的好选择有MAMP(Mac和Windows)和AMPPS(Mac、Windows、Linux)。
|
||||
例子: Python
|
||||
|
||||
这个例子展示了如何使用Python完成同样的事情——在web页面上显示提交的数据。
|
||||
这将使用Flask framework来呈现模板、处理表单数据提交等(参见python-example.py)。
|
||||
|
||||
from flask import Flask, render_template, request
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/', methods=['GET', 'POST'])
|
||||
def form():
|
||||
return render_template('form.html')
|
||||
|
||||
@app.route('/hello', methods=['GET', 'POST'])
|
||||
def hello():
|
||||
return render_template('greeting.html', say=request.form['say'], to=request.form['to'])
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
|
||||
以上代码中引用的两个模板如下:
|
||||
|
||||
form.html: 与我们在The POST method小节中看到的相同的表单,但是将action设置为{{ url_for('hello') }}。(这是一个Jinja2模板,它基本上是HTML,但是可以包含对运行包含在花括号中的web服务器的Python代码的调用。url_for('hello')基本上是在“提交表单时重定向到/hello”。
|
||||
greeting.html: 这个模板只包含一行,用于呈现渲染时传递给它的两个数据块。
|
||||
这是通过前面所见的hello()函数完成的,该函数在/helloURL被导向时运行。
|
||||
|
||||
注意:同样,如果您只是尝试将其直接加载到浏览器中,那么这段代码将无法工作。Python的工作方式与PHP略有不同——要在本地运行此代码,您需要安装Python/pip,然后使用pip3 install flask安装Flask。此时,您应该能够使用python3 python-example.py来运行这个示例,然后在浏览器中导航到localhost:5000。
|
||||
其他语言和框架
|
||||
|
||||
还有许多其他的服务器端技术可以用于表单处理,包括Perl、Java、 .Net、Ruby等。只挑你最喜欢的用就好。话虽如此,但值得注意的是,直接使用这些技术并不常见,因为这可能很棘手。更常见的是使用许多优秀的框架,这些框架使处理表单变得更容易,例如:
|
||||
|
||||
Django for Python (比Flask要重量级一些,但是有更多的工具和选项。)
|
||||
Express for Node.js
|
||||
Laravel for PHP
|
||||
Ruby On Rails for Ruby
|
||||
Phoenix for Elixir
|
||||
|
||||
要注意的是,即使使用这些框架,使用表单也不一定很容易。但这比从头开始编写所有功能要简单得多,而且会节省很多时间。
|
||||
|
||||
注意:向您介绍任何服务器端语言或框架超出了本文的范围。如果你想要学习这些它们,上面的链接会给你一些帮助。
|
||||
|
||||
特殊案例:发送文件
|
||||
|
||||
用HTML表单发送文件是一个特殊的例子。文件是二进制数据——或者被认为是这样的——而所有其他数据都是文本数据。由于HTTP是一种文本协议,所以处理二进制数据有特殊的要求。
|
||||
enctype 属性
|
||||
|
||||
该属性允许您指定在提交表单时所生成的请求中的Content-Type的HTTP数据头的值。这个数据头非常重要,因为它告诉服务器正在发送什么样的数据。默认情况下,它的值是application/x-www-form-urlencoded。它的意思是:“这是已编码为URL参数的表单数据。”
|
||||
|
||||
如果你想要发送文件,你需要额外的三个步骤:
|
||||
|
||||
将method属性设置为POST,因为文件内容不能放入URL参数中。
|
||||
将enctype的值设置为multipart/form-data,因为数据将被分成多个部分,每个文件单独占用一个部分,表单正文中包含的文本数据(如果文本也输入到表单中)占用一个部分。
|
||||
包含一个或多个File picker小部件,允许用户选择将要上传的文件。
|
||||
|
||||
例如:
|
||||
|
||||
```
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div>
|
||||
<label for="file">Choose a file</label>
|
||||
<input type="file" id="file" name="myFile">
|
||||
</div>
|
||||
<div>
|
||||
<button>Send the file</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
```
|
||||
|
||||
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div>
|
||||
<label for="file">Choose a file</label>
|
||||
<input type="file" id="file" name="myFile">
|
||||
</div>
|
||||
<div>
|
||||
<button>Send the file</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
注意:一些浏览器支持\<input>的multiple属性,它允许只用一个 \<input> 元素选择一个以上的文件上传。服务器如何处理这些文件取决于服务器上使用的技术。如前所述,使用框架将使您的生活更轻松。
|
||||
|
||||
警告:为了防止滥用,许多服务器配置了文件和HTTP请求的大小限制。在发送文件之前,先检查服务器管理员的权限是很重要的。
|
||||
常见的安全问题
|
||||
|
||||
每次向服务器发送数据时,都需要考虑安全性。到目前为止,HTML表单是最常见的攻击路径(可能发生攻击的地方)。这些问题从来都不是来自HTML表单本身,它们来自于服务器如何处理数据。
|
||||
|
||||
根据你所做的事情,你会遇到一些非常有名的安全问题:
|
||||
XSS 和 CSRF
|
||||
|
||||
跨站脚本(XSS)和跨站点请求伪造(CSRF)是常见的攻击类型,它们发生在当您将用户发送的数据显示给这个用户或另一个用户时。
|
||||
|
||||
XSS允许攻击者将客户端脚本注入到其他用户查看的Web页面中。攻击者可以使用跨站点脚本攻击的漏洞来绕过诸如同源策略之类的访问控制。这些攻击的影响可能从一个小麻烦到一个重大的安全风险。
|
||||
|
||||
CSRF攻击类似于XSS攻击,因为它们以相同的方式开始攻击——向Web页面中注入客户端脚本——但它们的目标是不同的。CSRF攻击者试图将权限升级到特权用户(比如站点管理员)的级别,以执行他们不应该执行的操作(例如,将数据发送给一个不受信任的用户)。
|
||||
|
||||
XSS攻击利用用户对web站点的信任,而CSRF攻击则利用网站对其用户的信任。
|
||||
|
||||
为了防止这些攻击,您应该始终检查用户发送给服务器的数据(如果需要显示),尽量不要显示用户提供的HTML内容。相反,您应该对用户提供的数据进行处理,这样您就不会逐字地显示它。当今市场上几乎所有的框架都实现了一个最小的过滤器,它可以从任何用户发送的数据中删除HTML<script>、<iframe> 和<object> 元素。这有助于降低风险,但并不一定会消除风险。
|
||||
SQL注入
|
||||
|
||||
SQL 注入是一种试图在目标web站点使用的数据库上执行操作的攻击类型。这通常包括发送一个SQL请求,希望服务器能够执行它(通常发生在应用服务器试图存储由用户发送的数据时)。这实际上是攻击网站的主要途径之一。
|
||||
|
||||
其后果可能是可怕的,从数据丢失到通过使用特权升级控制整个网站基础设施的攻击。这是一个非常严重的威胁,您永远不应该存储用户发送的数据,而不执行一些清理工作(例如,在php/mysql基础设施上使用mysql_real_escape_string()。
|
||||
HTTP数据头注入和电子邮件注入
|
||||
|
||||
这种类型的攻击出现在当您的应用程序基于表单上用户的数据输入构建HTTP头部或电子邮件时。这些不会直接损害您的服务器或影响您的用户,但它们会引发一个更深入的问题,例如会话劫持或网络钓鱼攻击。
|
||||
|
||||
这些攻击大多是无声的,并且可以将您的服务器变成僵尸。
|
||||
偏执:永远不要相信你的用户
|
||||
|
||||
那么,你如何应对这些威胁呢?这是一个远远超出本指南的主题,不过有一些规则需要牢记。最重要的原则是:永远不要相信你的用户,包括你自己;即使是一个值得信赖的用户也可能被劫持。
|
||||
|
||||
所有到达服务器的数据都必须经过检查和消毒。总是这样。没有例外。
|
||||
|
||||
远离有潜在危险的字符转义。应该如何谨慎使用的特定字符取决于所使用的数据的上下文和所使用的服务器平台,但是所有的服务器端语言都有相应的功能。
|
||||
限制输入的数据量,只允许有必要的数据。
|
||||
沙箱上传文件(将它们存储在不同的服务器上,只允许通过不同的子域访问文件,或者通过完全不同的域名访问文件更好)。
|
||||
|
||||
如果你遵循这三条规则,你应该避免很多问题,但是如果你想要得到一个有能力的第三方执行的安全检查,这是一个好主意。不要以为你已经看到了所有可能的问题。
|
||||
|
||||
注意:我们的服务器端学习主题的网站安全性文章更详细地讨论了上述威胁和潜在的解决方案。
|
||||
结论
|
||||
|
||||
如您所见,发送表单数据很容易,但要确保应用程序的安全性是很棘手的。请记住,前端开发人员不是应该定义数据安全模型的人。是的,我们将看到,执行客户端数据验证是可能的,但是服务器不能信任这种验证,因为它无法真正知道客户端到底发生了什么。
|
||||
|
454
htmlpress/表格.md
@ -1,134 +1,370 @@
|
||||
# 表格(table)
|
||||
HTML 表格 入门
|
||||
|
||||
表格:由行和列组成的结构化数据集(表格数据)
|
||||
学习 Web 开发
|
||||
学习 HTML :指南与教程
|
||||
HTML 表格
|
||||
HTML 表格 入门
|
||||
|
||||
### 使用场景
|
||||
Select your preferred language
|
||||
Table of contents
|
||||
|
||||
html表格应用于展示表格数据,而不是用来实现网页布局
|
||||
什么是表格?
|
||||
动手练习: 创建你的第一个表格
|
||||
使用 <th> 元素添加标题
|
||||
允许单元格跨越多行和列
|
||||
为表格中的列提供共同的样式
|
||||
小结
|
||||
在本单元中
|
||||
|
||||
用表格实现网页布局出现的问题:
|
||||
Overview: Tables
|
||||
下一页
|
||||
|
||||
1. 表格布局减少了视觉受损的用户的可访问性
|
||||
2. 表格会产生更多的标签,使代码变得更难于编写,维护,调试
|
||||
3. 表格不能自动响应 正确的布局容器(如div ) 他们的默认宽度是父元素的100% 但表格的默认大小是根据其内容而定的。因此 如果要做移动端适配,就需要采取额外的措施来改变表格的样式
|
||||
本文将从HTML表格开始,介绍一些基本的内容,如行和单元格、标题、使单元格跨越多个列和行,以及如何将列中的所有单元组合在一起进行样式化。
|
||||
前置知识: HTML基本概念 (参见 Introduction to HTML)。
|
||||
目标: 了解熟悉HTML表格基本知识。
|
||||
什么是表格?
|
||||
|
||||
### 新建一个表格
|
||||
表格是由行和列组成的结构化数据集(表格数据),它能够使你简捷迅速地查找某个表示不同类型数据之间的某种关系的值 。比如说,某个人和他的年龄,一天或是一周,当地游泳池的时间表 。
|
||||
|
||||
1. 每个表格的内容都被包含在<table></table> 中 而且这些内容需要写在html结构的body部分
|
||||
2. 在表格中,最小的内容容器是单元格,是通过(td)创建的 这是一列
|
||||
3. 如果想换行,需要把位于同一行的内容包含在 一个tr 标签中 即用<tr></tr> 定义一行
|
||||
A sample table showing names and ages of some people - Chris 38, Dennis 45, Sarah 29, Karen 47.
|
||||
|
||||
示例:
|
||||
A swimming timetable showing a sample data table
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td>姓名</td>
|
||||
<td>年龄</td>
|
||||
<td>性别</td>
|
||||
<td>班级</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
表格在人类社会中很常见,而且已经存在很长时间了,下面这张1800年的美国人口普查文件中就可以证明:
|
||||
|
||||
效果如下:
|
||||
A very old parchment document; the data is not easily readable, but it clearly shows a data table being used.
|
||||
|
||||
![image-20210105170312759](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210105170312759.png)
|
||||
因此,HTML的创建者们提供了一种方法来构建和呈现web上的表格数据,这也就不足为奇了。
|
||||
表格如何工作?
|
||||
|
||||
上面的代码中出现的 <table border="1"></table> 中的border 用于给表格加上边框
|
||||
表格的一个特点就是严格. 通过在行和列的标题之间进行视觉关联的方法,就可以让信息能够很简单地被解读出来。观察下面的示例表格,然后找一个单数人称代词,这个单数人称代词是用于第三人称的, 用于女性的, 用作句子中的对象. 你可以把相应的行和列的标题关联起来,找到答案。
|
||||
|
||||
人称代词
|
||||
Subject Object
|
||||
单数 第一人称 I me
|
||||
第二人称 you you
|
||||
第三人称 ♂ he him
|
||||
♀ she her
|
||||
o it it
|
||||
复数 第一人称 we us
|
||||
第二人称 you you
|
||||
第三人称 they them
|
||||
|
||||
正确完成后, 即使是盲人也可以解析 HTML 表格中的数据,一个成功的 HTML 表格应该做到无论用户是视力正常还是视力受损,都能提高用户的体验。
|
||||
表格风格
|
||||
|
||||
#### 表格表头(th)
|
||||
你可以在 GitHub 上找到上面表格的 HTML源码 ; 先去看看, 当然也可以看看这个 look at the live example! 你也许会注意到一件事情,那就是这个表格看上去可读性不是很好,那是因为现在这个页面上面的那个表格通过 MDN 站点添加了一些样式, 而 GitHub 上面的并没有添加。
|
||||
|
||||
table包裹的 th标签会有加粗的效果 看起来是表格的表头
|
||||
不要幻想; 为了能够让表格在网页上有效, 你需要提供一些 CSS 的样式信息,以及尽可能好的 HTML 固定结构. 在这个模块中,我们将专注于 HTML 部分; 在你完成这里的内容之后,你可以浏览 Styling tables 来了解 CSS 的部分。
|
||||
|
||||
把上面表格的顶部四个单元格做成表头效果:
|
||||
虽然在这个模块中我们不会专注于 CSS, 但是我们提供了一个较小的 CSS 样式表让你使用,和默认的没有采用任何 CSS 样式的表相比,表格会更加可读。 你可以在 stylesheet here 获取样式表,以及在 HTML template 获取 HTML 文件来应用样式表,这些会让你在 “测试 HTML 表格” 中有一个好的起点。
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<th>姓名</th>
|
||||
<th>年龄</th>
|
||||
<th>性别</th>
|
||||
<th>班级</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>asd</td>
|
||||
<td>14</td>
|
||||
<td>男</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lily</td>
|
||||
<td>12</td>
|
||||
<td>女</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
注意: 也可以看下 personal_pronouns table with this styling applied 这个版本, 这个是应用了 CSS 以后表格看上去的样子。
|
||||
什么时候你不应该使用 HTML 表格?
|
||||
|
||||
![image-20210105172500056](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210105172500056.png)
|
||||
HTML 表格 应该用于表格数据 ,这正是 HTML 表格设计出来的用途. 不幸的是, 许多人习惯用 HTML 表格来实现网页布局, e.g. 一行包含 header, 一行包含几列内容, 一行包含 footer, etc. 你可以在我们的 Accessibility Learning Module 中的 Page Layouts 获得更多细节内容和一个示例。这种做法以前是很常见的,因为以前 CSS 在不同浏览器上的兼容性比较糟糕 ; 表格布局现在不太普遍,但您可能仍然会在网络的某些角落看到它们。
|
||||
|
||||
简单来说, 使用表格布局而不使用 CSS layout techniques 是很糟糕的. 主要的理由有以下几个:
|
||||
|
||||
表格布局减少了视觉受损的用户的可访问性: 屏幕阅读器, 被盲人所使用, 解析存在于 HTML 页面上的标签,然后为用户读出其中的内容。因为对于布局来说,表格不是一个正确的工具, 使用的标记比使用 CSS 布局技术更复杂, 所以屏幕阅读器的输出会让他们的用户感到困惑。
|
||||
表格会产生很多标签: 正如刚才提到的, 表格布局通常会比正确的布局技术涉及更复杂的标签结构,这会导致代码变得更难于编写、维护、调试.
|
||||
表格不能自动响应: 当你使用正确的布局容器 (比如 <header>, <section>, <article>, 或是 <div>), 它们的默认宽度是父元素的 100%. 而表格的的默认大小是根据其内容而定的。因此,需要采取额外的措施来获取表格布局样式,以便有效地在各种设备上工作。
|
||||
|
||||
### 允许单元格跨行或列
|
||||
动手练习: 创建你的第一个表格
|
||||
|
||||
对于表格的理论知识,我们已经说了很多了,所以, 让我们来看一个使用的例子,并建立一个简单的表格.
|
||||
|
||||
首先, 将 blank-template.html 和 minimal-table.css 拷贝到你的本地环境上。
|
||||
每一个表格的内容都包含在这两个标签中 : <table></table>. 在你的 HTML 的 <body> 中添加这些内容。
|
||||
在表格中,最小的内容容器是单元格, 是通过 <td> 元素创建的 ('td' 代表 'table data'). 把下面的内容添加到你的表格标签中:
|
||||
|
||||
<td>Hi, I'm your first cell.</td>
|
||||
|
||||
如果我们想要一行四个单元格,我们需要把这组标签拷贝三次,更新你表中的内容,让它看起来是这样的:
|
||||
|
||||
<td>Hi, I'm your first cell.</td>
|
||||
<td>I'm your second cell.</td>
|
||||
<td>I'm your third cell.</td>
|
||||
<td>I'm your fourth cell.</td>
|
||||
|
||||
你会看到, 单元格不会放置在彼此的下方, 而是自动与同一行上的其他单元格对齐. 每个 <td> 元素 创建一个单独单元格,它们共同组成了第一行。我们添加的每个单元格都使行的长度变长。
|
||||
|
||||
如果想让这一行停止增加,并让单元格从第二行开始,我们需要使用 <tr> 元素 ('tr' 代表 'table row'). 让我们现在来证实一下。
|
||||
|
||||
把你已经创建好的 4 个单元格放入 <tr> 标签, 就像:
|
||||
|
||||
<tr>
|
||||
<td>Hi, I'm your first cell.</td>
|
||||
<td>I'm your second cell.</td>
|
||||
<td>I'm your third cell.</td>
|
||||
<td>I'm your fourth cell.</td>
|
||||
</tr>
|
||||
|
||||
现在你已经实现了一行,可以继续增加至两行、三行。每一行都需要一个额外的 <tr> 元素来包装,每个单元格的内容都应该写在 <td>中。
|
||||
|
||||
这样会产生一个如下所示的表:
|
||||
Hi, I'm your first cell. I'm your second cell. I'm your third cell. I'm your fourth cell.
|
||||
Second row, first cell. Cell 2. Cell 3. Cell 4.
|
||||
|
||||
注意: 你也可以在 GitHub 中查看 simple-table.html (see it live also).
|
||||
使用 <th> 元素添加标题
|
||||
|
||||
现在,让我们把注意力转向表格标题,表格中的标题是特殊的单元格,通常在行或列的开始处,定义行或列包含的数据类型 (举个例子, 看到本篇文章中第一个示例中的 "单数" 或者 "Object" ). 为了说明它们为什么这么有用, 来看下面这个例子,首先是源代码:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Knocky</td>
|
||||
<td>Flor</td>
|
||||
<td>Ella</td>
|
||||
<td>Juan</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Breed</td>
|
||||
<td>Jack Russell</td>
|
||||
<td>Poodle</td>
|
||||
<td>Streetdog</td>
|
||||
<td>Cocker Spaniel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Age</td>
|
||||
<td>16</td>
|
||||
<td>9</td>
|
||||
<td>10</td>
|
||||
<td>5</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Owner</td>
|
||||
<td>Mother-in-law</td>
|
||||
<td>Me</td>
|
||||
<td>Me</td>
|
||||
<td>Sister-in-law</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Eating Habits</td>
|
||||
<td>Eats everyone's leftovers</td>
|
||||
<td>Nibbles at food</td>
|
||||
<td>Hearty eater</td>
|
||||
<td>Will eat till he explodes</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
这是表格实际呈现的效果:
|
||||
Knocky Flor Ella Juan
|
||||
Breed Jack Russell Poodle Streetdog Cocker Spaniel
|
||||
Age 16 9 10 5
|
||||
Owner Mother-in-law Me Me Sister-in-law
|
||||
Eating Habits Eats everyone's leftovers Nibbles at food Hearty eater Will eat till he explodes
|
||||
|
||||
这里的问题是:虽然你可以弄清楚发生了什么,但是尽可能的交叉参考数据并不容易。如果列和行的标题以某种方式出现,那将会更好。
|
||||
动手练习: 表格标题
|
||||
|
||||
让我们来改进这个表格.
|
||||
|
||||
首先, 把 dogs-table.html 和 minimal-table.css 文件保存到你的本地环境,HTML 文件包含上文你看到的几种狗的数据。
|
||||
为了将表格的标题在视觉上和语义上都能被识别为标题,你可以使用 <th> 元素 ('th' 代表 'table header'). 用法和 <td>是一样的,除了它表示为标题,不是普通的单元格以外。进入你的 HTML 文件, 将表格中应该是标题的 <td> 元素标记的内容,都改为用 <th> 元素标记。
|
||||
保存你的 HTML 文件,然后在浏览器中加载,然后你应该会看到,现在的标题更像标题了。
|
||||
|
||||
注意: 你可以在 GitHub 中找到完成的版本 dogs-table-fixed.html (see it live also).
|
||||
为什么标题是有用的?
|
||||
|
||||
我们已经给出了部分答案,当标题明显突出的时候,你可以更加简单地找到你想找的数据,设计上也会看起来更好。
|
||||
|
||||
注意: 即使你不给表格添加你自己的样式,表格标题也会带有一些默认样式:加粗和居中,让标题可以突出显示。
|
||||
|
||||
表格标题也有额外的好处,随着 scope 属性 (我们将在下一篇文章中了解到),这个属性允许你让表格变得更加无障碍,每个标题与相同行或列中的所有数据相关联。屏幕阅读设备能一次读出一列或一行的数据,这是非常有帮助的。
|
||||
允许单元格跨越多行和列
|
||||
|
||||
有时我们希望单元格跨越多行或多列。以下是一个简单的例子,显示了一些常见动物的名字。在某些情况下,我们要显示动物名称旁边的男性和女性的名字。有时候我们又不需要,那不需要的情况下,我们希望写着动物的名字的单元格的宽度可以是两个单元格的宽度 (因为写着名字的行会有两列,而没有写名字的行只有一列,行的宽度是不一样的)。
|
||||
|
||||
一开始的标记写法是这样的:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Animals</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Hippopotamus</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Horse</th>
|
||||
<td>Mare</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stallion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Crocodile</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Chicken</th>
|
||||
<td>Hen</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rooster</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
但是输出的结果不是我们想要的:
|
||||
Animals
|
||||
Hippopotamus
|
||||
Horse Mare
|
||||
Stallion
|
||||
Crocodile
|
||||
Chicken Hen
|
||||
Rooster
|
||||
|
||||
我们需要一个方法,让 "Animals", "Hippopotamus", 和 "Crocodile" 的单元格的宽度变为两个单元格, "Horse" 和 "Chicken" 的高度变为两行 (因为要拥有一个男性名字和女性名字,可以先看效果图)。幸好, 表格中的标题和单元格有 colspan 和 rowspan 属性,这两个属性可以帮助我们实现这些效果。这两个属性接受一个没有单位的数字值,数字决定了它们的宽度或高度是几个单元格。比如, colspan="2" 使一个单元格的宽度是两个单元格。
|
||||
|
||||
让我们使用 colspan 和 rowspan 来改进现有的表格。
|
||||
|
||||
首先,把 animals-table.html 和 minimal-table.css 文件复制到你的本地环境,HTML 文件中包含了你刚才看到的动物示例的数据。
|
||||
接着,使用 colspan 让 "Animals", "Hippopotamus", 和 "Crocodile" 占 2 个单元格的宽度。
|
||||
最后,使用 rowspan 让 "Horse" 和 "Chicken" 占 2 个单元格的高度。
|
||||
保存后,用浏览器打开你写的 HTML 文件,看看改进的地方。
|
||||
|
||||
注意: 你也可以在 GitHub 上找到完成的版本 animals-table-fixed.html (see it live also).
|
||||
为表格中的列提供共同的样式
|
||||
|
||||
在我们继续介绍之前,我们将介绍本文中的最后一个功能。HTML有一种方法可以定义整列数据的样式信息:就是 <col> 和 <colgroup> 元素。 它们存在是因为如果你想让一列中的每个数据的样式都一样,那么你就要为每个数据都添加一个样式,这样的做法是令人厌烦和低效的。你通常需要在列中的每个 <td> 或 <th> 上定义样式,或者使用一个复杂的选择器,比如 :nth-child()。
|
||||
|
||||
下面是一个简单的示例:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Data 1</th>
|
||||
<th style="background-color: yellow">Data 2</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Calcutta</td>
|
||||
<td style="background-color: yellow">Orange</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Robots</td>
|
||||
<td style="background-color: yellow">Jazz</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
下面就是上述代码的结果:
|
||||
Data 1 Data 2
|
||||
Calcutta Orange
|
||||
Robots Jazz
|
||||
|
||||
这样不太理想,因为我们不得不在列中的每个单元格中重复那些样式信息 (在真实的项目中,我们或许会设置一个 class 包含那三个单元格 ,然后在一个单独的样式表中定义样式). 为了舍弃这种做法,我们可以只定义一次,在 <col> 元素中。<col> 元素被规定包含在 <colgroup> 容器中,而 <colgroup>就在 <table> 标签的下方。我们可以通过如下的做法来创建与上面相同的效果:
|
||||
|
||||
<table>
|
||||
<colgroup>
|
||||
<col>
|
||||
<col style="background-color: yellow">
|
||||
</colgroup>
|
||||
<tr>
|
||||
<th>Data 1</th>
|
||||
<th>Data 2</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Calcutta</td>
|
||||
<td>Orange</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Robots</td>
|
||||
<td>Jazz</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
我们使用了两个 <col>来定义“列的样式”,每一个<col>都会制定每列的样式,对于第一列,我们没有采取任何样式,但是我们仍然需要添加一个空的 <col> 元素,如果不这样做,那么我们的样式就会应用到第一列上,这和我们预想的不一样。
|
||||
|
||||
如果你想把这种样式信息应用到每一列,我们可以只使用一个 <col> 元素,不过需要包含 span 属性,像这样:
|
||||
|
||||
<colgroup>
|
||||
<col style="background-color: yellow" span="2">
|
||||
</colgroup>
|
||||
|
||||
就像 colspan 和 rowspan, span 需要一个无单位的数字值,用来制定你想要让这个样式应用到表格中多少列
|
||||
动手练习: colgroup and col
|
||||
|
||||
又到了需要你自己独立完成的时间了。
|
||||
|
||||
下面你可以看到一位语言老师的时间表。星期五,她有一个新的课程,全天教荷兰语,但是在星期二和星期四的几个时间点,她也教德语。她想把那些包含她教学的日子的列高亮显示。
|
||||
|
||||
通过下面这些步骤来重构这个表格。
|
||||
|
||||
首先,把 timetable.html 文件复制到你的本地环境。这个 HTML 文件包含你在上文中看到的表格,不过是减去样式信息的。
|
||||
在 table 的顶部添加一个 <colgroup> 元素,就放在 <table> 标签下面,<colgroup>可以添加 <col> 元素 (继续看下面剩余的步骤)。
|
||||
第一列和第二列不需要应用样式。
|
||||
为第三列添加一个背景颜色。style 属性是 background-color:#97DB9A;
|
||||
为第四列设置一个独立的宽度,style 属性是 width: 42px;
|
||||
为第五列添加一个背景颜色。style 属性是 background-color: #97DB9A;
|
||||
为第六列添加不同的背景颜色和边框,表示这是一个特殊的日子,表示她正在教一个新的课。 style 属性是 background-color:#DCC48E; border:4px solid #C1437A;
|
||||
最后两天是休息日,所以只需将它们设置为无背景颜色,但需要设置宽度;style 属性是 width: 42px;
|
||||
|
||||
看看你是否能完成这个示例,如果你遇到了困难,或想要核对你完成的作品,你可以在 GitHub 上找到完成的版本 timetable-fixed.html (see it live also)。
|
||||
小结
|
||||
|
||||
本章节仅仅包含了 HTML 表格的基础。在下一篇文章中,我们将介绍一些稍微更高级的表格功能,并开始考虑方便视力障碍的人士的访问
|
||||
|
||||
Overview: Tables
|
||||
下一页
|
||||
|
||||
在本单元中
|
||||
|
||||
HTML table basics
|
||||
HTML table advanced features and accessibility
|
||||
Structuring planet data
|
||||
|
||||
Related Topics
|
||||
|
||||
新手请从这开始!
|
||||
Web 入门
|
||||
HTML — 构建 Web
|
||||
HTML 介绍
|
||||
多媒体与嵌入
|
||||
HTML 表格
|
||||
HTML 表格概览
|
||||
HTML 表格基础
|
||||
HTML 高级表格特性和可访问性
|
||||
作业:构建行星数据
|
||||
CSS — 设计 Web
|
||||
CSS first steps
|
||||
CSS building blocks
|
||||
样式化文字
|
||||
CSS 排版概述
|
||||
JavaScript — 用户端动态脚本
|
||||
JavaScript 第一步
|
||||
JavaScript 基础要件
|
||||
JavaScript 对象介绍
|
||||
Asynchronous JavaScript
|
||||
客户端网页 API
|
||||
Web forms — Working with user data
|
||||
Core forms learning pathway
|
||||
Advanced forms articles
|
||||
可访问性 — 使每个人都能使用 Web
|
||||
可访问性指南
|
||||
可访问性测评
|
||||
工具与测试
|
||||
Client-side web development tools
|
||||
Introduction to client-side frameworks
|
||||
React
|
||||
Ember
|
||||
Vue
|
||||
Svelte
|
||||
Git and GitHub
|
||||
跨浏览器测试
|
||||
服务端网页编程
|
||||
第一步
|
||||
Django 网站框架 (Python)
|
||||
Express 网页框架 (node.js/JavaScript)
|
||||
更多资源
|
||||
常见问题
|
||||
|
||||
Last modified: 2020年9月15日, by MDN contributors
|
||||
|
||||
Web Technologies
|
||||
Learn Web Development
|
||||
About MDN
|
||||
Feedback
|
||||
|
||||
About
|
||||
MDN Web Docs Store
|
||||
Contact Us
|
||||
Firefox
|
||||
|
||||
|
213
htmlpress/表格2.md
Normal file
@ -0,0 +1,213 @@
|
||||
HTML表格高级特性和可访问性
|
||||
|
||||
学习 Web 开发
|
||||
学习 HTML :指南与教程
|
||||
HTML 表格
|
||||
HTML表格高级特性和可访问性
|
||||
|
||||
Select your preferred language
|
||||
Table of contents
|
||||
|
||||
使用 <caption> 为你的表格增加一个标题
|
||||
添加 <thead>, <tfoot>, 和 <tbody> 结构
|
||||
嵌套表格
|
||||
对于视力受损的用户的表格
|
||||
总结
|
||||
|
||||
上一页
|
||||
Overview: Tables
|
||||
下一页
|
||||
|
||||
这个模块的第二篇文章中,我们来看一下 HTML 表格更高级的功能,比如像 表格的标题/摘要,以及将你表格中的各行分组成头部、正文、页脚部分,提高视力受损用户的可访问性。
|
||||
学习本章节的前提条件: HTML 的基础知识 (see Introduction to HTML).
|
||||
目的: 学习 HTML 表格进一步的功能,以及表格的无障碍访问性。
|
||||
使用 <caption> 为你的表格增加一个标题
|
||||
|
||||
你可以为你的表格增加一个标题,通过 <caption> 元素,再把 <caption> 元素放入 <table> 元素中. 你应该把它放在<table> 标签的下面。
|
||||
|
||||
<table>
|
||||
<caption>Dinosaurs in the Jurassic period</caption>
|
||||
|
||||
...
|
||||
</table>
|
||||
|
||||
从上面简单的例子可以推断,标题意味着包含对于表格内容的描述,这对那些希望可以快速浏览网页中的表格对他们是否有帮助的读者们来说,是非常好的功能。特别是盲人用户,不需要让屏幕阅读设备读出很多单元格的内容,来让用户了解这张表格讲的是什么,而是可以依靠标题的内容,来决定是否需要了解更详细的内容。
|
||||
|
||||
标题就放在 <table> 标签的下面。
|
||||
|
||||
注意: 这个 summary 属性也可以在<table> 元素中使用,用来提供一段描述,同样可以被屏幕阅读设备阅读。我们推荐使用 <caption> 元素来代替使用,因为 summary 被 HTML5 规范, deprecated (废除了),也不能被视力正常的用户阅读。 (它不会出现在页面上)
|
||||
动手练习: 添加一个标题
|
||||
|
||||
我们来试试看吧,回顾一下我们在之前的文章中第一次遇到的例子。.
|
||||
|
||||
打开你的语言老师的学校时间表,就是 HTML Table Basics 结尾中的例子,或者把 timetable-fixed.html 文件复制下面.
|
||||
为表格添加一个合适的标题。
|
||||
保存你的代码,然后用浏览器打开,看看你的表格是什么样的。
|
||||
|
||||
注意:你也可以在 GitHub 上找到我们的版本 timetable-caption.html (see it live also).
|
||||
添加 <thead>, <tfoot>, 和 <tbody> 结构
|
||||
|
||||
由于你的表格在结构上有点复杂,如果把它们定义得更加结构化,那会帮助我们更能了解结构。一个明确的方法是使用 <thead>, <tfoot>,和 <tbody>, 这些元素允许你把表格中的部分标记为表头、页脚、正文部分。
|
||||
|
||||
这些元素不会使表格更易于屏幕阅读器用户访问,也不会造成任何视觉上的改变。然而,它们在应用样式和布局上会起到作用,可以更好地让 CSS 应用到表格上。给你一些有趣的例子,在长表格的情况下,你可以在每个打印页面上使表格页眉和页脚重复,你也可以让表格的正文部分显示在一个单独的页面上,并通过上下滚动来获得内容。
|
||||
|
||||
试着使用它们:
|
||||
|
||||
<thead> 需要嵌套在 table 元素中,放置在头部的位置,因为它通常代表第一行,第一行中往往都是每列的标题,但是不是每种情况都是这样的。如果你使用了 <col>/<colgroup> 元素,那么 <thead>元素就需要放在它们的下面。
|
||||
<tfoot> 需要嵌套在 table 元素中,放置在底部 (页脚)的位置,一般是最后一行,往往是对前面所有行的总结,比如,你可以按照预想的方式将<tfoot>放在表格的底部,或者就放在 <thead> 的下面。(浏览器仍将它呈现在表格的底部)
|
||||
<tbody> 需要嵌套在 table 元素中,放置在 <thead>的下面或者是 <tfoot> 的下面,这取决于你如何设计你的结构。(<tfoot>放在<thead>下面也可以生效.)
|
||||
|
||||
注意: <tbody> 总是包含在每个表中,如果你没有在代码中指定它,那就是隐式的。可以来验证一下,打开一个你之前没有包含 <tbody> 的例子,然后在你的 browser developer tools 中观察你的代码,你会看到浏览器为你添加了这个标签。你也许会想问,为什么你应该在所有表中都需要这个元素,因为它可以让你更好地控制表格结构和样式。
|
||||
动手练习: 添加表格结构
|
||||
|
||||
让我们动手使用这些新元素。
|
||||
|
||||
首先,把 spending-record.html 和 minimal-table.css 拷贝到你的本地环境。
|
||||
尝试在浏览器中打开它,你会发现看起来不错,但是它可以被改善得更好。 "SUM" 行包含了已经使用的金额的总和,不过它出现在了错误的位置,以及代码中还遗失了一些细节。
|
||||
将明显的标题行改为使用 <thead> 元素,"SUM" 行使用 <tfoot> 元素,剩余的内容使用 <tbody> 元素。
|
||||
先保存,再刷新。你会看到,添加了 <tfoot> 元素后,导致 "SUM" 这行跑到了表格的底部。
|
||||
接着, 添加一个 colspan 属性,使 "SUM" 单元格占 4 个单元格的位置,所以实际数字是显示在 “Cost” 列的底部。
|
||||
让我们为表格添加一些简单的额外属性,能够让你理解这些属性是如何帮助更好地让表格应用 CSS 的。在你的 HTML 文件的 head 标签部分,你会看到一个空的 <style> 元素. 在 style 元素中添加下列 CSS 代码:
|
||||
|
||||
tbody {
|
||||
font-size: 90%;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
tfoot {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
先保存,再刷新,然后观察一下结果。如果没有 <tbody> 和 <tfoot> 元素,你也许会写更加复杂的选择器来应用同样的样式。
|
||||
|
||||
注意: 我们并不期望目前你可以理解所有 CSS 的内容。当你经过我们的 CSS 模块的时候,你应该会了解更多 (Introduction to CSS 是一个好的起点;我们也有专门的文章 styling tables).
|
||||
|
||||
你完成的表格应该如下所示:
|
||||
|
||||
注意: 你也可以在 GitHub 上找到 spending-record-finished.html (see it live also).
|
||||
嵌套表格
|
||||
|
||||
在一个表格中嵌套另外一个表格是可能的,只要你包含完整的结构,包括 <table> 元素。这样通常是不建议的,因为这种做法会使标记看上去很难理解,对使用屏幕阅读的用户来说,可访问性也降低了。以及在很多情况下,也许你只需要插入额外的 单元格/行/列 到已有的表格中。然而有时候是必要的,比如你想要从其他资源中更简单地导入内容。
|
||||
|
||||
下面的代码演示了一个简单的嵌套表格:
|
||||
|
||||
<table id="table1">
|
||||
<tr>
|
||||
<th>title1</th>
|
||||
<th>title2</th>
|
||||
<th>title3</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nested">
|
||||
<table id="table2">
|
||||
<tr>
|
||||
<td>cell1</td>
|
||||
<td>cell2</td>
|
||||
<td>cell3</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td>cell2</td>
|
||||
<td>cell3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cell4</td>
|
||||
<td>cell5</td>
|
||||
<td>cell6</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
输出看起来是这样的:
|
||||
title1 title2 title3
|
||||
cell1 cell2 cell3
|
||||
cell2 cell3
|
||||
cell4 cell5 cell6
|
||||
对于视力受损的用户的表格
|
||||
|
||||
让我们简要回顾一下如何使用数据表。一个表格可以是一个便利的工具,或者让我们快速访问数据,并允许我们查找不同的值。比如,你只需要稍微看一眼下列的表格,你就能得知 2016 年 8 月份在 Gent 出售了多少个 Rings (戒指)。为了理解信息,我们让数据与列标题或行标题之间建立视觉联系。
|
||||
Items Sold August 2016 Clothes Accessories
|
||||
Trousers Skirts Dresses Bracelets Rings
|
||||
Belgium Antwerp 56 22 43 72 23
|
||||
Gent 46 18 50 61 15
|
||||
Brussels 51 27 38 69 28
|
||||
The Netherlands Amsterdam 89 34 69 85 38
|
||||
Utrecht 80 12 43 36 19
|
||||
|
||||
但假设你无法通过视觉关联这些数据呢? 那么你应该如何阅读上述的表格? 视力受损的用户经常使用一个屏幕阅读设备来为他们读出网页上的信息。对于盲人来说,阅读简单的文字没有什么问题,但是要理解一张表格的内容,这就有一些难度了。虽然,使用正确的标记,我们可以用程序化来代替视觉关联。
|
||||
|
||||
注意: 根据世界卫生组织 2017 年的数据,大约有 2.53 亿人患有视觉障碍。
|
||||
|
||||
本篇文章提供了更一步的技术来使表格的可访问性尽可能地提高。
|
||||
使用列和行的标题
|
||||
|
||||
屏幕阅读设备会识别所有的标题,然后在它们和它们所关联的单元格之间产生编程关联。列和行标题的组合将标识和解释每个单元格中的数据,以便屏幕阅读器用户可以类似于视力正常的用户的操作来理解表格。
|
||||
|
||||
我们之前的文章就提到过这一点,可见 Adding headers with <th> elements.
|
||||
scope 属性
|
||||
|
||||
本篇文章的一个新话题是 scope 属性,可以添加在<th> 元素中,用来帮助屏幕阅读设备更好地理解那些标题单元格,这个标题单元格到底是列标题呢,还是行标题。比如: 回顾我们之前的支出记录示例,你可以明确地将列标题这样定义:
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Purchase</th>
|
||||
<th scope="col">Location</th>
|
||||
<th scope="col">Date</th>
|
||||
<th scope="col">Evaluation</th>
|
||||
<th scope="col">Cost (€)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
以及每一行都可以这样定义一个行标题 (如果我们已经使用了 th 和 td 元素):
|
||||
|
||||
<tr>
|
||||
<th scope="row">Haircut</th>
|
||||
<td>Hairdresser</td>
|
||||
<td>12/09</td>
|
||||
<td>Great idea</td>
|
||||
<td>30</td>
|
||||
</tr>
|
||||
|
||||
屏幕阅读设备会识别这种结构化的标记,并一次读出整列或整行,比如:
|
||||
|
||||
scope 还有两个可选的值 : colgroup 和 rowgroup。这些用于位于多个列或行的顶部的标题。 如果你回顾这部分文章开始部分的 "Items Sold August 2016" 表格。你会看到 "Clothes" 单元格在"Trousers", "Skirts", 和 "Dresses" 单元格的上面。这几个单元格都应该被标记为 (<th>),但是 "Clothes" 是一个位于顶部且定义了其他三个子标题的标题。 因此 "Clothes" 应该有一个 scope="colgroup"属性,而另外三个子标题应该有 scope="col"属性。
|
||||
id 和标题属性
|
||||
|
||||
如果要替代 scope 属性,可以使用 id 和 headers 属性来创造标题与单元格之间的联系。使用方法如下:
|
||||
|
||||
为每个<th> 元素添加一个唯一的 id 。
|
||||
为每个 <td> 元素添加一个 headers 属性。每个单元格的headers 属性需要包含它从属于的所有标题的id,之间用空格分隔开。
|
||||
|
||||
这会给你的HTML表格中每个单元格的位置一个明确的定义。像一个电子表格一样,通过 headers 属性来定义属于哪些行或列。为了让它工作良好,表格同时需要列和行标题。
|
||||
|
||||
回到我们的花费成本示例,前两个片段可以重写为:
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="purchase">Purchase</th>
|
||||
<th id="location">Location</th>
|
||||
<th id="date">Date</th>
|
||||
<th id="evaluation">Evaluation</th>
|
||||
<th id="cost">Cost (€)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th id="haircut">Haircut</th>
|
||||
<td headers="location haircut">Hairdresser</td>
|
||||
<td headers="date haircut">12/09</td>
|
||||
<td headers="evaluation haircut">Great idea</td>
|
||||
<td headers="cost haircut">30</td>
|
||||
</tr>
|
||||
|
||||
...
|
||||
|
||||
</tbody>
|
||||
|
||||
注意: 这个放进为标题单元格和数据单元格之间创造了非常精确的联系。但是这个方法使用了大量的标记,所以容错率比较低。使用 scope 的方法对于大多数表格来说,也够用了。
|
||||
动手练习: 使用 scope 和 headers
|
||||
|
||||
对于这个最后的练习,首先把 items-sold.html 和 minimal-table.css,拷贝到你的本地环境。
|
||||
现在尝试添加适当的 scope 属性来让表格变得更加恰当。
|
||||
最后,尝试把未添加 scope 属性的源文件再复制一份。这次使用 id 和 headers 属性让表格变得更加恰当。
|
||||
|
||||
|
12
js/.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="N802" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
6
js/.idea/inspectionProfiles/profiles_settings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
8
js/.idea/js.iml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
8
js/.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/js.iml" filepath="$PROJECT_DIR$/.idea/js.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
js/.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
56
js/.idea/workspace.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="03ca334c-40bc-4c12-a388-bb2facf7de9b" name="Default Changelist" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/../csspress/1.css基础.md" beforeDir="false" afterPath="$PROJECT_DIR$/../csspress/1.css基础.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../csspress/2.盒模型.md" beforeDir="false" afterPath="$PROJECT_DIR$/../csspress/2.盒模型.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../csspress/4.flex.md" beforeDir="false" afterPath="$PROJECT_DIR$/../csspress/4.flex.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../csspress/5.自适应和响应式.md" beforeDir="false" afterPath="$PROJECT_DIR$/../csspress/5.自适应和响应式.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../csspress/demo/flex.html" beforeDir="false" afterPath="$PROJECT_DIR$/../csspress/demo/flex.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../csspress/demo/position.html" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../csspress/demo/zishiying1.html" beforeDir="false" afterPath="$PROJECT_DIR$/../csspress/demo/zishiying1.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../csspress/demo/zishiying2.html" beforeDir="false" afterPath="$PROJECT_DIR$/../csspress/demo/zishiying2.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../htmlpress/html基础.md" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../htmlpress/表格.md" beforeDir="false" afterPath="$PROJECT_DIR$/../htmlpress/表格.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/demo/day4.html" beforeDir="false" afterPath="$PROJECT_DIR$/demo/day4.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/kejian/jsinfo - 副本.md" beforeDir="false" afterPath="$PROJECT_DIR$/kejian/jsinfo - 副本.md" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
|
||||
</component>
|
||||
<component name="ProjectId" id="1pH7VEJc50BfKDqtzBqB3lhLTmj" />
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
<property name="settings.editor.selected.configurable" value="configurable.group.appearance" />
|
||||
</component>
|
||||
<component name="SvnConfiguration">
|
||||
<configuration />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="03ca334c-40bc-4c12-a388-bb2facf7de9b" name="Default Changelist" comment="" />
|
||||
<created>1614828184663</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1614828184663</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="WindowStateProjectService">
|
||||
<state x="419" y="120" key="FileChooserDialogImpl" timestamp="1616051273471">
|
||||
<screen x="0" y="0" width="1280" height="760" />
|
||||
</state>
|
||||
<state x="419" y="120" key="FileChooserDialogImpl/0.0.1280.760@0.0.1280.760" timestamp="1616051273471" />
|
||||
</component>
|
||||
</project>
|
113
js/demo/bibao.html
Normal file
@ -0,0 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
// 目标 :从全局访问函数内部的变量
|
||||
// 方法1
|
||||
// function f1() {
|
||||
// var n = 999;
|
||||
// return {
|
||||
// n:n
|
||||
// }
|
||||
// }
|
||||
|
||||
// alert(f1().n)
|
||||
|
||||
// 方法2:
|
||||
// function f1() {
|
||||
// var n = 999;
|
||||
// function show(){
|
||||
// return n
|
||||
// }
|
||||
// show()
|
||||
// }
|
||||
// alert(f1()) //undefined F1函数没有返回值
|
||||
// alert(show()) // show is not defined show()在函数f1的作用域中
|
||||
// alert(f1()) //undeined F1函数没有返回值
|
||||
|
||||
// 作用域:
|
||||
//
|
||||
// window
|
||||
// f1
|
||||
// n
|
||||
// show
|
||||
|
||||
// function f1() {
|
||||
// var n = 999;
|
||||
// function show(){
|
||||
// return n
|
||||
// }
|
||||
// return show()
|
||||
// }
|
||||
// alert(f1())
|
||||
|
||||
// 方法三
|
||||
// function f1(){
|
||||
// var n=999;
|
||||
// function show(){
|
||||
// alert(n)
|
||||
// }
|
||||
// show()
|
||||
// }
|
||||
|
||||
// f1()
|
||||
|
||||
function f1(){
|
||||
var n=999;
|
||||
function add(){
|
||||
return n++
|
||||
}
|
||||
return add() //函数返回值
|
||||
}
|
||||
console.log(f1()) //999
|
||||
var res=f1() //999
|
||||
console.log(f1()) //999
|
||||
|
||||
// GO: f1
|
||||
// ao: n, add
|
||||
|
||||
|
||||
|
||||
|
||||
function f1(){
|
||||
var n=999;
|
||||
function add(){
|
||||
return n++
|
||||
}
|
||||
return add //函数体
|
||||
}
|
||||
var res=f1() //通过return add 将add赋给res
|
||||
// console.log(res)
|
||||
// add 其实就是 全局访问f1中变量的一个桥
|
||||
console.log(res()) //999
|
||||
console.log(res()) //1000
|
||||
|
||||
|
||||
// GO: f1,
|
||||
// res:add
|
||||
// AO: n
|
||||
// add
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h3>作用域</h3>
|
||||
<p>
|
||||
函数内部的变量叫局部变量 只能再函数体内部访问 外部无法访问。 前提是 声明变量的方式是var
|
||||
如果变量前面没有修饰,那么它就是 全局变量
|
||||
</p>
|
||||
<p>
|
||||
闭包的形式上是父级函数返回的是子函数的函数体,从全局变量接收后就相当于把子函数塞给go,执行后不会被销毁
|
||||
</p>
|
||||
<p>
|
||||
闭包的用处:一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
83
js/demo/buhuo.html
Normal file
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
.box{
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
.box1{
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
background: pink;
|
||||
}
|
||||
.box2{
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: gold;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="box">
|
||||
<div class="box1" >
|
||||
<div class="box2"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
总结:点击box2时,会接连触发 box() -> box1() -> box2() 整个过程叫做捕获(从外往里)
|
||||
|
||||
冒泡和捕获不会同时发生
|
||||
<p>addEventListener 能给目标元素添加多个事件</p>
|
||||
<p> 阻止捕获: event.stopImmediatePropagation() event.stopPropagation()</p>
|
||||
<p>stopImmediatePropagation和stopPropagation 都能阻止捕获,但是同一个元素有多个同类型事件的时候,stopPropagation不能阻止其他事件的发生
|
||||
stopImmediatePropagation能阻止其他事件发生的 </p>
|
||||
</div>
|
||||
<script>
|
||||
var boxdj=document.getElementsByClassName('box')[0]
|
||||
boxdj.addEventListener("click", function (){
|
||||
console.log("box被点击了")
|
||||
event.stopImmediatePropagation()
|
||||
},true)
|
||||
boxdj.addEventListener("click", function (){
|
||||
console.log("box被点击了2!!!!!")
|
||||
event.stopImmediatePropagation()
|
||||
},true)
|
||||
var box1dj=document.getElementsByClassName('box1')[0]
|
||||
box1dj.addEventListener("click", function (){
|
||||
console.log("box1被点击了")
|
||||
event.stopPropagation()
|
||||
},true)
|
||||
var box2dj=document.getElementsByClassName('box2')[0]
|
||||
box2dj.addEventListener("click", function (){
|
||||
console.log("box2被点击了")
|
||||
event.stopImmediatePropagation()
|
||||
},true)
|
||||
|
||||
|
||||
function box(){
|
||||
console.log("box被点击了")
|
||||
}
|
||||
function box1(){
|
||||
console.log("box1被点击了")
|
||||
return
|
||||
}
|
||||
function box2(){
|
||||
console.log("box2被点击了")
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
function box3(){
|
||||
console.log("box1被点击了2")
|
||||
event.stopPropagation();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
71
js/demo/callapply.html
Normal file
@ -0,0 +1,71 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
// call,apply 用其他函数的方法
|
||||
function add(a,b){
|
||||
return a+b;
|
||||
}
|
||||
function sub(a,b){
|
||||
return a-b;
|
||||
}
|
||||
var a1 = add.apply(sub,[4,2]); //sub调用add的方法
|
||||
var a2 = sub.apply(add,[4,2]);
|
||||
// alert(a1); //6
|
||||
// alert(a2); //2
|
||||
|
||||
/*call的用法*/
|
||||
var a1 = add.call(sub,4,2); //sub调用add的方法
|
||||
console.log(a1)
|
||||
|
||||
// 实现继承 cat 继承animal
|
||||
function Animal(name){
|
||||
this.name = name;
|
||||
this.showName = function(){
|
||||
alert(this.name);
|
||||
}
|
||||
}
|
||||
|
||||
function Cat(name){
|
||||
console.log(this)
|
||||
Animal.apply(this,[name]); // this new以后指向的是他的实例,cat 但是cat的构造函数里面通过apply把当前的this指向了animal
|
||||
//所以他实例出来的对象cat 就能用 animal里面的属性和方法
|
||||
}
|
||||
|
||||
var cat = new Cat("咕咕");
|
||||
cat.showName();
|
||||
|
||||
/*call的用法*/
|
||||
Animal.call(this,name);
|
||||
|
||||
|
||||
// bind
|
||||
var a = {
|
||||
b : function(){
|
||||
var func = function(){
|
||||
console.log(this.c);
|
||||
}
|
||||
func.bind(this)(); //等价于 this.func()
|
||||
},
|
||||
c : 'Hello!'
|
||||
}
|
||||
a.b();
|
||||
//Hello!
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p> call和apply的作用都是 修改this的指向</p>
|
||||
<p> call和apply 操作的都是函数 而不是对象</p>
|
||||
<p>区别:
|
||||
<p>call 需要的参数都写上(单独的)</p>
|
||||
<p>apply 需要的参数 如果有多个的话,需要用数组的形式传过去</p>
|
||||
</p>
|
||||
<p>bind()方法主要就是将函数绑定到
|
||||
<p>f.bind(obj),实际上可以理解为obj.f()</p>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Documen</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
var box = document.createElement('div')
|
||||
box.innerHTML = 'happy new year'
|
||||
box.setAttribute('style', 'width:100px;height:100px;background:red;color:white')
|
||||
var main = document.body
|
||||
main.append(box)
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
51
js/demo/digui&bibao.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>递归和杨辉三角</title>
|
||||
</head>
|
||||
<body>
|
||||
<button onclick="ljq()">点我加一</button>
|
||||
<p></p>
|
||||
<script>
|
||||
|
||||
function combine (m, n) {
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
} else if (m == n) {
|
||||
return 1;
|
||||
} else {
|
||||
return combine(m - 1, n) + combine(m - 1, n - 1);
|
||||
}
|
||||
}
|
||||
|
||||
function put (len) {
|
||||
for (let i = 0; i < len; i++) {
|
||||
for (let j = 0; j <= i; j++) {
|
||||
document.write(combine(i, j) + ' ');
|
||||
}
|
||||
document.write('<br/>');
|
||||
}
|
||||
}
|
||||
put(5);
|
||||
|
||||
|
||||
|
||||
function add(){
|
||||
var count = 0;
|
||||
function demo(){
|
||||
count ++;
|
||||
console.log("现在的值:"+count);
|
||||
}
|
||||
return demo;
|
||||
}
|
||||
var counter = add();
|
||||
function ljq(){counter(); }
|
||||
|
||||
// 目的:从全局访问add里面的count变量
|
||||
// 点击调用ljq -> counter-> counter=demo->demo() -> 输出结果
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
29
js/demo/digui.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
function a(n) {
|
||||
if (n <= 1) {
|
||||
return 1
|
||||
} else {
|
||||
return n * a(n - 1)
|
||||
}
|
||||
}
|
||||
console.log(a(5)) //120
|
||||
|
||||
var cheng=a
|
||||
a=null
|
||||
console.log(cheng(5))// : a is not a function
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
97
js/demo/diguibibao.html
Normal file
@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
// 递归 函数内部调用他自己 必须有个终点
|
||||
let num = 0;
|
||||
function a(index){
|
||||
if(index == 0){
|
||||
return 0;
|
||||
}else {
|
||||
return index + a(index - 1)
|
||||
//10+a(9)
|
||||
//10+9+a(8)
|
||||
//10+9+8+a(7)
|
||||
//.....
|
||||
//10+9+8+7+......+3+2+1+0
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
num = a(10)
|
||||
alert(num)
|
||||
|
||||
// function a (){
|
||||
// let b = 100;
|
||||
// return function (){
|
||||
// b++;
|
||||
// return b;
|
||||
// }
|
||||
// }
|
||||
// let c = a()
|
||||
// alert(c())
|
||||
// alert(c())
|
||||
// alert(c())
|
||||
// alert(c())
|
||||
// alert(c())
|
||||
|
||||
function a (){
|
||||
let name = "123"
|
||||
var shop = {
|
||||
a: "商品c",
|
||||
b: "商品d"
|
||||
}
|
||||
return {
|
||||
name: "321",
|
||||
getname(name){
|
||||
return "商品" + name +"的值是" + shop[name]
|
||||
},
|
||||
addshop(name1,item){
|
||||
shop[item] = name1 // shop['pingguo']="苹果"
|
||||
alert(this.name) //543
|
||||
},
|
||||
getlist(){
|
||||
return shop
|
||||
},
|
||||
setname(name){
|
||||
this.name = name
|
||||
}
|
||||
}
|
||||
}
|
||||
let sa = a()
|
||||
alert(sa.getname('a')) //商品a的值是商品c
|
||||
sa.setname("543") // sa.name = 543
|
||||
sa.addshop("苹果","pingguo") //543
|
||||
alert(sa.getname('pingguo')) //商品pingguo的值是、苹果
|
||||
|
||||
console.log(sa.getlist())
|
||||
function b (){
|
||||
var shop = {
|
||||
a: "商品a",
|
||||
b: "商品b"
|
||||
}
|
||||
return {
|
||||
getname(name){
|
||||
return "商品" + name +"的值是" + shop[name]
|
||||
},
|
||||
addshop(name,item){
|
||||
shop[item] = name
|
||||
},
|
||||
getlist(){
|
||||
return shop
|
||||
}
|
||||
}
|
||||
}
|
||||
let sb = b()
|
||||
|
||||
// 递归 生成杨辉三角
|
||||
// 闭包 封装一个累加器 调用add 方法+1 调用get方法 获取现在的累加值 ‘当前值是 ’
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
38
js/demo/dingshiqi.html
Normal file
@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
// 每三秒打印一次“Hello”
|
||||
var h = setInterval(function () {
|
||||
console.log("hello")
|
||||
}, 3000)
|
||||
setTimeout(function () {
|
||||
clearInterval(h)
|
||||
}, 9000)
|
||||
|
||||
(function () {
|
||||
var m = 0;
|
||||
function getM() {
|
||||
return m;
|
||||
}
|
||||
function seta(val) {
|
||||
m = val;
|
||||
}
|
||||
window.g = getM;
|
||||
window.f = seta;
|
||||
})();
|
||||
f(100);
|
||||
console.info(g());
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
104
js/demo/dom.html
Normal file
@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
.gaibianzhuti{
|
||||
color: white;
|
||||
background-color: black;
|
||||
width: 100px;
|
||||
}
|
||||
.biaoge{
|
||||
width: 100px;
|
||||
display: none;
|
||||
}
|
||||
.div1 {
|
||||
border: 1px dashed black;
|
||||
padding: 27px;
|
||||
width: 350px;
|
||||
height: 350px;
|
||||
margin: 100px auto;
|
||||
}
|
||||
.div2 {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
padding: 20px;
|
||||
border: 5px solid #d7effe;
|
||||
}
|
||||
.div3 {
|
||||
background-color: #ffa0df;
|
||||
overflow: hidden;
|
||||
}
|
||||
.div4 {
|
||||
margin: 40px;
|
||||
border: 1px dashed white;
|
||||
width: 218px;
|
||||
height: 218px;
|
||||
}
|
||||
.div5 {
|
||||
margin: 3px;
|
||||
border: 1px dotted white;
|
||||
width: 210px;
|
||||
height: 210px;
|
||||
}
|
||||
.div6 {
|
||||
margin: 49px;
|
||||
border: 5px solid #fcff00;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: #96ff38;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="div1">
|
||||
|
||||
</div>
|
||||
<script>
|
||||
var div1 = document.getElementsByClassName("div1")[0];
|
||||
var d2=document.createElement('div')
|
||||
d2.setAttribute('class','div2')
|
||||
div1.append(d2);
|
||||
var d3=document.createElement('div')
|
||||
d3.setAttribute('class','div3')
|
||||
d2.append(d3);
|
||||
var d4=document.createElement('div')
|
||||
d4.setAttribute('class','div4')
|
||||
d3.append(d4);
|
||||
var d5=document.createElement('div')
|
||||
d5.setAttribute('class','div5')
|
||||
d4.append(d5);
|
||||
var d6=document.createElement('div')
|
||||
d6.setAttribute('class','div6')
|
||||
d5.append(d6);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<!--
|
||||
html
|
||||
head
|
||||
title
|
||||
meta
|
||||
|
||||
text --回车
|
||||
body
|
||||
text
|
||||
-->
|
||||
|
||||
<!--
|
||||
html
|
||||
head
|
||||
meta
|
||||
title
|
||||
body
|
||||
table
|
||||
tbody
|
||||
tr
|
||||
th
|
||||
td
|
||||
text
|
||||
-->
|
39
js/demo/jqajax.html
Normal file
@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script src="https://cdn.staticfile.org/jquery/2.0.0/jquery.min.js"></script>
|
||||
<script>
|
||||
$.ajax({
|
||||
url:"http://127.0.0.1:5000/userlist",
|
||||
type:"GET",
|
||||
dataType:"json",
|
||||
success:function(res){
|
||||
console.log(res)
|
||||
var uinfo=res
|
||||
$.each(uinfo,function(i,val){
|
||||
// console.log(i,val)
|
||||
var obj=val
|
||||
console.log(obj.username)
|
||||
var list=$("<tr><td>"+obj.userid+"</td><td>"+obj.username+"</td><td>"+obj.account+"</td><td>"+obj.pwd+"</td></tr>")
|
||||
$('#uinfo').append(list)
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<table id="uinfo">
|
||||
<tr>
|
||||
<th>编号</th>
|
||||
<th>姓名</th>
|
||||
<th>账号</th>
|
||||
<th>密码</th>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
58
js/demo/jqchildren.html
Normal file
@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
.ancestors *
|
||||
{
|
||||
display: block;
|
||||
border: 2px solid lightgrey;
|
||||
color: lightgrey;
|
||||
padding: 5px;
|
||||
margin: 15px;
|
||||
}
|
||||
.descendants *
|
||||
{
|
||||
display: block;
|
||||
border: 2px solid lightgrey;
|
||||
color: lightgrey;
|
||||
padding: 5px;
|
||||
margin: 15px;
|
||||
}
|
||||
.descendants1 *
|
||||
{
|
||||
display: block;
|
||||
border: 2px solid grey;
|
||||
color: grey;
|
||||
padding: 5px;
|
||||
margin: 15px;
|
||||
}
|
||||
.demo2{
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdn.staticfile.org/jquery/2.0.0/jquery.min.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="descendants" style="width:500px;">div (当前元素)
|
||||
<p class="11">p (子)
|
||||
<span>span (孙)</span>
|
||||
</p>
|
||||
<p class="11">p (子)
|
||||
<span>span (孙)</span>
|
||||
</p>
|
||||
<p class="22">p (子)
|
||||
<span>span (孙)</span>
|
||||
</p>
|
||||
</div>
|
||||
<script>
|
||||
// $(".descendants").children(":first").css({"color":"red","border":"2px solid red"});
|
||||
// $(".descendants").children(".11").css({"color":"red","border":"2px solid red"});
|
||||
$(".descendants").child().css({"color":"red","border":"2px solid red"});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
53
js/demo/jsdom.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
.box{
|
||||
width:100px;
|
||||
height: 100px;
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<p class="newyear" id="niu" name="neo">过年好</p>
|
||||
<div id="old">
|
||||
ppplolk
|
||||
<p>bye 2020</p>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var str=""
|
||||
str=document.getElementsByTagName('p')[0] //通过标签获取元素
|
||||
// 通过类名获取元素 str=document.getElementsByClassName('newyear')[0].innerHTML
|
||||
// 通过id获取元素 str=document.getElementById('niu').innerHTML
|
||||
// console.log(str)
|
||||
str.innerHTML="新年快乐"
|
||||
var attr=str.getAttribute('name') //获取属性
|
||||
str.setAttribute('name','tom')
|
||||
str.setAttribute('class','demo2')
|
||||
// console.log(attr)
|
||||
|
||||
var oldyear=document.getElementById('old')
|
||||
// oldyear.remove()
|
||||
// oldyear.parentNode.removeChild(oldyear); 通过父级删自己
|
||||
|
||||
var val=document.querySelectorAll("#old")
|
||||
// document.querySelectorAll("p")
|
||||
// document.querySelectorAll(".demo2")
|
||||
console.log(val[0].innerHTML)
|
||||
var myele=document.createElement('div')
|
||||
myele.setAttribute('class','box')
|
||||
myele.innerHTML="happy new year"
|
||||
// console.log(myele)
|
||||
document.body.append(myele)
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
99
js/demo/jsform.html
Normal file
@ -0,0 +1,99 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script src="https://cdn.staticfile.org/jquery/2.0.0/jquery.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<input type="text" placeholder="姓名" value="" name="name" id="name">
|
||||
<div>
|
||||
<input type="radio" value="1" name="sex">男
|
||||
<input type="radio" value="2" name="sex">女
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="hob" value="game">玩游戏
|
||||
<input type="checkbox" name="hob" value="bilibili">看小视频
|
||||
<input type="checkbox" name="hob" value="tv">电视剧
|
||||
</div>
|
||||
|
||||
<select name="lesson" id="lesson">
|
||||
<option value="1">法学</option>
|
||||
<option value="2">医学</option>
|
||||
<option value="3">哲学</option>
|
||||
</select>
|
||||
<div>
|
||||
<button onclick="save()">保存</button>
|
||||
</div>
|
||||
总结一:
|
||||
1.radio 选中的时候for循环checked
|
||||
2.checkbox 选中的时候要用个数组接收,判断是否选中也是用checked属性值
|
||||
3.select 下拉框 选中的时候要用selected 判断是否选中
|
||||
4.数组转字符串 可以用join(),toString,for循环遍历数组再拼接字符串
|
||||
|
||||
<script>
|
||||
var obj = {}
|
||||
// function save(){
|
||||
// var uname=document.getElementById('name')
|
||||
// // console.log(uname.value)
|
||||
// var sex= document.getElementsByName("sex");
|
||||
// // console.log(sex[0].checked,sex[0].value)
|
||||
// var hobby=document.getElementsByName('hob')
|
||||
// // console.log(hobby[0].checked,hobby[0].value)
|
||||
// var lesson=document.getElementById('lesson')
|
||||
// // console.log(lesson.options)
|
||||
// for(let i=0; i<lesson.options.length;i++){
|
||||
// console.log(lesson.options[i].selected,lesson.options[i].value)
|
||||
// }
|
||||
// }
|
||||
function save() {
|
||||
|
||||
obj.name = document.getElementById('name').value;
|
||||
// console.log(obj,123)
|
||||
var sex = document.getElementsByName('sex')
|
||||
for (let i = 0; i < sex.length; i++) {
|
||||
|
||||
if (sex[i].checked) {
|
||||
obj.sex = sex[i].value
|
||||
}
|
||||
}
|
||||
|
||||
var hob = document.getElementsByName("hob")
|
||||
obj.hob = []
|
||||
for (let i = 0; i < hob.length; i++) {
|
||||
if (hob[i].checked) {
|
||||
obj.hob[i] = hob[i].value
|
||||
}
|
||||
}
|
||||
|
||||
var lesson = document.getElementById('lesson')
|
||||
for (let i = 0; i < lesson.length; i++) {
|
||||
console.log(lesson[i])
|
||||
if (lesson[i].selected) {
|
||||
obj.lesson = lesson[i].value
|
||||
}
|
||||
}
|
||||
// obj.hob=obj.hob.join(',')
|
||||
obj.hob = obj.hob.toString()
|
||||
console.log(obj, 123)
|
||||
|
||||
|
||||
// 下面是ajax
|
||||
$.ajax({
|
||||
url: "https://kaoshi-shangpin.theluyuan.com/findshop",
|
||||
data:obj,
|
||||
type:"GET",
|
||||
dataType:"json",
|
||||
success: function (res) {
|
||||
console.log(res)
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
34
js/demo/jsshijian.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
function say(){
|
||||
alert("你好")
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<button onclick="say()">say</button>
|
||||
<div>
|
||||
<button class="says">say1</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="say2">say2</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var mouse=document.getElementsByClassName('says')[0]
|
||||
mouse.onclick=function(){
|
||||
alert('nihao')
|
||||
}
|
||||
|
||||
var mouse1=document.getElementsByClassName('say2')[0]
|
||||
mouse1.addEventListener("click",function(){alert("hello")})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
57
js/demo/maopao.html
Normal file
@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
.box{
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
.box1{
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
background: pink;
|
||||
}
|
||||
.box2{
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: gold;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function box(){
|
||||
console.log("box被点击了")
|
||||
}
|
||||
function box1(){
|
||||
console.log("box1被点击了")
|
||||
return
|
||||
}
|
||||
function box2(){
|
||||
console.log("box2被点击了")
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
function box3(){
|
||||
console.log("box1被点击了2")
|
||||
event.stopPropagation();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box" onclick="box()">
|
||||
<div class="box1" onclick="box1(),box3()">
|
||||
<div class="box2" onclick="box2()"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
总结:点击box2时,会接连触发 box2() -> box1() -> box() 整个过程叫做冒泡
|
||||
<p> 阻止冒泡: event.stopImmediatePropagation() event.stopPropagation()</p>
|
||||
冒泡和捕获不会同时发生
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
25
js/demo/riqishijian.html
Normal file
@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
// 2021-2-26
|
||||
// 9:58:12
|
||||
var now=new Date()
|
||||
console.log(now)
|
||||
console.log(now.getFullYear()) //2021
|
||||
console.log(now.getMonth()+1) //2
|
||||
console.log(now.getDate())
|
||||
console.log(now.getDay()) //星期
|
||||
console.log(now.getTime()) //时间戳
|
||||
|
||||
console.log(now.getHours()+":"+now.getMinutes()+":"+now.getSeconds())
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
73
js/demo/yuanxing.html
Normal file
@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
var val=999
|
||||
var obj={name:"ming"} // 字面量创建
|
||||
function Grand(){
|
||||
this.name="root"
|
||||
this.pow=2
|
||||
this.say=function(){
|
||||
console.log("我是根")
|
||||
}
|
||||
}
|
||||
var grand1=new Grand()
|
||||
console.log(grand1.__proto__) //grand1 obj 中有个 prototype, 对象里面只能用__proto__ 访问原型(左右两个横线)
|
||||
console.log(Grand.prototype) //Grand 函数里面有个 prototype
|
||||
// console.log(Grand.__proto__) error写法 函数里面只能用prototype属性访问原型
|
||||
|
||||
|
||||
function f(){
|
||||
this.name="father"
|
||||
|
||||
}
|
||||
f.prototype=grand1 //原型指向的只能是实例对象 不能是函数
|
||||
f.prototype.val="miku"
|
||||
var fa=new f()
|
||||
fa.say()
|
||||
console.log(fa)
|
||||
|
||||
var me={}
|
||||
me.__proto__=fa
|
||||
console.log(me.name)
|
||||
console.log(me.val)
|
||||
//grand1 => fa =>me :原型链
|
||||
|
||||
// me.pow
|
||||
// me 从me对象中查找pow属性的值
|
||||
// |
|
||||
// fa me对象中找不到属性时 就会去 上一级 也就是fa对象中找 Pow的值
|
||||
// |
|
||||
// grand1 fa 对象中也找不到这个属性的话 ,那么就再往上一层 找grand1中的 pow的值
|
||||
|
||||
// 如grand1中也找不到这个值呢 就结果上来说 结果是Undefined 而且原型链的尽头不是window
|
||||
function A(sa){
|
||||
this.sa = sa;
|
||||
this.hello = function(){console.log("hello")}
|
||||
}
|
||||
function Aa(saa){
|
||||
this.saa = saa;
|
||||
|
||||
}
|
||||
function Aaa(saaa){
|
||||
this.saaa = saaa;
|
||||
|
||||
}
|
||||
var z = new A();
|
||||
Aa.prototype = z;
|
||||
var za = new Aa();
|
||||
Aaa.prototype = za;
|
||||
var zaa = new Aaa();
|
||||
|
||||
zaa.hello();
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
29
js/demo/zuoyongyulx.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
function createPerson(name) {
|
||||
let localPerson = new Object();
|
||||
localPerson.name = name;
|
||||
return localPerson;
|
||||
}
|
||||
|
||||
let globalPerson = createPerson("Nicholas");
|
||||
|
||||
// 解除globalPerson对值的引用
|
||||
|
||||
// globalPerson = null;
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
65
js/kejian/bom.md
Normal file
@ -0,0 +1,65 @@
|
||||
# Bom
|
||||
bom 全称是浏览器对象模型 ,他提供的是浏览器操作的方法
|
||||
bom 组成:
|
||||
* window对象 js顶层对象 全局global
|
||||
* location 浏览器当前url信息
|
||||
* screen 客户端屏幕信息
|
||||
* navigator 浏览器本身信息
|
||||
* history 记录历史信息
|
||||
|
||||
## window
|
||||
* 通过js通过浏览器访问的接口
|
||||
* esma 规定的global对象
|
||||
|
||||
```
|
||||
var a=9
|
||||
console.log(a) //9
|
||||
console.log(window.a)
|
||||
console.log(top) //top 指的是顶层对象也等于window
|
||||
|
||||
```
|
||||
window 对象的方法有:
|
||||
alert()
|
||||
confirm() //弹出一个确认框
|
||||
prompt() //弹出一个带输入框的弹窗
|
||||
open(url,打开方式,新窗口的尺寸)
|
||||
打开方式 默认新窗口打开 ,self/black
|
||||
close() 关闭当前的网页
|
||||
|
||||
|
||||
窗口的尺寸
|
||||
document.documentElement.clientWidth 和document.documentElement.clientHeight ;(非严格模式)
|
||||
|
||||
pageWidth = document.body.clientWidth;
|
||||
pageHeight = document.body.clientHeight;(严格模式)
|
||||
## location
|
||||
window.location.href(url) 页search 返回?号后面的所有值。
|
||||
port 返回URL中的指定的端口号,如URL中不包含端口号返回空字符串
|
||||
|
||||
portocol 返回页面使用的协议。 http:或https:面跳转
|
||||
|
||||
|
||||
## navigator
|
||||
navigator.platform:操作系统类型;
|
||||
navigator.userAgent:浏览器设定的User-Agent字符串。 浏览器相关信息都能返回
|
||||
navigator.appName:浏览器名称;
|
||||
navigator.appVersion:浏览器版本;
|
||||
navigator.language:浏览器设置的语言;
|
||||
|
||||
## screen
|
||||
存储客户端屏幕信息
|
||||
属性: screen.availWidth //屏幕宽度
|
||||
screen.availHeigh //屏幕高度
|
||||
|
||||
|
||||
## history
|
||||
包含浏览器的浏览历史
|
||||
history.back() 返回上一页
|
||||
history.forward() 返回下一页
|
||||
|
||||
|
||||
# 本地缓存 localstorage
|
||||
localStorage.setItem(键,值) 存值
|
||||
localStorage.getItem(键) 取值
|
||||
localStorage.clear(); 清空
|
||||
localStorage.removeItem(键); 删除
|
39
js/kejian/digui.md
Normal file
@ -0,0 +1,39 @@
|
||||
# 递归
|
||||
|
||||
### 发生前提:
|
||||
递归是在一个函数通过名字调用自身的情况下发生的
|
||||
如:
|
||||
```
|
||||
function a(n){
|
||||
if(n<=1){
|
||||
return 1
|
||||
}else{
|
||||
return num*a(n-1)
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
这是一个经典的递归阶乘函数,但是接下来的操作却可能会导致他出错
|
||||
|
||||
```
|
||||
function a(n) {
|
||||
if (n <= 1) {
|
||||
return 1
|
||||
} else {
|
||||
return n * a(n - 1)
|
||||
}
|
||||
}
|
||||
console.log(a(5)) //120
|
||||
|
||||
var cheng=a
|
||||
a=null
|
||||
console.log(cheng(5))// : a is not a function
|
||||
|
||||
|
||||
```
|
||||
以上代码把a保存在一个变量(cheng)中,然后将a赋值为null
|
||||
在cheng执行的过程中 必然会执行到a (在cheng 中else代码块的函数名字改不了)
|
||||
但是此时a已经不是函数了,所以会报错 a is not a function
|
||||
|
||||
|
||||
上面问题的解决措施:
|
1
js/kejian/domshijian.md
Normal file
@ -0,0 +1 @@
|
||||
# dom事件
|
96
js/kejian/jqdom.md
Normal file
@ -0,0 +1,96 @@
|
||||
# dom
|
||||
|
||||
|
||||
## jq操作dom
|
||||
|
||||
* 查询元素并获取元素的值
|
||||
查询元素:
|
||||
* 根据标签选取:$('目标标签')
|
||||
* 根据class选取:$('.类名')
|
||||
* 根据id选取:$('#id值')
|
||||
* 根据属性选取 $('[目标属性]')
|
||||
|
||||
获取值:
|
||||
* element.html() 也就是从对象的起始位置到终止位置的全部内容,包括Html标签。
|
||||
* element.text() 也就是从对象的起始位置到终止位置的全部内容,去除Html标签。
|
||||
* element.val() 返回表单字段的值
|
||||
|
||||
demo:
|
||||
html:
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>标题</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>提瓦特大陆最好吃的食物是派蒙嗷!</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
js:
|
||||
```
|
||||
var str=$('div').text() //提瓦特大陆最好吃的食物是派蒙嗷!
|
||||
|
||||
```
|
||||
|
||||
|
||||
获取属性值:
|
||||
eg:
|
||||
|
||||
str=$('p')
|
||||
var attr=str.attr('name')
|
||||
document.write($('#image').attr('href'))
|
||||
|
||||
* 删除元素 自身
|
||||
element.remove()
|
||||
|
||||
* 修改元素
|
||||
* 修改元素的文本内容
|
||||
* element.text('修改后的文本内容')
|
||||
* elenment.html("\<p>修改后的文本内容\</p>")
|
||||
* 修改元素的属性
|
||||
element.setAttribute('属性名','属性值')
|
||||
eg:
|
||||
|
||||
|
||||
var myele=document.createElement('div')
|
||||
myele.setAttribute('class','box')
|
||||
|
||||
|
||||
* <p style="color:red;font-weight:bold">创建元素:</p>
|
||||
|
||||
* 创建新的html节点
|
||||
$('要创建的标签名')
|
||||
|
||||
* 为新创建的节点添加文本内容
|
||||
element.html('想要添加的文本内容')
|
||||
element.text('想要添加的文本内容')
|
||||
|
||||
* 为新创建的添加属性及属性值
|
||||
方法一: element.attr('属性名','属性值')
|
||||
|
||||
|
||||
* 查找一个现有的元素(新元素的父级元素)
|
||||
* 向已有的元素追加新元素
|
||||
* fuelement.append(创建的新元素)
|
||||
|
||||
demo:
|
||||
```
|
||||
var box =$('div')
|
||||
box.text('happy new year')
|
||||
box.attr('style', 'width:100px;height:100px;background:red;color:white')
|
||||
var main = document.body
|
||||
main.append(box)
|
||||
|
||||
```
|
||||
|
||||
追加元素的方式:
|
||||
* append(),在父级最后追加一个子元素
|
||||
* appendTo(),将子元素追加到父级的最后
|
||||
* prepend(),在父级最前面追加一个子元素
|
||||
* prependTo(),将子元素追加到父级的最前面
|
||||
* after(),在当前元素之后追加(是同级关系)
|
||||
* before(),在当前元素之前追加(是同级关系)
|
||||
* insertAfter(),将元素追加到指定对象的后面
|
||||
* insertBefore(),将元素追加到指定对象的前面
|
||||
```
|
128
js/kejian/jsdom.md
Normal file
@ -0,0 +1,128 @@
|
||||
# dom
|
||||
|
||||
## dom 节点树
|
||||
dom 包含 :元素节点,文本节点,注释节点
|
||||
demo:
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
hello world
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
```
|
||||
html
|
||||
head
|
||||
title
|
||||
meta
|
||||
|
||||
text --回车
|
||||
body
|
||||
text
|
||||
```
|
||||
|
||||
## js操作dom
|
||||
|
||||
* 查询元素并获取元素的值
|
||||
查询元素:
|
||||
* 根据标签选取:document.getElementsByTagName('目标标签')
|
||||
* 根据class选取:document.getElementsByClassName('目标类名')
|
||||
* 根据id选取:document.getElementById('目标id')
|
||||
* js直接访问html对象:
|
||||
* document.title 获取文档的标题
|
||||
* document.body 获取body元素
|
||||
* document.head 获取head元素
|
||||
...
|
||||
|
||||
通过id获取document.querySelectorAll("#old")
|
||||
通过标签获取 document.querySelectorAll("p")
|
||||
通过类名获取document.querySelectorAll(".demo2")
|
||||
|
||||
|
||||
获取值:
|
||||
* element.innerHTML 也就是从对象的起始位置到终止位置的全部内容,包括Html标签。
|
||||
* element.innerText 也就是从对象的起始位置到终止位置的全部内容,去除Html标签。
|
||||
|
||||
特别说明 innerHTML是符合W3C标准的属性,而innerText只适用于IE浏览器,因此,尽可能地去使用innerHTML,而少用
|
||||
innerText,如果要输出不含HTML标签的内容,可以使用innerHTML取得包含HTML标签的内容后,再用正则表达式去除HTML标签,下面是一个简单的符合W3C标准的示例:
|
||||
|
||||
```
|
||||
<a href="javascript:alert(document.getElementById('test').innerHTML.replace(/<.+?>/gim,''))">去除HTML标签后的文本</a>
|
||||
|
||||
```
|
||||
获取属性值:
|
||||
方法一:element.属性名
|
||||
eg:document.write(document.getElementById("image").src)
|
||||
|
||||
方法二:element.getAttribute('属性名')
|
||||
eg:
|
||||
str=document.getElementsByTagName('p')[0]
|
||||
var attr=str.getAttribute('name')
|
||||
|
||||
* 删除元素 自身
|
||||
element.remove()
|
||||
|
||||
* 修改元素
|
||||
* 修改元素的文本内容
|
||||
* element.innerHTML="修改后的文本内容"
|
||||
* elenment.innerText="修改后的文本内容"
|
||||
* 修改元素的属性
|
||||
* 方法一:
|
||||
element.属性名="属性值"
|
||||
demo:
|
||||
```
|
||||
document.getElementById("myImage").src = "landscape.jpg";
|
||||
```
|
||||
* 方法二:
|
||||
element.setAttribute('属性名','属性值')
|
||||
eg:
|
||||
```
|
||||
var myele=document.createElement('div')
|
||||
myele.setAttribute('class','box')
|
||||
|
||||
```
|
||||
|
||||
* <p style="color:red;font-weight:bold">创建元素:</p>
|
||||
|
||||
* 创建新的html节点
|
||||
document.createElement('要创建的标签名')
|
||||
|
||||
* 为新创建的节点添加文本内容
|
||||
element.innerHTNL="想要添加的文本内容"
|
||||
element.innerText="想添加的文本内容"
|
||||
|
||||
* 为新创建的添加属性及属性值
|
||||
方法一: element.setAttribute('属性名','属性值')
|
||||
方法二: element.属性名='属性值'
|
||||
|
||||
* 查找一个现有的元素(新元素的父级元素)
|
||||
* 向已有的元素追加新元素
|
||||
* fuelement.append(创建的新元素)
|
||||
|
||||
demo:
|
||||
```
|
||||
var box = document.createElement('div')
|
||||
box.innerHTML = 'happy new year'
|
||||
box.setAttribute('style', 'width:100px;height:100px;background:red;color:white')
|
||||
var main = document.body
|
||||
main.append(box)
|
||||
|
||||
```
|
||||
|
||||
追加元素的方式:
|
||||
* append(),在父级最后追加一个子元素
|
||||
* appendTo(),将子元素追加到父级的最后
|
||||
* prepend(),在父级最前面追加一个子元素
|
||||
* prependTo(),将子元素追加到父级的最前面
|
||||
* after(),在当前元素之后追加(是同级关系)
|
||||
* before(),在当前元素之前追加(是同级关系)
|
||||
* insertAfter(),将元素追加到指定对象的后面
|
||||
* insertBefore(),将元素追加到指定对象的前面
|
||||
```
|
@ -3,6 +3,10 @@
|
||||
链接:
|
||||
* https://juejin.cn/post/6916046341131599879
|
||||
* https://juejin.cn/post/6896445621273083912
|
||||
|
||||
### this 指向
|
||||
https://www.cnblogs.com/pssp/p/5216085.html
|
||||
|
||||
demo1:
|
||||
```
|
||||
function f() {
|
||||
@ -89,3 +93,48 @@ function zxxFn () {
|
||||
}
|
||||
zxxFn()
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### js dom
|
||||
|
||||
js dom 初识: https://juejin.cn/post/6907112616221966350
|
||||
|
||||
js dom操作 https://juejin.cn/post/6844903593011576845
|
||||
|
||||
jq dom操作
|
||||
|
||||
|
||||
|
||||
### 作业:
|
||||
|
||||
通过在页面上点击button,实现主题切换
|
||||
主题1:黑底白字
|
||||
主题2:粉底绿字
|
||||
|
||||
|
||||
|
||||
五环之歌
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
点击按钮显示一个五行四列的表格 内容自定义
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
自定义一个6行的ul列表 点击删除
|
||||
|
||||
|
||||
|
||||
### dom事件
|
||||
https://www.w3school.com.cn/js/js_htmldom_events.asp
|
0
js/kejian/jsmaopaobuhuo.md
Normal file
7
js/kejian/menu.md
Normal file
@ -0,0 +1,7 @@
|
||||
# menu
|
||||
|
||||
* 作用域
|
||||
* 闭包
|
||||
* 预编译
|
||||
* this指向
|
||||
* 构造函数
|
106
js/kejian/this.md
Normal file
@ -0,0 +1,106 @@
|
||||
# this
|
||||
首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上** this的最终指向的是那个调用它的对象 **
|
||||
|
||||
例1
|
||||
```
|
||||
function a(){
|
||||
var user = "追梦子";
|
||||
console.log(this.user); //undefined
|
||||
console.log(this); //Window
|
||||
}
|
||||
window.a();
|
||||
//判断this跟this所处的函数没有关系,结果取决于哪个对象调用的他 最外层的对象是window
|
||||
|
||||
```
|
||||
|
||||
例2
|
||||
|
||||
```
|
||||
|
||||
|
||||
var o = {
|
||||
user:"追梦子",
|
||||
fn:function(){
|
||||
console.log(this.user); //追梦子
|
||||
}
|
||||
}
|
||||
o.fn();
|
||||
// fn外部是对象O,访问的是this.user 即o.user => o.user的值是“追梦子”
|
||||
|
||||
```
|
||||
|
||||
例3
|
||||
|
||||
```
|
||||
var user="pplok
|
||||
var o = {
|
||||
user:"追梦子",
|
||||
fn:function(){
|
||||
console.log(this.user); //追梦子
|
||||
}
|
||||
}
|
||||
window.o.fn();
|
||||
|
||||
```
|
||||
|
||||
例4
|
||||
```
|
||||
|
||||
|
||||
var o = {
|
||||
a:10,
|
||||
b:{
|
||||
a:12,
|
||||
fn:function(){
|
||||
console.log(this.a); //12
|
||||
}
|
||||
}
|
||||
}
|
||||
o.b.fn();
|
||||
|
||||
```
|
||||
总结:
|
||||
情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题,你想了解可以自行上网查找。
|
||||
|
||||
情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
|
||||
|
||||
情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
|
||||
|
||||
|
||||
例5
|
||||
```
|
||||
|
||||
|
||||
var o = {
|
||||
a:10,
|
||||
b:{
|
||||
a:12,
|
||||
fn:function(){
|
||||
console.log(this.a); // undefined
|
||||
console.log(this); //window
|
||||
}
|
||||
}
|
||||
}
|
||||
var j = o.b.fn;
|
||||
j();
|
||||
|
||||
|
||||
```
|
||||
|
||||
判断this时,需要看函数调用的位置,而不是我们定义函数的位置
|
||||
this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的
|
||||
|
||||
this 遇到return 时
|
||||
```
|
||||
function fn()
|
||||
{
|
||||
this.user = '追梦子';
|
||||
return
|
||||
}
|
||||
var a = new fn;
|
||||
console.log(a.user); //undefined
|
||||
|
||||
```
|
||||
函数return的值为对象时,this就指向 这个被return的对象
|
||||
|
||||
|
193
js/kejian/zuoyongyu.md
Normal file
@ -0,0 +1,193 @@
|
||||
# 作用域
|
||||
### 练习
|
||||
```
|
||||
var color = "blue";
|
||||
|
||||
function changeColor() {
|
||||
let anotherColor = "red";
|
||||
|
||||
function swapColors() {
|
||||
let tempColor = anotherColor;
|
||||
anotherColor = color;
|
||||
color = tempColor;
|
||||
|
||||
// 这里可以访问color、anotherColor和tempColor
|
||||
}
|
||||
|
||||
// 这里可以访问color和anotherColor,但访问不到tempColor
|
||||
swapColors();
|
||||
}
|
||||
|
||||
// 这里只能访问color
|
||||
changeColor();
|
||||
|
||||
```
|
||||
|
||||
分析上面的作用域链:
|
||||
<details>
|
||||
<summary>展开查看</summary>
|
||||
|
||||
* window
|
||||
* color
|
||||
* changecolor()
|
||||
* anothercolor
|
||||
* swapcolors()
|
||||
* tempcolor
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
### 垃圾回收机制
|
||||
优化内存占用的最佳手段就是保证在执行代码时只保存必要的数据。如果数据不再必要,那么把它设置为null ,从而释放其引用。这也可以叫作解除引用 。这个建议最适合全局变量和全局对象的属性。
|
||||
局部变量在超出作用域后会被自动解除引用
|
||||
即 全局变量(GO) 不会被销毁,但是局部变量(AO)函数执行完后会被销毁
|
||||
也可以手动销毁变量,即赋值为null
|
||||
|
||||
如下面的例子所示:
|
||||
```
|
||||
function createPerson(name){
|
||||
let localPerson = new Object();
|
||||
localPerson.name = name;
|
||||
return localPerson;
|
||||
}
|
||||
|
||||
let globalPerson = createPerson("Nicholas");
|
||||
|
||||
// 解除globalPerson对值的引用
|
||||
|
||||
//globalPerson = null;
|
||||
|
||||
```
|
||||
解析:
|
||||
<details>
|
||||
<summary>展开查看</summary>
|
||||
在上面的代码中,变量globalPerson 保存着createPerson() 函数调用返回的值。在createPerson() 内部,localPerson 创建了一个对象并给它添加了一个name 属性。然后,localPerson 作为函数值被返回,并被赋值给globalPerson 。localPerson 在createPerson() 执行完成超出上下文后会自动被解除引用,不需要显式处理。但globalPerson 是一个全局变量,应该在不再需要时手动解除其引用,最后一行就是这么做的。
|
||||
|
||||
不过要注意,解除对一个值的引用并不会自动导致相关内存被回收。解除引用的关键在于确保相关的值已经不在上下文里了,因此它在下次垃圾回收时会被回收。
|
||||
</details>
|
||||
|
||||
### 闭包
|
||||
闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。
|
||||
|
||||
```
|
||||
|
||||
function a() {
|
||||
var x = 0;
|
||||
return function(y) {
|
||||
x = x + y;
|
||||
// return x;
|
||||
console.log(x);
|
||||
}
|
||||
}
|
||||
var b = a();
|
||||
b(1); //1
|
||||
b(1); //2
|
||||
```
|
||||
练习1:
|
||||
```
|
||||
function fn() {
|
||||
var max = 10;
|
||||
return function bar(x) {
|
||||
if (x > max) {
|
||||
console.log(x);
|
||||
}
|
||||
};
|
||||
}
|
||||
var f1 = fn();
|
||||
f1(15);
|
||||
|
||||
```
|
||||
练习2
|
||||
```
|
||||
function init() {
|
||||
var name = "Mozilla"; // name 是一个被 init 创建的局部变量
|
||||
function displayName() { // displayName() 是内部函数,一个闭包
|
||||
alert(name); // 使用了父函数中声明的变量
|
||||
}
|
||||
displayName();
|
||||
}
|
||||
init();
|
||||
|
||||
```
|
||||
<details>
|
||||
init() 创建了一个局部变量 name 和一个名为 displayName() 的函数。displayName() 是定义在 init() 里的内部函数,并且仅在 init() 函数体内可用。请注意,displayName() 没有自己的局部变量。然而,因为它可以访问到外部函数的变量,所以 displayName() 可以使用父函数 init() 中声明的变量 name 。
|
||||
|
||||
</details>
|
||||
hrefs:
|
||||
https://blog.csdn.net/weixin_43586120/article/details/89456183
|
||||
|
||||
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
|
||||
|
||||
```
|
||||
|
||||
(function() {
|
||||
var m = 0;
|
||||
function getM() { return m; }
|
||||
function seta(val) { m = val; }
|
||||
window.g = getM;
|
||||
window.f = seta;
|
||||
})();
|
||||
f(100);
|
||||
console.info(g());
|
||||
|
||||
```
|
||||
<hr/>
|
||||
|
||||
```
|
||||
function fn(){
|
||||
var arr = [];
|
||||
for(var i = 0;i < 5;i ++){
|
||||
arr[i] = (function(i){
|
||||
return function (){
|
||||
return i;
|
||||
};
|
||||
})(i);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
// 立即执行函数 每调用一次完成后就自动销毁
|
||||
|
||||
var list = fn();
|
||||
for(var i = 0,len = list.length;i < len ; i ++){
|
||||
console.log(list[i]());
|
||||
} //0 1 2 3 4
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
function fn(){
|
||||
var arr = [];
|
||||
for(var i = 0;i < 5;i ++){
|
||||
arr[i] = function(){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
var list = fn();
|
||||
for(var i = 0,len = list.length;i < len ; i ++){
|
||||
console.log(list[i]());
|
||||
} //5 5 5 5 5
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
var lis = document.getElementsByTagName("li");
|
||||
for(var i=0;i<lis.length;i++){
|
||||
(function(i){
|
||||
lis[i].onclick = function(){
|
||||
console.log(i);
|
||||
};
|
||||
})(i); //事件处理函数中闭包的写法
|
||||
}
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
var li = document.getElementsByTagName( "li" );
|
||||
for ( var i = 0; i < li.length; i++) {
|
||||
li[i].addEventListener( "click" , function () {
|
||||
console.log(i);
|
||||
})
|
||||
}
|
||||
```
|
92
js/lx/a.html
Normal file
@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script>
|
||||
var a = 2
|
||||
// var obj1 = {
|
||||
// a: 1,
|
||||
// fn1: (function (a) {
|
||||
// this.a = a
|
||||
// a++
|
||||
// return function () {
|
||||
// this.a = a++
|
||||
// console.log(this)
|
||||
// console.log(a)
|
||||
// }
|
||||
|
||||
// })(a)
|
||||
|
||||
// }
|
||||
// var fn1 = obj1.fn1
|
||||
// var fn1=function () {
|
||||
// this.a = a++
|
||||
// console.log(this)
|
||||
// console.log(a)
|
||||
// }
|
||||
|
||||
// console.log(fn1.toString())
|
||||
// fn1()
|
||||
|
||||
// console.log(getA)
|
||||
// if ('a' in window) {
|
||||
// var a = ''
|
||||
// function getA(a) {
|
||||
// a = a || this.a
|
||||
// console.log(this.a)
|
||||
// }
|
||||
// getA(a)
|
||||
// }
|
||||
|
||||
|
||||
|
||||
var c = 3
|
||||
function getC() {
|
||||
this.c++
|
||||
console.log(this,'kkkk')
|
||||
return function () {
|
||||
c = this.c * 2
|
||||
console.log(c)
|
||||
}
|
||||
}
|
||||
var obj3 = {
|
||||
c: 2,
|
||||
getC: (function () {
|
||||
this.c -= 1 //win.c-1 win.c=2
|
||||
console.log(this.c, this,'sss')
|
||||
return this.getC //obj3.getc=win.getc
|
||||
})()
|
||||
|
||||
}
|
||||
// var a=obj3.getC()
|
||||
// a()
|
||||
// obj3.getC()()
|
||||
|
||||
getC() //win.c++ =>win.c=3
|
||||
|
||||
console.log(obj3.getC.toString(),"aaaaaaa")
|
||||
obj3.getC()
|
||||
// console.log(obj3.c,window.c)
|
||||
var f3=obj3.getC;
|
||||
f3()
|
||||
// console.log(window.c)
|
||||
// console.log(obj3.c)
|
||||
|
||||
//step1 立即执行函数 => this 指向window win.c-1 -> win.c=2
|
||||
//step2 getC() this.c -=> win.c++ =>2+1 =>3
|
||||
//step3 obj3.getC() step1中 obj3.getc= win.getc 所以就是执行win.getc
|
||||
// 即 winc++ win.c=3
|
||||
//obj3.getc时 this指向的是obj3,this.c操作的是obj3.c , 所以obj3.c 也+1等于3
|
||||
//step4 f3本身等于win.getc函数, 执行f3() 即执行 win.getc() =>win.c++ win.c=4
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
97
js/lx/callapply.md
Normal file
@ -0,0 +1,97 @@
|
||||
1.
|
||||
window.color = 'red';
|
||||
document.color = 'yellow';
|
||||
|
||||
var s1 = {color: 'blue' };
|
||||
function changeColor(){
|
||||
console.log(this.color);
|
||||
}
|
||||
|
||||
changeColor.call(); //red (默认传递参数)
|
||||
changeColor.call(window); //red
|
||||
changeColor.call(document); //yellow
|
||||
changeColor.call(this); //red
|
||||
changeColor.call(s1); //blue
|
||||
|
||||
2
|
||||
var Pet = {
|
||||
words : '...',
|
||||
speak : function (say) {
|
||||
console.log(say + ''+ this.words)
|
||||
}
|
||||
}
|
||||
Pet.speak('Speak'); // 结果:Speak...
|
||||
|
||||
var Dog = {
|
||||
words:'Wang'
|
||||
}
|
||||
|
||||
//将this的指向改变成了Dog
|
||||
Pet.speak.call(Dog, 'Speak'); //结果: SpeakWang
|
||||
|
||||
3
|
||||
用 apply重写上面两个函数
|
||||
|
||||
4
|
||||
function add(c,d){
|
||||
return this.a + this.b + c + d;
|
||||
}
|
||||
|
||||
var s = {a:1, b:2};
|
||||
console.log(add.call(s,3,4)); // 1+2+3+4 = 10
|
||||
console.log(add.apply(s,[5,6])); // 1+2+5+6 = 14
|
||||
|
||||
5.画出原型链
|
||||
//游戏--->王者---->小乔---->花嫁
|
||||
|
||||
6
|
||||
function C1(name) {
|
||||
if (name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
function C2(name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
function C3(name) {
|
||||
this.name = name || 'join';
|
||||
}
|
||||
C1.prototype.name = 'Tom';
|
||||
C2.prototype.name = 'Tom';
|
||||
C3.prototype.name = 'Tom';
|
||||
alert((new C1().name) + (new C2().name) + (new C3().name));
|
||||
|
||||
7
|
||||
function Fn(num) {
|
||||
this.x = this.y = num;
|
||||
}
|
||||
Fn.prototype = {
|
||||
x: 20,
|
||||
sum: function () {
|
||||
console.log(this.x + this.y);
|
||||
}
|
||||
};
|
||||
let f = new Fn(10);
|
||||
console.log(f.sum === Fn.prototype.sum);
|
||||
f.sum();
|
||||
Fn.prototype.sum();
|
||||
console.log(f.constructor);
|
||||
|
||||
8
|
||||
var print=function(){alert(1);}
|
||||
function Fn() {
|
||||
print=function(){alert(2);}
|
||||
return this;
|
||||
}
|
||||
function print(){alert(3);}
|
||||
Fn.prototype.print=function(){alert(4);}
|
||||
Fn.print=function(){alert(5);}
|
||||
|
||||
print();
|
||||
Fn.print();
|
||||
Fn().print();
|
||||
new Fn.print();
|
||||
new Fn().print();
|
||||
|
120
js/lx/jsthis.md
Normal file
@ -0,0 +1,120 @@
|
||||
# this
|
||||
1
|
||||
|
||||
function fn2(){
|
||||
console.log(this.n)
|
||||
var n='n'
|
||||
this.n=10
|
||||
console.log(n)
|
||||
}
|
||||
var obj={fn2:fn2, n:1}
|
||||
fn2()
|
||||
obj.fn2()
|
||||
console.log(obj.n, window.n)
|
||||
|
||||
//undefined 'n'
|
||||
//1 'n'
|
||||
//10 10
|
||||
|
||||
2
|
||||
|
||||
function f(){console.log(this)}
|
||||
|
||||
var obj={
|
||||
fn: (function(){
|
||||
return this.f
|
||||
})(),
|
||||
f: function(){console.log(this)}
|
||||
}
|
||||
f()
|
||||
obj.f()
|
||||
obj.fn()
|
||||
// window obj obj
|
||||
|
||||
3
|
||||
|
||||
var n = 10
|
||||
var obj1={
|
||||
n:1,
|
||||
f:function(){this.n++; n=this.n++}
|
||||
}
|
||||
|
||||
obj1.f()
|
||||
console.log(n) // 2
|
||||
console.log(obj1.n) // 2
|
||||
window.setTimeout(obj1.f, 1000)
|
||||
|
||||
//2
|
||||
//3
|
||||
|
||||
4
|
||||
|
||||
console.log(getA)
|
||||
if('a' in window){
|
||||
var a = ''
|
||||
function getA(a){
|
||||
a = a||this.a
|
||||
console.log(this.a)
|
||||
}
|
||||
getA(a)
|
||||
}
|
||||
|
||||
5
|
||||
|
||||
var a=2
|
||||
var obj1 = {
|
||||
a:1,
|
||||
fn1: (function(a){
|
||||
this.a = a
|
||||
a++
|
||||
return function(){
|
||||
this.a = a++
|
||||
console.log(a)
|
||||
}
|
||||
|
||||
})(a)
|
||||
}
|
||||
obj1.fn1() // 4
|
||||
var fn1 = obj1.fn1
|
||||
fn1() // window.a = 4,a=5
|
||||
|
||||
6
|
||||
|
||||
var c=3
|
||||
function getC(){
|
||||
this.c++
|
||||
return function (){
|
||||
c=this.c*2
|
||||
console.log(c)
|
||||
}
|
||||
}
|
||||
var obj3={
|
||||
c: 2,
|
||||
getC:(function(){
|
||||
this.c -= 1
|
||||
return this.getC
|
||||
})()
|
||||
}
|
||||
getC() // window.c = 3
|
||||
obj3.getC() // obj3.c=3
|
||||
var f3=obj3.getC
|
||||
f3() // window.c=4
|
||||
console.log(window.c) // 4
|
||||
console.log(obj3.c) // 3
|
||||
|
||||
|
||||
for (var i = 1; i <= 5; i++) {
|
||||
|
||||
setTimeout( function timer() {
|
||||
|
||||
console.log(i);
|
||||
|
||||
}, 1000 );
|
||||
|
||||
}
|
||||
|
||||
上面的代码会输出什么?怎么改动上述代码,使其依次输出1、2、3、4、5 并说明原因
|
||||
|
||||
|
||||
理论题:
|
||||
谈谈什么是闭包
|
115
js/lx/this.md
Normal file
@ -0,0 +1,115 @@
|
||||
# this
|
||||
1
|
||||
|
||||
function fn2(){
|
||||
console.log(this.n)
|
||||
var n='n'
|
||||
this.n=10
|
||||
console.log(n)
|
||||
}
|
||||
var obj={fn2:fn2, n:1}
|
||||
fn2()
|
||||
obj.fn2()
|
||||
console.log(obj.n, window.n)
|
||||
|
||||
|
||||
2
|
||||
|
||||
function f(){console.log(this)}
|
||||
|
||||
var obj={
|
||||
fn: (function(){
|
||||
return this.f
|
||||
})(),
|
||||
f: function(){console.log(this)}
|
||||
}
|
||||
f()
|
||||
obj.f()
|
||||
obj.fn()
|
||||
|
||||
|
||||
3
|
||||
|
||||
var n = 10
|
||||
var obj1={
|
||||
n:1,
|
||||
f:function(){this.n++; n=this.n++}
|
||||
}
|
||||
|
||||
obj1.f()
|
||||
console.log(n)
|
||||
console.log(obj1.n)
|
||||
window.setTimeout(obj1.f, 1000)
|
||||
|
||||
|
||||
4
|
||||
|
||||
console.log(getA)
|
||||
if('a' in window){
|
||||
var a = ''
|
||||
function getA(a){
|
||||
a = a||this.a
|
||||
console.log(this.a)
|
||||
}
|
||||
getA(a)
|
||||
}
|
||||
|
||||
5
|
||||
|
||||
var a=2
|
||||
var obj1 = {
|
||||
a:1,
|
||||
fn1: (function(a){
|
||||
this.a = a
|
||||
a++
|
||||
return function(){
|
||||
this.a = a++
|
||||
console.log(a)
|
||||
}
|
||||
|
||||
})(a)
|
||||
}
|
||||
obj1.fn1()
|
||||
var fn1 = obj1.fn1
|
||||
fn1() // window.a = 4,a=5
|
||||
|
||||
6
|
||||
|
||||
var c=3
|
||||
function getC(){
|
||||
this.c++
|
||||
return function (){
|
||||
c=this.c*2
|
||||
console.log(c)
|
||||
}
|
||||
}
|
||||
var obj3={
|
||||
c: 2,
|
||||
getC:(function(){
|
||||
this.c -= 1
|
||||
return this.getC
|
||||
})()
|
||||
}
|
||||
getC()
|
||||
obj3.getC()
|
||||
var f3=obj3.getC
|
||||
f3()
|
||||
console.log(window.c)
|
||||
console.log(obj3.c)
|
||||
|
||||
|
||||
for (var i = 1; i <= 5; i++) {
|
||||
|
||||
setTimeout( function timer() {
|
||||
|
||||
console.log(i);
|
||||
|
||||
}, 1000 );
|
||||
|
||||
}
|
||||
|
||||
上面的代码会输出什么?怎么改动上述代码,使其依次输出1、2、3、4、5 并说明原因
|
||||
|
||||
|
||||
理论题:
|
||||
谈谈什么是闭包
|
342
jslearn/初步认识javascript.md
Normal file
@ -0,0 +1,342 @@
|
||||
# 什么是 JavaScript?
|
||||
|
||||
广义的定义
|
||||
它到底可以做什么?
|
||||
JavaScript 在页面上做了什么?
|
||||
怎样向页面添加 JavaScript?
|
||||
注释
|
||||
小结
|
||||
本章目录
|
||||
|
||||
欢迎来到 JavaScript 初学者课程!本节将在一定高度俯瞰 JavaScript,回答一些诸如“它是什么?”和“它能做什么?”的问题 。并使你熟悉 JavaScript 的用途。
|
||||
预备知识: 计算机基础知识,初步理解 HTML 和 CSS 。
|
||||
目标: 初步了解 JavaScript,包括一些概念、用途、嵌入网站的方法。
|
||||
广义的定义
|
||||
|
||||
JavaScript 是一种脚本,一门编程语言,它可以在网页上实现复杂的功能,网页展现给你的不再是简单的静态信息,而是实时的内容更新,交互式的地图,2D/3D 动画,滚动播放的视频等等。JavaScript 怎能缺席。它是标准 Web 技术蛋糕的第三层,其中 HTML 和 CSS 我们已经在学习中心的其他部分进行了详细的讲解。
|
||||
|
||||
HTML是一种标记语言,用来结构化我们的网页内容并赋予内容含义,例如定义段落、标题和数据表,或在页面中嵌入图片和视频。
|
||||
CSS 是一种样式规则语言,可将样式应用于 HTML 内容, 例如设置背景颜色和字体,在多个列中布局内容。
|
||||
JavaScript 是一种脚本语言,可以用来创建动态更新的内容,控制多媒体,制作图像动画,还有很多。(好吧,虽然它不是万能的,但可以通过简短的代码来实现神奇的功能。)
|
||||
|
||||
这三层依次建立,秩序井然。以文本标签(text label)的简单示例。首先用 HTML 将文本标记起来,从而赋予它结构和目的:
|
||||
```
|
||||
<p>玩家1:小明</p>
|
||||
|
||||
```
|
||||
|
||||
玩家1:小明
|
||||
|
||||
|
||||
然后我们可以为它加一点 CSS 让它更好看:
|
||||
```
|
||||
|
||||
p {
|
||||
font-family: sans-serif, '黑体';
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
border: 2px solid rgba(0, 0, 200, 0.6);
|
||||
background: rgba(0, 0, 200, 0.3);
|
||||
color: rgba(0, 0, 200, 0.6);
|
||||
box-shadow: 1px 1px 2px rgba(0, 0, 200, 0.4);
|
||||
border-radius: 10px;
|
||||
padding: 3px 10px;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
最后,我们可以再加上一些 JavaScript 来实现动态行为:
|
||||
|
||||
```
|
||||
const para = document.querySelector('p');
|
||||
|
||||
para.addEventListener('click', updateName);
|
||||
|
||||
function updateName() {
|
||||
let name = prompt('输入一个新的名字:');
|
||||
para.textContent = '玩家1:' + name;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
尝试点击最后一个版本的文本标签,观察会发生什么
|
||||
|
||||
JavaScript 能做的远不止这些。让我们来仔细探索。
|
||||
它到底可以做什么?
|
||||
|
||||
客户端(client-side)JavaScript 语言的核心包含一些普遍的编程特性,以让你可以做到如下的事情:
|
||||
|
||||
在变量中储存有用的值。比如上文的示例中,我们请求客户输入一个新名字,然后将其储存到 name 变量中。
|
||||
操作一段文本(在编程中称为“字符串”(string))。上文的示例中,我们取字符串 "玩家1:",然后把它和 name 变量连结起来,创造出完整的文本标签,比如:"玩家1:小明"。
|
||||
运行代码以响应网页中发生的特定事件。上文的示例中,我们用一个 click 事件来检测按钮什么时候被点击,然后运行代码更新文本标签。
|
||||
以及更多!
|
||||
|
||||
JavaScript 语言核心之上所构建的功能更令人兴奋。应用程序接口(Application Programming Interfaces(API))将为你的代码提供额外的超能力。
|
||||
|
||||
API 是已经建立好的一套代码组件,可以让开发者实现原本很难甚至无法实现的程序。就像现成的家具套件之于家居建设,用一些已经切好的木板组装一个书柜,显然比自己设计,寻找合适的木材,裁切至合适的尺寸和形状,找到正确尺寸的螺钉,再组装成书柜要简单得多。
|
||||
|
||||
API 通常分为两类。
|
||||
|
||||
浏览器 API 内建于 web 浏览器中,它们可以将数据从周边计算机环境中筛选出来,还可以做实用的复杂工作。例如:
|
||||
|
||||
文档对象模型 API(DOM(Document Object Model)API) 能通过创建、移除和修改 HTML,为页面动态应用新样式等手段来操作 HTML 和 CSS。比如当某个页面出现了一个弹窗,或者显示了一些新内容(像上文小 demo 中看到那样),这就是 DOM 在运行。
|
||||
地理位置 API(Geolocation API) 获取地理信息。这就是为什么 谷歌地图 可以找到你的位置,而且标示在地图上。
|
||||
画布(Canvas) 和 WebGL API 可以创建生动的 2D 和 3D 图像。人们正运用这些 web 技术制作令人惊叹的作品。参见 Chrome Experiments 以及 webglsamples。
|
||||
诸如 HTMLMediaElement 和 WebRTC 等 影音类 API 让你可以利用多媒体做一些非常有趣的事,比如在网页中直接播放音乐和影片,或用自己的网络摄像头获取录像,然后在其他人的电脑上展示(试用简易版 截图 demo 以理解这个概念)。
|
||||
|
||||
注: 上述很多演示都不能在旧浏览器中运行。推荐你在测试代码时使用诸如 Firefox, Chrome, Edge 或者 Opera 等现代浏览器。当代码即将交付生产环境时(也就是真实的客户即将使用真实的代码时),你还需要深入考虑 跨平台测试。
|
||||
|
||||
第三方 API 并没有默认嵌入浏览器中,一般要从网上取得它们的代码和信息。比如:
|
||||
|
||||
Twitter API、新浪微博 API 可以在网站上展示最新推文之类。
|
||||
谷歌地图 API、高德地图 API 可以在网站嵌入定制的地图等等。
|
||||
|
||||
注:这些 API 较为高级,我们的课程中不会涉及,更多信息请参考:客户端 web API 模块.
|
||||
|
||||
先稳住!你看到的只是冰山一角。你不可能学一天 JavaScript 就能构建下一个Facebook, 谷歌地图, 或者 Instagram。敬请「牢记初心,砥砺前行」。
|
||||
JavaScript 在页面上做了什么?
|
||||
|
||||
现在我们实实在在的学习一些代码,与此同时,探索 JavaScript 运行时背后发生的事情。
|
||||
|
||||
让我们简单回顾一下,浏览器在读取一个网页时都发生什么(CSS 如何工作 一文中首次谈及)。浏览器在读取一个网页时,代码(HTML, CSS 和 JavaScript)将在一个运行环境(浏览器标签页)中得到执行。就像一间工厂,将原材料(代码)加工为一件产品(网页)。
|
||||
|
||||
在 HTML 和 CSS 集合组装成一个网页后,浏览器的 JavaScript 引擎将执行 JavaScript 代码。这保证了当 JavaScript 开始运行之前,网页的结构和样式已经就位。
|
||||
|
||||
这样很好,因为JavaScript 最普遍的用处是通过 DOM API(见上文)动态修改 HTML 和 CSS 来更新用户界面 (user interface)。如果 JavaScript 在 HTML 和 CSS 就位之前加载运行,就会引发错误。
|
||||
浏览器安全
|
||||
|
||||
每个浏览器标签页就是其自身用来运行代码的独立容器(这些容器用专业术语称为“运行环境”)。大多数情况下,每个标签页中的代码完全独立运行,而且一个标签页中的代码不能直接影响另一个标签页(或者另一个网站)中的代码。这是一个好的安全措施,如果不这样,黑客就可以从其他网站盗取信息,等等。
|
||||
|
||||
注:以安全的方式在不同网站/标签页中传送代码和数据的方法是存在的,但这些技术较为高级,本课程不会涉及。
|
||||
JavaScript 运行次序
|
||||
|
||||
当浏览器执行到一段 JavaScript 代码时,通常会按从上往下的顺序执行这段代码。这意味着你需要注意代码书写的顺序。比如,我们回到第一个例子中的 JavaScript 代码:
|
||||
|
||||
const para = document.querySelector('p');
|
||||
|
||||
para.addEventListener('click', updateName);
|
||||
|
||||
function updateName() {
|
||||
let name = prompt('输入一个新的名字:');
|
||||
para.textContent = '玩家1:' + name;
|
||||
}
|
||||
|
||||
这里我们选定一个文本段落(第 1 行),然后给它附上一个事件监听器(第 3 行),使得在它被点击时,updateName() 代码块(code block) (5 – 8 行)便会运行。updateName() (这类可以重复使用的代码块称为“函数”)向用户请求一个新名字,然后把这个名字插入到段落中以更新显示。
|
||||
|
||||
如果你互换了代码里最初两行的顺序,会导致问题。浏览器开发者控制台将返回一个错误: TypeError: para is undefined。这意味着 para 对象还不存在,所以我们不能为它增添一个事件监听器。
|
||||
|
||||
注:这是一个很常见的错误,在引用对象之前必须确保该对象已经存在。
|
||||
解释代码 vs 编译代码
|
||||
|
||||
作为程序员,你或许听说过这两个术语:解释(interpret)和 编译(compile)。在解释型语言中,代码自上而下运行,且实时返回运行结果。代码在由浏览器执行前,不需要将其转化为其他形式。代码将直接以文本格式(text form)被接收和处理。
|
||||
|
||||
相对的,编译型语言需要先将代码转化(编译)成另一种形式才能运行。比如 C/C++ 先被编译成汇编语言,然后才能由计算机运行。程序将以二进制的格式运行,这些二进制内容是由程序源代码产生的。
|
||||
|
||||
JavaScript 是轻量级解释型语言。浏览器接受到JavaScript代码,并以代码自身的文本格式运行它。技术上,几乎所有 JavaScript 转换器都运用了一种叫做即时编译(just-in-time compiling)的技术;当 JavaScript 源代码被执行时,它会被编译成二进制的格式,使代码运行速度更快。尽管如此,JavaScript 仍然是一门解释型语言,因为编译过程发生在代码运行中,而非之前。
|
||||
|
||||
两种类型的语言各有优势,这个问题我们暂且不谈。
|
||||
服务器端代码 vs 客户端代码
|
||||
|
||||
你或许还听说过服务器端(server-side)和 客户端(client-side)代码这两个术语,尤其是在web开发时。客户端代码是在用户的电脑上运行的代码,在浏览一个网页时,它的客户端代码就会被下载,然后由浏览器来运行并展示。这就是客户端 JavaScript。
|
||||
|
||||
而服务器端代码在服务器上运行,接着运行结果才由浏览器下载并展示出来。流行的服务器端 web 语言包括:PHP、Python、Ruby、ASP.NET 以及...... JavaScript!JavaScript 也可用作服务器端语言,比如现在流行的 Node.js 环境,你可以在我们的 动态网页 - 服务器端编程 主题中找到更多关于服务器端 JavaScript 的知识。
|
||||
动态代码 vs 静态代码
|
||||
|
||||
“动态”一词既适用于客户端 JavaScript,又适用于描述服务器端语言。是指通过按需生成新内容来更新 web 页面 / 应用,使得不同环境下显示不同内容。服务器端代码会在服务器上动态生成新内容,例如从数据库中提取信息。而客户端 JavaScript 则在用户端浏览器中动态生成新内容,比如说创建一个新的 HTML 表格,用从服务器请求到的数据填充,然后在网页中向用户展示这个表格。两种情况的意义略有不同,但又有所关联,且两者(服务器端和客户端)经常协同作战。
|
||||
|
||||
没有动态更新内容的网页叫做“静态”页面,所显示的内容不会改变。
|
||||
怎样向页面添加 JavaScript?
|
||||
|
||||
可以像添加 CSS 那样将 JavaScript 添加到 HTML 页面中。CSS 使用 \<link> 元素链接外部样式表,使用 <style> 元素向 HTML 嵌入内部样式表,JavaScript 这里只需一个元素——<script>。我们来看看它是怎么工作的。
|
||||
内部 JavaScript
|
||||
|
||||
首先,下载示例文件 apply-javascript.html。放在一个好记的文件夹里。
|
||||
分别在浏览器和文本编辑器中打开这个文件。你会看到这个 HTML 文件创建了一个简单的网页,其中有一个可点击按钮。
|
||||
然后转到文本编辑器,在 </body> 标签结束前插入以下代码:
|
||||
|
||||
<script>
|
||||
|
||||
// 在此编写 JavaScript 代码
|
||||
|
||||
</script>
|
||||
|
||||
下面,在 <script> 元素中添加一些 JavaScript 代码,这个页面就能做一些更有趣的事。在“/ /在此编写 JavaScript 代码”一行下方添加以下代码:
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
function createParagraph() {
|
||||
let para = document.createElement('p');
|
||||
para.textContent = '你点击了这个按钮!';
|
||||
document.body.appendChild(para);
|
||||
}
|
||||
|
||||
const buttons = document.querySelectorAll('button');
|
||||
|
||||
for(let i = 0; i < buttons.length ; i++) {
|
||||
buttons[i].addEventListener('click', createParagraph);
|
||||
}
|
||||
});
|
||||
|
||||
保存文件并刷新浏览器,然后你会发现,点击按钮文档下方将会添加一个新段落。
|
||||
|
||||
注: 如果示例不能正常工作,请依次检查所有步骤,并保证没有纰漏。原始文件是否以 .html 为扩展名保存到本地了?\</body> 标签前是否添加了 \<script> 元素?JavaScript 代码输入是否正确 ? JavaScript 是区分大小写的,而且非常精确,所以你需要准确无误地输入所示的句法,否则可能会出错。
|
||||
|
||||
注: 你可以在 GitHub 上查看此版本 apply-internal.html (也可在线查看)。
|
||||
外部 JavaScript
|
||||
|
||||
这很不错,但是能不能把 JavaScript 代码放置在一个外部文件中呢?现在我们来研究一下。
|
||||
|
||||
首先,在刚才的 HTML 文件所在的目录下创建一个名为 script.js 的新文件。请确保扩展名为 .js,只有这样才能被识别为 JavaScript 代码。
|
||||
将 <script> 元素替换为:
|
||||
|
||||
<script src="script.js" async></script>
|
||||
|
||||
在 script.js 文件中,添加下面的脚本:
|
||||
|
||||
function createParagraph() {
|
||||
let para = document.createElement('p');
|
||||
para.textContent = '你点击了这个按钮!';
|
||||
document.body.appendChild(para);
|
||||
}
|
||||
|
||||
const buttons = document.querySelectorAll('button');
|
||||
|
||||
for(let i = 0; i < buttons.length ; i++) {
|
||||
buttons[i].addEventListener('click', createParagraph);
|
||||
}
|
||||
|
||||
保存并刷新浏览器,你会发现二者完全一样。但是现在我们把 JavaScript 写进了一个外部文件。这样做一般会使代码更加有序,更易于复用,且没有了脚本的混合,HTML 也会更加易读,因此这是个好的习惯。
|
||||
|
||||
注:你可以在 GitHub 上查看这个版本 apply-external.html 以及 script.js (也可在线查看).
|
||||
内联 JavaScript 处理器
|
||||
|
||||
注意,有时候你会遇到在 HTML 中存在着一丝真实的 JavaScript 代码。它或许看上去像这样:
|
||||
|
||||
function createParagraph() {
|
||||
const para = document.createElement('p');
|
||||
para.textContent = '你点击了这个按钮!';
|
||||
document.body.appendChild(para);
|
||||
}
|
||||
|
||||
<button onclick="createParagraph()">点我呀</button>
|
||||
|
||||
你可以在下面尝试这个版本的 demo。
|
||||
|
||||
这个 demo 与之前的两个功能完全一致,只是在 <button> 元素中包含了一个内联的 onclick 处理器,使得函数在按钮被按下时运行。
|
||||
|
||||
然而请不要这样做。 这将使 JavaScript 污染到 HTML,而且效率低下。对于每个需要应用 JavaScript 的按钮,你都得手动添加 onclick="createParagraph()" 属性。
|
||||
|
||||
可以使用纯 JavaScript 结构来通过一个指令选取所有按钮。下文的这段代码即实现了这一目的:
|
||||
|
||||
const buttons = document.querySelectorAll('button');
|
||||
|
||||
for(let i = 0; i < buttons.length ; i++) {
|
||||
buttons[i].addEventListener('click', createParagraph);
|
||||
}
|
||||
|
||||
这样写乍看去比 onclick 属性要长一些,但是这样写会对页面上所有按钮生效,无论多少个,或添加或删除,完全无需修改 JavaScript 代码。
|
||||
|
||||
注:请尝试修改 apply-javascript.html 以添加更多按钮。刷新后可发现按下任一按钮时都会创建一个段落。很高效吧。
|
||||
脚本调用策略
|
||||
|
||||
要让脚本调用的时机符合预期,需要解决一系列的问题。这里看似简单,实际大有文章。最常见的问题就是:HTML 元素是按其在页面中出现的次序调用的,如果用 JavaScript 来管理页面上的元素(更精确的说法是使用 文档对象模型 DOM),若 JavaScript 加载于欲操作的 HTML 元素之前,则代码将出错。
|
||||
|
||||
在上文的“内部”、“外部”示例中,JavaScript 调用于文档头处,解析 HTML 文档体之前。这样做是有隐患的,需要使用一些结构来避免错误发生。
|
||||
|
||||
“内部”示例使用了以下结构:
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
. . .
|
||||
});
|
||||
|
||||
这是一个事件监听器,它监听浏览器的 "DOMContentLoaded" 事件,即 HTML 文档体加载、解释完毕事件。事件触发时将调用 " . . ." 处的代码,从而避免了错误发生(事件 的概念稍后学习)。
|
||||
|
||||
“外部”示例中使用了 JavaScript 的一项现代技术(async “异步”属性)来解决这一问题,它告知浏览器在遇到 <script> 元素时不要中断后续 HTML 内容的加载。
|
||||
|
||||
<script src="script.js" async></script>
|
||||
|
||||
上述情况下,脚本和 HTML 将一并加载,代码将顺利运行。
|
||||
|
||||
注:“外部”示例中 async 属性可以解决调用顺序问题,因此无需使用 DOMContentLoaded 事件。而 async 只能用于外部脚本,因此不适用于“内部”示例。
|
||||
|
||||
解决此问题的旧方法是:把脚本元素放在文档体的底端(</body> 标签之前,与之相邻),这样脚本就可以在 HTML 解析完毕后加载了。此方案(以及上述的 DOMContentLoaded 方案)的问题是:只有在所有 HTML DOM 加载完成后才开始脚本的加载/解析过程。对于有大量 JavaScript 代码的大型网站,可能会带来显著的性能损耗。这也是 async 属性诞生的初衷。
|
||||
async 和 defer
|
||||
|
||||
上述的脚本阻塞问题实际有两种解决方案 —— async 和 defer。我们来依次讲解。
|
||||
|
||||
浏览器遇到 async 脚本时不会阻塞页面渲染,而是直接下载然后运行。这样脚本的运行次序就无法控制,只是脚本不会阻止剩余页面的显示。当页面的脚本之间彼此独立,且不依赖于本页面的其它任何脚本时,async 是最理想的选择。
|
||||
|
||||
比如,如果你的页面要加载以下三个脚本:
|
||||
|
||||
<script async src="js/vendor/jquery.js"></script>
|
||||
|
||||
<script async src="js/script2.js"></script>
|
||||
|
||||
<script async src="js/script3.js"></script>
|
||||
|
||||
三者的调用顺序是不确定的。jquery.js 可能在 script2 和 script3 之前或之后调用,如果这样,后两个脚本中依赖 jquery 的函数将产生错误,因为脚本运行时 jquery 尚未加载。
|
||||
|
||||
解决这一问题可使用 defer 属性,脚本将按照在页面中出现的顺序加载和运行:
|
||||
|
||||
<script defer src="js/vendor/jquery.js"></script>
|
||||
|
||||
<script defer src="js/script2.js"></script>
|
||||
|
||||
<script defer src="js/script3.js"></script>
|
||||
|
||||
添加 defer 属性的脚本将按照在页面中出现的顺序加载,因此第二个示例可确保 jquery.js 必定加载于 script2.js 和 script3.js 之前,同时 script2.js 必定加载于 script3.js 之前。
|
||||
|
||||
脚本调用策略小结:
|
||||
|
||||
如果脚本无需等待页面解析,且无依赖独立运行,那么应使用 async。
|
||||
如果脚本需要等待页面解析,且依赖于其它脚本,调用这些脚本时应使用 defer,将关联的脚本按所需顺序置于 HTML 中。
|
||||
|
||||
注释
|
||||
|
||||
就像 HTML 和 CSS,JavaScript 代码中也可以添加注释,浏览器会忽略它们,注释只是为你的同事(还有你,如果半年后再看自己写的代码你会说,这是什么垃圾玩意。)提供关于代码如何工作的指引。注释非常有用,而且应该经常使用,尤其在大型应用中。注释分为两类:
|
||||
|
||||
在双斜杠后添加单行注释,比如:
|
||||
|
||||
// 我是一条注释
|
||||
|
||||
在 /* 和 */ 之间添加多行注释,比如:
|
||||
|
||||
/*
|
||||
我也是
|
||||
一条注释
|
||||
*/
|
||||
|
||||
比如说,我们可以这样为上一个 demo 添加注释:
|
||||
|
||||
// 函数:创建一个新的段落并添加至 HTML body 底部。
|
||||
function createParagraph() {
|
||||
let para = document.createElement('p');
|
||||
para.textContent = '你点了这个按钮!';
|
||||
document.body.appendChild(para);
|
||||
}
|
||||
|
||||
/*
|
||||
1. 取得页面上所有按钮的引用并将它们置于一个数组中。
|
||||
2. 通过一个循环为每个按钮添加一个点击事件的监听器。
|
||||
当按钮被点击时,调用 createParagraph() 函数。
|
||||
*/
|
||||
|
||||
const buttons = document.querySelectorAll('button');
|
||||
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
buttons[i].addEventListener('click', createParagraph);
|
||||
}
|
||||
|
||||
小结
|
||||
|
||||
恭喜你,迈出了探索 JavaScript 世界的第一步。我们从理论开始,介绍为什么要使用 JavaScript,以及用它能做什么事情。过程中穿插了一些代码示例并讲解了 JavaScript 如何与网站中其他代码适配,等等。
|
||||
|
||||
现在 JavaScript 或许还有些令人生畏,但不用担心。在课程中我们会循序渐进。下一节将 全力投入实战,让你专注其中,并建立自己的 JavaScript 示例。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
23
vuenew/cli/demo/.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
24
vuenew/cli/demo/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# demo
|
||||
|
||||
## Project setup
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
yarn serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
yarn lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
5
vuenew/cli/demo/babel.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
47
vuenew/cli/demo/package.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "demo",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.21.1",
|
||||
"core-js": "^3.6.5",
|
||||
"element-ui": "^2.15.1",
|
||||
"qs": "^6.9.6",
|
||||
"vue": "^2.6.11",
|
||||
"vue-axios": "^3.2.4",
|
||||
"vue-router": "^3.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead"
|
||||
]
|
||||
}
|
BIN
vuenew/cli/demo/public/favicon.ico
Normal file
After Width: | Height: | Size: 4.2 KiB |
17
vuenew/cli/demo/public/index.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<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">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
17
vuenew/cli/demo/src/App.vue
Normal file
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
BIN
vuenew/cli/demo/src/assets/static/img/clothes.jpg
Normal file
After Width: | Height: | Size: 2.0 KiB |
93
vuenew/cli/demo/src/components/bottomjiesuan.vue
Normal file
@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div class="bottom-jiesuan">
|
||||
<div class="js-right">
|
||||
<div class="js-right-right">
|
||||
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" >全选</el-checkbox>
|
||||
<a href="">删除</a>
|
||||
<a href="">移入收藏夹</a>
|
||||
<a href="">分享</a>
|
||||
</div>
|
||||
<div class="js-right-left">
|
||||
<p>已选商品<span>{{sumnum}}</span>件</p>
|
||||
<p>合计(不含运费):<span>{{sumprice.toFixed(2)}}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="js-left">
|
||||
<p>结算</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'bottomjiesuan',
|
||||
props:{
|
||||
sumnum:Number,
|
||||
sumprice:Number
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.bottom-jiesuan{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 10px 0px;
|
||||
margin: 0 auto ;
|
||||
background-color: #e5e5e5;
|
||||
width: 98%;
|
||||
height: 40px;
|
||||
}
|
||||
.js-right{
|
||||
display: flex;
|
||||
justify-content:space-between;
|
||||
width: 90%;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.js-right a{
|
||||
margin-left: 30px;
|
||||
color: black;
|
||||
}
|
||||
.js-right a:hover{
|
||||
color: #e2231a;
|
||||
}
|
||||
.js-right-left{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
}
|
||||
.js-right-left p{
|
||||
margin-left: 20px;
|
||||
}
|
||||
.js-right-left span{
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #e2231a;
|
||||
margin: 0 5px;
|
||||
}
|
||||
.js-left p{
|
||||
/* margin-right: 20px; */
|
||||
line-height:18px ;
|
||||
font-size: 18px;
|
||||
color: white;
|
||||
margin: auto 0;
|
||||
margin-top: 12px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.js-left{
|
||||
background-color: #B0B0B0;
|
||||
width: 80px;
|
||||
height: 40px;
|
||||
}
|
||||
</style>
|
141
vuenew/cli/demo/src/components/gouwuchelist - 副本.vue
Normal file
@ -0,0 +1,141 @@
|
||||
<template>
|
||||
|
||||
<div class="gouwuchelist">
|
||||
|
||||
<div class="row1">
|
||||
<el-checkbox :label="checkeddianpu" @click="childClick"></el-checkbox>
|
||||
<svg t="1616141748140" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2334" width="16" height="16"><path d="M761.9 927.6H264.1c-70.5 0-125.7-42.6-125.7-97V550.9c0-24.3 19.7-44 44-44s44 19.7 44 44v277.2c3.5 3.7 16.4 11.5 37.7 11.5H762c21.3 0 34.2-7.7 37.7-11.5V550.9c0-24.3 19.7-44 44-44s44 19.7 44 44v279.7c-0.1 54.4-55.3 97-125.8 97z" fill="#e2231a" p-id="2335"></path><path d="M513.7 633.7c-11.1 0-22.1-1.5-32.9-4.6l-181.2-52.2c-2.6-0.8-5.3-1.1-7.9-0.9l-129.3 8.2c-24.6 1.6-48.7-8.7-65.7-28.2C77 533.6 68.9 501.7 75 470.9l52.2-261.6c13-65 63-110.4 121.6-110.4h528.4c58.6 0 108.6 45.4 121.6 110.4L951 470.9c6.1 30.8-2 62.6-21.7 85.2-17 19.5-41.1 29.8-65.7 28.2l-129.4-8.2c-2.7-0.2-5.3 0.1-7.9 0.9l-179.4 52c-10.9 3.1-22.1 4.7-33.2 4.7zM293.2 488c10.4 0 20.7 1.5 30.7 4.4l181.2 52.1c5.7 1.6 11.5 1.6 17.2 0l179.4-52c12.4-3.6 25.2-5 38-4.2l124.5 7.9c0.7-1.8 1.2-4.5 0.5-8l-52.2-261.6c-4.6-23-19.4-39.7-35.3-39.7H248.8c-15.9 0-30.7 16.7-35.3 39.7l-52.2 261.6c-0.7 3.5-0.1 6.2 0.5 8l124.3-7.9c2.4-0.2 4.7-0.3 7.1-0.3z m576 8.5h0.2-0.2z" fill="#e2231a" p-id="2336"></path><path d="M513.7 447.6c-24.3 0-44-19.7-44-44V293.5c0-24.3 19.7-44 44-44s44 19.7 44 44v110.2c0 24.2-19.7 43.9-44 43.9zM702.9 422.7c-20.9 0-39.5-15-43.3-36.3l-15.2-85.2c-4.3-23.9 11.7-46.8 35.6-51 24.1-4.3 46.8 11.7 51 35.6l15.2 85.2c4.3 23.9-11.7 46.8-35.6 51-2.6 0.4-5.2 0.7-7.7 0.7zM319.8 422.7c-2.5 0-5.1-0.2-7.6-0.7-24-4.2-39.9-27-35.8-50.9l14.9-85.2c4.2-23.9 27-39.9 50.9-35.8 24 4.2 39.9 27 35.8 50.9l-14.9 85.2c-3.7 21.4-22.3 36.5-43.3 36.5z" fill="#e2231a" p-id="2337"></path></svg>
|
||||
<span>店铺:</span>
|
||||
<a href="">{{shangpin.dianpuname}}</a>
|
||||
</div>
|
||||
<div class="gwc-content">
|
||||
<div class="tuhejieshao">
|
||||
<el-checkbox :label="checkeddingdan" ></el-checkbox>
|
||||
<img src="..\assets\static\img\clothes.jpg" alt="">
|
||||
<p>{{shangpin.shangpinname}}</p>
|
||||
</div>
|
||||
<div class="canshu">
|
||||
<p v-for="(casnhu,index) in shangpin.canshulist" :key="index">{{casnhu.canshuname}}:{{casnhu.canshuvalue}}</p>
|
||||
<svg style="display:none" t="1616146720956" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3457" width="16" height="16"><path d="M369.269 883.675l-321.935 91.337 91.335-321.938z" p-id="3458" fill="#9c9c9c"></path><path d="M1000.772 252.109l-77.526 77.526-230.598-230.598 77.522-77.524c0 0 36.951-36.895 74.509 0.663 37.562 37.563 110.575 110.574 151.709 151.71 41.138 41.134 4.385 78.223 4.385 78.223z" p-id="3459" fill="#9c9c9c"></path><path d="M900.035 352.787l-507.821 507.821-230.54-230.54 507.821-507.821 230.54 230.54z" p-id="3460" fill="#9c9c9c"></path></svg>
|
||||
</div>
|
||||
<div class="danjia">
|
||||
<p>¥{{(shangpin.yuanjia).toFixed(2)}}</p>
|
||||
<p>¥{{(shangpin.xianjia).toFixed(2)}}</p>
|
||||
</div>
|
||||
<div class="shuliang">
|
||||
<el-input-number size="mini" v-model="shangpin.num4" :min="1" @change="handleChange"></el-input-number>
|
||||
</div>
|
||||
<div class="jine">
|
||||
<!-- <span>¥{{(shangpin.xianjia*shangpin.num4).toFixed(2)}}</span> -->
|
||||
|
||||
<span>¥{{(shangpin.xianjia,shangpin.num4)}}</span>
|
||||
</div>
|
||||
<div class="caozuo">
|
||||
<a href="">移入收藏夹</a>
|
||||
<a href="">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'gouwuchelist',
|
||||
props:{
|
||||
shangpin:Object
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
handleChange(value) {
|
||||
console.log(value);
|
||||
},
|
||||
childClick(e){
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.gouwuchelist .row1{
|
||||
padding: 10px 30px;
|
||||
|
||||
}
|
||||
.gouwuchelist .row1 svg{
|
||||
margin: 0px 5px 0 15px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
}
|
||||
.gouwuchelist .row1 span,a{
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.gwc-content {
|
||||
padding:20px 0 20px 0;
|
||||
width: 98%;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
background: #fcfcfc;
|
||||
border:1px solid #e7e7e7; ;
|
||||
}
|
||||
.gwc-content .tuhejieshao p{
|
||||
width: 160px;
|
||||
overflow: hidden;
|
||||
height: 31px;
|
||||
font-size: 12.5px;
|
||||
display: inline-block;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.gwc-content .tuhejieshao img{
|
||||
margin-left: 20px;
|
||||
}
|
||||
.gwc-content .tuhejieshao{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.gwc-content .canshu{
|
||||
font-size: 13px;
|
||||
margin-left: -20px;
|
||||
}
|
||||
.gwc-content .danjia p:first-child{
|
||||
font-size: 12px;
|
||||
text-decoration: line-through;
|
||||
color: darkgray;
|
||||
}
|
||||
.gwc-content .danjia p:last-child{
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.gwc-content .caozuo a{
|
||||
display: block;
|
||||
/* text-decoration: none; */
|
||||
color: black;
|
||||
}
|
||||
.gwc-content .caozuo a:hover{
|
||||
text-decoration: #e2231a;
|
||||
color: #e2231a;
|
||||
}
|
||||
.gwc-content .jine{
|
||||
color: #e2231a;
|
||||
font-weight:bold;
|
||||
margin-left: -20px;
|
||||
}
|
||||
.gwc-content .shuliang{
|
||||
margin-left: -20px;
|
||||
}
|
||||
</style>
|
204
vuenew/cli/demo/src/components/gouwuchelist.vue
Normal file
@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<div class="gouwuchelist">
|
||||
<div class="row1">
|
||||
<!-- <el-checkbox :label="checkeddianpu" @click="childClick"></el-checkbox> -->
|
||||
<svg
|
||||
t="1616141748140"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2334"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
d="M761.9 927.6H264.1c-70.5 0-125.7-42.6-125.7-97V550.9c0-24.3 19.7-44 44-44s44 19.7 44 44v277.2c3.5 3.7 16.4 11.5 37.7 11.5H762c21.3 0 34.2-7.7 37.7-11.5V550.9c0-24.3 19.7-44 44-44s44 19.7 44 44v279.7c-0.1 54.4-55.3 97-125.8 97z"
|
||||
fill="#e2231a"
|
||||
p-id="2335"
|
||||
></path>
|
||||
<path
|
||||
d="M513.7 633.7c-11.1 0-22.1-1.5-32.9-4.6l-181.2-52.2c-2.6-0.8-5.3-1.1-7.9-0.9l-129.3 8.2c-24.6 1.6-48.7-8.7-65.7-28.2C77 533.6 68.9 501.7 75 470.9l52.2-261.6c13-65 63-110.4 121.6-110.4h528.4c58.6 0 108.6 45.4 121.6 110.4L951 470.9c6.1 30.8-2 62.6-21.7 85.2-17 19.5-41.1 29.8-65.7 28.2l-129.4-8.2c-2.7-0.2-5.3 0.1-7.9 0.9l-179.4 52c-10.9 3.1-22.1 4.7-33.2 4.7zM293.2 488c10.4 0 20.7 1.5 30.7 4.4l181.2 52.1c5.7 1.6 11.5 1.6 17.2 0l179.4-52c12.4-3.6 25.2-5 38-4.2l124.5 7.9c0.7-1.8 1.2-4.5 0.5-8l-52.2-261.6c-4.6-23-19.4-39.7-35.3-39.7H248.8c-15.9 0-30.7 16.7-35.3 39.7l-52.2 261.6c-0.7 3.5-0.1 6.2 0.5 8l124.3-7.9c2.4-0.2 4.7-0.3 7.1-0.3z m576 8.5h0.2-0.2z"
|
||||
fill="#e2231a"
|
||||
p-id="2336"
|
||||
></path>
|
||||
<path
|
||||
d="M513.7 447.6c-24.3 0-44-19.7-44-44V293.5c0-24.3 19.7-44 44-44s44 19.7 44 44v110.2c0 24.2-19.7 43.9-44 43.9zM702.9 422.7c-20.9 0-39.5-15-43.3-36.3l-15.2-85.2c-4.3-23.9 11.7-46.8 35.6-51 24.1-4.3 46.8 11.7 51 35.6l15.2 85.2c4.3 23.9-11.7 46.8-35.6 51-2.6 0.4-5.2 0.7-7.7 0.7zM319.8 422.7c-2.5 0-5.1-0.2-7.6-0.7-24-4.2-39.9-27-35.8-50.9l14.9-85.2c4.2-23.9 27-39.9 50.9-35.8 24 4.2 39.9 27 35.8 50.9l-14.9 85.2c-3.7 21.4-22.3 36.5-43.3 36.5z"
|
||||
fill="#e2231a"
|
||||
p-id="2337"
|
||||
></path>
|
||||
</svg>
|
||||
<span>店铺:</span>
|
||||
<a href="">{{ shangpin.dianpuname }}</a>
|
||||
</div>
|
||||
<div class="gwc-content">
|
||||
<div class="tuhejieshao">
|
||||
<el-checkbox :label="shangpin.xianjia" @change="xz(shangpin.xianjia)">
|
||||
<img src="..\assets\static\img\clothes.jpg" alt="" />
|
||||
<p>{{ shangpin.shangpinname }}</p>
|
||||
</el-checkbox>
|
||||
</div>
|
||||
<div class="canshu">
|
||||
<p v-for="(casnhu, index) in shangpin.canshulist" :key="index">
|
||||
{{ casnhu.canshuname }}:{{ casnhu.canshuvalue }}
|
||||
</p>
|
||||
<svg
|
||||
style="display: none"
|
||||
t="1616146720956"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="3457"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
d="M369.269 883.675l-321.935 91.337 91.335-321.938z"
|
||||
p-id="3458"
|
||||
fill="#9c9c9c"
|
||||
></path>
|
||||
<path
|
||||
d="M1000.772 252.109l-77.526 77.526-230.598-230.598 77.522-77.524c0 0 36.951-36.895 74.509 0.663 37.562 37.563 110.575 110.574 151.709 151.71 41.138 41.134 4.385 78.223 4.385 78.223z"
|
||||
p-id="3459"
|
||||
fill="#9c9c9c"
|
||||
></path>
|
||||
<path
|
||||
d="M900.035 352.787l-507.821 507.821-230.54-230.54 507.821-507.821 230.54 230.54z"
|
||||
p-id="3460"
|
||||
fill="#9c9c9c"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="danjia">
|
||||
<p>¥{{ shangpin.yuanjia.toFixed(2) }}</p>
|
||||
<p>¥{{ shangpin.xianjia.toFixed(2) }}</p>
|
||||
</div>
|
||||
<div class="shuliang">
|
||||
<el-input-number
|
||||
size="mini"
|
||||
v-model="shangpin.num4"
|
||||
:min="1"
|
||||
@change="handleChange"
|
||||
></el-input-number>
|
||||
</div>
|
||||
<div class="jine">
|
||||
<!-- <span>¥{{(shangpin.xianjia*shangpin.num4).toFixed(2)}}</span> -->
|
||||
|
||||
<span>¥{{ (shangpin.xianjia, shangpin.num4) }}</span>
|
||||
</div>
|
||||
<div class="caozuo">
|
||||
<a href="">移入收藏夹</a>
|
||||
<a href="">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "gouwuchelist",
|
||||
props: {
|
||||
shangpin: Object,
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
handleChange(value) {
|
||||
console.log(value);
|
||||
},
|
||||
childClick(e) {
|
||||
console.log(e);
|
||||
},
|
||||
xz(e){
|
||||
if(e){
|
||||
this.$emit("xz",e)
|
||||
}
|
||||
|
||||
}
|
||||
// selectone(value) {
|
||||
// console.log(value)
|
||||
// // let checkedCount = value.length;
|
||||
// // this.checkAll = checkedCount === this.cities.length;
|
||||
// // this.isIndeterminate = checkedCount > 0 && checkedCount < this.cities.length;
|
||||
// }
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.gouwuchelist .row1 {
|
||||
padding: 10px 30px;
|
||||
}
|
||||
.gouwuchelist .row1 svg {
|
||||
margin: 0px 5px 0 15px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
}
|
||||
.gouwuchelist .row1 span,
|
||||
a {
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.gwc-content {
|
||||
padding: 20px 0 20px 0;
|
||||
width: 98%;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
background: #fcfcfc;
|
||||
border: 1px solid #e7e7e7;
|
||||
}
|
||||
.gwc-content .tuhejieshao p {
|
||||
width: 160px;
|
||||
overflow: hidden;
|
||||
height: 31px;
|
||||
font-size: 12.5px;
|
||||
display: inline-block;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.gwc-content .tuhejieshao img {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.gwc-content .tuhejieshao {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.gwc-content .canshu {
|
||||
font-size: 13px;
|
||||
margin-left: -20px;
|
||||
}
|
||||
.gwc-content .danjia p:first-child {
|
||||
font-size: 12px;
|
||||
text-decoration: line-through;
|
||||
color: darkgray;
|
||||
}
|
||||
.gwc-content .danjia p:last-child {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.gwc-content .caozuo a {
|
||||
display: block;
|
||||
/* text-decoration: none; */
|
||||
color: black;
|
||||
}
|
||||
.gwc-content .caozuo a:hover {
|
||||
text-decoration: #e2231a;
|
||||
color: #e2231a;
|
||||
}
|
||||
.gwc-content .jine {
|
||||
color: #e2231a;
|
||||
font-weight: bold;
|
||||
margin-left: -20px;
|
||||
}
|
||||
.gwc-content .shuliang {
|
||||
margin-left: -20px;
|
||||
}
|
||||
</style>
|
196
vuenew/cli/demo/src/components/navbar1.vue
Normal file
@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<div class="search-m">
|
||||
<div class="search-logo">
|
||||
<a href="" class="search_logo_lk"></a>
|
||||
<span>{{logopangzi}}</span>
|
||||
</div>
|
||||
<div class="search-box">
|
||||
<!-- <div class="search_bg" >枣夹核桃</div> -->
|
||||
<input type="text" class="text" label="搜索" >
|
||||
<svg t="1616050698526" class="icon-xiangji" viewBox="0 0 1164 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2753" width="16" height="16"><path d="M959.326316 377.263158m-64.673684 0a64.673684 64.673684 0 1 0 129.347368 0 64.673684 64.673684 0 1 0-129.347368 0Z" fill="#9f9f9f" p-id="2754"></path><path d="M1099.452632 1024H64.673684a64.673684 64.673684 0 0 1-64.673684-64.673684V226.357895a64.673684 64.673684 0 0 1 64.673684-64.673684h275.941053S433.249011 0 463.494737 0h237.136842c32.983579 0 116.412632 161.684211 116.412632 161.684211H1099.452632a64.673684 64.673684 0 0 1 64.673684 64.673684v732.968421a64.673684 64.673684 0 0 1-64.673684 64.673684zM668.294737 64.673684H495.831579c-18.248758 0-70.063158 97.010526-70.063158 97.010527H732.968421s-45.023663-97.010526-64.673684-97.010527z m431.157895 204.8a43.115789 43.115789 0 0 0-43.11579-43.115789H107.789474a43.115789 43.115789 0 0 0-43.11579 43.115789v646.736842a43.115789 43.115789 0 0 0 43.11579 43.11579h948.547368a43.115789 43.115789 0 0 0 43.11579-43.11579V269.473684zM926.989474 388.042105a64.673684 64.673684 0 1 1 64.673684-64.673684 64.673684 64.673684 0 0 1-64.673684 64.673684zM587.452632 797.642105A199.410526 199.410526 0 1 1 786.863158 598.231579 199.410526 199.410526 0 0 1 587.452632 797.642105z m0-344.926316A145.515789 145.515789 0 1 0 732.968421 598.231579 145.515789 145.515789 0 0 0 587.452632 452.715789z" p-id="2755" fill="#9f9f9f"></path></svg>
|
||||
<button class="button" label="搜索">
|
||||
<svg t="1616049602935" class="icon" viewBox="0 0 1028 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1391" width="16" height="16"><path d="M1007.548064 899.256487L801.043871 692.754294c-3.577986-3.577986-8.032969-5.329979-12.194952-8.032969C908.82345 515.091988 893.926508 279.233909 742.042101 127.349503c-169.701337-169.775337-444.918262-169.775337-614.692598 0-169.775337 169.701337-169.775337 444.845262 0 614.692598 153.5634 153.5644 392.635466 166.708349 562.701801 42.498834 2.701989 3.869985 4.380983 8.104968 7.73997 11.536955L904.296468 1002.582084c28.624888 28.551888 74.773708 28.551888 103.252596 0 28.477889-28.623888 28.477889-74.846708 0-103.324597zM655.074441 654.927442c-121.653525 121.654525-318.884754 121.654525-440.611279 0-121.653525-121.652525-121.653525-318.956754 0-440.610279s318.884754-121.653525 440.611279 0c121.726525 121.726525 121.726525 318.957754 0 440.611279z" p-id="1392" fill="#ffffff"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="gouwuche">
|
||||
<div class="cw-icon">
|
||||
<svg t="1616051372800" class="icon" viewBox="0 0 1028 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3934" width="16" height="16"><path d="M332.8 790.528q19.456 0 36.864 7.168t30.208 19.968 20.48 30.208 7.68 36.864-7.68 36.864-20.48 30.208-30.208 20.48-36.864 7.68q-20.48 0-37.888-7.68t-30.208-20.48-20.48-30.208-7.68-36.864 7.68-36.864 20.48-30.208 30.208-19.968 37.888-7.168zM758.784 792.576q19.456 0 37.376 7.168t30.72 19.968 20.48 30.208 7.68 36.864-7.68 36.864-20.48 30.208-30.72 20.48-37.376 7.68-36.864-7.68-30.208-20.48-20.48-30.208-7.68-36.864 7.68-36.864 20.48-30.208 30.208-19.968 36.864-7.168zM930.816 210.944q28.672 0 44.544 7.68t22.528 18.944 6.144 24.064-3.584 22.016-13.312 37.888-22.016 62.976-23.552 68.096-18.944 53.248q-13.312 40.96-33.28 56.832t-49.664 15.872l-35.84 0-65.536 0-86.016 0-96.256 0-253.952 0 14.336 92.16 517.12 0q49.152 0 49.152 41.984 0 20.48-9.728 35.84t-38.4 14.336l-49.152 0-94.208 0-118.784 0-119.808 0-99.328 0-55.296 0q-20.48 0-34.304-9.216t-23.04-24.064-14.848-32.256-8.704-32.768q-1.024-6.144-5.632-29.696t-11.264-58.88-14.848-78.848-16.384-87.552q-19.456-103.424-44.032-230.4l-76.8 0q-15.36 0-25.6-7.68t-16.896-18.432-9.216-23.04-2.56-22.528q0-20.48 13.824-33.792t37.376-12.288l103.424 0q20.48 0 32.768 6.144t19.456 15.36 10.24 18.944 5.12 16.896q2.048 8.192 4.096 23.04t4.096 30.208q3.072 18.432 6.144 38.912l700.416 0zM892.928 302.08l-641.024-2.048 35.84 185.344 535.552 1.024z" p-id="3935" fill="#f10214"></path></svg>
|
||||
<a target="_blank" href="//cart.jd.com/cart.action">我的购物车</a>
|
||||
<i class="ci-count" id="shopping-amount">{{gouwuchenum}}</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="login">
|
||||
<a href=""></a>
|
||||
<p>{{loginmsg}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'navbar1',
|
||||
props:{
|
||||
logopangzi:String,
|
||||
gouwuchenum:Number,
|
||||
loginmsg:String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.search{
|
||||
/* position: fixed; */
|
||||
z-index: 100;
|
||||
/* left: 0;
|
||||
top: 0; */
|
||||
width: 100%;
|
||||
border-bottom: 2px solid #f10214;
|
||||
background-color: #fff;
|
||||
}
|
||||
.search-m{
|
||||
height: 50px;
|
||||
width: 80%;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin:0 auto ;
|
||||
}
|
||||
.search-m .search-logo{
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 4px;
|
||||
width: 125px;
|
||||
height: 40px;
|
||||
}
|
||||
.search-m .search-logo span{
|
||||
color: #e2231a;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
top: -33px;
|
||||
left: 115px;
|
||||
|
||||
}
|
||||
.search-m .search_logo_lk {
|
||||
background-image: url(//misc.360buyimg.com/mtd/pc/index_2019/1.0.0/assets/sprite/header/sprite.png);
|
||||
background-position: 0 -120px;
|
||||
background-repeat: no-repeat;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
width: 125px;
|
||||
height: 40px;
|
||||
text-indent: -999px;
|
||||
}
|
||||
.search-m .search-box{
|
||||
position: absolute;
|
||||
height: 32px;
|
||||
border: 2px solid #e2231a;
|
||||
background: #fff;
|
||||
width: 486px;
|
||||
left: 220px;
|
||||
top: 8px;
|
||||
}
|
||||
.search-m .search-box .button:hover{
|
||||
background-color: #bd1108;
|
||||
}
|
||||
.search-m .search-box .button{
|
||||
border-radius: 0;
|
||||
right: 0;
|
||||
width: 58px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
background-color: #e1251b;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
.search-m .text {
|
||||
left: 0;
|
||||
padding: 2px 44px 2px 17px;
|
||||
width: 330px;
|
||||
height: 26px;
|
||||
border: none;
|
||||
line-height: 26px;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
outline: none;
|
||||
}
|
||||
/* .search-m .search_bg {
|
||||
color: #989898;
|
||||
} */
|
||||
.search-m .icon-xiangji{
|
||||
margin-bottom: -4px
|
||||
}
|
||||
.search-m .gouwuche .cw-icon:hover{
|
||||
border-color: #e1251b;
|
||||
}
|
||||
.search-m .gouwuche .cw-icon{
|
||||
width: 130px;
|
||||
height: 34px;
|
||||
background-color: #fff;
|
||||
text-align: center;
|
||||
line-height: 34px;
|
||||
border-color: #eee;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
top: 8px;
|
||||
left: 71%;
|
||||
border: 1px solid #e3e4e5;
|
||||
}
|
||||
.search-m .gouwuche .cw-icon a{
|
||||
color: #e1251b;
|
||||
text-decoration: none;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 49px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.search-m .cw-icon .ci-count {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 29px;
|
||||
right: auto;
|
||||
display: inline-block;
|
||||
padding: 1px 3px;
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
color: #fff;
|
||||
background-color: #e1251b;
|
||||
border-radius: 7px;
|
||||
min-width: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
.search-m .cw-icon svg{
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 18px;
|
||||
}
|
||||
.search-m .login:hover{
|
||||
background-color: #bd1108;
|
||||
}
|
||||
.search-m .login{
|
||||
width: 100px;
|
||||
height: 35px;
|
||||
font-size: 15px;
|
||||
color: white;
|
||||
background-color: #e1251b;
|
||||
text-align: center;
|
||||
line-height: 34px;
|
||||
border-color: #e1251b;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 8px;
|
||||
left: 85%;
|
||||
}
|
||||
</style>
|
71
vuenew/cli/demo/src/components/shangpin - 副本.vue
Normal file
@ -0,0 +1,71 @@
|
||||
<template>
|
||||
|
||||
<div class="shangpin">
|
||||
|
||||
<img class="spimg" src="//img12.360buyimg.com/jdcms/s150x150_jfs/t1/159091/6/13582/351629/60515ec7Eae162e4d/5fbdf654ea0fd7cc.jpg.webp" alt="美国(G-force)无链条折叠电动车外卖代驾成人电动自行车迷你轴传动电瓶车闪电发货 深空灰-汽车电芯无链条传动技术-6AH60公里">
|
||||
<div class="box">
|
||||
<p class="jianjie">
|
||||
美国(G-force)无链条折叠电动车外卖代驾成人电动自行车迷你轴传动电瓶车闪电发货 深空灰-汽车电芯无链条传动技术-6AH60公里
|
||||
</p>
|
||||
<div class="price">
|
||||
<i>¥</i>
|
||||
<span class="zheng">2998.<span class="ling">00</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'shangpin'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.shangpin{
|
||||
width: 190px;
|
||||
height: 266px;
|
||||
margin: 0 5px 8px;
|
||||
background: #fff;
|
||||
}
|
||||
.shangpin .spimg{
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin: 30px 0 0 28px;
|
||||
}
|
||||
.shangpin .jianjie{
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: left;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
height: 40px;
|
||||
}
|
||||
.shangpin .box{
|
||||
margin: 30px 15px 0 15px;
|
||||
}
|
||||
.shangpin .box .price{
|
||||
color: #e1251b;
|
||||
margin: 5px 0 0 0;
|
||||
}
|
||||
.shangpin .box .price i{
|
||||
vertical-align: middle;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
font-family: MicrosoftYahei-regular,Arial,Helvetica,sans-serif;
|
||||
}
|
||||
.shangpin .box .price .zheng{
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
font-family: arial,sans-serif;
|
||||
}
|
||||
.shangpin .box .price .ling{
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
71
vuenew/cli/demo/src/components/shangpin.vue
Normal file
@ -0,0 +1,71 @@
|
||||
<template>
|
||||
|
||||
<div class="shangpin">
|
||||
|
||||
<img class="spimg" src="//img12.360buyimg.com/jdcms/s150x150_jfs/t1/159091/6/13582/351629/60515ec7Eae162e4d/5fbdf654ea0fd7cc.jpg.webp" alt="美国(G-force)无链条折叠电动车外卖代驾成人电动自行车迷你轴传动电瓶车闪电发货 深空灰-汽车电芯无链条传动技术-6AH60公里">
|
||||
<div class="box">
|
||||
<p class="jianjie">
|
||||
美国(G-force)无链条折叠电动车外卖代驾成人电动自行车迷你轴传动电瓶车闪电发货 深空灰-汽车电芯无链条传动技术-6AH60公里
|
||||
</p>
|
||||
<div class="price">
|
||||
<i>¥</i>
|
||||
<span class="zheng">2998.<span class="ling">00</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'shangpin'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.shangpin{
|
||||
width: 190px;
|
||||
height: 266px;
|
||||
margin: 0 5px 8px;
|
||||
background: #fff;
|
||||
}
|
||||
.shangpin .spimg{
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin: 30px 0 0 28px;
|
||||
}
|
||||
.shangpin .jianjie{
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: left;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
height: 40px;
|
||||
}
|
||||
.shangpin .box{
|
||||
margin: 30px 15px 0 15px;
|
||||
}
|
||||
.shangpin .box .price{
|
||||
color: #e1251b;
|
||||
margin: 5px 0 0 0;
|
||||
}
|
||||
.shangpin .box .price i{
|
||||
vertical-align: middle;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
font-family: MicrosoftYahei-regular,Arial,Helvetica,sans-serif;
|
||||
}
|
||||
.shangpin .box .price .zheng{
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
font-family: arial,sans-serif;
|
||||
}
|
||||
.shangpin .box .price .ling{
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
122
vuenew/cli/demo/src/components/topjiesuan.vue
Normal file
@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="top-jiesuan">
|
||||
<span>全部商品</span>
|
||||
<div>
|
||||
<span>已选商品价格:</span>
|
||||
<span>{{sumprice.toFixed(2)}}</span>
|
||||
<button>结算</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="xian"></div>
|
||||
<div class="jsbiaotou">
|
||||
<div class="jsbtleft">
|
||||
<p>
|
||||
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" >全选</el-checkbox>
|
||||
|
||||
</p>
|
||||
<p>商品信息</p>
|
||||
</div>
|
||||
<div class="jsbtright">
|
||||
<p>单价</p>
|
||||
<p>数量</p>
|
||||
<p>金额</p>
|
||||
<p>操作</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'topjiesuan',
|
||||
props:{
|
||||
sumprice:Number
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
checkAll: false,
|
||||
isIndeterminate: true,
|
||||
checkedCities: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// handleCheckAllChange(val) {
|
||||
// this.checkedCities = val ? cityOptions : [];
|
||||
// this.isIndeterminate = false;
|
||||
// }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.top-jiesuan{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 10px 30px;
|
||||
}
|
||||
.top-jiesuan span:nth-child(1){
|
||||
color: #e2231a;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.top-jiesuan div span:nth-child(1){
|
||||
color: black;
|
||||
font-size: 15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.top-jiesuan div span:nth-child(2){
|
||||
color:#e2231a;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.top-jiesuan button{
|
||||
border-radius: 0;
|
||||
right: 0;
|
||||
width: 50px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
border: none;
|
||||
background-color: #e1251b;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
|
||||
}
|
||||
.top-jiesuan button:hover{
|
||||
background-color: #bd1108;
|
||||
}
|
||||
.xian{
|
||||
width: 95%;
|
||||
height: 1px;
|
||||
background-color:rgb(209, 208, 208);
|
||||
margin: 0 auto;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.jsbiaotou{
|
||||
padding: 10px 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
}
|
||||
.jsbiaotou .jsbtleft{
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
}
|
||||
.jsbiaotou .jsbtright{
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
margin-right: 50px;
|
||||
|
||||
}
|
||||
.jsbiaotou .jsbtleft p:last-child{
|
||||
margin-left: 50px;
|
||||
}
|
||||
.jsbiaotou .jsbtright p{
|
||||
margin-left: 100px;
|
||||
}
|
||||
.el-checkbox:checked .el-checkbox__label{
|
||||
color: #e2231a!important;
|
||||
}
|
||||
</style>
|
140
vuenew/cli/demo/src/components/tuijian.vue
Normal file
@ -0,0 +1,140 @@
|
||||
<template>
|
||||
|
||||
<div class="feed-tab-wrapper ">
|
||||
<ul class="feed-tab">
|
||||
<li :class="{active:active==index?'active':'',active1:active1==index?'active1':''}" label="精选 猜你喜欢" @click="active=index" @mouseenter="active1=index" @mouseleave="active1=null" aria-selected="true" v-for="(item,index) in tabs" :key="index">
|
||||
<div class="feed-tab__item-title">
|
||||
<span class="feed-tab__item-title-text">{{item.jingxuan}}</span>
|
||||
</div>
|
||||
<div class="feed-tab__item-desc">{{item.cainixihuan}}</div>
|
||||
<div class="feed-tab__item-gap" v-if='xiaoshi!=index' ></div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'tuijian',
|
||||
data(){
|
||||
return{
|
||||
xiaoshi:5,
|
||||
active:0,
|
||||
active1:null,
|
||||
|
||||
tabs:[
|
||||
{
|
||||
jingxuan:'精选',
|
||||
cainixihuan:'猜你喜欢',
|
||||
},
|
||||
{
|
||||
jingxuan:'智能先锋',
|
||||
cainixihuan:'大电器城',
|
||||
},
|
||||
{
|
||||
jingxuan:'居家优品',
|
||||
cainixihuan:'品质生活',
|
||||
},
|
||||
{
|
||||
jingxuan:'超市百货',
|
||||
cainixihuan:'百货生鲜',
|
||||
},
|
||||
{
|
||||
jingxuan:'时尚达人',
|
||||
cainixihuan:'美妆穿搭',
|
||||
},
|
||||
{
|
||||
jingxuan:'进口好物',
|
||||
cainixihuan:'京东国际',
|
||||
},
|
||||
|
||||
],
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
||||
|
||||
},
|
||||
mounted:{
|
||||
// if(this.xiangtong == 'active'){
|
||||
// active1=null;
|
||||
// }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.feed-tab-wrapper {
|
||||
background: #fff;
|
||||
margin: 0 auto ;
|
||||
|
||||
/* position: relative; */
|
||||
/* top: 70px;
|
||||
left: 12.5%; */
|
||||
width:74% ;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.feed-tab-wrapper .feed-tab {
|
||||
height: 60px;
|
||||
margin-left: 12px;
|
||||
|
||||
}
|
||||
.feed-tab-wrapper li {
|
||||
list-style: none;
|
||||
}
|
||||
.feed-tab-wrapper li {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 150px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.active .feed-tab__item-title-text {
|
||||
background: #e1251b;
|
||||
color: #fff!important;
|
||||
width: 70px;
|
||||
height: 27px;
|
||||
display: inline-block;
|
||||
border-radius: 50px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.active .feed-tab__item-desc {
|
||||
color: #e1251b;
|
||||
}
|
||||
.active1 .feed-tab__item-desc {
|
||||
color: #e1251b;
|
||||
}
|
||||
.active1 .feed-tab__item-title-text {
|
||||
color: #e1251b;
|
||||
}
|
||||
.feed-tab__item-desc {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
.feed-tab__item-title {
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 27px;
|
||||
}
|
||||
.feed-tab__item-gap {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 40px;
|
||||
margin: 10px 0;
|
||||
width: 1px;
|
||||
background: #dfdfdf;
|
||||
|
||||
}
|
||||
|
||||
</style>
|
17
vuenew/cli/demo/src/main.js
Normal file
@ -0,0 +1,17 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import ElementUI from 'element-ui';
|
||||
import 'element-ui/lib/theme-chalk/index.css';
|
||||
import router from './router'
|
||||
import axios from 'axios'
|
||||
import VueAxios from 'vue-axios'
|
||||
|
||||
Vue.use(ElementUI);
|
||||
Vue.use(VueAxios, axios);
|
||||
Vue.prototype.$axios = axios;
|
||||
Vue.config.productionTip = false;
|
||||
new Vue({
|
||||
el:'#app',
|
||||
router:router,
|
||||
render: h => h(App),
|
||||
})
|
325
vuenew/cli/demo/src/pages/gouwuche.vue
Normal file
@ -0,0 +1,325 @@
|
||||
<template>
|
||||
<div>
|
||||
<navbar1
|
||||
:logopangzi="logopangzi"
|
||||
:gouwuchenum="gouwuchenum"
|
||||
:loginmsg="loginmsg"
|
||||
></navbar1>
|
||||
<div class="gwccontent">
|
||||
<!-- <topjiesuan :sumprice=sumprice></topjiesuan> -->
|
||||
<div>
|
||||
<div class="top-jiesuan">
|
||||
<span>全部商品</span>
|
||||
<div>
|
||||
<span>已选商品价格:</span>
|
||||
<span>{{ sumprice.toFixed(2) }}</span>
|
||||
<button>结算</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="xian"></div>
|
||||
<div class="jsbiaotou">
|
||||
<div class="jsbtleft">
|
||||
<p>商品信息</p>
|
||||
</div>
|
||||
<div class="jsbtright">
|
||||
<p>单价</p>
|
||||
<p>数量</p>
|
||||
<p>金额</p>
|
||||
<p>操作</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-checkbox-group v-model="selected" @change="selectone">
|
||||
<gouwuchelist
|
||||
v-for="(shangpin, index) in shangpinlist"
|
||||
:shangpin="shangpin"
|
||||
:key="index"
|
||||
@xz="xuanzhong"
|
||||
></gouwuchelist>
|
||||
</el-checkbox-group>
|
||||
|
||||
<div class="bottom-jiesuan">
|
||||
<div class="js-right">
|
||||
<div class="js-right-right">
|
||||
<el-checkbox v-model="checkAll" @change="selectall"
|
||||
>全选</el-checkbox
|
||||
>
|
||||
<a href="">删除</a>
|
||||
<a href="">移入收藏夹</a>
|
||||
<a href="">分享</a>
|
||||
</div>
|
||||
<div class="js-right-left">
|
||||
<p>
|
||||
已选商品<span>{{ sumnum }}</span
|
||||
>件
|
||||
</p>
|
||||
<p>
|
||||
合计(不含运费):<span>{{ sumprice.toFixed(2) }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="js-left">
|
||||
<p>结算</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <bottomjiesuan :sumnum=sumnum :sumprice=sumprice class="bottomjiesuan"></bottomjiesuan> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import navbar1 from "../components/navbar1";
|
||||
// import topjiesuan from "../components/topjiesuan"
|
||||
import gouwuchelist from "../components/gouwuchelist";
|
||||
// import bottomjiesuan from "../components/bottomjiesuan"
|
||||
|
||||
export default {
|
||||
name: "gouwuche",
|
||||
data() {
|
||||
return {
|
||||
logopangzi: "购物车",
|
||||
gouwuchenum: 0,
|
||||
loginmsg: "返回首页",
|
||||
sumprice: 0.0,
|
||||
sumnum: 0,
|
||||
shangpinlist: [
|
||||
{
|
||||
dianpuname: "xxx店铺",
|
||||
shangpinname:
|
||||
"珊瑚绒睡衣女士春秋冬季长袖韩版法兰绒加厚可爱冬天家居服套装",
|
||||
yuanjia: 50.0,
|
||||
xianjia: 11.9,
|
||||
num4: 1,
|
||||
img: "1",
|
||||
ahrsf: "",
|
||||
canshulist: [
|
||||
{
|
||||
canshuname: "颜色分类",
|
||||
canshuvalue: "咖啡爱心",
|
||||
},
|
||||
{
|
||||
canshuname: "尺码",
|
||||
canshuvalue: "(170)xxl",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
dianpuname: "xxx店铺",
|
||||
shangpinname:
|
||||
"珊瑚绒睡衣女士春秋冬季长袖韩版法兰绒加厚可爱冬天家居服套装",
|
||||
yuanjia: 50.0,
|
||||
xianjia: 13.9,
|
||||
num4: 1,
|
||||
img: "2",
|
||||
ahrsf: "",
|
||||
canshulist: [
|
||||
{
|
||||
canshuname: "颜色分类",
|
||||
canshuvalue: "咖啡爱心",
|
||||
},
|
||||
{
|
||||
canshuname: "尺码",
|
||||
canshuvalue: "(170)xxl",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
dianpuname: "xxx店铺",
|
||||
shangpinname:
|
||||
"珊瑚绒睡衣女士春秋冬季长袖韩版法兰绒加厚可爱冬天家居服套装",
|
||||
yuanjia: 50.0,
|
||||
xianjia: 198.9,
|
||||
num4: 1,
|
||||
img: "",
|
||||
ahrsf: "",
|
||||
canshulist: [
|
||||
{
|
||||
canshuname: "颜色分类",
|
||||
canshuvalue: "咖啡爱心",
|
||||
},
|
||||
{
|
||||
canshuname: "尺码",
|
||||
canshuvalue: "(170)xxl",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
checkAll: false,
|
||||
selected: [],
|
||||
// cities: cityOptions,
|
||||
isIndeterminate: true,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
navbar1,
|
||||
// topjiesuan,
|
||||
gouwuchelist,
|
||||
// bottomjiesuan,
|
||||
},
|
||||
methods: {
|
||||
selectone(value) {
|
||||
console.log(value);
|
||||
// this.selected=[]
|
||||
// let checkedCount = value.length;
|
||||
// this.checkAll = checkedCount === this.cities.length;
|
||||
// this.isIndeterminate = checkedCount > 0 && checkedCount < this.cities.length;
|
||||
},
|
||||
xuanzhong(e) {
|
||||
console.log(e);
|
||||
// this.selected.push(e)
|
||||
},
|
||||
selectall(e) {
|
||||
console.log(e)
|
||||
if (e){
|
||||
for (let i in this.shangpinlist) {
|
||||
// this.selected[i]=this.shangpinlist[i].xianjia;
|
||||
this.selected.push(this.shangpinlist[i].xianjia)
|
||||
// this.zong = this.zong + this.shangpinlist[i].xianjia;
|
||||
}
|
||||
console.log(this.selected)
|
||||
// console.log(this.checkedlist);
|
||||
} else {
|
||||
this.selected=[]
|
||||
console.log(this.selected)
|
||||
// this.zong = 0;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.bottom-jiesuan {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 10px 0px;
|
||||
margin: 0 auto;
|
||||
background-color: #e5e5e5;
|
||||
width: 98%;
|
||||
height: 40px;
|
||||
}
|
||||
.js-right {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 90%;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.js-right a {
|
||||
margin-left: 30px;
|
||||
color: black;
|
||||
}
|
||||
.js-right a:hover {
|
||||
color: #e2231a;
|
||||
}
|
||||
.js-right-left {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
}
|
||||
.js-right-left p {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.js-right-left span {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #e2231a;
|
||||
margin: 0 5px;
|
||||
}
|
||||
.js-left p {
|
||||
/* margin-right: 20px; */
|
||||
line-height: 18px;
|
||||
font-size: 18px;
|
||||
color: white;
|
||||
margin: auto 0;
|
||||
margin-top: 12px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.js-left {
|
||||
background-color: #b0b0b0;
|
||||
width: 80px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.top-jiesuan {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 10px 30px;
|
||||
}
|
||||
.top-jiesuan span:nth-child(1) {
|
||||
color: #e2231a;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.top-jiesuan div span:nth-child(1) {
|
||||
color: black;
|
||||
font-size: 15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.top-jiesuan div span:nth-child(2) {
|
||||
color: #e2231a;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.top-jiesuan button {
|
||||
border-radius: 0;
|
||||
right: 0;
|
||||
width: 50px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
border: none;
|
||||
background-color: #e1251b;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
}
|
||||
.top-jiesuan button:hover {
|
||||
background-color: #bd1108;
|
||||
}
|
||||
.xian {
|
||||
width: 95%;
|
||||
height: 1px;
|
||||
background-color: rgb(209, 208, 208);
|
||||
margin: 0 auto;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.jsbiaotou {
|
||||
padding: 10px 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
}
|
||||
.jsbiaotou .jsbtleft {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
}
|
||||
.jsbiaotou .jsbtright {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
margin-right: 50px;
|
||||
}
|
||||
.jsbiaotou .jsbtleft p:last-child {
|
||||
margin-left: 50px;
|
||||
}
|
||||
.jsbiaotou .jsbtright p {
|
||||
margin-left: 100px;
|
||||
}
|
||||
.el-checkbox:checked .el-checkbox__label {
|
||||
color: #e2231a !important;
|
||||
}
|
||||
|
||||
.gwccontent {
|
||||
background-color: white;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.bottomjiesuan {
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
75
vuenew/cli/demo/src/pages/index.vue
Normal file
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div >
|
||||
<navbar1 class="navbar" :logopangzi='logopangzi' :gouwuchenum=gouwuchenum :loginmsg='loginmsg'></navbar1>
|
||||
<div class="zhankong"></div>
|
||||
<tuijian class="tuijian"></tuijian>
|
||||
<div class="shangpinlist">
|
||||
<shangpin class="shangpin"></shangpin>
|
||||
<shangpin class="shangpin"></shangpin>
|
||||
<shangpin class="shangpin"></shangpin>
|
||||
<shangpin class="shangpin"></shangpin>
|
||||
<shangpin class="shangpin"></shangpin>
|
||||
<shangpin class="shangpin"></shangpin>
|
||||
<shangpin class="shangpin"></shangpin>
|
||||
<shangpin class="shangpin"></shangpin>
|
||||
<shangpin class="shangpin"></shangpin>
|
||||
<shangpin class="shangpin"></shangpin>
|
||||
</div>
|
||||
<el-pagination class="fenye" background="#f10214" layout="prev, pager, next" :total="10"></el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import navbar1 from "../components/navbar1"
|
||||
import tuijian from "../components/tuijian"
|
||||
import shangpin from "../components/shangpin"
|
||||
|
||||
export default {
|
||||
name: 'index',
|
||||
data () {
|
||||
return {
|
||||
logopangzi: '',
|
||||
gouwuchenum:0,
|
||||
loginmsg:'注册/登录'
|
||||
}
|
||||
},
|
||||
components: {
|
||||
navbar1,
|
||||
tuijian,
|
||||
shangpin,
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body{
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.navbar{
|
||||
position: fixed;
|
||||
}
|
||||
.zhankong{
|
||||
height: 70px;
|
||||
}
|
||||
.tuijian{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.shangpinlist{
|
||||
width: 80%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.el-pagination.is-background .el-pager li:not(.disabled).active{
|
||||
background-color: #f10214;
|
||||
|
||||
}
|
||||
.fenye{
|
||||
margin: 50px 0 0 200px;
|
||||
}
|
||||
</style>
|
28
vuenew/cli/demo/src/router/index.js
Normal file
@ -0,0 +1,28 @@
|
||||
//配置路由相关的信息
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import index from '../pages/index'
|
||||
import gouwuche from '../pages/gouwuche'
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path:'/',
|
||||
redirect:'/gouwuche'
|
||||
},
|
||||
{
|
||||
path:'/index',
|
||||
component:index
|
||||
},
|
||||
{
|
||||
path:'/gouwuche',
|
||||
component:gouwuche
|
||||
},
|
||||
]
|
||||
|
||||
const router = new VueRouter({
|
||||
routes,
|
||||
})
|
||||
|
||||
export default router
|