CSS布局与定位

CSS布局与定位

题外话如果你想要一个高清的背景图你可以去 wallhaven

div的高度由谁决定(核心知识点)

div的高度由其内部文档流元素的高度总和决定

文档流是什么(核心知识点)

文档内元素的流动方向

  1. 如果你是一个内联元素,就是从左往右流动,如果宽度不够(流动遇到阻碍,它就换行继续从左往右)
1
2
3
4
5
6
<span>文字</span>
<span>文字</span>
<span>文字</span>
...
<span>文字</span>
<span>文字</span>
  1. 如果你是一个块级元素,就是从上往下,每个块级元素另起一行
1
2
3
4
5
6
7
<div>文字</div>
<div>文字</div>
<div>文字</div>
...
<div>文字</div>
<div>文字</div>
<div>文字</div>

如图

热干面的笑话

外语认为单词的不可分割性导致 老外学中文 “热干面” 他会连续的把字向英语单词一样读出来

答案是因为文化差异「haaaaaaaaaaaaaaaaa」 会被当作一个单词而不像汉字一样可以分开

你想分开它怎么办

1
span{word-break:break-all}

inline-block

想要块级元素 变成一行

本来可以float实现,但是很多人不会于是css3推出 inline-block

但是这是个触发很多问题的属性,会导致很多恶心的问题(建议float)

内联元素的高度由什么决定(很难很难的知识点)

这要从与前端不相关的问题说起

回忆起你上小学学汉语拼音的时候「四线谱」

你写汉字会中线对齐吗? 明显不会
你写第二行的时候你会紧贴着第一行吗?明显也不会(多少都会留一些空隙表示分割)

即使在我们知道了字有「建议行高」的存在,但是内联元素的高度仍然是不确定的

  • 因为不同字体设计的建议行高不同

结论就是:多个span在一起的时候,它的高度由字体建议行高最高的那个span决定

我们怎么避免内联元素这些奇怪的问题

假设需求是 span 16px 高度40px

1
2
3
4
5
6
7
8
9
10
11
<style>
span{font-size:16px;}
div{
line-height:24px;
padding:6px 0;
}
</style>

<div>
<span>你好</span>
</div>
  • 在font-size比较小的时候,可以用line-height控制
  • 建议设置的行高稍大于字体的大小

迫不得已的 height (最容易出bug的属性)

初学前端的你是不是经常看到设计图之后立刻一个 height:300px;

  • 一定不要写height,我们刚已经说了div的高度由其内部文档流元素的高度总和决定
  • 你上来一个 height:300px; 万一div里面文档流高度301你怎么办?

  • 不到情非得已千万不要写高度

脱离文档流

请问 .main的高度是多少? 300px

  1. div1 脱离了文档流
  2. .main的高度由其内部文档流元素的高度总和决定
1
2
3
4
<div class="main">
<div class="div1" style="position:fixed;height:40px;">222</div>
<div class="div2" style="height:300px"></div>
</div>

如果一个元素它是fixed定位,它的宽度就不会向外扩展

  • 如果你fixed的元素原来是宽度占满的,通常要设置 width:100%;

width:100%(bug的根源)

  • 如果你没什么事,千万不要加width:100%;

如果你fixed定位的元素有padding:20px; 再加上width:100%;那么它就比它爸爸的宽度还要大

div1的宽度已经比 main大了

1
2
3
4
<div class="main">
<div class="div1" style="position:fixed;height:40px;padding:20px;width:100%">222</div>
<div class="div2" style="height:300px"></div>
</div>

套路

  • 移除fixed元素的padding
  • 在fixed元素内部在包含一个div,让这个div有padding
1
2
3
4
5
6
<div class="main">
<div class="div1" style="position:fixed;height:40px;width:100%">
<div style="padding:20px;">222</div>
</div>
<div class="div2" style="height:300px"></div>
</div>

背景图自适应

1
2
3
4
5
div{
background-img:url(./img/aa.png);
background-position:center center;
background-size:cover;
}

宽度自适应

  • 不要写 width:1000px 这样你怎么拖拽网页它都是1000px

max-width:940px; 网页宽度小于940的时候它也跟着缩小

div水平居中的套路

1
2
3
4
div{
margin-left:auto;
margin-right:auto;
}

不接受宽高设置的 span

  • 因为span是内联元素(display:inline)设置宽高是无效的
  • 通常你要设置 display:inline-block

需求一个span 内容是 hello 宽70 高30你会怎么办

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*新手*/
span{
display:inline-block;
height:30px;
width:70px;
line-height:30px;
text-align:center;
}

/*老司机
1.先看不设置样式时hello会占据多少的宽高
2.经发现宽38px高22px
3.设置line-height:22px因为不同机器上字体表现的高度有所差异
*/
span{
display:inline-block;
padding:4px 16px;
line-height:22px;
}

css画三角形

  • border属性的使用
  1. 先画个带边框的盒子

    1
    2
    3
    4
    5
    div{
    border:10px solid red;
    height:50px;
    width:50px;
    }
  2. 给四个边框四个颜色

    1
    2
    3
    4
    5
    6
    7
    8
    9
    div{
    border:10px solid red;
    height:50px;
    width:50px;
    border-top-color:black;
    border-right-color:red;
    border-bottom-color:green;
    border-left-color:blue;
    }
  3. 把div高度和宽度设置为0,四个三角出现了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    div{
    border:10px solid red;
    height:0px;
    width:0px;
    border-top-color:black;
    border-right-color:red;
    border-bottom-color:green;
    border-left-color:blue;
    }
  4. 将上边框宽度设置为0

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    div{
    border:10px solid red;
    height:0px;
    width:0px;
    border-top-color:black;
    border-right-color:red;
    border-bottom-color:green;
    border-left-color:blue;
    border-top-width:0px;
    }
  5. 将其他方向的border颜色设置为透明

    1
    2
    3
    4
    5
    6
    7
    div{
    border:10px solid transparent;
    height:0px;
    width:0px;
    border-left-color:blue;
    border-top-width:0px;
    }

iconfont 字体图标的使用

iconfont

  1. 建议你先登录一下,有好几种那种都可以

  1. 搜搜你需要的图标然后添加购物车

  1. 点击购物车,添加新项目.如xxx

  1. 添加项目成功后,你可以看到如下内容

  1. 点击查看在线链接然后生成文件,然后引入到项目中,然后点击使用帮助对着文档抄

  1. 以下是步骤

