之前已发布了一次了。在编写和发布的过程中一直有一个BUG困扰着我。最后被我找到了,只能暂时避开这个BUG重新发布一篇了。之前那篇就被我删掉了,浏览和收藏的也没了。
创新互联建站成立与2013年,是专业互联网技术服务公司,拥有项目网站建设、成都网站制作网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元霍邱做网站,已为上家服务,为霍邱各地企业和个人服务,联系电话:13518219792
那个问题我也记录下来了:https://blog.51cto.com/steed/2071264
网页设计思路是把网页分成三个层次,即:结构层(HTML)、表示层(CSS)、行为层(Javascript)。
形象的比喻,先是HTML捏了一个人,然后CSS则是给人穿上衣服,最后通过JS让人动起来。
对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。用户向服务器发送一个请求。然后服务器响应,将数据和格式发回给客户端,然后断开这个连接。客户端收到返回的数据后,通过浏览器将数据按照一定的格式呈现出来。整个过程就是一个socket的短连接。
下面是一个服务端的python代码,实现一个简单的Hello World:
import socket
def handle_request(conn):
data = conn.recv(1024) # 接收数据,随便收到啥我们都回复Hello World
conn.send('HTTP/1.1 200 OK\r\n\r\n'.encode('utf-8')) # 这是什么暂时不需要知道,客户端浏览器会处理
conn.send('Hello World'.encode('utf-8')) # 回复的内容,就是网页的内容
def main():
# 先起一个socket服务端
server = socket.socket()
server.bind(('localhost', 8000))
server.listen(5)
# 然后持续监听
while True:
conn, addr = server.accept() # 开启监听
handle_request(conn) # 将连接传递给handle_request函数处理
conn.close() # 关闭连接
if __name__ == '__main__':
main()
在本机启动上面的socket之后,直接使用浏览器作为客户端连接。在地址栏输入 http://127.0.0.1:8000/
或 http://localhost:8000/
之后,浏览器上就会显示服务端返回的内容了。
这里显示的内容比较low,实际应用中,要返回给客户端的网页内容比较大。而且除了数据,还会包括格式(html标签)。实际应用中会将所有的内容写成一个html文件,然后再返回数据的时候调用这个文件。
先写一个简单的带一点标签的html文件,index.html:
Hello World
51CTO
1
2
3
A
B
C
然后我们的socket不再发送简单的数据,而是读取文件,将文件中的数据发送给客户端。
在上面代码的基础上修改一下handle_request函数的内容:
def handle_request(conn):
data = conn.recv(1024) # 接收数据,随便收到啥我们都回复Hello World
conn.send('HTTP/1.1 200 OK\r\n\r\n'.encode('utf-8')) # 这是什么暂时不需要知道,客户端浏览器会处理
# conn.send('Hello World'.encode('utf-8')) # 回复的内容
# 读取html文件,将文件内容返回给客户端
with open('index.html' , encoding='utf-8') as file:
html = file.read()
conn.send(html.encode('utf-8'))
现在已经将html和我们的socket服务分离了,需要返回给客户端什么样的页面,我们只需要编辑修改我们的html文件即可。而我们的socket服务器代码则负责和客户端的数据交换。
之后学习Web暂时只需要关注html的部分就好了,直接使用浏览器打开本地的html文件就可以查看实现的效果。
使用pycharm直接创建一个html文件,内容如下(HTML5的模板):
Title
:这是一个声明,声明下面html的版本。这里是一个html5的声明。这个不是html标签,下面的都是。
:这是一个html标签,里面的 lang="en"
是标签内部的属性。一般html标签这么写就行了。这个属性也用不着。
:head标签,html的头,后面详讲
:body标签,html的主体,后面详讲
最后补充一个
注释 :
主动闭合标签:大多数的标签都是这种形式。标签有两部分,比如上面的、、,后面都有一个对应的、、来主动闭合这个标签。
自闭合标签:像上面 head 中的 meta 标签,就是一个自闭合标签。这类标签比较少。另外也可以这样写,加上一个/
符号,不影响浏览器的识别,但是可以直观的让人看明白各个标签已经闭合了。推荐加上表示闭合的/
。
:指定页面的字符编码,否则中文可能会变成乱码。
type="text" :可以输入文本,
type="password" :可以输入密码,
type="button" :是一个按钮,现在点下去没效果,还需要其他东西。
type="submit" :提交表单,是另外一种按钮。同样没效果,直接将form表单的内容提交到form的action属性指定的url。
不过上面的input内容还无法识别,需要加上name属性:
这样就会把数据组织成一个字典的形式提交出去,name就是字典的key,你在前端文本框输入的数据就是字典的value。这样提交之后,就可以通过name属性的值也就是字典的key获取到前端文本的内容。这部分还得后面再讲了,暂时只要会以这样的形式提交,之后再学怎么获取到值以及处理。
现在用浏览器打开我们自己的网页,在文本框输入你要搜索的内容,然后点击搜索按钮查看效果。
:这里也可以加上value属性,这样打开的页面中文本框中不再是空白,而是会有一个默认值。
type="radio" :单选框,相同的name属性表示是一个选择项的,定义不同的value值可以获取到你的选择
type="checkbox" :复选框,相同的name属性表示是一个选择项的,每个选项给不用的value值,可以判断你选中了哪些,没选中哪些。
请选择性别:
男:
女:
爱好:
足球:
蓝球:
排球:
棒球:
通过属性 checked="checked"
可以设置选项默认被选中。
上传文件
:可以用于上传文件。要上传文件,需要将这个input放到form标签中,并且在form标签中要定义 enctype="multipart/form-data" 。因为还需要服务器端处理,在讲到web框架的时候再细讲了。
:可以重置form中的所有内容,还原到打开时候的默认值。
textarea标签,用于实现输入多行文本,主动闭合标签,在标签之间的部分可以写上默认值。一般会加上name属性,用于取数据。
这个就不贴代码了。而且就是这个标签会被页面识别为代码,即使你放在代码块中,感觉是个BUG。导致后面的内容都会有问题。
简单的下拉列表代码如下:
在select标签里设置name属性,用于取数据
每个option标签里设置value属性,用于确认该选项是否被选中
size属性 :可以设置size属性,将列表自动展开一定的项目
selected属性 :设置 selected="selected"
,将该选项设为默认
multiple属性 :设置 multiple="multiple"
,将列表定义为多选。可以通过Ctrl选中多个,也可以通过Shift或者拖拽来连续选中多个
另外还有一个分组的下拉列表,代码如下:
以上,能够把数据提交给服务器的标签就讲完了。
之后的标签就是用来点缀,用来页面布局等等这类功能了。
下面是一些常用的功能性的或者是页面布局的标签
通过a标签可以定义超链接,通过超链接我们可以实现页面的跳转:
百 度
网易
标签之间的内容是你的超链接显示的内容,然后定义href的属性,指向你要跳转的页面。
另外还可以定义target属性,这里用了“_blank”,可以在新的标签页打开。另外target还有别的属性,反正不是很重要,有兴趣就自己再去试了。
另外a标签还有一个作用,就是锚。我理解为页面内的跳转。
为了让页面内容足够大(需要滚动),定义一下div的高度,这个以后会讲。
另外这里不能用name属性定位了,需要用id属性。
第一章
第二章
第三章
第四章
第一章节的内容
第二章节的内容
第三章节的内容
第四章节的内容
a标签中的href属性在定位锚点的时候需要在前面加上"/#"号,后面跟上id的值。另外,如果在浏览器中直接输入url,后面跟上"#chapter_3"的话,也是打开页面并且直接定位到锚点。
先准备好出的图片的路径,可以是本地的图片,也可以是网上的图片。本地图片貌似不能是绝对路径,不过应该可以用 ..\ 表示上一级目录。 我这里都把图片放到html文件的同级目录里测试了。
另外,还可以为图片加上超链接。只需要将图片包在一个a标签里面就行了(之前放的是文字,这里只是换成了图片)。
图片的大小也可以调整,在img标签中设置style属性(这个还得后面讲):

