12.5-12.9周末小结
JavaScript网页脚本语言
§ ECMAScript
一、基础
1.注释语法
// 单行注释
/*多行注释*/
2.结束符号
JS的结束符号为英文状态下的分号;
,也可以不写
3.在html内引入JS的方式
(1)head内script标签内填写
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
prompt('提示标题','提示内容')
</script>
</head>
(2)head内script标签内src属性引入外部资源
比如引入bootstrap资源
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
</head>
(3)body内最底部通过script标签src属性引入外部js资源
保证标签都加载完毕,所以为标签添加JS样式的时候,标签可以找的到,也是各大网站最常用的方式
二、变量与常量
1.声明变量的关键字
可以声明变量的时候定义,也可以先声明,之后再定义
- var
var pwd = 123;
var pwd;
pwd = 123;
-
let
let声明的变量只属于块级作用域,在外部无法访问,并且无法变量提升等等
var和let都用于声明变量,不同的是:
1.let声明的变量不能重复声明
2.let声明的变量不能变量提升:
当使用var声明一个var变量时,该变量会被提升到作用域的顶端,但是赋值的部分不会提升。
console.log(a);
var a = 'boo'
在声明a的语句之前就可以输出a,值为undefined,这就是变量提升。使用let声明变量时不能变量提升。
3.var是函数作用域,let是块状作用域:
在函数里使用var声明了一个变量,那么这个变量在整个函数内都是有效的,例如在for循环里用var声明一个变量,在for循环外也是可以使用的。但是let作用域是块状作用域,只在作用域里有效,例如在for循环里用let声明一个变量,在for循环外面是不能被访问的。
4.使用let声明的变量不属于顶层对象
顶层对象,在浏览器中指的是window,在node环境中指的是global对象。
var声明的变量属于顶层对象window,因此可以通过 window. 变量名 来访问这些变量,而let和const声明的变量不能这样访问。
2.声明常量的关键字
const
三、JS中的基本数据类型
1.数值类型Number
数据类型 | 表示 |
---|---|
Number | 整型或者浮点型 |
NaN | not a number |
2.字符类型String
表示方法 | 例 |
---|---|
单引号 | 'duoduo' |
双引号 | "duoduo" |
- 模版字符串
`${变量名}`
- 字符串方法
方法 | 说明 |
---|---|
.length |
返回长度 |
.trim() |
移除空白 |
.trimLeft() |
移除左边的空白 |
.trimRight() |
移除右边的空白 |
.charAt(n) |
返回第n个字符 |
.concat(value, ...) |
拼接,拼接字符串通常使用“+”号 |
.indexOf(substring, start) |
子序列位置 |
`.substring(from, to) | 根据索引获取子序列 |
.slice(start, end) |
切片 |
.toLowerCase() |
小写 |
.toUpperCase() |
大写 |
.split(delimiter, limit) |
分割 |
3.布尔类型boolean
布尔类型 | 表示 |
---|---|
true | 真 |
false | 假 |
- JS中布尔值为false的数据类型
''、 0 、 null、 undefined、 NaN
4.null
和 undefined
名称 | 含义 |
---|---|
nullnull |
表示值为空--曾经拥有过 |
undefined |
表示没有定义--从来没有过 |
5.对象object
对象只是带有属性和方法的特殊数据类型
(1)对象之数组(Array
)
数组对象的作用是使用单独的变量名来储存一系列的值,类似于python中的列表
- 数组的方法
方法 | 作用 |
---|---|
.length |
数组的大小 |
.push(ele) |
尾部追加元素 |
.pop() |
获取尾部的元素 |
.unshift(ele) |
头部插入元素 |
.shift() |
头部移除元素 |
.slice(start, end) |
切片 |
.reverse() |
反转 |
.join(seq ) |
将数组元素连接成字符串 |
.concat(val, ...) |
连接数组 |
.sort() |
排序 |
.forEach() |
将数组的每个元素传递给回调函数 |
.splice() |
删除元素,并向数组添加新元素。 |
map() |
返回一个数组元素调用函数处理后的值的新数组 |
(2)对象之自定义对象object
类似于python中的字典
let d1={'name':'duo','pwd':123}
typeof d1
'object'
d1.name
'duo'
d1.pwd
123
d1['name']
'duo'
let d2={name:'duoduo',pwd:123}
d2['name']
'duoduo'
四、运算符
1.算数运算符
符号 | 含义 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 去余数 |
++ | 自增1 |
-- | 自减1 |
2.比较运算符
符号 | 作用 |
---|---|
!= | 值不等 (弱) |
== | 值相等 (弱) |
!== | 值相等 (强) |
=== | 值不等 (强) |
弱相等:相等运算符在进行比较的时候,如果两边操作数数据类型不同,则会尝试转换成相同的类型再进行比较,如果转换成相同类型后的值相同,则返回 true,否则返回 false。
强相等:严格相等在比较的时候,碰到两边的操作数类型不同,则会直接返回 false,不会进行类型的转换。
3.逻辑运算符
逻辑运算符 | 含义 |
---|---|
&& |
与 |
` | |
! |
非 |
4.三元运算符
(条件) ? 表达式1 : 表达式2
如果条件为真,执行操作1,否则执行操作2
五、流程控制
1.条件语句
(1)单if分支
if (条件){
条件成立执行的代码
}
(2)if...else分支
if(条件){
条件成立执行的代码
}else{
条件不成立执行的代码
}
(3)if...else if...else分支
if(条件1){
条件1成立执行的代码
}else if(条件2){
条件1不成立条件2执行的代码
}
else{
条件1和2都不成立执行的代码
}
let dd=new Date()
if(d3.getDay()==0){
console.log('今天周末')
}else if(d3.getDay()==6){
console.log('今天周六')
}else{
console.log('工作日')
}
VM2540:3 今天周末
(4)如果分支结构中else if很多还可以考虑使用switch语法
switch(条件){
case 条件1:
条件1成立执行的代码;
break;
case 条件2:
条件2成立执行的代码;
break;
case 条件3:
条件3成立执行的代码;
break;
case 条件4:
条件4成立执行的代码;
break;
default:
条件都不满足执行的代码
}
2.循环语句
(1)for循环
for(起始条件;循环条件;条件处理){
循环体代码
}
for(let i=0;i<10;i++){
console.log(i)
}
let dd = {'name':'jason','age':18}
for(let k in dd){
console.log(k)
}
(2)while循环
while(循环条件){
循环体代码
}
六、函数
1.语法
function 函数名(形参){
函数体代码
return 返回值
}
2.函数类型
- 无参函数
function f1() {
console.log('你好')
};
f1()
----
你好
- 有参函数
function f2(a, b) {
console.log(arguments);
console.log(arguments.length);
console.log(arguments[0],argument[1]);
console.log(a, b);
};
-
匿名函数
和python中的匿名函数
lambda
相似,不单独使用,配合其他好函数一起使用
var s1 = function(a, b){return a + b}
- 箭头函数
var f=v=>v;
// 完整写法
var f=function(v){
return v
}
七、内置对象
- 产生内置对象的标准语法
var obj1 = new Date()\RegExp()\Math()
1.时间对象
// 通过new方法产生时间对象
var d = new Date();
2.JSON对象
// 序列化
JSON.stringify(自定义对象)
// 反序列化
JSON.parse(序列化对象)
3.正则对象RegExp
- 定义正则的方式一:
var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9]{5,11}");
- 定义正则的方式二:
var reg2 = /^[a-zA-Z][a-zA-Z0-9]{5,9}$/;
§ BOM
一、BOM中的对象
1.window对象
window对象,表示浏览器的窗口
- 打开新窗口
window.open(url,target,features)
- 关闭当前窗口
window.close()
2.history对象
window.history
对象包含浏览器的历史
方法 | 作用 |
---|---|
history.forward() |
前进一页 |
history.back() |
后退一页 |
3.location对象
window.location
对象用于获得当前页面的地址 (URL),并把浏览器重定向到新的页面。
常用属性和方法:
方法 | 作用 |
---|---|
location.href |
获取URL |
location.href="URL" |
跳转到指定页面 |
location.reload() |
重新加载页面 |
4.弹出框
弹出框 | 关键字 | 返回值 |
---|---|---|
警告框 | alert('提示内容') |
点击确定之后没有返回值,出现undefined |
确认框 | confirm('确认内容') |
返回值为true和false |
提示框 | prompt('提示框标题','提示文本') |
当点击确定的时候,会返回提示文本,当点击取消的时候返回null |
二、定时任务
1.一次性定时任务
关键字 | 作用 |
---|---|
setTimeout() |
只在指定时间后执行一次,通常用于延迟执行某种方法或功能 |
clearTimeout() |
清除一次性定时任务Timeout |
2.循环定时任务
关键字 | 作用 |
---|---|
setInterval() |
在指定时间为周期循环执行 |
clearInterval() |
清除循环定时任务 |
§ DOM
一、JS代码查找HTML标签
1.节点查找
(1)直接查找
方法 | 作用 | 查找结果 |
---|---|---|
document.getElementById |
根据ID获取唯一一个标签 | 标签对象 |
document.getElementsByClassName |
根据class属性获取一系列标签 | 数组里面含有多个标签对象 |
document.getElementsByTagName |
根据标签名获取一系列标签 | 数组里面含有多个标签对象 |
document.getElementsByName |
根据标签的name值获取一系列标签 | 数组里面含有多个标签对象 |
(2)间接查找
方法 | 作用 |
---|---|
childNodes | 获取所有的子节点,除了元素还有文本等 |
children | 获取所有元素子节点,不包含文本 |
parentNode | 获取父节点 |
previousSibling | 获取上一个兄弟节点,包含文本 |
previousElementSibling | 获取上一个兄弟元素节点,不包含文本 |
nextSibling | 获取下一个兄弟节点,包含文本 |
nextElementSibling | 获取下一个兄弟元素节点,不包含文本 |
firstChild | 获取第一个子节点,包含文本 |
firstElementChild | 获取第一个子节点,不包含文本 |
lastChild | 获取最后一个子节点,包含文本 |
lastElementChild | 获取父元素最后一个元素节点。不包含文本 |
2.节点操作
(1)创建标签
- 创建标签对象
document.createElement()
let aEle=document.createElement('a')
- 操作标签属性
aEle.href='https://www.baidu.com/'
- 操作标签文本
aEle.innerText = '这是百度'
(2)属性操作
方法 | 作用 |
---|---|
setAttribute() |
兼容默认属性和自定义属性 |
getAttribute() |
获取属性的值 |
removeAttribute() |
移除属性的值 |
二、事件
1.常见事件
属性可插入 HTML 标签来定义事件动作
常见事件 | 触发事件的条件 |
---|---|
onclick | 单击(当用户点击某个对象时调用的事件句柄) |
ondbclick | 双击 |
onfocus | 元素获得焦点 |
onblur | 元素失去焦点 |
onchange | 域的内容被改变 |
onkeydown | 键盘按下 |
onkeypress | 键盘按下并松开 |
onkeyup | 键盘松开 |
onload | 一个页面加载完成 |
onmousedown | 鼠标按下元素 |
onmousemove | 鼠标移动 |
onmouseout | 鼠标移开元素 |
onmouseover | 鼠标在元素上方 |
onselect | 文本框的文本被选中 |
onsubmit | 确认按钮被点击 使用的对象是form |
2.绑定事件
标签.事件=function(){
this // 代表的就是标签本身
}
§ jQuery
一、jQuery查找标签
1.基本选择器
$('#d1') id选择器
$('.c2') class选择器
$('div') 标签选择器
2.组合选择器
$('标签1,标签2') 寻找标签1和标签2
$('标签1标签2') 寻找含有满足标签2的标签1
3.层级选择器
$('div p') 查找含有div中所有的后代p标签
$('div>p') 查找div里面的儿子p标签
$('div+p') 查找div同级别下面紧挨着的p标签
$('div~p') 查找div同级别下面所有的p标签
4.属性选择器
$('[username]') 查找含有username属性名的标签
$('[username="duoduo"]') 查找含有username属性名且值为“duoduo”的标签
$('div[username="duoduo"]') 查找含有username属性名且值为“duoduo”的div标签
5.基本筛查器
筛选器 | 作用 |
---|---|
:first |
第一个 |
:last |
最后一个 |
:eq(index) |
索引等于index的那个元素 |
:even |
匹配所有索引值为偶数的元素,从 0 开始计数 |
:odd |
匹配所有索引值为奇数的元素,从 0 开始计数 |
:gt(index) |
匹配所有大于给定索引值的元素 |
:lt(index) |
匹配所有小于给定索引值的元素 |
:not(元素选择器) |
移除所有满足not条件的标签 |
:has(元素选择器) |
选取所有包含一个或多个标签在其内的标签(指的是从后代元素找) |
6.表单筛选器
:text
:password
:file
:radio
:checkbox
:submit
:reset
:button
7.筛选器的方法
- 下一个元素:
$("#id").next()
$("#id").nextAll()
$("#id").nextUntil("#i2")
- 上一个元素:
$("#id").prev()
$("#id").prevAll()
$("#id").prevUntil("#i2")
- 父亲元素:
$("#id").parent()
$("#id").parents() // 查找当前元素的所有的父辈元素
$("#id").parentsUntil() // 查找当前元素的所有的父辈元素,直到遇到匹配的那个元素为止。
- 儿子和兄弟元素:
$("#id").children();// 儿子们
$("#id").siblings();// 兄弟们
- 查找
搜索所有与指定表达式匹配的元素。这个函数是找出正在处理的元素的后代元素的好方法。
$("div").find("p")
三、操作标签
1.class操作
addClass();// 添加指定的CSS类名。
removeClass();// 移除指定的CSS类名。
hasClass();// 判断样式存不存在
toggleClass();// 切换CSS类名,如果有就移除,如果没有就添加。
2.位置操作
返回当前滚动条距离顶端距离
$(window).scrollTop()
3.文本操作
jQuery对应js中的方法
text() innerText
html() innerHTML
val() value
jQuety对象[0].files files[0]
4.创建标签
document.createElement() $('<a>')
5.属性操作
attr(attrName)// 返回第一个匹配元素的属性值
attr(attrName, attrValue)// 为所有匹配元素设置一个属性值
attr({k1: v1, k2:v2})// 为所有匹配元素设置多个属性值
removeAttr()// 从每一个匹配的元素中删除一个属性
attr
对于动态变化的属性,获取会失真
-
prop和attr的区别:
attr全称attribute(属性)
prop全称property(属性)
虽然都是属性,但他们所指的属性并不相同,attr所指的属性是HTML标签属性,而prop所指的是DOM对象属性,可以认为attr是显式的,而prop是隐式的
prop('value') // 获取value属性的值
prop('checked',true); // 设置属性
removeProp('value') // 移除value属性
这已经可以证明attr的局限性,它的作用范围只限于HTML标签内的属性,而prop获取的是这个DOM对象的属性,选中返回true,没选中返回false。
总结一下:
- 对于标签上有的能看到的属性和自定义属性都用attr
- 对于返回布尔值的比如checkbox、radio和option的是否被选中都用prop。
6.文档处理
添加到指定元素内部的后面
$(A).append(B)// 把B追加到A
$(A).appendTo(B)// 把A追加到B
添加到指定元素内部的前面
$(A).prepend(B)// 把B前置到A
$(A).prependTo(B)// 把A前置到B
添加到指定元素外部的后面
$(A).after(B)// 把B放到A的后面
$(A).insertAfter(B)// 把A放到B的后面
添加到指定元素外部的前面
$(A).before(B)// 把B放到A的前面
$(A).insertBefore(B)// 把A放到B的前面
移除和清空元素
remove()// 从DOM中删除所有匹配的元素。
empty()// 删除匹配的元素集合中所有的子节点
四、jQuery事件
1.jQuery绑定事件
- 方式一:
jQuery对象.事件名(function(){
})
- 方式二
jQuery对象.on('事件名', function(){
})
2.常用事件
click(function(){...})
hover(function(){...})
blur(function(){...})
focus(function(){...})
change(function(){...})
keyup(function(){...})
Django
一、wsgiref模块
wsgiref中已经封装了socket的代码,是很多web框架底层使用的模块,将请求数据封装成了request大字典
1.wsgiref模块固定格式
1.固定内容
2.request大字典
3.根据不同网址后缀找到字典中的键值对
2.python代码
from wsgiref.simple_server import make_server
def run(request, response):
"""
:param request: 请求数据
:param response: 响应数据
:return: 返回给浏览器的数据
"""
response('200 OK', [])
path_info = request.get("PATH_INFO")
if path_info == '/index':
return [b'index page']
elif path_info == '/reg':
return [b'reg page']
return [b'other page']
if __name__ == '__main__':
server = make_server('127.0.0.1', 9000, run)
server.serve_forever()
二、python的web框架Django
1.命令行命令
-- 下载django
pip install django==版本 -i 仓库地址
-- 查看django版本
python -m django --version
-- 创建django项目
django-admin startproject 项目名(纯英文)
-- 切换到目录后,创建app
cd 项目名
python manage.py startapp app名称
-- 运行django项目
ptyhon manage.py runserver ip:port
2.django项目的目录
djangoweekend
├── app01 # app目录
│ ├── __init__.py
│ ├── admin.py # django内置的admin后台管理功能
│ ├── apps.py # 注册app相关的一些配置
│ ├── migrations # 操作数据库相关相关记录
│ │ └── __init__.py
│ ├── models.py # 模型层,数据库相关
│ ├── tests.py # 测试文件
│ └── views.py # 视图层 存储视图函数或者视图类
├── djangoweekend
│ ├── __init__.py
│ ├── settings.py # django相关配置文件
│ ├── urls.py # 路由列表目录,用于绑定视图和url的映射关系
│ └── wsgi.py # wsgiref网关文件
├── templates # 模版层,存放html文件
├── db.sqlite3 # django自带的小型数据库,项目启动之后才会出现
└── manage.py # 终端脚步命令文件,提供了一系列用于生产文件或者目录的命令
3.django配置
(1)settings.py中
- 1.添加app名称
- 2.注释掉csrf令牌
- 3.添加模版目录到settings文件中
-
4.添加static文件
添加存储静态文件的目录名称
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
(2)__init__.py
文件
在__init__.py
文件中添加pymysql模块
import pymysql
pymysql.install_as_MySQLdb()
三、Django中的三大方法
方法名 | 作用 |
---|---|
HttpResponse | 返回字符串类型的数据 |
render | 返回html页面并支持传值给html页面 |
redirect | 重定向 |
1.HttpResponse
HttpResponse('字符串')
2.render
render(requeset,'html页面',context)
context是html页面和视图函数中共用到的数据
3.redirect
重定向到一个页面上
redirect('路由/网址')
四、Django中的静态文件
主要针对html文件所使用的各种资源,不经常变化的资源文件叫做静态文件
1.常见的静态文件
css文件,js文件,img图片文件,插件,模块文件
2.存放静态文件
新建static目录,存放静态文件
3.资源访问与静态文件配置
想让我们使用的静态文件能在浏览器中渲染出来,需要我们开放静态文件的接口
- settings.py中配置
在settings.py文件中,将存储静态文件的static目录添加到路径中
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
- html页面上
html页面上的接口前缀要和settings文件中的接口前缀保持一致
使用Django中的模版语法,保持接口前缀的动态匹配
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
这样在settings文件中,接口前缀如何变化,静态文件中的接口不用一一修改了
四、form表单和request对象
1.form表单
(1)action属性
action中的值 | 含义 |
---|---|
action="" |
*数据默认提及给当前页面所在的地址 |
action="完整网址" |
如action="https://www.baidu.com" ,超当前网址提交数据 |
action="/index/" |
action中填写路由,超当前服务端的路由提交数据 |
(2)method属性
method属性 | 作用 | 提交额外数据的方式 | 提交数据的特点 |
---|---|---|---|
get | 向服务端所要数据 | URL?xxx=yyy&uuu=zzz |
提交数据的大小有限制:2kb左右,且不能提交敏感数据 |
post | 向服务端提交数据 | 请求体 | 提交数据的大小没有现实,可以提交敏感数据 |
2.request对象
首先是socket将获得了请求数据,wsgiref模块将其封装成了request大字典,Django在其之上封装成了request对象
request方法 | 作用 |
---|---|
request.method |
获得请求方式POST或者GET |
request.GET |
拿到get方式提交的数据,也就是URL? 后面的数据 |
request.POST |
获得POST请求请求体中的数据,是一个QueryDict{'':['']} |
request.POST.get()
获取值列表中最后一个字符串
request.POST.getlist()
获取整个列表
五、Django连接MySQL数据库
1.下载MySQL安装驱动
pip install PyMySQL
2.在settings.py中修改配置
3.点击database连接mysql数据库
六、ORM
1.orm中的映射关系
Python | 数据库 |
---|---|
类 | 数据表 |
对象 | 记录 |
对象点属性 | 字段对应的值 |
2.models模型层
当我们在模型层中创建了orm时的映射模型时
- 需要我们将其记录到应用文件夹的migrations目录下
python manage.py makemigrations
- 手动同步到数据库中
python manage.py migrate
3.Django中的orm操作语句
ORM 库不是轻量级工具,需要花很多精力学习和设置,甚至不同的框架,会存在不同操作的ORM
- 定义模型类
from django.db import models
# Create your models here.
# 创建用户数据表
class UserInfo(models.Model):
# 字段名id int pk auto_increment
# 字段名 = 字段类型 + (约束提哦啊键)
id = models.AutoField(primary_key=True)
# username varchar(32) unique not null
username = models.CharField(unique=True, null=False, max_length=32)
# pwd varchar(32) not null
pwd = models.CharField(null=False, max_length=32)
# age int
age = models.IntegerField()
# gender varchar(32) default other
gender = models.CharField(max_length=12, default='other')
- views.py使用orm语句操作数据库
使用ORM需要在views.py
文件中导入models
from app01 import models
-
创建表
models.类名.objects.create()
-
查询记录
models.类名.objects.filter()
-
修改记录
models.类名.objects.update()
-
删除记录
不添加查询条件的话,则删除整张表
models.类名.objects.delete()
from django.shortcuts import render, HttpResponse, redirect
from app01 import models
# Create your views here.
def register_page(request):
"""
如果是get请求 返回register页面
如果是post请求 返回写入数据库
"""
if request.method == "POST":
# 1 获取页面返回的数据
username = request.POST.get('username')
password = request.POST.get('pwd')
age = request.POST.get('age')
gender = request.POST.get('gender')
models.UserInfo.objects.create(username=username, pwd=password, age=int(age), gender=gender)
return HttpResponse('注册成功')
return render(request, "register_page.html")
def login_page(request):
"""
如果是get请求 返回login.html页面
POST请求就去比对数据库的数据
"""
if request.method == 'POST':
username = request.POST.get('username')
pwd = request.POST.get('pwd')
res = models.UserInfo.objects.filter(username=username, pwd=pwd)
print('查询结果', res)
print('查询结果索引0', res[0].username)
if res:
return HttpResponse('登录成功')
else:
return HttpResponse('用户名或者密码不正确')
return render(request, 'login_page.html')