以上步骤后你就可以使用 svg了

  • 如何控制svg的大小 height/width
  • 如何控制svg的背景色 fill
1
2
3
4
5
svg{
height:30px;
width:30px;
fill:#0089e1;
}

CSS

CSS (Cascading Style Sheets)

CSS历史

英文维基百科

凯斯kei丁(如果你实在不知道第一个咋读)注意!中文维基已经落后很久了

  1. 两个人合作发明了 CSS
    1994年哈肯·维姆·莱提出了CSS的最初建议。伯特·波斯(Bert Bos)当时正在设计一个叫做“Argo”的浏览器,他们决定一起合作设计CSS。

  2. W3C 开始接管 CSS
    1997年初,W3C内组织了专门管CSS的工作组,其负责人是克里斯·里雷。

  3. CSS 2.1
    1998年5月W3C发表了CSS2
    CSS2.1修改了CSS2中的一些错误,删除了其中基本不被支持的内容和增加了一些已有的浏览器的扩展内容。

  4. CSS 3
    从 2011 年开始 CSS 被分为多个模块单独升级,统称为 CSS 3。这些模块有:
    CSS 选择器 level 3
    CSS 媒体查询 level 3
    CSS Color level 3
    更多请 google 搜索 CSS spec 你可以看看

  5. CSS 4?
    不好意思,没有 CSS 4,只有各个模块的 level 4(每个功能独立写文档)

ps 文档很多 学海无涯生命有限,所以我们要先用在学,碰到了再去细究

周边工具

  • LESS CSS
    一种简化、功能更多的 CSS 语言 中文官网 英文官网
  • SASS
    一种简化、功能更多的 CSS 语言(请自行搜索中英文官网)
  • PostCSS
    一种 CSS 处理程序

建议是,先不要看周边工具,学好最朴素的 CSS,然后升级就很容易了。

CSS 学习资源

  1. Google: 关键词 MDN
  2. CSS Tricks( 「居中」搜索 center css tricks)
  3. Google: 阮一峰 css
  4. 张鑫旭的 240 多篇 CSS 博客
  5. Codrops 炫酷 CSS 效果
  6. CSS揭秘 (如果买书只推荐这一本,你买前端书千万别买中国人写的。。。)
  7. CSS 2.1 中文 spec
  8. Magic of CSS 免费在线书(如果你三天8h看完直接成为CSS大神)

建议是:中文学习资源只看大 V 的(毕竟他们要维护形象不能瞎写),英文资源看 CSS Tricks、MDN 和 Codrops。书的话作用不大,最权威的书其实是文档。

  • 如果你想快速上手,就先写小 demo 再学理论。
  • 如果你想一鸣惊人,就仔细看 CSS 规范文档。

开始写 CSS

  1. 引入 CSS 的三/四种方式
  2. 从最小的东西开始入手
  3. 逐渐变大
  4. 学会组织 CSS(以后再说)
  5. 自己写 CSS UI 库

引入CSS的四种方式

  1. 行间样式(内联样式)

    1
    <p style="color:red;"></p>
  2. style标签 (内嵌样式)

    1
    2
    3
    4
    5
    <head>
    <style>
    p{color:red;}
    </style>
    </head>
  3. link引入

    1
    <link href="mystyle.css" rel="stylesheet" type="text/css"/>
  4. import导入

    1
    <style type="text/css"> @import url(./b.css)</style>

li 的小圆点问题

1
li{list-style:none;}

默认样式

除了div和span其他所有标签都有默认样式(css一个问题就是要清除默认样式)具体你可以搜 base.css/reset.css

float 一定会出问题

如果你非要深究为什么那你就回答我为啥 color:red;字会变红

解决 float 的bug 业界已经同一有了一个规范就是 .clearfix

1
2
3
4
5
.clearfix::after{
content:'',
display:block;
clear:both;
}

口诀

  1. 子集浮动父级要清浮动(class=”clearfix”)
  2. 同级一个浮动其他都浮动

选择器 “>”加与不加的区别

直接子集

1
2
/* 匹配.topNavBar的儿子nav nav的儿子ul */
.topNavBar > nav > ul

默认字体大小 16px

工具使用

chrome ==> F12 ==>Elements==> styles/computed

a标签默认样式

text-decoration:underline

如果你实在不知道用法,搜索 mdn text-decoration

ul里li 鼠标滑过有边框的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
.clearfix::after{
content:'';
display:block;
clear:both;
}
ul{border:1px solid red;}
li{list-style:none;}
li{float:left; ;}
li:hover{border:1px solid red;}
</style>

<body>
<ul class="clearfix">
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
</body>

你会发现鼠标滑过的时候字在发抖

套路就是在li一开始就设置边框,只不过颜色是透明的

1
2
li{border:1px solid transparent;}
li:hover:{border:1px solid red;}

li里的a标签为什么有时候比li大

答案是因为a是 display:inline

1
2
3
4
5
a{display:block;}

<li>
<a href="javascrip:;">关于</a>
</li>

inherit 值啥意思

inherit意思是继承的意思就是你爸爸什么样你就继承过来