alt属性:为img加上alt属性,如果图片不存在,则会显示alt的值。
title属性:为img加上title属性,鼠标悬停在图片上的时候,会显示title的值。
ul是无序列表,ol是有序列表。效果直接上代码试:
- 萨尔
- 沃金
- 希尔瓦娜斯
- 耐奥祖
- 阿尔萨斯
- 伯瓦尔·弗塔根
还有一个是分组的列表:
- 部落:
- 兽人
- 巨魔
- 牛头人
- 被遗忘者
- 联盟:
- 人类
- 矮人
- 侏儒
- 暗夜精灵
table标签包住一张表格,设置一下border属性,可以显示几种边框效果。
table内嵌tr标签包住一行,tr内嵌td标签是每一列。
简单的表格,就这样:
玛法里奥
伊利丹
泰兰德
吉安娜
乌瑟尔
安度因
这里还缺少表头,一般第一行是标题行,我们用thead标签包起来,并且这一行里都是标题,所以不用td标签,而是用th标签。
然后,后面的行都内嵌在tbody标签中。另外,如果需要,每行的第一列,也可以用th标签,或者也可以不要行标题,那就全用td标签
这么做主要是为了规范,下面是更加规范完整的表格:
种族
英雄1
英雄2
英雄3
暗夜精灵
玛法里奥
伊利丹
泰兰德
人类
吉安娜
乌瑟尔
安度因
colspan 和 rowspan 属性可以实现合并单元格的效果。下面把标题行和标题列都合并了。
合并效果的表格可以这么写:
英雄
名字
玛法里奥
伊利丹
泰兰德
吉安娜
乌瑟尔
安度因
典型的用法,一般lable标签会结合input标签一起使用。
"for" 属性可把 label 绑定到另外一个元素。请把 "for" 属性的值设置为相关元素的 id 属性的值。
建议使用的时候在lable中设置一个for属性,指向input的id,这样点击lable的内容的时候,光标也会出现在指向的input框内。代码如下,可以比较一下差别(点一下用户名看看有没有效果,点一下昵称看看有没有效果):
首先这个标签不常用,不过还是知道一下。效果就是绘制一个边框,边框上面可以加个标题。把其他标签都放在一个fileset标签里实现分组。
内部写一个legend标签,定义一个标题,如果什么内容的没有,那么就一直一个边框,边框上部边缘有一个标题:
当然使用的时候,内部添加一些相关的内容,现在只能粗糙的弄一个:
上面总共也就讲了20个左右标签,去掉那几个不常用的,基本只要掌握15个左右的标签就OK了。
在标签上可以设置style属性,style属性的值写在引号内。
每一个样式都是一个key:value的形式,样式之间用";"分号隔开。
写前端,一般是先用div标签把页面进行分块,然后对每一块分别设置css即style属性:
红色
绿色
蓝色
上面的代码,写了3个div,设置了一个背景色,和一个高度。
看前面的例子,分别用了3中方式表示颜色。3种方式都是一样的,但是颜色和代码的对应关系可以去搜索一下rgb,有一个叫做RGB颜色对照表的东西,可以查询到颜色和对应的编码。
我们可以在head标签内事先设置好style标签,然后在body里需要应用该样式的标签内引用这个样式,即选择对应的css样式。
有多种方式来选择css。
以#id设置样式,对应的id的标签就会应用该样式。上面的代码也可以这样实现:
Title
第一块
第二块
第三块
body中的标签只要id正确,就是应用上对应的style样式了。
这样貌似看着更复杂了,但是body内的结果更加清晰了,而且这只是因为我们的web页面还不是太复杂。
另外如果多个标签的样式其实是一样的,但是id只能用一次,我们可以为一个样式定义多个id,就是这样,如此也解决的代码重用的问题:
Title
第一块
第二块
第三块
因为id不能重复,上面的方式应用起来不方便。最常用的是这里的方式。
现在以 .class 来设置sytle,标签中只要设置对应项class属性,就会应用该样式。关键是class属性是可以重复使用的:
Title
第一块
第二块
第三块
就是标签选择器。以标签的名字来设置style,这样所有的标签都会应用这个样式:
Title
第一块
红色的内容
第二块
2.1
第三块
也可以理解为层级选择器,每一个层级关系之间用空格分隔。现在我们以 "div span" 来设置style。如此,所有div标签下的span标签就都会应用这个样式。
Title
第一块
第一模块的内容
第二块
第二模块的内容
第三块
第三模块的内容
另外,这里的层级也可以使用class,比如以 ".c1 spen" 来设置style:
Title
第一块
第一模块的内容
第二块
第二模块的内容
第三块
第三模块的内容
这样c2这个class下的pan就会应该到这个样式。
使用#id也是一样的道理。
和层级关系类似,组合之间用","逗号分隔。在id选择器后面的例子里,其实就是组合了。所以就不试了。
现在我们知道,不只是id,class和标签都可以用来组合。
另外,组合是一个或的关系,上面的层级是一个与的关系。
这里先用 input[type='text']
来举例,前面是一个选择器,后面中括号是判断属性,如果有这个属性,就应该改样式。
对于前半部分,同样可以使用 #id 或 .class 。
对于后半部分,我们还可以使用自定义的属性,比如下面例子用自定义了一个myattr属性,来应用了一个样式:
Title
我们可以在标签内设置有限级,还可以在head里设置优先级模板,按几个选择器的规则应用其中的样式。所有可能出现符合多个要求而会应用到多个要是的情况。这里就有了一个优先级的概念。
对于不重复的样式,要么会全部应用上。
对于重复的要是,会应用最下面的那个样式。即body中的样式优先级高于head中的样式。同在body或head中,那么下面的样式优先级高。
总结,按我的理解,应该就是最新加载的样式会覆盖之前的样式。不冲突就追加上是,有冲突就替代掉。
上一个例子:
Title
优先级测试1
优先级测试2
优先级测试3
这里标签中的字体颜色属性就覆盖掉了 .c2 中的字体颜色。
而前2个div都是同时属于 c1 和 c2 这2个class,背景色的样式应用的都是处于下面的 c2 的样式。
class属性赋予多个值:这里的class属性同时赋了2个值,注意一下这个赋值的格式。
如果有多个页面文件,但用的是同一套css样式。我们目前只能在每个页面文件的head里都写上全部的css代码。这样又有代码重复的问题了。
可以创建一个css文件(pycharm里选择New->Stylesheet),将