1
2
body{color:#333;}
a{color:inherit;}

如果你不写a{color:inherit;} a标签有默认样式就会是蓝色的

清除a的默认样式

1
a{color:inherit;text-decoration:none;}

span之间有什么

如果你回车了不管你空了多少行,span直接都会有一个空格

1
2
3
4
5
6
7
<span>aaa</span>



<span>bbb</span>
<span>ccc</span>
<span>ddd</span>

你应该这样

1
<span>aaa</span><span>bbb</span>

给你个需求

我需要一个 div 高30px,div 里有一行字垂直居中,字的大小为 14px,应该怎么写 CSS?

  • 给 div 的样式为 font-size: 14px; line-height: 20px; padding: 5px 0;
  • 给 div 的样式为 font-size: 14px; line-height: 24px; padding: 3px 0;
  • 给 div 的样式为 font-size: 14px; line-height: 30px;

HTML续2

HTML续

一些标签总结

跳转页面

  • a 发起get请求
  • form 发起post请求(默认get但是谁这么无聊)

回忆知识点:get是获取内容,post是上传内容

form 标签

  • 如果form 里没有提交按钮就无法提交,除非你用JS
  • method 请求方式(没人用get)只有两个值 get/post
  • action 请求路径
1
2
3
4
5
<form action="index2.html" method="post">
<input type="text" name="username">
<input type="text" name="password">
<input type="submit" value="提交">
</form>

如上你点击提交后我们在chrome里点击Network

如果提交的是中文,就把对应字符的UTF-8编码每个字节分开并加一个%

1
Content-Type: application/x-www-form-urlencoded

问题1 form 标签在哪些情况下可以被用户提交

  1. form 标签里面有一个 input type=submit 的元素
  2. form 标签里面有一个 button 元素,button 的 type 属性为空

详细讲一下第二种

form里存在一个button它会升级为提交按钮

1
2
3
4
<form action="index2.html" method="post">
<input type="text" name="username">
<button>提交</button>
</form>
  • 如果你添加了 type=”button” 就无法提交
1
<button type="button">提交</button>
  • 如果你是 input的button也是无法提交的
1
<input type="button" value="提交">

问题2 form 标签里面的 input 加不加 name 属性有什么区别?

如果 input 不加 name,那么在表单提交时,input 的值就不会出现在请求里

form与 a标签一样 也有target属性

行为同 a标签一样 具体看上一篇博客

  • _blank
  • _slef
  • _parent
  • _top

checkbox

问题1 有时候你想点击「免单」也会勾选此时发现无法勾选

  • 给input添加id=”xxx”
  • 给触发的文本套上 label标签并指定 for=”xxx”
1
2
3
4
5
<input type="checkbox">免单

<!-- 你应该这样 -->
<input type="checkbox" id="free">
<label for="free">免单</label>

老司机应该这样,直接用label把整体包起来

1
2
3
<label>账号<input type="text" name="username"></label>
<label>密码<input type="password" name="password"></label>
<label><input type="checkbox">免单</label>

问题2 如果是多个复选框

你应该让它们的name相同

1
2
3
4
<label><input type="checkbox" name="fruit" value="apple">苹果</label>
<label><input type="checkbox" name="fruit" value="banana">香蕉</label>

提交后参数会形如 fruit=apple&fruir=banana

radio 单选框

1
2
<label><input type="radio" name="gender" value="man">男</label>
<label><input type="radio" name="gender" value="woman">女</label>

select 下拉选

如果想多选请添加 multiple属性

1
2
3
4
5
<select name="local">
<option value=""></option>
<option value="1">北京</option>
<option value="2">天津</option>
</select>

textarea 文本域

  1. 默认它可以拖动的 要用style控制 resize:none;
  2. 建议用CSS控制它的宽高
  3. 它提供的cols和rows是不准的 列和行设置
1
<textarea name="" cols="30" style="resize:none;"rows="10"></textarea>

table 标签 (用的很少)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<table>
<thead>
<tr>
<th>姓名</th><th>班级</th>
</tr>
</thead>
<tbody>
<tr>
<td>hjx</td><td>1</td>
</tr>
<tr>
<td>aaa</td><td>2</td>
</tr>
</tbody>
<tfoot></tfoot>
</table>

table之慎用标签 colgroup col

之所以慎用,就因为2017年11月某天我知道它的用法然后就用了,结果导致一个bug(firefox里不支持这个标签#仅对应2017年11月那个我使用的firefox版本)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<table border=1>
<colgroup>
<col width=100>
<col width=200>
</colgroup>
<thead>
<tr>
<th>姓名</th>
<th>班级</th>
</tr>
</thead>
<tbody>
<tr>
<td>hjx</td>
<td>1</td>
</tr>
<tr>
<td>aaa</td>
<td>2</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>xxx</td>
<td>22</td>
</tr>
</tfoot>
</table>

PS建议控制 td 样式还是追随大众使用 class

thead tbody tfoot如果顺序错了会咋样

不管你怎样放置它们的顺序,即使F12里查到对应标签顺序是你写的顺序,但是浏览器会自动纠错依然会以thead tbody tfoot的顺序展现在表格上

不写thead/tfoot 会咋样

没有问题

不写tbody会咋样

它会自动帮你生成tbody 并把 tr放在里面

最后说一下默认表格设置了边框是很丑的,一般要设置边框融合

1
table{border-collapse:collapse}

HTML续

html一些标签总结

iframe

通常用来嵌套一个页面如百度

  • 它的宽高是由自己决定的,而且你只能设置宽度100%,高度100%是没用的(CSS蛋疼之处)
  • 如果你用iframe会明显感觉页面变卡了
  • 它一般会出现在五年前的项目里
  • frameborder=”0”是去除iframe的边框的(3d边框)
1
<iframe src="http://www.baidu.com" frameborder="0"></iframe>
iframe 和 a标签一起使用时会发生什么?
  • 给iframe 加上name属性 如name=”xxx”
  • 给a 加上target属性 如target=”xxx”
1
2
3
<iframe name="xxx" src="#" frameborder="0"></iframe>
<a target="xxx" href="http://www.baidu.com">百度</a>
<a target="xxx" href="http://www.qq.com">QQ</a>

这样页面上你点击「百度」iframe就会显示百度的网页,点击「QQ」就会显示qq的网页

iframe的src属性也可以写相对路径,包含页面

前提你至少得开一个本地服务

1
<iframe src="./index2.html" frameborder="0"></iframe>

a 标签

我们分别写四个target它们都会在哪里打开呢?

建立如下文件

index3.html

1
2
3
4
5
index3页面
<a target="_blank" href="http://www.baidu.com">百度</a>
<a target="_self" href="http://www.qq.com">QQ</a>
<a target="_parent" href="http://www.jd.com">京东</a>
<a target="_top" href="http://www.taobao.com">淘宝</a>

index2.html

1
2
index2页面
<iframe src="./index3.html" frameborder="0"></iframe>

index.html

1
2
index页面
<iframe src="./index2.html" frameborder="0"></iframe>

你可以 http-server的工具

1
2
3
4
#全局安装
npm install http-server -g
#开启本地服务
http-server -c-1
  • _blank 会新开一个窗口打开
  • _self 会在自己页面打开,如上结果会在index3页面打开
  • _parent 会在父页面打开,如上结果会在index2页面打开
  • _top 会在顶级窗口打开, 如上结果会在index页面打开
a标签之 download 属性

download可以下载东西,可能是安装包可能是网页

  • 如果不加download
    服务器要设置 Content-Type:application/octet-stream

  • 加了 download 就可以直接下载

1
<a  href="http://www.qq.com" download>下载</a>
a标签纸 href属性

只写qq.com会跳转到 qq.com的网页吗? 不会

因为这是一个相对地址

比如你在命令行里 touch 1.txt / open 1.txt 都是相对当前命令行的目录执行的

1
<a  href="qq.com">qq</a>

修改 href=”//qq.com”

代表以当前协议打开

  • 如果你是一个本地文件打开是文件协议 file协议

  • 如果你想打开qq.com的网页,你需要以http协议打开

那么你要下载一个 http-server 的工具,这样就能本地开一个node服务

1
2
3
4
#全局安装
npm install http-server -g
#开启本地服务 -c-1代表不要缓存
http-server -c-1
href=”//qq.com”是 无协议绝对地址自动继承协议
href=”xxx.html” 相对路径
  • A /index.html/xxx.html
  • B /xxx.html √
href=”?name=hjx”
  • A 保存
  • B 这样很自然 √ 如果你点击会发起get请求并把参数拼接到当前url上
href=”#sss” 锚点是不发请求了
href=”javascript:;” 伪协议

一些问题

1
2
3
4
5
<a href="">link</a> 标签被点击后会发生什么?
当前页面刷新

<a href="/..">link</a> 标签被点击后会发生什么?
浏览器发起 GET / HTTP/1.1请求

我想写一个a标签,但是点击之后不要跳转

  • 写#(锚点) 页面会动
  • 不写href属性 a就跟span一样了
  • 伪协议 href=”javascript:;”

HTML

HTML Hypertext Markup Language

维基百科HTML

HTML 的版本(W3C 组织制定规范)

  • HTML 4.01
  • XHTML
  • HTML 5 √(我们从这里开始学)
  • HTML 5.1

规范文档(Specifications)

你可以google 搜 html spec 这个网址

  1. 由 W3C 写文档(李爵士)
  2. W3C 根据浏览器的实际情况总结文档,并不是凭空想象

    DOCTYPE 文档头

html / head / body

head可省略吗? body可省略吗? 可以

省略标签

常见标签:a、form、input、button、h1、p、ul、ol、small、strong、div、span、kbd、video、audio、svg

  • 基本上,你知道标签对应单词的意思,就知道这个标签怎么用了(语义化)
  • 除了 div 和 span,其他标签都有默认样式
  • MDN 上有所有标签的文档

如何查看 MDN 文档

Google:关键词 + MDN

HTML 中 b 标签和 strong 标签有什么区别

b 表示样式上的加粗,strong 是逻辑状态表示内容重要。strong表示语气很强烈含有感情成分

p 标签的英文全称是什么?

paragraph

a 标签的英文全称是什么

anchor

什么是空元素

1
input/img/meta/link/hr/br/col....

空元素

HTML5推荐写法

1
2
3
4
5
<-- 更加严格的写法要自闭合 -->
<input type="text"/>

<-- H5推荐的用法 -->
<input type="text">

div span 可以写在head里吗?

答案是不可以,但是你写了HTML会自动纠错将你写的div放到body里

可替换元素

可替换元素

w3cschool html测试题

测试题

HTML究竟要不要管元素是不是块级元素还是内联元素

  • HTML是不管块级元素和内联元素的区别的
  • HTML只定义这是什么,不管样式
  • 样式由CSS控制

所以写HTML时候一定不要想样式问题

写页面千万别自己设计

你可以去 dribbble.com 你可以看到外国优秀设计师的作品

如果你要psd,就搜索 webpage free psd

初学HTML时写页面你可能会这样想

想着上面两个一左一右下面是一个盒子

实际上这样的布局是很难实现的因为目前
CSS只支持横向布局和纵向布局

实际应该这样

实际上应该上面两个左右的盒子外面包一个div当做一个整体

网络_ip_server

打电话是如何运作的

1.将你的”音波”变成”电波”–调制器
2.电波传递到电话的另一边
3.电话那头将你的”电波”变成”音波”–解调器

网络与IP

http(控制书写内容的)协议是建立在TCP(传输协议)和IP(控制连接)协议的基础之上的

TCP 传输控制协议(Transmission Control Protocol)

面试要点

  1. TCP 和 UDP 的区别是什么
    简答:TCP 可靠、面向连接、相对 UDP 较慢;UDP 不可靠,不面向连接、相对 TCP 较快。搞定。

    1. TCP 的三次握手指的是什么
      简答:每次建立连接前,客户端和服务端之前都要先进行三次对话才开始正式传输内容,三次对话大概是这样的:
    1
    2
    3
    4
    1. 客户端:我要连接你了,可以吗
    2. 服务端:嗯,我准备好了,连接我吧
    3. 客户端:那我连接你咯。
    4. 开始后面步骤
  1. 上面内容足以应付前端面试中关于 TCP 的考题 :)

如果你想更了解 TCP 可以看 此文,也可以买一本《TCP/IP 详解(卷一)》(共三卷,先只买一卷即可)。

不过再强调一遍,这不是前端的内容,以后的课程中我也不会再对 TCP 有任何涉及,你只需稍微了解一下 TCP 即可。

IP 网络协议(英语:Internet Protocol)

只要你在互联网中,那么你就会有一个 IP。通俗上理解,IP 分为「内网 IP」 和「外网 IP」,以下图为例:
示意图

  • 你从电信那里买来带宽,一年一千多。
  • 电信为你提供 DNS 服务。
  • 你买了一个路由器,然后用电脑和手机分别连接路由器广播出来的无线 WIFI。
  • 只要路由器连上电信的服务器,那么路由器就会有一个「外网 IP」,比如「14.17.32.211」就是一个外网 IP。这就是你在互联网中的地址。
  • 但是如果你重启路由器,那么你很有「可能」被重新分配一个「外网 IP」,也就是说 你的路由器没有「固定的外网 IP」
  • 你可以花每年几千块钱租用一个「固定的外网 IP」,但是显然不会这么浪费钱。像腾讯、阿里这样的大公司租用了很多外网 IP,这样才能对我们提供稳定的服务。
  • 但是有个问题,你的路由器的外网 IP 如果是14.17.32.211,那么你的手机和电脑的 IP 又是什么呢?答案是「内网 IP」
  • 路由器会在你家里创建一个内网,内网中的设备使用内网 IP,一般来说这个 IP 的格式都是 192.168.xxx.xxx。
    • 一般路由会给自己分配一个好记的内网 IP,如 192.168.1.1
    • 然后路由会给每一个内网中的设备分配一个不同的内网 IP,如电脑是 192.168.1.2,手机是 192.168.1.3,以此类推。
    • 现在路由器有两个 IP,一个外网 IP(14.17.32.211)和一个内网 IP(192.168.1.1)
      • 内网中的设备可以互相访问(比如你可以用电脑或手机进入 http://192.168.1.1 来查看你的路由器),但是不能直接访问外网,内网设备想要访问外网,就必须经过路由器中转。
      • 外网中的设备可以互相访问(比如 qq.com 可以把首页发送给你的路由器,你的路由器有外网 IP),但是外网中的设备无法访问你的内网设备(这很好理解,内网是一个封闭的网络,外人进不来,所以实际上 qq.com 无法直接把首页放送给你的电脑和手机)
        • 问题来了,那 qq.com 是怎么把首页发送到我的手机上的呢?答案是通过路由器来中转。
        • 路由器接收到 qq.com 的页面后,把页面发送给你的电脑或手机。路由器知道如何给这些信息指路,路由器就是一个指路人,这就是「路由」两个字的来历。
        • 路,就是「必由之路」中的路。由,就是「必由之路」中的由(由是经过、缘由的意思)。所有的信息都要经过路由器,然后被指向一条它该去的路。
      • 也就是说内网和外网就像两个隔绝的空间,无法互通,唯一的联通点就是路由器(因为路由器既有外网 IP 也有内网 IP),所以路由器有时候也被叫做「网关」,这个「关」是「一夫当关,万夫莫开」的「关」。如果路由器到电信的连接中断了,那么内网中所有的设备也就无法上网了。(这很好理解,相当于唯一一条出去的路断了)
  • 除了内网 IP 和外网 IP,还有两个特别特殊的 IP,就是本地 IP:127.0.0.1。本地 IP 永远表示设备自己。不信你可以 ping 127.0.0.1 一下,会发现只需要 0.01 ms 就得到了响应(你 ping qq.com 需要几十毫秒才得到响应)
    • 默认情况下,hosts 文件里会有一行127.0.0.1 localhost,意思就是 localhost 指向 127.0.0.1,所以 localhost 也表示设备自己。不信你 ping localhost 试试,会发现实际上是在 ping 127.0.0.1
  • 还有一个特别特殊的 IP:0.0.0.0,它不表示任何设备。这个 IP 不同的地方含义不同,以后我们会用到,用到的时候再说意思。

内网之间可以相互访问
外网之间可以相互访问
内网和外网不可相互访问
内网想要与外网互相访问必须有一个路由器
路由器的主要功能就是内容分发
0.0.0.0 不表示任何设备 它是一个不该使用的IP
127.0.0.1 表示本机
localhost 表示本机

端口

你想要访问一个设备(前提是你使用的是 TCP 或 UDP 协议。还记得吗,HTTP 就使用了 TCP),只指定 IP 是不够的,还必须指定端口(Port)。

端口其实就是一个编号,并不是一种硬件。

一个服务器(硬件)不一定只提供一种服务,比如一个服务器既提供 HTTP 服务,又提供 FTP 服务,还提供 SMTP 服务(邮件服务),那么只用一个 IP 是无法告诉服务器你想要使用哪种服务。

所以这里有一个重要的原则:一个端口对应一个服务。

比如

  1. 要提供 HTTP 服务你最好使用 80 端口(能不能使用别的端口?可以,不过不建议你违反约定)
  2. 要提供 HTTPS 服务你最好使用 443 端口(能不能使用别的端口?可以,不过不建议你违反约定)
  3. 要提供 FTP 服务你最好使用 21 端口(能不能使用别的端口?可以,不过不建议你违反约定)

问题1:我怎么知道应该使用什么端口?

维基百科 把 0 到 1023 号端口对应的服务都告诉你了,点进去看看吧。

问题2:一共有多少端口?

每个机器一共有 65535(2的16次方减1)个端口(这是协议规定的)。不过这些端口的使用由一些规定

  1. 0 到 1023(2的10次方减1)号端口是留给系统使用的,你只有拥有了管理员权限后,才能使用这 1024 个端口。
  2. 其他端口可以给普通用户使用
  3. 如果一个端口正在提供服务,也就是被占用了,那么就不能再使用这个端口。除非你先停掉正在占用这个端口的服务。以后你们会经常遇到这个问题。

总结

上面都是 TCP/IP 相关的知识,如果你记不住,就记住下面这句话:

使用 HTTP 协议访问另一个 IP 时,必须同时提供 IP 和端口号,缺一不可。

那么问题来了

我访问http://qq.com时并没有提供端口号,为什么我依然可以访问

答:因为浏览器帮你加了默认端口号 80。

HTTP入门

www(World Wide Web)

主要有三个概念

  • URI 俗称网址
  • HTTP 两台电脑之间的传输协议
  • HTML 超文本标记语言,用于页面跳转
    URL的作用是让你访问一个网页,HTTP的作用是让你能下载这个页面,HTML是让你能看懂这个网页。

URI 是什么(统一资源标识符)

URI分为两种URL(统一资源定位符)和URN(统一资源名称)

URN

ISBN:9934123123123 书号,这就是一个URN 可以确定一个”唯一的”资源

URL

https://www.baidu.com/s?wd=hello&rev_spt=1#5

  • https代表–协议
  • www.baidu.com 代表–域名
  • /s代表–路径
  • wd=hello&rev_spt=1代表–查询参数
  • “#5” 代表–锚点

.com代表一级(顶级)域名 baidu代表二级域名 www是三级域名

但是一般的工程师都会把.com忽略掉,把baidu叫做一级域名 此时要脑补他说的是错的

URL的常见组成

DNS 域名解析器

命令行里输入 nslookup www.baidu.com就可以看见这个网址对应服务器相关信息

1
2
3
4
5
6
7

Server: 192.168.5.1
这个是我的路由(他去问的电信,电信帮你解析网址对应的ip电信为什么知道你花钱啦)
Address: 192.168.5.1#53

Name: www.baidu.com
Address: 119.75.213.61 这个服务器告诉你百度的ip 每个人返回的IP不一样

dns会根据一个域名返回一个ip
那我可以不可以指定一个ip(可以)这就是如何绕过dns自己指定一个ip
非常时期可以修改host文件(window系统)自己指定google的ip
因为电信返回的ip是错的。

示意图

http

示意图

curl 命令

1
curl -s -v -H "hjx:xxx" -- "https://www.baidu.com"
  • -s代表不显示进度
  • -v代表显示请求和响应
  • -H “hjx:xxx” 添加一个请求头
  • – ‘https://www.baidu.com ‘ 代表要请求的网址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
* Rebuilt URL to: https://www.baidu.com/
* Trying 119.75.216.20...
* TCP_NODELAY set
...
* SSL certificate verify ok.

> GET / HTTP/1.1 "/"代表根目录 HTTP/1.1代表协议和版本号
> Host: www.baidu.com 就是访问的域名
> User-Agent: curl/7.55.1 我用的什么软件发起的响应
> Accept: */* 我接受你返回给我的任何内容
> hjx:xxx 可以删掉没有任何意义 删除 - H参数就可以
>

< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
< Connection: Keep-Alive
< Content-Length: 2443
< Content-Type: text/html
< Date: Tue, 02 Jan 2018 15:44:59 GMT
< Etag: "588603ec-98b"
< Last-Modified: Mon, 23 Jan 2017 13:23:56 GMT
< Pragma: no-cache
< Server: bfe/1.0.8.18
< Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
<
* Connection #0 to host www.baidu.com left intact
  • *开头的代表注释
  • “>” 代表请求内容
  • ”<“ 代表响应内容

重新修改请求

1
curl -X POST -s -v -H "hjx:xxx" -- "https://www.baidu.com"

请求的内容为

1
2
3
4
5
POST / HTTP/1.1
Host: www.baidu.com
User-Agent: curl/7.54.0
Accept: */*
hjx: xxx

继续修改

1
curl -X POST -d "1234567890" -s -v -H "hjx: xxx" -- "https://www.baidu.com"

1
2
3
4
5
6
7
8
9
POST / HTTP/1.1
Host: www.baidu.com
User-Agent: curl/7.54.0
Accept: */*
hjx: xxx
Content-Length: 10 代表上传数据的字节
Content-Type: application/x-www-form-urlencoded 上传的格式

1234567890

get和post的区别

  • get就是获取内容
  • post就是上传内容

    疑问

    1
    2
    curl -s -v -H "host:www.qq.com" -- "https://www.baidu.com" 修改访问的域名
    相当于你去麦当劳问有没有老北京鸡肉卷

请求的格式

  1. 动词 路径 协议/版本 第一部分路径随便写 一定要以”/“开头
  2. 第二部分 键值对
    • Key1: value1
    • Key2: value2
    • Key3: value3
    • Content-Type: application/x-www-form-urlencoded
    • Host: www.baidu.com
    • User-Agent: curl/7.54.0
  3. 回车 就一个目的区分 第二部分和第四部分
  4. 要上传的数据

请求包含的内容

  1. 请求最多包含四部分,最少包含三部分。(也就是说第四部分可以为空)
  2. 第三部分永远都是一个回车(\n)
  3. 动词有 GET POST PUT PATCH DELETE HEAD OPTIONS 等

    • PUT 代表 五行话替换成一行 整体更新
    • PATCH 代表 五行话里其中一行替换 一行 局部更新
    • DELETE 删除
  4. 这里的路径包括「查询参数」,但不包括「锚点」

  5. 如果你没有写路径,那么路径默认为 /
  6. 第 2 部分中的 Content-Type 标注了第 4 部分的格式

    x-www-form-urlencoded

  • x 代表没有被写入规范的格式
  • www 万维网
  • urlencoded 解析中文

用 Chrome 查看响应

  1. 打开 Network
  2. 输入网址
  3. 选中第一个响应
  4. 查看 Response Headers,点击「view source」,点击「view source」,点击「view source」
  5. 你会看到响应的前两部分
  6. 查看 Response 或者 Preview,你会看到响应的第 4 部分

http 和https

http是明文传输 就是你的登录密码,别人可以看到不是加密的

https 就是 密码这些东西是经过加密的 无法直接看到内容

响应

请求了之后,应该都能得到一个响应,除非断网了,或者服务器宕机了。

响应示例
上面三个请求示例,前两个请求对应的响应分别为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: Keep-Alive
Content-Length: 2443
Content-Type: text/html
Date: Tue, 10 Oct 2017 09:14:05 GMT
Etag: "5886041d-98b"
Last-Modified: Mon, 23 Jan 2017 13:24:45 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/

<!DOCTYPE html>
<!--STATUS OK--><html> <head> 后面太长,省略了……
HTTP/1.1 302 Found
Connection: Keep-Alive
Content-Length: 17931
Content-Type: text/html
Date: Tue, 10 Oct 2017 09:19:47 GMT
Etag: "54d9749e-460b"
Server: bfe/1.0.8.18

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"> 后面太长,省略了……

GET 请求和 POST 请求对应的响应可以一样,也可以不一样
响应的第四部分可以很长很长很长
响应的格式

1
2
3
4
5
6
7
1. 协议/版本号 状态码 状态解释
2. Key1: value1
2. Key2: value2
2 Content-Length: 17931
2 Content-Type: text/html
3
4 要下载的内容

状态码要背,是服务器对浏览器说的话

1
2
3
4
5
6
7
8
9
10
11
12
1xx 不常用
2xx 表示成功
3xx 表示滚吧
4xx 表示你丫错了
5xx 表示好吧,我错了
200 一般的成功
204 创建成功 一般post返回204
301 表示你访问的资源已经不在了 迁移到其他域名返还给你新的地址
302 表示你访问的资源只是临时不在了 敏感信息封禁了一段时间
304 表示你访问的内容和上一次一样,返回上一次的内容
404 未找到页面 网址错了
502 服务器挂了
1
2
3
4
5
6
7
8
9
10
状态解释没什么用
第 2 部分中的 Content-Type 标注了第 4 部分的格式
第 2 部分中的 Content-Type 遵循 MIME 规范
用 Chrome 查看响应
打开 Network
输入网址
选中第一个响应
查看 Response Headers,点击「view source」,点击「view source」,点击「view source」
你会看到响应的前两部分
查看 Response 或者 Preview,你会看到响应的第 4 部分

简单脚本的编写

实现如下目标

如下命令你应该看得懂

1
2
3
4
5
cd ~/Desktop
mkdir demo
cd demo
echo "hi" > index.html
cd ~/Desktop

脚本就是给计算机照着做的。这是我们对「脚本」的一个感性认识。接下来我们写一个脚本。

写一个脚本

  1. 找个地方新建文件,后缀随意,一般来说脚本的后缀是 .sh。我喜欢把脚本放在 ~/local 目录里。(我知道你没有这个目录,创建这个目录不就行了)
    1. mkdir ~/local
    2. cd ~/local
    3. touch demo.txt
  2. 编辑 demo.txt,内容如下:

    1
    2
    3
    4
    5
    mkdir demo
    cd demo
    mkdir css js
    touch index.html css/style.css js/main.js
    exit
  3. (Windows 用户请跳过这一步)给 demo.sh 添加执行权限

    chmod +x demo.txt

  4. 在任意位置执行

    sh ~/local/demo.txt

    即可运行此脚本

    1. cd ~/Desktop
    2. sh ~/local/demo.txt
    3. 你会看到当前目录里多出一个 demo 目录,demo 目录里面还有一些文件
      好了,这个 demo.txt 就是你写出的第一个 Bash 脚本了。
  5. 将 ~/local 添加到 PATH 里

    1. cd ~/local; pwd

      得到 local 的绝对路径

    2. 创建 ~/.bashrc:touch ~/.bashrc
    3. 编辑 ~/.bashrc:start ~/.bashrc,在最后一行添加

      export PATH="local的绝对路径:$PATH"

    4. source ~/.bashrc
    5. 之前你要运行

      sh ~/local/demo.txt,现在你只需要运行 demo.txt 就行了(想想为什么,道理显而易见)

  6. demo.txt 的后缀 .txt 很无聊,删掉它

    1. mv ~/local/demo.txt ~/local/demo
    2. 现在你只要运行

      demo

      就能执行该脚本了。

细节

  1. PATH 的作用
    你每次在 Bash 里面输入一个命令时(比如 ls、cp、demo),Bash 都会去 PATH 列表里面寻找对应的文件,如果找到了就执行。
  2. 使用 type demo 可以看到寻找过程
  3. 使用 which demo 可以看到寻找结果
  4. 文件后缀的作用:毫无作用
    你以为一个文件以 .exe 结尾就一定可以双击吗?你以为一个文件以 .png 结尾就一定是图片吗?图样图森破!

参数

demo 脚本只能创建名字为 demo 的目录,太无聊了,我们让目录名是可变的吧。

1
2
3
4
5
mkdir $1
cd $1
mkdir css js
touch index.html css/style.css js/main.js
exit

$1 表示你传的第一个参数。

老师你怎么知道 $1 表示第一个参数?

好问题,答案是

我 Google 出来的

http://lmgtfy.com/?q=bash+first+param
用百度也行

http://www.baidu-x.com/?q=bash+%E7%AC%AC%E4%B8%80%E4%B8%AA+%E5%8F%82%E6%95%B0

判断目录是否已存在

1
2
3
4
5
6
7
8
9
10
11
if [ -d $1 ]; then
echo 'error: dir exists'
exit
else
mkdir $1
cd $1
mkdir css js
touch index.html css/style.css js/main.js
echo 'success'
exit
fi

你怎么知道 -d $1 可以判断目录是否存在?

我 Google 出来的

http://lmgtfy.com/?q=bash+dir+exists

返回值

  • exit 0

    表示没有错误

  • exit 1

    表示错误代码为 1

1
demo && echo '结束'

只有在 demo 成功时,才会执行

echo '结束'

Node.js 写脚本

上面我们写的脚本叫做 Bash Script(Bash脚本)。

JS 的全称叫做 JavaScript(Java脚本),虽然 JS 和 Java 没什么关系,但是 JS 依然是一种脚本。

  1. 我们在 Bash 命令行里输入 Bash 命令,也可以在 Node.js 命令行里输入 JS 命令(Ctrl + D 退出)
  2. Bash 脚本能做的事情,JS 脚本也能做。(sh demo.sh

    对应

    node demo.js

用 JS 切换目录

1
2
3
4
console.log(process.cwd()) // 打印当前目录
// process.chdir('~/Desktop'); // 这句话不行的,因为 JS 不认识 ~ 目录
process.chdir("/Users/frank/Desktop")
console.log(process.cwd()) // 打印当前目录

console.log 就相当于 echo

用 JS 脚本创建目录

Google nodejs create dir

文档:https://nodejs.org/api/fs.html#fs_fs_mkdirsync_path_mode

1
2
let fs = require("fs")
fs.mkdirSync("demo")

用 JS 脚本创建文件

Google nodejs create file

文档:

https://nodejs.org/api/fs.html#fs_fs_writefilesync_file_data_options

1
2
let fs = require('fs')
fs.writeFileSync("./index.html", "")

用 JS 脚本来重写 demo.sh

  1. 创建 ~/local/jsdemo.js,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var fs = require('fs')

    var dirName = process.argv[2] // 你传的参数是从第 2 个开始的

    process.chdir("/Users/frank/Desktop") // cd ~/Desktop
    fs.mkdirSync("./" + dirName) // mkdir $1
    process.chdir("./" + dirName) // cd $1
    fs.mkdirSync('css') // mkdir css
    fs.mkdirSync('js') // mkdir js

    fs.writeFileSync("./index.html", "")
    fs.writeFileSync("css/style.css", "")
    fs.writeFileSync("./js/main.js", "")

    process.exit(0)
  2. (Windows 用户跳过这一步)给 jsdemo.js 加上执行权限

    chmod +x ~/local/jsdemo.js

  3. cd ~/Desktop
  4. node ~/local/jsdemo.js zzz,就可以看到 zzz 目录创建成功了

shebang

我们每次执行 ~/local/jsdemo.js 都要用 node 来执行,能不能做到不加 node 也能执行呢(也就是指定执行环境),可以,在 jsdemo.js 第一行加上这一句即可:

1
#!/usr/bin/env node

(以下操作在 Windows 上可能失败,失败了就算了)

  1. 然后你就可以直接用

    ~/local/jsdemo.js zzz

    了(省得输入 node 了)。

  2. 如果你已经把 ~/local 加入了 PATH,那么甚至可以直接输入

    jsdemo.js zzz

    来执行。

  3. 如果你再把 jsdemo.js 的后缀 .js 去掉,就可以直接

    jsdemo zzz

    了。

注意,你每次执行前最好删掉 zzz 目录,以免发生冲突。

脚本

理解脚本

如果你打开一本 JavaScript 教程,那么很可能在第一章就看到这句话:

JavaScript 是一门动态类型、面向对象的脚本语言。

然而很多工作一年都不清楚这个脚本是什么意思。

其实脚本原本来自戏剧舞台,比如下面这个脚本:

公馆一室内
王妈:(小心翼翼地)小姐,您还是得注意身子,就吃点东西吧。
鸡小姐:(把碗砸在地上)不吃,我就是不吃。
(王妈下)

脚本主要由人物对话和舞台提示组成。演员和道具组只需要按照脚本说的做即可。

编程领域的脚本也是类似的,计算机只要照着脚本上说的做即可,比如下面这个脚本:

1
2
3
4
5
cd ~/Desktop
mkdir demo
cd demo
echo "hi" > index.html
cd ~/Desktop

所以说,脚本就是给计算机照着做的。这是我们对「脚本」的一个感性认识。接下来我们写一个脚本。

自己写一个脚本

默认你在window下并且安装了gitbash

  1. 第一步
1
2
3
cd ~/local   //切换到用户目录下的 local目录
touch demo.txt //新建一个txt文件 后续我们会改为.sh文件因为linux里sh后缀打开会认为是执行程序
open demo.txt //window不支持 如果你会vim 可以vi demo.txt 不然你就双击好了
  1. 打开demo.txt后编辑
1
2
3
4
5
mkdir demo
cd demo
mkdir css js
touch index.html css/style.css js/main.js
exit
  1. 修改后缀为.sh(如果是非window 要添加可执行权限 chmod +x demo.sh)
1
mv demo.txt demo.sh
  1. 执行脚本,然后查看对应目录会有一个demo文件夹里面会有js css index.html
1
sh ~/local/demo.sh

path是什么

  • 你每次在 Bash 里面输入一个命令时(比如 ls、cp、demo),- Bash 都会去 PATH 列表里面寻找对应的文件,如果找到了就执行。
  • 使用 type demo 可以看到命令寻找过程
  • 使用 which demo 可以看到命令寻找结果
  • 文件后缀的作用:毫无作用

你以为一个文件以 .exe 结尾就一定可以双击吗?你以为一个文件以 .png 结尾就一定是图片吗?图样图森破!

jQuery_HelloWorld

What is jQuery?

jQuery is a fast, small, and feature-rich JavaScript library.

ready()

1
2
3
$(document).ready(function() {
//逻辑处理
});

ready() 的作用是等页面的文档(document)中的节点都加载完毕后,再执行后续的代码,因为我们在执行代码的时候,可能会依赖页面的某一个元素,我们要确保这个元素真正的的被加载完毕后才能正确的使用。

原生JS 和 jQ

1
2
3
4
5
6
7
8
9
10
11
12
window.onload = function(){
var p = document.getElementById('#xxx');
p.innerHTML = 'hello 我是原生方式操作dom';
p.style.color = 'red';
}
.....
// jquery

$(document).ready(function(){
var $p = $('#yyy');
$p.html('hello 我是jqery方式操作dom').css('color','red');
})

通过jQuery方法包装后的对象,是一个类数组对象。它与DOM对象完全不同,唯一相似的是它们都能操作DOM。

dom对象和 jq对象相互转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div></div>
<div></div>
<div></div>
...
// 返回一个类数组对象 包含三个div的jq对象
var $div = $('div');
// 转换为原生对象
var oDiv = $div[0]
oDiv.style.color = 'red';

//也可以使用get(索引) 转换成dom对象
var oDiv2 = $div.get(1);

... dom对象转 jq对象
//getElementsByTagName() 返回的是一个集合,dom对象数组 三个div
var aDiv = document.getElementsByTagName('div');
// 转换jq对象只需要这样
var $div = $(aDiv)
$div.first().css('background','red');

id选择器

1
2
3
<div id="oDiv"></div>
//注意 id是唯一的 如果存在多个相同id的元素 ,则只返回第一个dom元素
$('#oDiv')

class选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="xxx"></div>
<div class="xxx"></div>
<div class="xxx"></div>
...
//通过原生方法处理
//样式是可以多选的,所以得到的是一个合集
//需要通过循环给合集中每一个元素修改样式
var aDiv = document.getElementsByClassName('xxx');
for (var i = 0; i < aDiv.length; i++) {
aDiv[i].style.border = "3px solid blue";
}
-------------------------------------------------
//通过jQuery直接传入class
//class选择器可以选择多个元素
$(".xxx").css("border", "3px solid red");
//$(".xxx").css()方法内部肯定是带了一个隐式的循环处理

标签选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="xxx"></div>
<div class="xxx"></div>
<div class="xxx"></div>
....

//通过原生方法处理
//获取到所有的节点标记名为div的元素
//给每一个div加上蓝色的边框
var aDiv = document.getElementsByTagName('div');
for (var i = 0; i < aDiv.length; i++) {
aDiv[i].style.border = "3px solid blue";
}
------------------------------------
$("div").css("border", "3px solid red");

通配符选择器

如果要获取文档中所有的元素,通过document.getElementsByTagName()中传递”*”

1
2
3
var elements1 = document.getElementsByTagName('*');
//jquery
var elements2 = $("*");

各种选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$('parent > child') //子选择器  直接子集  父子关系  
$('parent xxx') //后代选择器 儿子 孙子 曾孙子
$('prev + next') //相邻兄弟选择器 选择紧邻在 prev元素后的 next元素
$('prev ~ siblings') //匹配prev元素后的 所有siblings元素

$(".div:first")
$(".div:last")
$(".div:even")
$(".div:odd")
$(".div:eq(2)")
$(".div:gt(3)")
$(".div:lt(4)")

...
$('input:enabled')
$('input:disabled')
$('input:checked')
$('option:selected')

this选择器

1
2
3
4
5
6
7
8
var aaa = {
name:"almost",
getName:function(){
//this,就是aaa对象
return this.name;
}
}
aaa.getName(); //almost
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var p1 = document.getElementById('test1')
p1.addEventListener('click',function(){
// this === p1
//直接通过dom的方法改变颜色
this.style.color = "red";
},false);

...

$('#test2').click(function(){
//这里的this 是原生dom对象 需要转换为jquery对象才可以使用
//通过包装成jQuery对象改变颜色
$(this).css('color','blue');
})

属性与样式

设置属性

1
2
//找到第一个input,通过attr设置属性value的值
$('input').attr('value','001')

获取属性

1
$('input').attr('value')

通过function设置属性值

1
2
3
$('input').attr('value',function(i, val){
return '通过function设置' + val
})

删除属性

1
$('input').removeAttr('aaa')