并发编程

进程

操作系统的历史

# 手工操作 —— 穿孔卡片
    # 程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入输入机,然后启动输入机把程序和数据输入计算机内存,接着通过控制台开关启动程序针对数据运行;计算完毕,打印机输出计算结果;用户取走结果并卸下纸带(或卡片)后,才让下一个用户上机。
    # 手工操作方式两个特点:
    # (1)用户独占全机。不会出现因资源已被其他用户占用而等待的现象,但资源的利用率低。
    # (2)CPU 等待手工操作。CPU的利用不充分。
    # 20世纪50年代后期,出现人机矛盾:手工操作的慢速度和计算机的高速度之间形成了尖锐矛盾,手工操作方式已严重损害了系统资源的利用率(使资源利用率降为百分之几,甚至更低),不能容忍。唯一的解决办法:只有摆脱人的手工操作,实现作业的自动过渡。这样就出现了成批处理。
# 批处理 —— 磁带存储
    # 批处理系统:加载在计算机上的一个系统软件,在它的控制下,计算机能够自动地、成批地处理一个或多个用户的作业(这作业包括程序、数据和命令)。
    # 联机批处理系统:主机与输入机之间增加一个存储设备——磁带,在运行于主机上的监督程序的自动控制下,计算机可自动完成:成批地把输入机上的用户作业读入磁带,依次把磁带上的用户作业读入主机内存并执行并把计算结果向输出机输出。完成了上一批作业后,监督程序又从输入机上输入另一批作业,保存在磁带上,并按上述步骤重复处理。
        # 监督程序不停地处理各个作业,从而实现了作业到作业的自动转接,减少了作业建立时间和手工操作时间,有效克服了人机矛盾,提高了计算机的利用率。
        # 但是,在作业输入和结果输出时,主机的高速CPU仍处于空闲状态,等待慢速的输入/输出设备完成工作: 主机处于“忙等”状态。
    # 脱机批处理系统:为克服与缓解:高速主机与慢速外设的矛盾,提高CPU的利用率,又引入了脱机批处理系统,即输入/输出脱离主机控制。
        # 卫星机:一台不与主机直接相连而专门用于与输入/输出设备打交道的。
        # 其功能是:
            # (1)从输入机上读取用户作业并放到输入磁带上。
            # (2)从输出磁带上读取执行结果并传给输出机。
            # 这样,主机不是直接与慢速的输入/输出设备打交道,而是与速度相对较快的磁带机发生关系,有效缓解了主机与设备的矛盾。主机与卫星机可并行工作,二者分工明确,可以充分发挥主机的高速计算能力。
        # 脱机批处理系统:20世纪60年代应用十分广泛,它极大缓解了人机矛盾及主机与外设的矛盾。
        # 不足:每次主机内存中仅存放一道作业,每当它运行期间发出输入/输出(I/O)请求后,高速的CPU便处于等待低速的I/O完成状态,致使CPU空闲。
        # 为改善CPU的利用率,又引入了多道程序系统。
    # 多道程序系统
        # 多道程序设计技术
        # 单处理机系统中多道程序运行时的特点:
        # (1)多道:计算机内存中同时存放几道相互独立的程序;
        # (2)宏观上并行:同时进入系统的几道程序都处于运行过程中,即它们先后开始了各自的运行,但都未运行完毕;
        # (3)微观上串行:实际上,各道程序轮流地用CPU,并交替运行。
        # 多道程序系统的出现,标志着操作系统渐趋成熟的阶段,先后出现了作业调度管理、处理机管理、存储器管理、外部设备管理、文件系统管理等功能。
        # 由于多个程序同时在计算机中运行,开始有了空间隔离的概念,只有内存空间的隔离,才能让数据更加安全、稳定。
        # 出了空间隔离之外,多道技术还第一次体现了时空复用的特点,遇到IO操作就切换程序,使得cpu的利用率提高了,计算机的工作效率也随之提高。
    # 多道批处理系统
        # 它有两个特点:
        # (1)多道:系统内可同时容纳多个作业。这些作业放在外存中,组成一个后备队列,系统按一定的调度原则每次从后备作业队列中选取一个或多个作业进入内存运行,运行作业结束、退出运行和后备作业进入运行均由系统自动实现,从而在系统中形成一个自动转接的、连续的作业流。
        # (2)成批:在系统运行过程中,不允许用户与其作业发生交互作用,即:作业一旦进入系统,用户就不能直接干预其作业的运行。
    # 分时系统
        # 特点:
        # (1)多路性。若干个用户同时使用一台计算机。微观上看是各用户轮流使用计算机;宏观上看是各用户并行工作。
        # (2)交互性。用户可根据系统对请求的响应结果,进一步向系统提出新的请求。这种能使用户与系统进行人机对话的工作方式,明显地有别于批处理系统,因而,分时系统又被称为交互式系统。
        # (3)独立性。用户之间可以相互独立操作,互不干扰。系统保证各用户程序运行的完整性,不会发生相互混淆或破坏现象。
        # (4)及时性。系统可对用户的输入及时作出响应。分时系统性能的主要指标之一是响应时间,它是指:从终端发出命令到系统予以应答所需的时间。
    # 实时系统
        #  实时系统可分成两类:
        # (1)实时控制系统。当用于飞机飞行、导弹发射等的自动控制时,要求计算机能尽快处理测量系统测得的数据,及时地对飞机或导弹进行控制,或将有关信息通过显示终端提供给决策人员。当用于轧钢、石化等工业生产过程控制时,也要求计算机能及时处理由各类传感器送来的数据,然后控制相应的执行机构。
        # (2)实时信息处理系统。当用于预定飞机票、查询有关航班、航线、票价等事宜时,或当用于银行系统、情报检索系统时,都要求计算机能对终端设备发来的服务请求及时予以正确的回答。此类对响应及时性的要求稍弱于第一类。
        # 实时操作系统的主要特点:
        # (1)及时响应。每一个信息接收、分析处理和发送的过程必须在严格的时间限制内完成。
        # (2)高可靠性。需采取冗余措施,双机系统前后台工作,也包括必要的保密措施等。
        # 分时系统和实时系统的比较
        # 分时——现在流行的PC,服务器都是采用这种运行模式,即把CPU的运行分成若干时间片分别处理不同的运算请求 linux系统
        # 实时——一般用于单片机上、PLC等,比如电梯的上下控制中,对于按键等动作要求进行实时处理
    # 通用操作系统
        # 操作系统的三种基本类型:多道批处理系统、分时系统、实时系统。
        # 通用操作系统:具有多种类型操作特征的操作系统。可以同时兼有多道批处理、分时、实时处理的功能,或其中两种以上的功能。
    # 操作系统的进一步发展
        # 个人计算机操作系统
        # 个人计算机上的操作系统是联机交互的单用户操作系统,它提供的联机交互功能与通用分时系统提供的功能很相似。
        # 网络操作系统
        # 计算机网络:通过通信设施,将地理上分散的、具有自治功能的多个计算机系统互连起来,实现信息交换、资源共享、互操作和协作处理的系统。
            # 网络操作系统:在原来各自计算机操作系统上,按照网络体系结构的各个协议标准增加网络管理模块,其中包括:通信、资源共享、系统安全和各种网络应用服务。
        # 分布式操作系统
        # 网络操作系统和分布式操作系统的区别
            # (1)分布式系统要求一个统一的操作系统,实现系统操作的统一性。
            # (2)分布式操作系统管理分布式系统中的所有资源,它负责全系统的资源分配和调度、任务划分、信息传输和控制协调工作,并为用户提供一个统一的界面。
            # (3)用户通过这一界面,实现所需要的操作和使用系统资源,至于操作定在哪一台计算机上执行,或使用哪台计算机的资源,则是操作系统完成的,用户不必知道,此谓:系统的透明性。
            # (4)分布式系统更强调分布式计算和处理,因此对于多机合作和系统重构、坚强性和容错能力有更高的要求,希望系统有:更短的响应时间、高吞吐量和高可靠性。
# 总结
# 操作系统应该分成两部分功能
#一:隐藏了丑陋的硬件调用接口,为应用程序员提供调用硬件资源的更好,更简单,更清晰的模型(系统调用接口)。应用程序员有了这些接口后,就不用再考虑操作硬件的细节,专心开发自己的应用程序即可。
#二:将应用程序对硬件资源的竞态请求变得有序化

操作系统的历史的理论知识

进程的理论知识

# 什么是进程:
#狭义定义:运行中的程序
#广义定义 : 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
# 进程的特征:
#动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
#并发性:任何进程都可以同其他进程一起并发执行
#独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;
#异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进
#结构特征:进程由程序、数据和进程控制块三部分组成。
# 程序和进程的区别
    # 程序是永久存在硬盘中
    # 进程是运行时暂时存在内存中
# 进程调度
    # 先来先服务调度算法
    # 先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。FCFS算法比较有利于长作业(进程),而不利于短作业(进程)。由此可知,本算法适合于CPU繁忙型作业,而不利于I/O繁忙型的作业(进程)。
    # 短作业优先调度算法
    # 短作业(进程)优先调度算法(SJ/PF)是指对短作业或短进程优先调度的算法,该算法既可用于作业调度,也可用于进程调度。但其对长作业不利;不能保证紧迫性作业(进程)被及时处理;作业的长短只是被估算出来的。
    # 时间片轮法
    # 时间片轮转(Round Robin,RR)法的基本思路是让每个进程在就绪队列中的等待时间与享受服务的时间成比例。把一个时间分成多份,每一份的时间就是时间片,每一片时间就是CPU调度的时间
    # 多级反馈队列
        # 根据优先级和时间片轮转分配任务的时间,越短的作业优先级越高,分配的时间越短,越长的优先级越低的作业分配的时间也就越长

 # 进程的并行和并发
    # 并行 并行是指两者同时执行,比如赛跑,两个人都在不停的往前跑;只有多核的时候才能实现并行
    # 并发 并发是指资源有限的情况下,两者交替轮流使用资源

# 进程的三状态装换图
    # 创建 —— 提交 —— 就绪 —— 进程调度 —— 运行 —— 释放 —— 退出
    # 创建 —— 提交 —— 就绪 —— 运行 —— 时间片到 —— 就绪
    # 创建 —— 提交 —— 就绪 —— 运行 —— 事件请求 —— 阻塞 —— 事件发生 —— 就绪
# 三状态
# (1)就绪(Ready)状态
    # 当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态
# (2)执行/运行(Running)状态
    # 当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。
# (3)阻塞(Blocked)状态
    # 阻塞(Blocked)状态正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。

# 同步和异步
    # 同步:所谓同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列
    # 异步:所谓异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。
# 例如:比如我去银行办理业务,可能会有两种方式:
第一种 :选择排队等候;
第二种 :选择取一个小纸条上面有我的号码,等到排到我这一号时由柜台的人通知我轮到我去办理业务了;
第一种:前者(排队等候)就是同步等待消息通知,也就是我要一直在等待银行办理业务情况;
第二种:后者(等待别人通知)就是异步等待消息通知。在异步消息处理中,等待消息通知者(在这个例子中就是等待办理业务的人)往往注册一个回调机制,在所等待的事件被触发时由触发机制(在这里是柜台的人)通过某种机制(在这里是写在小纸条上的号码,喊号)找到等待该事件的人。
# 阻塞和非阻塞
    # 阻塞:程序过程中停止了
    # 非阻塞:程序过程中一直不停止

# 1. 同步阻塞形式
    #效率最低。拿上面的例子来说,就是你专心排队,什么别的事都不做。
# 2. 异步阻塞形式
    # 如果在银行等待办理业务的人采用的是异步的方式去等待消息被触发(通知),也就是领了一张小纸条,假如在这段时间里他不能离开银行做其它的事情,那么很显然,这个人被阻塞在了这个等待的操作上面;
    #异步操作是可以被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞。
# 3. 同步非阻塞形式
  #实际上是效率低下的。想象一下你一边打着电话一边还需要抬头看到底队伍排到你了没有,如果把打电话和观察排队的位置看成是程序的两个操作的话,这个程序需要在这两种不同的行为之间来回的切换,效率可想而知是低下的。
# 4. 异步非阻塞形式
  #效率更高,因为打电话是你(等待者)的事情,而通知你则是柜台(消息触发机制)的事情,程序没有在两种不同的操作中来回切换。的
# 进程的创建与结束
    # 进程的创建
而对于通用系统(跑很多应用程序),需要有系统运行过程中创建或撤销进程的能力,主要分为4中形式创建新的进程:
  #1. 系统初始化(查看进程linux中用ps命令,windows中用任务管理器,前台进程负责与用户交互,后台运行的进程与用户无关,运行在后台并且只在需要时才唤醒的进程,称为守护进程,如电子邮件、web页面、新闻、打印)
  #2. 一个进程在运行过程中开启了子进程(如nginx开启多进程,os.fork,subprocess.Popen等)
  #3. 用户的交互式请求,而创建一个新进程(如用户双击暴风影音)
  #4. 一个批处理作业的初始化(只在大型机的批处理系统中应用)
  #无论哪一种,新进程的创建都是由一个已经存在的进程执行了一个用于创建进程的系统调用而创建的。  
# 进程的结束
#1. 正常退出(自愿,如用户点击交互式页面的叉号,或程序执行完毕调用发起系统调用正常退出,在linux中用exit,在windows中用ExitProcess)
#2. 出错退出(自愿,python a.py中a.py不存在)
#3. 严重错误(非自愿,执行非法指令,如引用不存在的内存,1/0等,可以捕捉异常,try...except...)
#4. 被其他进程杀死(非自愿,如kill -9)

进程的理论知识

多进程的操作

多进程的使用

#开启多进程的第一种方式
import time
import os
from multiprocessing import Process
def func(*args):
    print(*args)
    time.sleep(2)
    print("子进程 :",os.getpid())
    print("子进程的父进程 :",os.getppid())
if __name__ in "__main__":
    p = Process(target=func,args=("参数1","参数2","参数3"))
    # 注册,p是一个进程对象,还没有启动进程
    p.start()    # 开启了一个子进程
    print("*" * 10)
    print("父进程 :",os.getpid())    # 查看当前进程的进程号
    print("父进程的父进程 :",os.getppid())
    # 查看当前进程的父进程
# 进程的生命周期
    # 主进程
    # 子进程
    # 开启了子进程的主进程:
        # 主进程自己的代码如果长,等待自己的代码执行结束
        # 子进程的执行时间长,主进程会在主进程代码执行完毕之后,等待子进程执行完毕之后,主进结束
#开启多进程的第二种方式
import os
from multiprocessing import Process
class Myprocess(Process):
    def __init__(self,args1,args2):
        super().__init__()
        self.args1 = args1
        self.args2 = args2
    def run(self):
        print(self.pid)
        print(self.name)
        print(self.args1)
        print(self.args2)
if __name__ in "__main__":
    print("主进程 : ",os.getpid())
    p1 = Myprocess(1,2)
    p1.start()
    p2 = Myprocess(3,4)
    p2.start()
# 1.自定义类,继承process类
# 2.必须实现一个run方法,run方法中是子进程中执行的代码

多进程的使用

多进程的几个方法

# join方法的使用 感知一个子进程的结束,将异步改成同步
from multiprocessing import Process
import time
def func(args,args2):
    print("*" * args)
    time.sleep(5)
    print("*" *args2)
if __name__ in "__main__":
    p = Process(target=func,args=(10,20))
    p.start()
    print("hahaha")
    p.join()
    print("====:执行完了")
"""
hahaha
**********
sleep 5 秒
********************
====:执行完了
"""
# p.daemon 守护进程
import time
from multiprocessing import Process
def func():
    while True:
        time.sleep(0.2)
        print("我还活着")
def func2():
    print("in func2")
    time.sleep(8)
    print("in func2 finished")
if __name__ == '__main__':
    p = Process(target=func)
    p.daemon = True # 设置子进程为守护进程
    p.start()
    p2 = Process(target=func2)
    p2.start()
    time.sleep(1)
    i = 0
    while i<5:
        print("我是socketserver")
        time.sleep(1)
        i += 1
'''
in func2
sleep 前5秒
我还活着
我还活着
我还活着
我是socketserver * sleep 1秒 一边 执行4遍
sleep 等待8秒
in func2 finished 结束
'''
# 守护进程会随着主进程的代码执行结束 而 结束
# p.terminate 结束一个子进程
# p.alive    检测一个进程是否还活着
# p.name | p.pid 这个进程的名字和进程号
import time
from multiprocessing import Process
def func():
    while True:
        time.sleep(0.2)
        print("我还活着")
def func2():
    print("in func2")
    time.sleep(8)
    print("in func2 finished")
if __name__ in "__main__":
    p1 = Process(target=func)
    p1.deamon = True # 设置子进程为守护进程
    p1.start()
    p2 = Process(target=func2)
    p2.start()
    p2.terminate()    # 结束一个子进程
    print(p2.is_alive())
    print(p2.name)
'''
True
我还活着
我还活着
我还活着
False
Process-2
'''
# 在主进程内结束一个子进程 p.terminate()
    # 结束一个进程不是在执行方法之后立即生效,需要一个操作系统响应的过程
# 检测一个进程是否活着的状态 p.is_alive()

多进程的几个方法

开启多个子进程

# 写文件操作
from multiprocessing import Process
import time
import os
def func(filename,content):
    with open(filename,"w") as f:
        f.while(content*10*"*")
if __name__ in "__main__":
    p_lst = []
    for i in range(5):
        p = Process(target=func,args=(info%s) % i,i)
        p_lst.append(p)
        p.start()
    [p.join() for p in p_lst ]
    print([i for i in os.walk(r"E:\\fullstack\day35")])
# 同步 0.1*500 = 50
# 异步 500 0.1 = 0.1
# 多进程写文件
# 首先往文件夹中写文件
# 向用户展示写入文件夹之后文件夹中所有的文件名
# 进程 与 进程之间数据隔离问题
from multiprocessing import Process
def func():
    global n
    n = 0
    print("子进程内 :",n)
if __name__ == '__main__':
    n = 100
    p = Process(target=func)
    p.start()
    p.join()
    print("父进程内 :",n)
"""
子进程内: 0
父进程内: 100
"""

开启多个子进程

使用多进程实现socket服务端的并发效果

# server.py 文件
import socket
from multiprocessing import Process
def serve(conn):
    ret = "你好".encode("utf-8")
    conn.send(ret)
    msg = conn.recv(1024).decode("utf-8")
    print(msg)
    conn.close()
if __name__ == '__main__':
    sk = socket.socket()
    sk.bind(("127.0.0.1",8080))
    sk.listen()
    while True:
        conn,addr = sk.accept()
        p = Process(target=serve,args=(conn,))
        p.start()
    sk.close()
# client.py
import socket
sk = socket.socket()
sk.connect(("127.0.0.1",8080))
msg = sk.recv(1024).decode("utf-8")
print(msg)
while True:
    msg2 = input(">>>").encode("utf-8")
    sk.send(msg2)
sk.close()

socket并发效果

进程的同步控制

进程锁

# 火车票的例子
# ticket文件内容 {"ticket":1}
from multiprocessing import Process,Lock
import json
def show(i):
    with open("ticket") as f:
        dic = json.load(f)
    print("余票 %s" %dic["ticket"])
def buy_ticket(i,lock):
    lock.acquire()    # 拿到抢票的钥匙
    with open("ticket") as f:
        dic = json.load(f)
        time.sleep(0.2)
    if dic["ticket"] >0:
        dic["ticket"] -= 1
        print("\033[32m %s买到票了\033[0m" % i)
    else:
        print("\033[31m %s没买到票\033[0m" % i)
    time.sleep(0.2)
    with open("ticket","w") as f:
        json.dump(dic,f)
    lock.release()        # 还钥匙
if __name__ in "__main__":
    for i in range(5):
        p = Process(target=show,args=(i,))
        p.start()
    lock = Lock()
    for i in range(5):
        p.Process(target=buy_ticket,args=(i,lock))
        p.start()
# 执行结果
余票 1
余票 1
余票 1
余票 1
# 2买到票了
余票 1
"""
1没买到票
0没买到票
3没买到票
4没买到票
"""

进程锁Lock对象

信号量

# 信号量的操作类似于进程锁,添加了计数器
# KTV的例子
from multiprocessing import Semaphore,Process
import time
import random
def ktv(i,sem):
    sem.acquire()    # 拿钥匙
    print("%s走进KTV"%i)    # 进入ktv
    time.sleep(random.randint(1,3)) # 1-3秒
    print("%s走出KTV"%i)    # 走出ktv
    sem.release()    # 退还钥匙
if __name__ == "__main__":
    sem = Semaphore(4)    # 设置4把钥匙
    for i in range(20):    # 设置20个人进入ktv
        p = Process(target=ktv,args=(i,sem))
        p.start()
'''
14走进KTV
15走进KTV
8走进KTV
19走进KTV
# 最初有4个人拿到钥匙进入KTV
15走出KTV
16走进KTV
......
后面只要有人还钥匙走出KTV
才能有人拿到钥匙走进KTV
直到20个人都走出ktv执行结束
'''

信号量Semapore对象

事件

# 通过一个信息 来控制 多个进程 同时 执行或者阻塞
from multiprocessing import Event
# 一个信号可以使用所有的进程都进入阻塞状态
# 也可以控制所有的进程解除阻塞
# 一个事件被创建之后,默认就是阻塞状态
e = Event() # 创建一个事件
print(e.is_set())   # 查看一个事件的状态,默认被设置成阻塞
print(12345)
e.set() # 将这个事件的状态改为True
print(e.is_set())
e.wait()    # 是依据e.is_set()的值来决定是否阻塞的
print(123456)
e.clear()   # 将这个事件的状态改为False
print(e.is_set())
e.wait()    # 等待 事件的信号被变成True
print("*" * 10 )
# 总结
# set 和 clear
    # 分别用来修改一个事件 True或者False
# is_set() 用来查看一个事件的状态
# wait  是依据e.is_set()的值来决定是否在wait处阻塞
    # False阻塞 True不阻塞
# socket基于文件和网络
# 两个程序之间和两个进程之间数据都不能共享的
# 通过文件 一个写一个读
# Event和Lock 内部用了socket
# 红绿灯模型
from multiprocess import Event,Process
def cars(e,i):
    if not e.is_set():  # 如果Event为False
        print("car%i在等待"%i)
        e.wait()   # 阻塞直到得到一个 事件状态变成True的信号
    print("\033[1;32;40m%i通过\033[0m"%i)
def light(e):
    while True:
        if e.is_set():    # 如果Event为True
            e.clear()    # 将其改为False
            print("\033[31m红灯亮了\033[0m")
        else:
            e.set()    # 改为True
            print("\033[32m绿灯亮了\033[0m")
        time.sleep(2)    # 红绿灯切换为多少秒
if __name__ == "__main__":
    e = Event()
    tarffic = Process(target=light,args=(e,))
    tarffic.start()    # 创建红绿灯进程
    for i in range(100):    # 如果有100个车要通过
        car = Process( target=cars, args=(e,i) )
        car.start()  # 创建车进程
        time.sleep(random.random()) # 车的通过在1秒内

事件Event

进程间的通信

队列

from multiprocessing import Queue,Process
def produce(q):
    q.put("hello")
def consume(q):
    print(q.get())
if __name__ == '__main__':
    q = Queue()
    p = Process(target=produce,args=(q,))
    p.start()
    c = Process( target=consume, args=(q,) )
    c.start()
# 两个子进程的通信 通过队列
# 队列
# 生产者消费者模型
# 队列 Queue
    # put   # 给值
    # get   # 拿值
    # full  # 检测是否已满 不准确
    # empty # 检查是否已空 不准确
# 买包子
# 生产者 进程
# 消费者 进程
import time
import random
from multiprocessing import Process,Queue
def consumer(q,name):
    while True:
        food = q.get()
        if food is None:
            print("%s获取到了一个空"%name)
            break
        print("\033[31m%s消费%s\033[0m"%(name,food))
        time.sleep(random.randint(1,3))
def producer(name,food,q):
    for i in range(10):
        time.sleep(random.randint(1,3))
        f = "%s生产了%s%s"%(name,food,i)
        print(f)
        q.put(f)
if __name__ == '__main__':
    q = Queue(20)    # 队列大小为20
    p1 = Process(target=producer,args=("producer1","包子",q))
    p2 = Process(target=producer,args=("producer2","泔水",q))
    c1 = Process( target=consumer, args=(q,"consumer1") )
    c2 = Process( target=consumer, args=(q, "consumer2") )
    p1.start()
    p2.start()
    c1.start()
    c2.start()
    p1.join()
    p2.join()
    q.put(None)
    q.put(None)

队列Queue

# JoinableQueue队列
    # task_done() 用于get() 消费者拿值的时候每次减1
    # join() # 用于put() 等待把数据取完处理完执行
# 消费者和生成者模型
import time
import random
from multiprocessing import Process,JoinableQueue
def consumer(q,name):
    while True:
        food = q.get()
        print("\033[31m%s消费%s\033[0m"%(name,food))
        time.sleep(random.randint(1,3))
        q.task_done()   # count-1
def producer(name,food,q):
    for i in range(10):
        time.sleep(random.randint(1,3))
        f = "%s生产了%s%s"%(name,food,i)
        print(f)
        q.put(f)
    q.join()    # 阻塞 直到一个队列中的所有数据 全部被处理完毕
                # 等待消费拿走并吃完结束
if __name__ == '__main__':
    q = JoinableQueue(20)
    p1 = Process(target=producer,args=("producer1","包子",q))
    p2 = Process(target=producer,args=("producer2","泔水",q))
    c1 = Process( target=consumer, args=(q,"consumer1") )
    c2 = Process( target=consumer, args=(q, "consumer2") )
    p1.start()
    p2.start()
    c1.daemon = True # 设置为守护进程,主进程中的代码执行完毕之后,子进程自动结束
    c2.daemon = True
    c1.start()
    c2.start()
    p1.join()
    p2.join()   # 感知一个进程的结束
# 在消费者这一端:
    # 每次获取一个数据
    # 处理一个数据
    # 发送一个记号:标志一个数据被处理成功
# 在生产者这一端:
    # 每一次生成一个数据
    # 且每一次生成的数据都放在队列中
    # 在队列中刻上一个记号
    # 当生产者全部生产完毕之后
    # join信号:已经停止生产数据了
            # 且要等待之前被刻上的记号都被消费完
            # 当数据都被处理完时,join阻塞结束

# consumer 中把所有的任务消耗完
# producer 端 的 join感知到 停止zus
# 所有的producer进程结束
# 主进程中代码结束
# 守护进程(消费者的进程)结束

队列JoinableQueue

管道

#创建管道的类:
Pipe([duplex]):在进程之间创建一条管道,并返回元组(conn1,conn2),其中conn1,conn2表示管道两端的连接对象,强调一点:必须在产生Process对象之前产生管道
#参数介绍:
dumplex:默认管道是全双工的,如果将duplex设成False,conn1只能用于接收,conn2只能用于发送。
#主要方法:
    conn1.recv():接收conn2.send(obj)发送的对象。如果没有消息可接收,recv方法会一直阻塞。如果连接的另外一端已经关闭,那么recv方法会抛出EOFError。
    conn1.send(obj):通过连接发送对象。obj是与序列化兼容的任意对象
 #其他方法:
conn1.close():关闭连接。如果conn1被垃圾回收,将自动调用此方法
conn1.fileno():返回连接使用的整数文件描述符
conn1.poll([timeout]):如果连接上的数据可用,返回True。timeout指定等待的最长时限。如果省略此参数,方法将立即返回结果。如果将timeout射成None,操作将无限期地等待数据到达。
conn1.recv_bytes([maxlength]):接收c.send_bytes()方法发送的一条完整的字节消息。maxlength指定要接收的最大字节数。如果进入的消息,超过了这个最大值,将引发IOError异常,并且在连接上无法进行进一步读取。如果连接的另外一端已经关闭,再也不存在任何数据,将引发EOFError异常。
conn.send_bytes(buffer [, offset [, size]]):通过连接发送字节数据缓冲区,buffer是支持缓冲区接口的任意对象,offset是缓冲区中的字节偏移量,而size是要发送字节数。结果数据以单条消息的形式发出,然后调用c.recv_bytes()函数进行接收
conn1.recv_bytes_into(buffer [, offset]):接收一条完整的字节消息,并把它保存在buffer对象中,该对象支持可写入的缓冲区接口(即bytearray对象或类似的对象)。offset指定缓冲区中放置消息处的字节位移。返回值是收到的字节数。如果消息长度大于可用的缓冲区空间,将引发BufferTooShort异常。

管道的相关操作

# 管道实现消费者和生产者模型
from multiprocessing import Pipe,Process,Lock
import time
import random
def consumer(con,pro,name,lock):
    pro.close()
    while True:
        lock.acquire()
        food = con.recv()
        lock.release()
        if food is None:
            con.close()
            break
        print( "%s吃了%s" % (name, food) )
def producer(con,pro,name,food):
    con.close()
    for i in range(100):
        # time.sleep(random.random())
        f = "%s生产%s%s"%(name,food,i)
        print(f)
        pro.send(f)
    pro.send(None)
    pro.send(None)
    pro.send(None)
    pro.close()
if __name__ == '__main__':
    con,pro = Pipe()
    lock = Lock()
    p = Process(target=producer,args=(con,pro,"p","food"))
    c1 = Process(target=consumer,args=(con,pro,"c1",lock))
    c2 = Process(target=consumer,args=(con,pro,"c2",lock))
    c3 = Process(target=consumer,args=(con,pro,"c3",lock))
    p.start()
    c1.start()
    c2.start()
    c3.start()
    con.close()
    pro.close()
# Pipe 是进程数据不安全性
# IPC
# 加锁来控制操作管道的行为,来避免进程之间争抢数据造成的数据不安全现象

管道的实例

进程间的数据共享

# 数据共享是不安全的
# 下面的实例结果数据错乱,每次的结果都不一样
from multiprocessing import Manager,Process
def main(dic):
    dic["count"] -= 1
    print(dic)
if __name__ == '__main__':
    m = Manager()
    dic = m.dict({"count":100})
    p_lst = []
    p = Process( target=main, args=(dic,) )
    p.start()
    p.join()
    print("主进程",dic)
    for i in range(50):
        p = Process(target=main,args=(dic,))
        p.start()
# 正确的操作实例
from multiprocessing import Manager,Process,Lock
def main(dic,lock):
    lock.acquire()
    dic["count"] -= 1
    lock.release()
if __name__ == '__main__':
    m = Manager()
    l = Lock()
    dic = m.dict({"count":100})
    p_lst = []
    for i in range(50):
        p = Process(target=main,args=(dic,l))
        p.start()
        p_lst.append(p)
    for i in p_lst: i.join()
    print("主进程",dic)
# 为了数据安全 必须要加锁

进程之间数据共享Manager

进程池

# 为什么会有进程池的概念
    # 效率问题
    # 每开启进程,开启属于这个进程的内存空间
    # 寄存器 堆栈 文件
    # 进程过多 操作系统要调用进程
# 进程池
    # python中先创建一个属于进程的池子
    # 这个池子指定能存放n个进程
    # 先将这些进程创建好
    # 让这五十个进程排队
from multiprocessing import Pool,Process
import time
# Process 5个以下
def func(n):
    for i in range(10):
        print(n+1)
if __name__ == '__main__':
    # 进程池的操作
    start = time.time()
    pool = Pool(5)              # 5个进程(交替工作)
    pool.map(func,range(100))   # 100个任务
    t1 = time.time() - start
    # 单个进程的操作
    start = time.time()
    p_lst = []
    for i in range(100):
        p = Process(target=func,args=(i,))
        p_lst.append(p)
        p.start()
    for p in p_lst:p.join()
    t2 = time.time() - start
    print(t1,t2)
# 打印的时间差0.34201955795288086 5.51131534576416
# apply,apply_async的使用
import time
from multiprocessing import Pool
import os
def func(n):
    print("start func%s"%n,os.getpid())
    time.sleep(1)
    print( "end func%s" % n,os.getpid())
if __name__ == '__main__':
    p = Pool(5)
    for i in range(10):
        # p.apply(func,args=(i,)) # 同步提交任务的方式
        p.apply_async(func,args=(i,)) # 异步提交任务的方式
    p.close()   # 结束进程池任务
    p.join()    # 感知进程池中的任务执行结束
# p.map(funcname,iterable)  # 默认异步的执行任务,且自带close和join
# p.apply       # 同步调用的
# p.apply_async # 异步调用和主进程完全异步,需要手动close和join
# 进程池的返回值
# apply和apply_async实现返回值
import time
from multiprocessing import Pool
def func(i):
    time.sleep(0.5)
    return i*i
if __name__ == '__main__':
    p = Pool(5)
    res_l = []
    for i in range(10):
        # res = p.apply(func,args=(i,))   # apply的结果就是func的返回值
        res = p.apply_async(func,args=(i,))
        res_l.append(res)
    for res in res_l:print(res.get())    # get阻塞等待结果
"""
0
1
4
9
16
25
36
49
64
81
每次打印5个
"""
# map方法
import time
from multiprocessing import Pool
def func(i):
    time.sleep(0.5)
    return i*i
if __name__ == '__main__':
    p = Pool(5)
    res = p.map(func,range(10)) # 自带join
    print(res)
'''
等待所有进程执行完打印结果
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
'''
# 回调函数
import os
from multiprocessing import Pool
def func1(n):
    print("in func1",os.getpid())
    return n*n
def func2(nn):
    print("in func2",os.getpid())
    print(nn)
if __name__ == '__main__':
    print("主进程:",os.getpid())
    p = Pool(5)
    p.apply_async(func1,args=(10,),callback=func2)
    p.close()
    p.join()
# 回调函数将子进程的执行结果返回给主进程,再将执行结果给callback的对应的函数
'''
主进程: 2300
in func1 4840
in func2 2300
100
'''

进程池Pool

# 简单的爬虫
import requests
from multiprocess import Pool
def get(url):
    response = requests.get(url)
    if response.status_code == 200:
        return url,response.content.decode("utf-8")
if __name__ == "__main__":
    url_lst = [
        "https://www.cnblogs.com/",
        "http://www.sohu.com/",
        "http://www.sogou.com/",
        "http://www.baidu.com",
    ]
    p = Pool(5)
    for url in url_lst:
        p.apply_async(get,args=(url,),callback=call_back)
    p.close()
    p.join()
# 爬虫的例子2
from urllib.request import urlopen
from multiprocessing import Pool
import re
def get_page(url,pattern):
    response=urlopen(url).read().decode('utf-8')
    return pattern,response   # 正则表达式编译结果 网页内容
def parse_page(info):
    pattern,page_content=info
    res=re.findall(pattern,page_content)
    for item in res:
        dic={
            'index':item[0].strip(),
            'title':item[1].strip(),
            'actor':item[2].strip(),
            'time':item[3].strip(),
        }
        print(dic)
if __name__ == '__main__':
    regex = r'<dd>.*?<.*?class="board-index.*?>(\d+)</i>.*?title="(.*?)".*?class="movie-item-info".*?<p class="star">(.*?)</p>.*?<p class="releasetime">(.*?)</p>'
    pattern1=re.compile(regex,re.S)
    url_dic={'http://maoyan.com/board/7':pattern1}
    p=Pool()
    res_l=[]
    for url,pattern in url_dic.items():
        res=p.apply_async(get_page,args=(url,pattern),callback=parse_page)
        res_l.append(res)
    for i in res_l:
        i.get()

回调函数的例子

线程

线程的理论知识

#进程的缺陷
# 1.进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
# 2.进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。
# 区别:
# 进程是资源分配的最小单位
# 线程是CPU调度的最小单位.
# 线程的特点
# 1.轻型实体 线程中的实体基本上不拥有系统资源,只是有一点必不可少的、能保证独立运行的资源,线程的实体包括程序、数据和TCB。线程是动态概念,它的动态特性由线程控制块TCB(Thread Control Block)描述。
'''
TCB包括以下信息:
(1)线程状态。
(2)当线程不运行时,被保存的现场资源。
(3)一组执行堆栈。
(4)存放每个线程的局部变量主存区。
(5)访问同一个进程中的主存和其它资源。
用于指示被执行指令序列的程序计数器、保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈。
'''
# 2.独立调度和分派的基本单位。
# 在多线程OS中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。由于线程很“轻”,故线程的切换非常迅速且开销小(在同一进程中的)。
# 3.共享进程资源。
# 线程在同一进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的进程id,这意味着,线程可以访问该进程的每一个内存资源;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。由于同一个进程内的线程共享内存和文件,所以线程之间互相通信不必调用内核。
# 4. 可并发执行。
# 在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有线程都能并发执行;同样,不同进程中的线程也能并发执行,充分利用和发挥了处理机与外围设备并行工作的能力。

# 每一个进程中至少有一个线程
# 进程中可以开启多个线程
    # 开启一个线程所需要的时间要远远小于开启一个进程
    # 多个线程内部都有自己的数据栈,数据不共享
    # 全局变量在多个线程之间是共享的
# 关于以上结论实例
import os
from threading import Thread
# import time
def func(a,b):
    global g
    g = 0
    print(g,os.getpid())
g = 100
t_lst = []
for i in range(10):
    t = Thread(target=func,args=(i,5))
    t.start()
    t_lst.append(t)
for t in t_lst:t.join()
print(g)

# GIL锁
# 在Cpython解释器下的python程序,在同一时刻 多个线程中只有一个线程被CPU执行
'''
在多线程环境中,Python 虚拟机按以下方式执行:
  a、设置 GIL;
  b、切换到一个线程去运行;
  c、运行指定数量的字节码指令或者线程主动让出控制(可以调用 time.sleep(0));
  d、把线程设置为睡眠状态;
  e、解锁 GIL;
  d、再次重复以上所有步骤。
  在调用外部代码(如 C/C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止(由于在这期间没有Python的字节码被运行,所以不会做线程切换)编写扩展的程序员可以主动解锁GIL。
'''
# 多线程的实际场景
# 高CPU:计算类 —— 高CPU利用率   # 多进程
# 高IO: 抓取网页 200个网页    # 多线程
    # qq聊天 send recv
    # 处理日志文件 读文件
    # 处理web请求
    # 读数据库 写数据库

线程理论

线程的操作

# multiprocess 完全模仿Threading模块
# 多线程并发
from threading import Thread
import time
def func(n):
    time.sleep(1)
    print(n)
for i in range(10):
    t = Thread(target=func,args=(i,))
    t.start()
# 面向对象创建线程
from threading import Thread
import time
class MyThread(Thread):
    def __init__(self,args):
        super().__init__()
        self.args = args
    def run(self):
        time.sleep(1)
        print(self.args)
for i in range(10):
    t = MyThread(i)
    t.start()
# 线程和进程之间速度对比
import time
from threading import Thread
from multiprocessing import Process
def func(n):
    n + 1
if __name__ == '__main__':
    start = time.time()
    t_lst = []
    for i in range(100):
        t = Thread(target=func,args=(i,))
        t.start()
        t_lst.append(t)
    for t in t_lst:t.join()
    t1 = time.time()-start
    start = time.time()
    p_lst = []
    for i in range( 100 ):
        p = Process( target=func, args=(i,) )
        p.start()
        p_lst.append( p )
    for p in p_lst: p.join()
    t2 = time.time() - start
    print(t1,t2)
'''
[0.011000633239746094 5.255300760269165]
'''
# 线程模块中的其他方法
# Thread实例对象的方法
  # isAlive(): 返回线程是否活动的。
  # getName(): 返回线程名。
  # setName(): 设置线程名。
# threading模块提供的一些方法:
  # threading.currentThread(): 返回当前的线程变量。
  # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  # threading.activeCount(): 返回正在运行的线程数量,与
  # len(threading.enumerate())有相同的结果。

线程模块threading

# 多线程简单实现socket聊天代码
# server端
from threading import Thread
import socket
def chat(conn):
    conn.send(b"你好")
    msg = conn.recv(1024).decode("utf-8")
    print(msg)
    conn.close()
sk = socket.socket()
sk.bind(("127.0.0.1",8080))
sk.listen()
while True:
    conn,addr = sk.accept()
    Thread(target=chat,args=(conn,)).start()
sk.close()
# client端
import socket
sk = socket.socket()
sk.connect(("127.0.0.1",8080))
msg = sk.recv(1024)
print(msg)
inp = input(">>>").encode("utf-8")
sk.send(inp)
sk.close()

多线程实现socket聊天

# 守护进程随着主线程代码结束而结束
# 守护线程在主线程结束之后会等待其他子线程结束才结束
from threading import Thread
import time
def func1():
    while True:
        print("*" * 10)
        time.sleep(1)
def func2():
    print(666)
    time.sleep(5)
t = Thread(target=func1,)
t.daemon = True
t.start()
t2 = Thread(target=func2,)
t2.start()
print("主线程")

守护线程

线程的同步控制

线程锁

# Lock 互斥锁  互斥锁为资源引入一个状态:锁定/非锁定。某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
# 死锁是指一个资源被多次调用,而多次调用方都未能释放该资源就会造成一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁。
# RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。这里以例1为例,如果使用RLock代替Lock,则不会发生死锁:
# 互斥锁的例子
import threading
class Mythreading(threading.Thread)
    def run():
        global n
        lock.acquire()
        n += 1
        lock.release()
        print(self.name + "set to n" + str(n))
n = 0
lock = threading.Lock()
if __name__ == "__main__":
    for i in range(5):
        t = Mythreading()
        t.start()
    print('final num: %d' % n)
'''
输出结果
Thread-1 set n to 1
Thread-2 set n to 2
Thread-3 set n to 3
Thread-4 set n to 4
Thread-5 set n to 5
final num: 5
加锁之后,我们可以确保数据的正确性
'''
# 死锁的实例
import threading
class MyThread(threading.Thread):
    def run(self):
        global n1, n2
        lock.acquire()   # 加锁
        n1 += 1
        print(self.name + ' set n1 to ' + str(n1))
        lock.acquire()   # 再次加锁
        n2 += n1
        print(self.name + ' set n2 to ' + str(n2))
        lock.release()
        lock.release()
n1, n2 = 0, 0
lock = threading.Lock()
if __name__ == '__main__':
    thread_list = []
    for i in range(5):
        t = MyThread()
        t.start()
        thread_list.append(t)
    for t in thread_list:
        t.join()
    print('final num:%d ,%d' % (n1, n2))
'''
输出结果
Thread-1 set n1 to 1
'''
# 会一直等待
# 递归锁实例解决死锁问题
import threading
class MyThread(threading.Thread):
    def run(self):
        global n1, n2
        lock.acquire()   # 加锁
        n1 += 1
        print(self.name + ' set n1 to ' + str(n1))
        lock.acquire()   # 再次加锁
        n2 += n1
        print(self.name + ' set n2 to ' + str(n2))
        lock.release()
        lock.release()
n1, n2 = 0, 0
lock = threading.RLock()
if __name__ == '__main__':
    thread_list = []
    for i in range(5):
        t = MyThread()
        t.start()
        thread_list.append(t)
    for t in thread_list:t.join()
    print('final num:%d ,%d' % (n1, n2))
'''
Thread-1 set n1 to 1
Thread-1 set n2 to 1
Thread-2 set n1 to 2
Thread-2 set n2 to 3
Thread-3 set n1 to 3
Thread-3 set n2 to 6
Thread-4 set n1 to 4
Thread-4 set n2 to 10
Thread-5 set n1 to 5
Thread-5 set n2 to 15
final num:5 ,15
'''
# 科学家吃面问题
import time
from threading import RLock,Thread
fork_lock = noodle_lock = RLock()
def eat1(name):
    noodle_lock.acquire()
    print("%s拿着面条啦"%name)
    fork_lock.acquire()
    print("%s拿到叉子了"%name)
    print("%s吃面"%name)
    fork_lock.release()
    noodle_lock.release()
def eat2(name):
    fork_lock.acquire()
    print("%s拿到叉子了"%name)
    time.sleep(1)
    noodle_lock.acquire()
    print("%s拿着面条啦"%name)
    print("%s吃面"%name)
    fork_lock.release()
    noodle_lock.release()
Thread(target=eat1,args=("alex",)).start()
Thread(target=eat2,args=("egon",)).start()
Thread(target=eat1,args=("bossjin",)).start()
Thread(target=eat2,args=("nezha",)).start()
"""
输出结果
alex拿着面条啦
alex拿到叉子了
alex吃面
egon拿到叉子了
egon拿着面条啦
egon吃面
bossjin拿着面条啦
bossjin拿到叉子了
bossjin吃面
nezha拿到叉子了
nezha拿着面条啦
nezha吃面
"""

线程锁Lock,Rlock

信号量

# 信号量的实例
import time
from threading import Semaphore,Thread
def func(sem,a,b):
    time.sleep(1)
    sem.acquire()
    print(a+b)
    sem.release()
sem = Semaphore(4)
# 同一时间只能有n个线程
for i in range(10):
    t = Thread(target=func,args=(sem,i,i+5))
    t.start()
'''
输出结果
7
11
9
13
15
5
17
2123
19
'''

信号量Semaphore

事件

# 事件被创建的时候
# False状态
    # wait()阻塞
# True状态
    # wait()非阻塞
# clear 设置状态为False
# set 设置状态为True
# 连接数据库
# 检测数据库的可连接情况
# 数据库 —— 文件夹
# 文件夹里有好多Excel表格
    # 1.能够更方便的对数据进行增删改查
    # 2.安全访问的机制
# 起两个线程
# 第一个线程:连接数据库
    # 等待一个信号 告诉我们之间的网络是通的
# 第二个线程:检测与数据库之间的网络是否是连通
    # time.sleep(0,2)
    # 将事件的状态设置为True
import time
import random
from threading import Thread,Event

def connect_db(e):
    count = 0
    while count < 3:
        e.wait(0.5) # 状态为False的时候,我只等待1s就结束
        if e.is_set() == True:
            print("连接数据库")
            break
        else:
            print("第%s次连接失败"%count)
            count += 1
    else:
        raise TimeoutError("数据库连接超时")
def check_web(e):
    time.sleep(random.randint(0,3))
    e.set()
e = Event()
t1 = Thread(target=connect_db,args=(e,))
t2 = Thread(target=check_web,args=(e,))
t1.start()
t2.start()

事件Event

条件

# 条件
from threading import Condition,Thread
# 条件
# 锁
# acquire release
# 一个条件被创建之初,默认有一个False状态会影响wait一直处于等待状态
# wait
# notify(int数据类型) 制造一串钥匙 造钥匙
def func(con,i):
    con.acquire()
    con.wait()  # 等钥匙
    print("在第%s个循环里" % i)
    con.release()
con = Condition()
for i in range(10):
    Thread(target=func,args=(con,i)).start()
while True:
    num = int(input(">>>"))
    con.acquire()
    con.notify(num) # 造钥匙的过程 不归还
    con.release()

条件Condition

定时器

# 简单的Timer实例
from threading import Timer
import time
def func():
    print("时间同步")
while True:
    Timer(5,func).start()
    time.sleep(5)

定时器Timer

线程之间通讯

队列

# queue
import queue
# q = queue.Queue()
# q.put()
# q.put_nowait()
# q.get()
# q.get_nowait()
q = queue.LifoQueue() # 栈 先进后出
q.put(1)
q.put(2)
q.put(3)
print(q.get())
# 输出结果是3
q = queue.PriorityQueue()# 优先级队列
q.put((20,"a"))
q.put((10,"b"))
q.put((30,"c"))
q.put((-1,"d"))
q.put((1,"z"))
print(q.get())
# 输出结果(-1, 'd')
# 越小越优先

队列Queue

线程池

import time
from concurrent.futures import ThreadPoolExecutor
def func(n):
    time.sleep(2)
    print(n)
    return n*n
def call_back(m):
    print("结果是 %s" %m.result() )
tpool = ThreadPoolExecutor(max_workers = 5)    # 默认不要超过cpu个数*5
for i in range(20):
    tpool.submit(func,i).add_done_callback(call_back)
tpool.map(func,range(20))   # 拿不到返回值
t_lst = []
for i in range(20):         # 超过线程的数就不用shutdown
    t = tpool.submit(func,i)
    t_lst.append(t)
tpool.shutdown() # close + join
print("主线程")
for t in t_lst:print("***",t.result())
'''
输出结果
1
结果是 1
23
结果是 9
0
结果是 4
结果是 0
4
结果是 16
58
结果是 64
结果是 25
7
结果是 49
6
结果是 36
9
结果是 81
12
结果是 144
11
结果是 12113
结果是 169
10
结果是 100
14
结果是 196
17
结果是 289
16
结果是 256
18
15
结果是 225
结果是 324
19
结果是 361
31
0
2
4
65
8
7
9
10
12
11
13
14
17
16
15
18
19
2
0
1
3
4
76
5
8
9
1012
13
11
14
1718
15
16
19
'''

线程池ThreadPoolExecutor

协程与IO控制

# 进程 启动多个进程,进程由操作系统负责调用,操作有个时间片的概念
# 线程 启动多个线程,真正被cpu执行的最小单位,实际是线程
    # 开启一个线程 创建一个线程 寄存器 堆栈
    # 关闭一个线程 都需需时间开销
# 协程
    # 本质是一个线程,
    # 能够在多个任务之间切换,来节省IO时间
    # 协程中任务之间的切换也消耗时间,但是开销远远小于进程和线程之间的切换
# python中因为GIL锁,所以多线程 被弱化了
# 协程 一个线程的作用发挥到极致
# 在一个线程上提高CPU的利用率
# 协程相比于多线程的优势,切换的效率更快了
# 这些都是实现并发的手段
# 生成器协程的例子
import time
def consumer():
    while True:
        x = yield
        time.sleep(1)
        print("处理了数据",x)
def producer():
    c = consumer()
    next(c)
    for i in range(10):
        time.sleep(1)
        print("生产了数据",i)
        c.send(i)
producer()
# 不能节省IO时间
# 真正的携程模块使用greenlet完成的切换
# 4核CPU = 5个进程 = 每个进程有20个线程 = 每个线程有500个协程 = 50000个并发
from greenlet import greenlet
def eat():
    print("eating start")
    g2.switch()
    print("eating end")
    g2.switch()
def play():
    print("playing start")
    g1.switch()
    print("playing end")
g1 = greenlet(eat)
g2 = greenlet( play )
g1.switch()

初始协程greenlet

#gevent模块例子
from gevent import monkey;monkey.patch_all()
import time
import gevent
import threading
def eat():
    print(threading.current_thread().getName())
    print(threading.current_thread())
    print("eating start")
    time.sleep(1)
    print("eating end")
def play():
    print( threading.current_thread().getName() )
    print( threading.current_thread())
    print("playing start")
    time.sleep(2)
    print("playing end")
g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
g1.join()   # 等待线程执行完毕
g2.join()
# 进程和线程的任务切换,由操作系统完成
# 协程之间的任务切换,由程序(代码)完成
# 协程更适合用在网络上爬虫,socket连接
# 同步和异步
from gevent import monkey;monkey.patch_all()
import time
import gevent
def task():
    time.sleep(1)
    print(12345)
def sync(): # 同步
    for i in range(10):
        task()
def asyncs():   # 异步
    g_lst = []
    for i in range(10):
        g = gevent.spawn(task)
        g_lst.append(g)
    # for g in g_lst:g.join
    gevent.joinall(g_lst)   #
asyncs()
# sync()
# 协程:能够在一个线程中实现并发效果的概念
    # 能够规避一些任务中的IO操作
    # 在任务的执行过程中,检测到IO就切换其他任务

gevent模块

# 爬虫的例子
# 想要学会爬虫 正则一定要学会
# 请求过程中的IO等待
# from urllib.request import urlopen
# import requests
# url = 'http://www.baidu.com'
# res1 = urlopen(url)
# res2 = requests.get(url)
# print(res1)
# print(res1.read().decode("utf-8"))  # 有格式的
# print(res2)
# print(res2.content.decode("utf-8")) # 无格式的
# 执行速度更快
from gevent import monkey;monkey.patch_all()
import gevent
from urllib.request import urlopen
def get_url(url):
    response = urlopen(url)
    content = response.read().decode("utf-8")
    return len(content)
g1 = gevent.spawn(get_url,"http://www.baidu.com")
g2 = gevent.spawn(get_url,"http://www.sogou.com")
g3 = gevent.spawn(get_url,"http://www.taobao.com")
g4 = gevent.spawn(get_url,"http://www.hao123.com")
g5 = gevent.spawn(get_url,"http://www.cnblogs.com")
gevent.joinall([g1,g2,g3,g4,g5])
print(g1.value)
print(g2.value)
print(g3.value)
print(g4.value)
print(g5.value)
# ret = get_url("http://www.baidu.com")
# print(ret)
# 一个IO就没有必要协程了
# socket server

协程的应用

# server端
from gevent import monkey;monkey.patch_all()
import socket
import gevent
def talk(conn):
    conn.send( b"hello" )
    print( conn.recv( 1024 ).decode( "utf-8" ) )
    conn.close()
sk = socket.socket()
sk.bind(("127.0.0.1",8080))
sk.listen()
while True:
    conn,addr = sk.accept()
    gevent.spawn(talk,conn)
sk.close()
# client端
import socket
sk = socket.socket()
sk.connect(("127.0.0.1",8080))
msg = sk.recv(1024)
print(msg)
inp = input(">>>").encode("utf-8")
sk.send(inp)
sk.close()

协程socket操作

# *blocking IO      阻塞IO
# *nonblocking IO   非阻塞IO
# *IO multiplexing  IO多路复用
# *signal driven IO 信号驱动IO
# *asynchronous IO  异步IO
# 由signal driven IO(信号驱动IO)在实际中并不常用,所以主要介绍其余四种IO Model。
# 非阻塞IO的实例
# server端
import socket
sk = socket.socket()
sk.bind(("127.0.0.1",8080))
sk.setblocking(False)
sk.listen()
conn_lst = []
del_conn = []
while True:
    try:
        conn,addr = sk.accept() # 不阻塞,但是没人连我会报错
        print("建立连接了 : ",addr)
        conn_lst.append(conn)
        # msg = conn.recv(1024)   #不阻塞,但是没有消息会报错
        # print(msg)
    except BlockingIOError:
        for con in conn_lst:
            try:
                msg = con.recv(1024)    # 非阻塞,如果没有数据就报错
                if msg == b"":
                    del_conn.append(con)
                    continue
                print(msg)
                con.send(b"byebye")
            except BlockingIOError:pass
        for con in del_conn:
            conn_lst.remove(con)
        del_conn.clear()
# while True:10000次 500次
# 非阻塞并发
# client端
import time
import socket
import threading
def func():
    sk = socket.socket()
    sk.connect(("127.0.0.1",8080))
    sk.send(b"hello")
    time.sleep(0.1)
    sk.send(b"world")
    time.sleep(0.1)
    print(sk.recv(1024))
    sk.close()
for i in range(20):
    threading.Thread(target=func).start()
# IO多路复用的例子
# server端
from socket import *
import selectors
def accept(sk,mask):
    conn,addr=sk.accept()
    sel.register(conn,selectors.EVENT_READ,read)
def read(conn,mask):
    try:
        data=conn.recv(1024)
        if not data:
            print('closing',conn)
            sel.unregister(conn)
            conn.close()
            return
        conn.send(data.upper()+b'_SB')
    except Exception:
        print('closing', conn)
        sel.unregister(conn)
        conn.close()
sk = socket()
sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
sk.bind(('127.0.0.1',8088))
sk.listen(5)
sk.setblocking(False) #设置socket的接口为非阻塞
sel=selectors.DefaultSelector() # 选择一个适合我的IO多路复用的机制
sel.register(sk,selectors.EVENT_READ,accept)
#相当于网select的读列表里append了一个sk对象,并且绑定了一个回调函数accept
# 说白了就是 如果有人请求连接sk,就调用accept方法
while True:
    events=sel.select() #检测所有的sk,conn,是否有完成wait data的
    for sel_obj,mask in events:     # [sk][conn]
        callback=sel_obj.data #callback=accpet # callback = read
        callback(sel_obj.fileobj,mask) #accpet(sk,1) # accpet(conn,1)
# client端
from socket import *
c=socket()
c.connect(('127.0.0.1',8088))
while True:
    msg=input('>>: ')
    if not msg:continue
    c.send(msg.encode('utf-8'))
    data=c.recv(1024)
    print(data.decode('utf-8'))

IO控制模型

前端

前端的理论知识

<!--前端的理论
前端
    1. 前端是做什么的?
        web开发工作的
    2. 我们为什么要学前端?
        全栈必修的内容
    3. 前端都有哪些内容?
        1. HTML
        2. CSS
        3. JavaScript
        4.jQuery和Bootstrap
Web开发本质:
    1. 浏览器输入网址回车都发生了什么?
        1. 浏览器 给服务端 发送了一个消息
        2. 服务端拿到消息
        3. 服务端返回消息
        4. 浏览器展示页面
C/S架构 --> B/S架构
客户端和服务端 消息的格式是约定好的
HTTP协议: 浏览器和服务器之间约定好的消息格式  ==> "PUT|xxx.avi|1024"
WEB本质:
    服务端
    浏览器
    HTML文件
HTML是一个标准,规定了大家怎么写网页.
-->

前端的理论知识

HTML标签

常用标签

<!--被注释的内容--> <!--pycharm快捷键Ctrl+/-->
<!-DOCTYPE html> <!--默认使用html 5-->
<html lang="zn-CN"><!--必须要定义html标签默认使用中文显示-->
<head><!--html的标题头标签>
<!--浏览器相关的信息写在head标签中-->
<!--meta标签是提供有关页面的元信息
   用于搜索引擎、更新频度的描述和关键字 -->
    <meta charset="UTF-8"><!--charset默认使用什么编码-->
    <meta name="keywords" content="页面搜索的关键字">
    <!--keywords用于搜索引擎的关键字例如-->
    <meta name="description" content="描述内容">
    <!--description在搜索页面上显示的描述内容-->
    <meta http-equiv="refresh" content="10;www.soso.com">
    <!--http-equiv="refresh"可以跳转某个位置,content中,10;代表多少秒后跳转,;后面跟的是要跳转的地址-->
    <title>我的网页标题</title><!--title标签,html中的标题-->
    <style><!--html中的样式标签-->
        a{
                color:red;
            }
    </style><!--将所有a标签的字体修改为红色>
    <link rel="stylesheet" href="test.css">
    <!--转到css中的样式标签比较常用-->
    <!--test.css中的内容与style标签的方法一样-->
    <script><!--动作标签写js样式用的-->
        alert("hello world")
    </script>
</head>
<body><!--HTML中的身体标签-->
<!--在网页上显示的内容写在body标签中-->
<h1>标题内容</h1>
<h2>标题内容</h2>
<!--h1~h6标签,标题标签,字体随之变小-->
<p>段落内容</p><!--段落标签,注意h1~h6不能在段落标签中---->
<a href="http://www.baidu.com">百度一下你就知道</a>
<!--a标签用于超链接 href转到什么地址-->
<img src="a.jpg" alt="a图片的说明">
<!--alt是如果图片加载失败备注说明的-->
<img src="a.jpg" alt="a图片的说明" title="a.jpg">
<!-- title 是鼠标放在上面显示的内容-->
<div style="color:#00FF00">
<!--div标签可以把文档分割为独立的、不同的部分-->
<h3>标题3</h3>
<p>段落1</p>
</div>
<!--#+id内容可以实现页面跳转-->
<a href="#a2" id="a1">a1跳a2</a>
<div style="height:1000px;background-color: red"></div>
<div style="height: 500px;background-color: green"></div>
<a href="#a1" id="a2">a2跳a1</a>
</body>
</html>
<!--总结
常用标签
    h1~h6   标题
    img     插入图片
    a       插入超链接
    p        插入段落
    span    组合文档中的行内元素
    div    分割文档,独立内容
    i    显示斜体文本效果
    s   添加删除线文本
    u   添加下划线文本
    hr    创建一条水平线
    br    插入换行符
 特殊符号  空格 ©版权相关 <小于号 >大于号 ®注册商标相关 ...
   标签分类:
    块儿级标签            h1~h6 div p hr
        默认占浏览器宽度
        能设置长和宽
    内联标签(行内标签)   a img u s i b span
        根据内容决定长度
        不能设置长和宽
-->

html常用标签示例

列表标签

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>列表标签</title>
</head>
<body>
<!--无序的列表-->
<ul type="disc">
    <li>aaa</li>
    <li>bbb</li>
    <li>ccc</li>
</ul>
<!--实心圆-->
<ul type="circle">
    <li>aaa</li>
    <li>bbb</li>
    <li>ccc</li>
</ul>
<!--空心圆-->
<ul type="square">
    <li>aaa</li>
    <li>bbb</li>
    <li>ccc</li>
</ul>
<p>aaa</p>
<p>bbb</p>
<p>ccc</p>
<!--方形-->
<!--有序的列表-->
<ol type="I" start="3">
    <!--type = I代表罗马 start从多少开始-->
    <li>aaa</li>
    <li>bbb</li>
    <li>ccc</li>
</ol>
<ol type="A" start="3">
    <!--type = A代表大写字母 start从多少开始-->
    <li>aaa</li>
    <li>bbb</li>
    <li>ccc</li>
</ol>
<ol type="1" start="3">
    <!--type = 1代表数字 start从多少开始-->
    <li>aaa</li>
    <li>bbb</li>
    <li>ccc</li>
</ol>
<ol type="a" start="3">
    <!--type = 1代表小写字母 start从多少开始-->
    <li>aaa</li>
    <li>bbb</li>
    <li>ccc</li>
</ol>
<ol type="i" start="3">
    <!--type = i代表小写罗马 start从多少开始-->
    <li>aaa</li>
    <li>bbb</li>
    <li>ccc</li>
</ol>
<!--标题列表-->
<dl>
    <dt>标题1</dt>
    <dd>内容1</dd>
    <dt>标题2</dt>
    <dd>内容1</dd>
    <dd>内容2</dd>
</dl>
</body>
</html>

列表标签的示例

表格标签

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>表格标签</title>
</head>
<body>
<table border="10" cellpadding="10" cellspacing="10">
    <!--border是表格的边框 cellpadding是表格的内边距 cellspacing是表格的外边距-->
    <!--thead表格的头-->
    <thead>
    <!--tr表示一行-->
    <tr>
        <th>姓名</th>
        <!--thead中th表示一列-->
        <th>年龄</th>
        <th>爱好</th>
    </tr>
    </thead>
    <tbody>
    <!--tbody表格的身体-->
    <tr>
        <!--tbody中td表示一列-->
        <td colspan="2">小强</td>
        <!--colspan竖向合并单元格>
        <!--<td>20</td>-->
        <td rowspan="2">种地</td>
        <!--rowspan横向合并单元格-->
    </tr>
    <tr>
        <td>小李</td>
        <td>18</td>
        <!--<td>开车</td>-->
    </tr>
    </tbody>
</table>
<!--快捷创建标签
h1*4>a.c1[id=a$]{a标签的内容$}+tab快捷键
*创立多少个>a代表加a标签.c1代表添加class属性[id]代表添加id属性+{}代表输入标签内容,$代表数字排序-->
<!--CTRL+ALT+L快速格式化排序-->
<!--ALT+鼠标点击多行编辑内容-->
<!--emmt自动补全功能-->
<h1><a href="" class="c1" id="a1">a标签的内容1</a></h1>
<h1><a href="" class="c1" id="a2">a标签的内容2</a></h1>
<h1><a href="" class="c1" id="a3">a标签的内容3</a></h1>
<h1><a href="" class="c1" id="a4">a标签的内容4</a></h1>
</body>
</html>

表格标签的示例

表单标签

 <!DOCTYPE html>
 <html lang="zh-CN">
 <head>
     <meta charset="UTF-8">
     <title>form表单示例</title>
 </head>
 <body>
 <!--上传文件的固定格式-->
 <form action="http://127.0.0.1:8000/upload/" method="post" enctype="multipart/form-data" autocomplete="off">
     <!--搜索引擎展示信息用get请求——要东西-->
     <!--表单发送消息用post请求——给东西-->
     <!--action路径,往哪里提交的-->
     <p>
         <label for="i1">用户名:</label>
         <input name="username" type="text" id="i1" readonly value="小强">
         <input name="username" type="text" disabled placeholder="小强">
         <!--name往后端提交相当于字典中的键-->
     </p>
     <p>
         <label for="i2">密码:</label>
         <input id="i2" name="password" type="password">
     </p>
     <p>
         <label for="i3">邮箱:</label>
         <input id="i3" name="email" type="email">
     </p>
     <p>隐藏按钮:
         <input type="hidden" value="hidden">
     </p>
     <p> 性别:
         <label for="r1">男</label>
         <input id="r1" name="gender" type="radio" value="1">
         <label for="r2">女</label>
         <input id="r2" name="gender" type="radio" value="0">
         <label for="r3">保密</label>
         <input id="r3" checked name="gender" type="radio" value="0">
         <!--value往后端提交相当于字典中的值-->
     </p>
     <p>爱好:
         <label for="a1">篮球</label>
         <input id="a1" checked name="hobby" type="checkbox" value="basketball">
         <label for="a2">足球</label>
         <input id="a2" checked name="hobby" type="checkbox" value="football">
         <label for="a3">双色球</label>
         <input id="a3" checked name="hobby" type="checkbox" value="doublecolorball">
     </p>
     <p>
         <label for="b1">生日</label>
         <input id="b1" name="birthday" type="date">
     </p>
     <p>地址:
         <label>
             <select name="from1" id="s1">
                 <option value="bj">北京</option>
                 <option value="sh">上海</option>
                 <option value="sd">山东</option>
                 <option value="sc">四川</option>
             </select>
         </label>
         <label>
             <select name="from1" id="s2" multiple>
                 <option value="bj">北京</option>
                 <option value="sh" selected>上海</option>
                 <option value="sd">山东</option>
                 <option value="sc">四川</option>
             </select>
         </label>
         <label>
             <select name="from2" id="s3">
                 <optgroup label="北京">
                     <option value="cy">朝阳</option>
                     <option value="cp">昌平</option>
                     <option value="hd">海淀</option>
                     <option value="ft">丰台</option>
                 </optgroup>
                 <optgroup label="上海">
                     <option value="pdxq">浦东新区</option>
                     <option value="hpxq">黄埔新区</option>
                     <option value="mhq">闵行区</option>
                 </optgroup>
                 <optgroup label="四川">
                     <option value="pzh">攀枝花</option>
                     <option value="zg">自贡</option>
                     <option value="my">绵阳</option>
                 </optgroup>
             </select>
         </label>
     </p>
     <p>
         <label>
             <textarea name="info" id="t1" cols="30" rows="10"></textarea>
         </label>
     </p>
     <p>
         <input name="file" type="file">
     </p>
     <p>
         <input type="submit" value="提交">
         <input type="button" value="button">
         <input type="reset" value="重填">
     </p>
     <!--
     总结
     form标签 创建一个表单
     input标签 表单的输入
         type 表单的类型
             text 文本框
             submit 提交按钮
             password 密码文本框
             radio 复选框
                 name="gender" 单选框
             email 邮箱
             checkbox 多选框
             date 日期
             datetime 时间
             file 文件
             button 普通按钮,多用js给它绑定事件
             reset 重置按钮
             hidden 隐藏按钮
     select标签 下拉框

     option标签 配置下拉框名称
     optgroup标签 分组下拉框
     textarea标签 大文本框
     label标签 标注,标记标签
         标签的常用属性
             label  分组下拉框的名称
             name 传给后端相当于字典中的键 必须要添加
             value 传给后端相当于字典中的值 HTTP中设置默认值
             placeholder 设置占位的内容
             action 提交表单的位置路径,一般填写域名或IP地址
             autocomplete 开启和关闭自动补全功能
             novalldate 规定浏览器不验证表单
             method 规定在提交表单时所用的HTTP方法(默认GET)
             enctype 规定被提交数据的编码
             input单独属性
                 checked 默认选中什么
                 readonly 只读模式 配合value值使用
                 disabled 不可用,禁用
             select单独属性
                 multiple 布尔属性,设置后为多选,否则默认单选
                 selected 默认选中该项

     -->
 </form>
 </body>
 </html>

表单标签的示例

css样式

css选择器

 <!DOCTYPE html>
 <html lang="zh-CN">
 <head>
     <meta charset="UTF-8">
     <title>css引入的示例</title>
     <!--<style>-->
         <!--p{-->
             <!--color: green;-->
         <!--}-->
     <!--</style>-->
 </head>
 <body>
 <!--<p style="color: pink">海燕</p>-->
 <p id="p1">海燕</p>
 <p id="p2">这个是个黑色的海燕</p>
 <p class="c1">这个是个黄色的海燕</p>
 <p class="c1">这个是个黄色的海燕</p>
 <p class="c1">这个是个黄色的海燕</p>
 <p class="c1">这个是个黄色的海燕</p>

 <link rel="stylesheet" href="index.css">
 <!--index.css
 /*
 解释性的信息
 */

 /*全局通用的样式*/
 /*例如字体*/

 /*导航条的样式*/

 /*商品列表的样式*/
 p{
     color: red;
     font-size: 30px;
 }
 /*标签选择器*/
 h1{
     color: green;
     font-size: 60px;
 }
 /*ID选择器*/
 #p2{
     color: black;
 }
 /*类选择器*/
 .c1{
     color: yellow;
 }
 /*通用选择器*/
 *{
     margin-right: auto;
 }
 -->
 <h1>这是一个h1标签</h1>
 </body>
 </html>

css样式的引入

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>组合选择器的示例</title>
    <link rel="stylesheet" href="index2.css">
    <!-- index2.css的内容
/*组合选择器示例的css文件*/
/*后代选择器*/
/*两个元素中间加个空格*/
#d1 p{
    color: red;
}

/*儿子选择器*/
/*两个元素中间加个大于号*/
#d1 > p{
    color: green;
}

/*毗邻选择器:同级下面第一个*/
/*两个元素中间加个加号*/
div+p {
    color: yellow;
}

/*弟弟选择器:同级下面所有的*/
/*两个元素中间加个波浪线*/
div~p{
    color: blue;
} -->
    </head>
<body>
<div id="d1">
    <p>我是嵌套在div中的p标签</p>
    <span>我是嵌套在div中的span标签</span>
    <div>
        <p>我是嵌套在div中的div中的p标签</p>
        <span>我是嵌套在div中的div中的span标签</span>
    </div>
</div>
<hr>
<!--毗邻往下找第一个-->
<p>000</p>
<div>111</div>
<p>222</p>
<p>333</p>
</body>
</html>

组合选择器

 <!DOCTYPE html>
 <html lang="zh-CN">
 <head>
     <meta charset="UTF-8">
     <title>属性选择器示例</title>
     <style>
         /*属性选择器相关样式*/
         [s9] {
             color: red;
         }

         [s9="hao"] {
             color: green;
         }
     </style>
 </head>
 <body>
 <p s9="hao">我是一个p标签</p>
 <p s9="good">我也是一个p标签</p>
 <p>我还是一个p标签</p>
 </body>
 </html>

属性选择器

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>分组和嵌套示例</title>
    <style>
        /*分组和嵌套示例*/
        /*当样式有重复的时候*/
        /*,分割的是选择器属性*/
        /*推荐分行写选择器,但是要注意一定要加逗号*/
        #d1,
        p {
            color: red;
        }

        #p1 {
            color: deeppink;
        }

        /*嵌套使用选择器*/
        #d1 + p {
            color: blue;
        }

        /*权重就是2*/
        div + p {

        }

        /*权重就是101*/
        #d1 + p {

        }

        /*分组和嵌套示例*/
        /*当样式有重复的时候*/
        /*,分割的是选择器属性*/
        /*推荐分行写选择器,但是要注意一定要加逗号*/
        #d1,
        p {
            color: green;
        !important;
        }

        /*!important选择器优先级最高*/
        /*嵌套使用选择器*/
        /*#d1+p {*/
        /*color: blue;*/
        /*}*/
    </style>
</head>
<body>
<div id="d1">我是一个div标签</div>
<p id="p1">我是一个p标签</p>
<div id="d2" class="">11个类选择器</div>
<!--<p id="p1" style="color: pink">我是一个p标签</p>-->
</body>
</html>

分组和嵌套

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>伪类选择器</title>
    <style>
        /*链接没有被点击过的操作*/
        a:link {
            color: bisque;
        }
        /*链接被点击过操作*/
        a:visited {
            color: green;
        }
        /*鼠标移上去的操作*/
        a:hover {
            color: pink;
        }
        #d1{
            color: gray;
        }
        #d1:hover{
            color: #FF0000;
        }
        /*被选定的链接*/
        a:active {
            color: deeppink;
        }
        /*input获取光标时*/
        input:focus {
            outline: none;
            background-color: pink;
        }
    </style>
</head>
<body>
<a href="http://www.sogo.com">搜狗</a>
<a href="http://www.sohu.com">搜狐</a>
<div id="d1">我是div标签</div>
<input type="text">
</body>
</html>

伪类选择器

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>伪元素选择器</title>
    <style>
        /*开头文字*/
        p:first-letter {
            font-size: 40px;
            color: red;
        }
        /*在文字之前*/
        .c1:before {
            content: "*";
            color: red;
        }
        /*修改某文字*/
        .c1:after {
            content: "[?]";
            color: blue;
        }
    </style>
</head>
<body>
<p>
    在苍茫的大海上,狂风卷积着乌云.
    在苍茫的大海上,狂风卷积着乌云.
    在苍茫的大海上,狂风卷积着乌云.
    在苍茫的大海上,狂风卷积着乌云.
    在苍茫的大海上,狂风卷积着乌云.
    在苍茫的大海上,狂风卷积着乌云.</p>
<p class="c1">在苍茫的大海上,狂风卷积着乌云.[?]</p>
<p class="c1">在苍茫的大海上,狂风卷积着乌云.</p>
<p class="c1">在苍茫的大海上,狂风卷积着乌云.</p>
</body>
</html>

伪元素选择器

css的属性

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>字体属性的测试</title>
    <style>
        body {
            font-family: "Microsoft Uighur","微软雅黑","PingFang SC","Microsoft Yi Baiti","Arial";
            font-size: 30px;
        }
        /*rgb(红0~255绿0~255蓝0~255)*/
        .c0{

            color: rgb(255,0,0);
        }
        /*#二进制红绿蓝00=0~FF=255*/
        .c1{
            font-weight: 100;
            color: #00FF00;
        }
        /*rgba(红,绿,蓝,透明度)*/
        .c2 {
            font-weight: 900;
            color: rgba(0, 0, 255, 0.3);
        }
        .c3 {
            text-align: left;
            /* 左对齐 */
            text-align: right;
            /* 右对齐 */
            text-align: center;
            /* 居中对齐 */
            text-align: justify;
            /* 两端对齐 */
            text-decoration: underline;
            /*添加下划线*/
            text-indent: 30px;
            /*添加缩进*/
        ;
        }
        /*文字装饰 text-decoration 多用于去a标签的下划线*/
        a {
            text-decoration: none;
        }

    </style>
</head>
<body>
<h1>海燕</h1>
<p>在苍茫的大海上</p>
<p class="c0">默认的p</p>
<p class="c1">100 c1</p>
<p class="c2">900 c1</p>
<div class="c3">苍茫</div>
<p class="c3">
    在苍茫的大海上,狂风卷积着乌云.
    在苍茫的大海上,狂风卷积着乌云.
    在苍茫的大海上,狂风卷积着乌云.
    在苍茫的大海上,狂风卷积着乌云.
    在苍茫的大海上,狂风卷积着乌云.
    在苍茫的大海上,狂风卷积着乌云.</p>
<a href="http://www.sogo.com/">sogo</a>
</body>
</html>

字体属性

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>背景相关属性示例</title>
    <style>
        .c0{
            /*背景颜色*/
            background-color: #ff00ff;
        }
        .c1{
            width: 600px;
            /*宽*/
            height: 600px;
            /*高*/
            border: 1px;
            /*边框线*/
            background-image: url("图片地址");
            /*背景图片*/
            /*background-repeat: no-repeat;*/
            /*背景图片不重复操作,*/
            /*background-repeat: repeat-x;*/
            /*背景图片横着重复*/
            /*background-repeat: repeat-y;*/
            /*背景图片竖着重复*/
            /*background-position: center;*/
            /*背景图片居中*/
            /*background-position: 50% 50%;*/
            /*背景图片大小缩放*/
            background: url("图片地址") no-repeat 50% 50%;
            /*简写操作*/
        }
    </style>
</head>
<body>
<div class="c0">我是一个div标签</div>
<div class="c1"></div>
</body>
</html>

背景属性

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>背景不动效果示例</title>
    <style>
        .c1{
            height: 500px;
            background: red;
        }
        .c2{
            height: 500px;
            background: url("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1548074666379&di=f5fc0f092e6673c06556c327f270d2d1&imgtype=0&src=http%3A%2F%2Fs9.knowsky.com%2Fbizhi%2Fl%2F20100615%2F20109119%2520%25286%2529.jpg") no-repeat center;
            background-attachment: fixed;
            /*把背景图固定*/
        }
        .c3{
            height: 500px;
            background: green;
        }
    </style>
</head>
<body>
<div class="c1"></div>
<div class="c2"></div>
<div class="c3"></div>
</body>
</html>

背景不动的实例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>边框相关属性</title>
    <style>
        div {
            height: 200px;
            width: 300px;
            background-color: red;
            /*border-width: 10px;*/
            /*边框宽度*/
            /*border-color: green;*/
            /*边框颜色*/
            /*border-style: solid;*/
            /*边框样式*/
            /*border: 10px green solid;*/
            /*简写形式*/
            border-right: 10px solid green;
            /*右边框设置*/
        }
    </style>
</head>
<body>
<div></div>
</body>
</html>

边框属性

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>display属性示例</title>
    <style>
        .c1 {
            background-color: red;
            display: inline;
            /*以行内标签展示*/
        }

        .c2 {
            background-color: green;
            display: block;
            /*以块级标签展示*/
            width: 1000px;
        }

        li {
            list-style-type: none;
            /*去掉列表中小圆点*/
        }

        li {
            display: inline;
            /*将字体放在一行*/
            border-right: 2px solid #666;
            padding: 10px;

        }

        li.last {
            border-right: none;
        }
        li>a{
            border-right: 1px red solid;
            padding: 0 15px;
            display: inline-block;
            /*既有行内标签的特点又有块级标签的特点*/
        }
    </style>
</head>
<body>
<div class="c1">div</div>
<span class="c2">span</span>
<span class="c2">span</span>
<ul>
    <li><a href="">玉米商城</a></li>
    <li><a href="">电脑</a></li>
    <li><a href="">手机</a></li>
    <li class="last"><a href="">爆米花</a></li>
</ul>
</body>
</html>

display属性(展示标签属性)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>盒子模型的示例</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .c1{
            height: 200px;
            width: 300px;
            border: 5px solid green;
            margin-top: 5px;
            /*外边距上边是多少*/
            margin-right: 10px;
            /*外边距右边是多少*/
            margin-bottom: 15px;
            /*外边距下边是多少*/
            margin-left: 20px;
            /*外边距左边是多少*/
            margin: 5px 10px 15px 20px;
            /*上右下左简写形式*/
            /*4个顺序:上右下左*/
            margin: 20px 30px;
            /*上下各20px,左右各30px简写形式*/
            padding: 20px 30px;
            /*2个顺序上下各20px 左右各30px*/
            padding: 10px 20px 30px;
            /*三个顺序 上10px 左右20px 下30px*/
            margin: 0 auto;
            margin-bottom: 50px;
            /*两个标签之间上下边距会自动合并*/
            /*上下是0 左右是自动调整*/
        }
        /*1.padding:内容区和边框之间的距离(内填充/内边距)*/
        /*2.margin:边框之外的距离(多用来调整 标签和标签之间的距离)*/
        /*盒子顺序最内-最外 content(内容)->padding(内填充/内边距)->border(边距)->margin(外边距)*/
        .c2{
           height: 100px;
            width: 100%;
            background-color: red;
            margin-top: 100px;
            /*因此只用一个就可以了*/
        }
    </style>
</head>
<body>
<div class="c1"></div>
<div class="c2"></div>
</body>
</html>

盒子模型

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>float页面布局示例</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .c1{
            height: 1000px;
            width: 20%;
            background-color: red;
            float: left;
            /*左边浮动*/
        }
        .c2{
            height: 1000px;
            width: 10%;
            background-color: green;
            float: right;
            /*右边浮动*/
        }
        a{
            float: left;
            /*左边浮动*/
            width: 1000px;
        }
        /*浮动操作在超过宽度范围会另起一行*/
    </style>
</head>
<body>
<div class="c1"></div>
<div class="c2"></div>
<a href="">我是a标签</a>
</body>
</html>

float浮动示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>清除float示例</title>
    <style>
        #d1{
            border: 1px solid black;
        }
        .c1{
            height: 50px;
            width: 50px;
            background-color: blue;
            border: 1px solid red;
            float: right;
        }
        /*.c2{*/
            /*!*height: 50px;*!*/
            /*clear: left;*/
            /*清除左边的浮动*/

            /*background-color: pink;*/
        /*}*/
        .c3{
            height: 200px;
            background-color: red;
        }
        /*#d1:after{*/
            /*content: "";*/
            /*clear: both;*/
            /*display: block;*/
        /*}*/
        .clearfix:after{
            content: "";
            clear: both;
        /*清除两端浮动*/
            display: block;
        }
        /*清除浮动的副作用*/
    </style>
</head>
<body>
<div id="d1" class="clearfix">
    <div class="c1"></div>
    <div class="c1"></div>
    <div class="c1"></div>
    <div class="c1"></div>
    <!--<div class="c2"></div>-->
</div>
<div class="c3">我是正常的内容块</div>
</body>
</html>

清除浮动的示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>overflow示例</title>
    <style>
        .c1 {
            width: 120px;
            height: 120px;
            border: 1px solid black;
            overflow: hidden;
            /*hidden隐藏溢出属性*/
            overflow: auto;
            /*auto自动设置溢出属性*/
            overflow: scroll;
            /*scroll 下拉框溢出属性*/
            /*overflow溢出属性实例*/
        }
        .header-img{
            width: 120px;
            height: 120px;
           border: 2px solid red;
            border-radius: 100%;
            overflow: hidden;
        }
        img{
             max-width: 100%;
        }
    </style>
</head>
<body>
<div class="c1">
    海燕啊,你可长点心吧
    海燕啊,你可长点心吧
    海燕啊,你可长点心吧
    海燕啊,你可长点心吧 海燕啊,你可长点心吧,海燕啊,你可长点心吧
</div>
<div class="header-img">
    <img src="http://www.qq22.com.cn/uploads/allimg/c170107/14SH019253450-1215Q.jpg" alt="">
</div>
</body>
</html>

overflow溢出属性

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>定位属性的示例</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .c1,
        .c2,
        .c3,
        .c4,
        .c4-father{
            width: 150px;
            height: 150px;
        }

        .c1 {
            background-color: #FF0000;
        }

        .c2 {
            background-color: #00FF00;
            position: relative;
            /*相对定位相对于原来在的位置*/
            left: 400px;
            top: 150px;
            /*左边400,上下150+150*/
        }

        .c3 {
            background-color: blue;
        }

        .c4 {
            background-color: deeppink;
            position: absolute;
            /*绝对定位相对于最近的一个被定位过的祖宗标签*/
            top: 150px;
            left: 400px;
        }
        .c4-father{
            background-color: gray;
            position: relative;
            left: 150px;
        }
        .fixed-text{
            position: fixed;
            right: 20px;
            bottom: 20px;
            background-color: gray;
        }
        /*固定在某个位置(返回顶部)*/
    </style>
</head>
<body>
<div id="d1">
    <div class="c1">c1</div>
    <div class="c2">c2</div>
    <div class="c3">c3</div>
    <div class="c4-father">c4-father
        <div class="c4">c4</div>
    </div>
</div>
<div class="fixed-text">返回顶部</div>
</body>
</html>

定位属性

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>blog页面示例</title>
    <!--blog页面相关的css-->
    <style>
        /*公共样式*/
        * {
            font-family: Arial, "PingFang SC", "Microsoft JhengHei", sans-serif;
            font-size: 14px;
            margin: 0;
            padding: 0;
        }
        /*去掉a标签的下划线*/
        a {
            text-decoration: none;
        }
        /*左边栏样式*/
        .left {
            width: 20%;
            background-color: rgb(76, 77, 76);
            height: 100%;
            position: fixed;
            left: 0;
            top: 0;
        }
        /*头像样式*/
        .header-img {
            height: 128px;
            width: 128px;
            border: 5px solid white;
            border-radius: 50%;
            /*头像边框为圆*/
            overflow: hidden;
            /*头像溢出部分隐藏*/
            margin: 0 auto;
            margin-top: 20px;
        }
        .header-img > img {
            max-width: 100%;
            /*图片设定为父标签的100%大小*/

        }
        /*blog 名称*/
        .blog-name {
            color: white;
            font-size: 24px;
            font-weight: bold;
            text-align: center;
            margin-top: 15px;
        }
        /*blog 介绍*/
        .blog-info {
            color: white;
            text-align: center;
            border: 2px solid white;
            margin: 5px 15px;
        }
        /*去ul标签的点*/
        ul{
            list-style: none;
        }
        /*连接组和标签组*/
        .blog-links,
        .blog-tags {
            text-align: center;
            margin-top: 20px;
        }
        .blog-links a,
        .blog-tags a {
            color: #eee;
        }
        /*在标签前面添加#*/
        .blog-tags a:before {
            content: "#";
        }
        /*右边栏样式*/
        .right {
            width: 80%;
            background-color: rgb(238, 237, 237);
            height: 1000px;
            float: right;
        }
        /*文章列表样式*/
        .article-list {
            margin-left: 30px;
            margin-right: 10%;
            margin-top: 30px;
        }
        /*文章样式*/
        .article {
            margin-bottom: 15px;
            background-color: white;
        }
        /*文章发布时间*/
        .article-date {
            float: right;
        }
        /*文章名称样式*/
        .article-name {
            display: inline-block;
            /*将文章名称设定在一行*/
        }
        /*文章标题样式*/
        .article-title {
            padding: 15px;
            border-left: 3px solid red;
        }
        /*文章内容样式*/
        .article-info {
            padding: 15px;
        }
        /*文章标签样式*/
        .article-tag {
            padding: 15px 0;
            margin: 15px;
            border-top: 1px solid #eeeeee;
        }
    </style>
</head>
<body>
<!--左边栏 开始-->
<div class="left">
    <!--头像开始-->
    <div class="header-img">
        <img src="http://www.qq22.com.cn/uploads/allimg/c170107/14SH019253450-1215Q.jpg" alt="">
    </div>
    <!--头像结束-->
    <div class="blog-name">小强的blog</div>
    <div class="blog-info">这个人很懒什么都没有写</div>
    <!--连接区开始-->
    <div class="blog-links">
        <ul>
            <li><a href="">关于我</a></li>
            <li><a href="">关于你</a></li>
            <li><a href="">关于她</a></li>
        </ul>
    </div>
    <!--连接区 结束-->
    <!--文章分类开始-->
    <div class="blog-tags">
        <ul>
            <li><a href="">js</a></li>
            <li><a href="">css</a></li>
            <li><a href="">html</a></li>
        </ul>
    </div>
    <!--文章分类结束-->
</div>
<!--左边栏结束-->
<!--右边栏开始-->
<div class="right">
    <div class="article-list">
        <div class="article">
            <div class="article-title">
                <h1 class="article-name">海燕</h1>
                <span class="article-date">2018-1-22</span>
            </div>
            <div class="article-info">
                在苍茫的大海上,狂风卷积着乌云,在乌云和大海之间,海燕像黑色的闪电,在高傲的飞翔
            </div>
            <div class="article-tag">
                #HTML #CSS
            </div>
        </div>
        <div class="article">
            <div class="article-title">
                <h1 class="article-name">海燕</h1>
                <span class="article-date">2018-1-22</span>
            </div>
            <div class="article-info">
                在苍茫的大海上,狂风卷积着乌云,在乌云和大海之间,海燕像黑色的闪电,在高傲的飞翔
            </div>
            <div class="article-tag">
                #HTML #CSS
            </div>
        </div>
        <div class="article">
            <div class="article-title">
                <h1 class="article-name">海燕</h1>
                <span class="article-date">2018-1-22</span>
            </div>
            <div class="article-info">
                在苍茫的大海上,狂风卷积着乌云,在乌云和大海之间,海燕像黑色的闪电,在高傲的飞翔
            </div>
            <div class="article-tag">
                #HTML #CSS
            </div>
        </div>
    </div>
</div>
<!--右边栏结束-->
</body>
</html>

blog的实例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>脱离文档流的示例</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .c1{
            height: 100px;
            width: 100px;
            background-color: red;
        }
        .c2{
            height: 150px;
            width: 150px;
            background-color: green;
            /*float: right;*/
            /*position: relative;*/
            /*left: 300px;*/
            /*position: absolute;*/
            /*left: 400px;*/
            position: fixed;
            right: 100px;
            top: 100px;
        }
        .c3{
            height: 200px;
            width: 200px;
            background-color: blue;
        }
    </style>
</head>
<body>
<div class="c1"></div>
<div class="c2"></div>
<div class="c3"></div>
</body>
</html>

脱离文档流

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>透明度示例</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .c1,
        .c2 {
            height: 400px;
            width: 400px;
            color: red;
        }

        .c1 {
            background-color: black;
            opacity: 0.5;
        /*透明度的属性设置*/
        }

        .c2 {
            background-color: rgba(0, 0, 0, 0.5);
        }
        /*     opacity和rgba的区别:
                1.opacity改变元素|子元素的透明度效果
                2.rgba()只改变背景颜色的透明度效果/*
    </style>
</head>
<body>
<div class="c1">我是有c1类的div标签</div>
<div class="c2">我是有c2类的div标签</div>
</body>
</html>

透明度属性示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>z-index的示例</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .c1{
            height: 150px;
            width: 150px;
            background-color: red;
            position: relative;
            z-index: 2;
        }
        .c2{
            height: 200px;
            width: 200px;
            background-color: green;
            position: relative;
            top: -150px;
        }
        /*z-index
            1.数值越大,越靠近你
            2.只能作用于定位过的元素
            3.自定义的模态框示例*/
    </style>
</head>
<body>
<div class="c1"></div>
<div class="c2"></div>
</body>
</html>

z-index的示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>青春版模态框示例</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        .cover{
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            background-color: rgba(0,0,0,0.5);
            z-index: 999;
        }
        .modal{
            width: 500px;
            height: 400px;
            background-color: white;
            position: fixed;
            top: 50%;
            left:50%;
            margin-top: -200px;
            margin-left: -300px;
            z-index: 1000;
        }
    </style>
</head>
<body>
<div class="cover"></div>
<div class="modal"></div>
</body>
</html>

模态框示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>小米商城导航条</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            font-size: 14px;
            font-family: "Microsoft Uighur", "微软雅黑", "PingFang SC", "Microsoft Yi Baiti", "Arial",monospace;
        }
        a{
            color: #eeeeee;
            text-decoration: none;
            padding-right: 5px;
            border-right: 1px solid rgba(96,96,96,0.8);
            display: inline-block;
        }
        a.last{
            border-right: none;
        }
        a:hover{
            color: white;
        }
        ul {
            list-style: none;
        }

        .nav-left li {
            float: left;
            padding-right: 10px;
        }
        .nav-right {
            float: right;
            padding-right: 5px;
        }
        .nav {
            background-color: black;
            padding: 10px 0;
        }

        .clearfix:after,
        .clearfix:before {
            clear: both;
            content: "";
            display: block;
        }
        .s9{
            width: 95%;
            margin: 0 auto;
        }
    </style>
</head>
<body>
<div class="nav ">
    <div class="s9 clearfix">
        <div class="nav-left">
            <ul>
                <li><a href="">玉米商城</a></li>
                <li><a href="">小米</a></li>
                <li><a href="">小米</a></li>
                <li><a href="">黑米</a></li>
                <li><a href="">糙米</a></li>
                <li><a href="">花生油</a></li>
                <li><a href="">豆浆汁</a></li>
                <li><a href="" class="last">牛奶</a></li>
            </ul>
        </div>
        <div class="nav-right">
            <a href="">登录</a>
            <a href="">注册</a>
            <a href="" class="last">购物车</a>
        </div>
    </div>
</div>
</body>
</html>

小米商城导航条示例

<!--css的总结
    html相当于骨架
    css相当于衣服 穿上漂亮的衣服
    <标签1 样式=xxx>
    <标签2 样式=xxx>
    <标签3 样式=xxx>
    1.重复的样式
    2.文档内容和样式的解耦方便维护
    --;css 层叠cascade 样式style 表
    -->css 如何引入?
        1.直接写在标签里面 style="样式1;样式2"
        2.在head里面通过style标签定义
        3.把样式单独写在css文件中,然后在html文件中通过link
    css语法:
        选择器(找到某个标签){属性(color):值(red);样式2;}
    --> 选择器类型
        标签选择器 直接填标签
        ID选择器  填写ID的地址
        类选择器  最常用
        组合选择器
        属性选择
        分组和嵌套
    --> 选择器的优先级
        1.内联样式(直接在标签里面写style)优先级最高
        2.选择器都一样的情况下,谁靠近标签谁就生效
        3.选择器不一样的情况下 内联选择器权重1000>#id选择器权重100>.类选择权重10>元素(标签)选择器权重1
        !important选择器优先级最高
    1.伪类和伪元素
        1.伪类
            1.a:link
            2.a:visited
            3.a:hover(重要)
            4.:active
            5.:focus(input标签获取光标焦点)
        2.伪元素
            1.:first-letter(首字母样式)
            2.:before(重要 在内部前面添加)
            3.:after(重要 在内部后面添加)
    2.css属性
        1.字体
            1.font-family (默认字体)
            2.font-size (字体大小)
            3.font-weight   (字体宽度)
        2.文本属性
            1.text-align(对齐 重要)
            2.text-decoration 装饰 (去a标签下划线有用)
            3.text-indent 首行缩进
        3.背景属性
            1.background-color 背景颜色
            2.background-image 背景图片 url() no-repeat 50% 50%
        4.color
            1.red(直接写名字)
            2.#FF00FF
            3.rgb(255,0,0)
            4.rgba(255,0,0,0.2) a代表透明度
        5.边框属性 border
            1. border-width(边框宽度)
            2. border-style(边框边框)
            3. border-color(边框颜色)
            简写:
                border 1px solid red;
        6.css盒子模型
            1.content(内容)
            2.padding(内边距) 调整内容与边框之间距离
            3.border(边框)
            4.margin(外边距)  调整标签之间的距离(注意两个挨着的标签margin)
        注意:要习惯看浏览器console窗口的那个盒子模型
        7.display(标签的展现形式)
            1.inline (行内标签)
            2.block (块级标签) 菜单里的a标签可以设置成black
            3.inline-block (既有行内标签的特点又有块级标签的特点)
            4.none(不让标签显示,不占位)
        8.float(浮动)
            1.多用于实现布局效果
                1.顶部的导航条
                2.页面的左右分栏(博客页面:左边20%,右边80%)
            2.float
                1.任何标签都可以浮动,浮动之后都会变成块级,a标签float之后就可以设置高和宽
            3.float取值
                1.left
                2.right
                3.none
        9.clear 清除浮动-> 清除浮动的副作用(内容飞出,父标签撑不起来)
            1.结合伪元素来实现
            .clearfix:after{
                    content:"",
                    display:"block",
                    clear:both;
            }
            clear取值:
                1.left
                2.right
                3.both
        10. overflow
            1. 标签的内容放不下(溢出)
            2. 取值:
                1.hidden --> 隐藏
                2.scroll --> 出现滚动条
                3.inherit --> 继承
                4.auto --> 自动出现滚动条
                5.scroll-x -->
                5.scroll-y -->
            例子:
                圆形头像的例子
                    1.overflow:hidden
                    2.border-radius:50% (圆角)
        11. 定义 position
            1.static (默认)
            2.relative(相对定位--> 相当于原来的位置)
            3.abslute(绝对定位--> 相当对于定位过的前辈标签)
            4.fixed(固定位置) --> 返回顶部按钮示例
        补充:
            脱离文档流的三种方式
                float
                absolute
                fixed
        12. opacity(不透明度)
            1.取值0~1
            2.和rgba的区别:
                1.opacity改变元素|子元素的透明度效果
                2.rgba()只改变背景颜色的透明度效果
        13.z-index
            1.数值越大,越靠近你
            2.只能作用于定位过的元素
            3.自定义的模态框示例 -->

css的总结笔记

JavaScript

JS基础语法

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>BOM和DOM的示例</title>
</head>
<body>
<div id="s9">s9</div>
<script src="01.js"></script>
<!--引入js的方法1-->
<!--<script>-->
    <!--alert("欢迎进入网页")-->
<!--</script>-->
<!--引入js的方法2-->
<!--01.js内容
alert(
    "来自星星的你"
);
// 单行注释
/**
 * 多好注释
 */
//变量声明
var name = "alex";
var age = 32;
var $ = "女";
var userName = "aa";
//数字类型
var n1 = 18;
var n2 = 18.1;
var n3 = 1.81e5;
var n4 = NaN;
//变量名的命名规则
    //变量命名规则类似python JS中$也可以用来做变量名
//console.log相当于python中的print
console.log("name:",name);
console.log("age:",age);
console.log("$:",$);
console.log("userName:",userName);
-->
</body>
</html>

JS的引入

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>字符串的方法</title>
</head>
<body>
<script src="02.js"></script>
<!-- var s1 = "abc 12345";
    s1.length;
    // 查看字符串长度 相当于python的len
    var s2 = " abc  123456  ";
    s2.trim();
    // 去掉左右两端的空格 相当于python的strip
    s2.trim().length;
    //去掉左右空格后字符串的长度
    s2.charAt(5);
    //返回字符串的第几个字符,相当于python的查询
    s2.concat(1, 2, 3);
    //拼接,默认加到最后,相当于python的append
    s2.indexOf();
    //索引 相当于python中的index
    s2.substr();
    //根据索引取序列,注意slice的区别,start>end start和end交换,负数则归零
    s2.slice();
    //切片,与python中的slice一样
    s2.toUpperCase();
    //全部大写
    s2.toLowerCase();
    //全部小写
    s2.split(' ', 5)
    //分割, 第一个参数是根据什么分割,第二个参数限制返回的元素数量-->
</body>
</html>

字符串的方法

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>数据类型的方法</title>
</head>
<body>
<script src="03.js"></script>
<!--03.js的内容
var li = [1,2,3,4];
//创建一个列表
li.length;
//列表的长度
li.push(1,2,3);
//添加元素到最后尾部 类似于python的append
li.pop();
//跳出最后一个元素,与python的pop相同
li.join(li,"+");
//拼接,类似于python的join用法不同 "+".join(li)但python只能拼接字符串
li.concat([1,2,3],["a","b","c"]);
//连接数组,将几个数组连接到一起
li.unshift(1,2,3);
// 头部插入元素
li.shift(1,2,3);
// 头部移除元素
li.indexOf();
// 查找
li.reverse();
// 反转
li = [19,9,24,47];
li.sort();
/** 排序 有些问题,19,9,24,47排序是按照字符编码的顺序排序,因此19,24,47,9
 * 解决此问题的方法**/
function sortNumber(a,b){
    return a-b
}
li.sort(sortNumber);
//自定义数字排序
li.slice();
// 切片 与python不同的是不可以使用[0:2]
//数组的遍历
var a1 = [1,2,3,4];
for (var i=0;i<a1.length;i++){
    console.log(a1[i]);
}
// null表示值是空的,清空变量的值
// undefined 变量声明了而并没有赋值
// 查看数据类型的方法
var newName = "xiaoqiang";
//没有赋值的变量 就会返回一个undefined
var newAge = 18;
var shuai = false;
var exGirlFriends = ["凤姐","芙蓉阿姨","如花"];
var handPaper;
typeof newName;
//"string"
typeof newAge;
//"number"
typeof shuai;
//"boolean"
typeof exGirlFriends;
//"object"
typeof handPaper;
//"undefined"
handPaper = null;
// null
typeof handPaper;
//"object"
null == undefined;
//true
// 算术运算符
// + - * / % ++ -- 基本一样,只是++类型于python +=1 --是-=1
//比较运算符
/** > >= < <= != == 基本一样,只是==是弱等于,可以不判断类型,只判断值
 * === 和 !=== 跟python一样,!=是弱不等于**/
//逻辑运算符
// &&与 ||或 !非
//赋值运算符
//= += -= *= /= 与python一样
-->
</body>
</html>

数据类型的方法

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>判断与循环</title>
</head>
<body>
<script src="04.js"></script>
<!--04.js内容
// 判断if - else
var a = 10;
if (a > 5){
    console.log("yes")
}
else {
    console.log("no");
}
// 判断if-else if-else
var b = 10;
if (b > 5) {
    console.log("b > 5");
}
else if (b < 5){
    console.log("b < 5");
}
else {
    console.log("yes")
}
// for循环语句
n = [1,2,3,"alex","小强"];
for (var i = 0;i < n.length;i++){
    console.log(i);
    //显示的n的索引
    console.log(n[i]);
    //遍历n的值
}
// while循环语句
var age = 10;
while (age <= 18){
    console.log("再等一年");
    age ++;
}
// 三元运算
var num1 = 10;
var num2 = 20;
var num3 = num1 > num2 ? num1 : num2;
console.log(num3);
-->
</body>
</html>

分支和循环

JS的函数

// 函数的定义
function foo(a, b) {
    console.log("a:", a);
    console.log("b:", b);
    //函数的返回值
    return a + b;
}

//匿名函数
var func = function (a, b) {
    console.log("a:", a);
    console.log("b:", b);
    return a + b;
};
//立即执行函数
(function (a, b) {
    console.log("立即执行函数");
    console.log(a + b);
    var sss = "我是函数内部的变量";
})(11, 22);
// console.log(sss);// 外部访问不到函数内部定义的变量(用立即执行函数防止变量污染全局)

// console.log("立即执行函数");
// console.log(a + b);
// var sss = "我是函数内部的变量";
console.log("=============================");
//函数的调用
var ret = foo(11, 22, 33, 44);
//参数多了不报错,只是占位
var ret = foo(11);
//参数少了也不报错,会返回一个undefined,计算的结果是NaN(不是数字)

//返回值的调用
console.log("a+b=", ret);

//匿名函数的调用
var ret2 = func(11, 22);
console.log("a+b=", ret2);

// arguments 相当于python中的*args
function fun2() {
    console.log("总共有" + arguments.length + "个参数");
    var ret = 0;
    for (var i = 0; i < arguments.length; i++) {
        ret += arguments[i]
    }
    return ret;
}
console.log(fun2(11, 22, 33));
/**
 *函数的全局变量和局部变量
 *局部变量:

在JavaScript函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它(该变量的作用域是函数内部)。只要函数运行完毕,本地变量就会被删除。

全局变量:

在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。

变量生存周期:

JavaScript变量的生命期从它们被声明的时间开始。

局部变量会在函数运行以后被删除。

全局变量会在页面关闭后被删除。
 **/

// JS中的作用域
var city1 = "BeiJing";
function f1() {
  var city1 = "ShangHai";
  function inner(){
    var city1 = "ShenZhen";
    console.log(city1);
  }
  inner();
}
f1();  //输出结果是? //"ShenZhen"

var city2 = "BeiJing";
function Bar() {
  console.log(city2);
}
function f2() {
  var city2 = "ShangHai";
  return Bar;
}
var ret1 = f2();
ret1();  // 打印结果是? // "BeiJing"

// JS中的闭包
var city3 = "BeiJing";
function f3(){
    var city3 = "ShangHai";
    function inner(){
        console.log(city3);
    }
    return inner;
}
var ret3 = f3();
ret3();  // 打印结果是? // "ShangHai"

// JS中的词法分析
var age1 = 18;

function func3() {
    console.log(age1); // 去alive object(AO)找age
    var age1 = 22; // AO.age = undefined
    console.log(age1);

    // function age() { // AO.age = function(){...}
    //     console.log("xxxx");
    // }
}

func3();// 问: 执行func3()之后的结果是? H
// A:18 22
// B:22 22
// C:22 18
// E:18 18
// F:null 22
// H:undefined 22

var age = 18;
function foo1() {
    console.log(age);
    console.log(typeof age);
    age();
    console.log("=================");
    var age = 22;
    console.log(age);
    function age() {
        console.log("呵呵");
    }
    console.log(age);
}

foo();  // 执行后的结果是?

//1. 先分析 给AO赋值
// var age = 22 --> AO.age = undefined;
// function age(){console.log("呵呵");} -- > AO.age = function(){...};

//2. 真正执行阶段
// function(){...};
//
//

//3. 总共三个值

/**
词法分析过程:
1、分析参数,有一个参数,形成一个 AO.age=undefine;
2、分析变量声明,有一个 var age, 发现 AO 上面已经有一个 AO.age,因此不做任何处理
3、分析函数声明,有一个 function age(){...} 声明, 则把原有的 age 覆盖成 AO.age=function(){...};

最终,AO上的属性只有一个age,并且值为一个函数声明

执行过程:
注意:执行过程中所有的值都是从AO对象上去寻找

1、执行第一个 console.log(age) 时,此时的 AO.age 是一个函数,所以第一个输出的一个函数
2、这句 var age=22; 是对 AO.age 的属性赋值, 此时AO.age=22 ,所以在第二个输出的是 2
3、同理第三个输出的还是22, 因为中间再没有改变age值的语句了**/

JS的函数

JS内置对象和方法

// JS中自定义对象
var person = {name: '小强', age: 18};
// 在JS的对象中,键(属性)默认不用加引号;并且自动把单引号转成双引号;
console.log(person);
// 单独取对象的属性
console.log("name:", person.name);
console.log("age:", person.age);
// 遍历对象的属性
for (var i in person) {
    console.log(i);
    //打印出的i是person的键
    console.log(person[i])
    //person[i]打印出的是值
}
var name = "abc";
var person1 = {
    name: "小强",
    age: 18,
    abc: 100,
};
console.log(person1.name);
//对象内部取对象值直接用.就可以取到
console.log(person1[name]);
console.log(person1["abc"]);
// 中括号是在属性名是保存在变量中的情况
// 自定义对象的另一种方式
var person2 = Object();
person2.name = "小强";
person2.age = 22;
for (var i1 in person2) {
    console.log(person2[i1]);
}
// Data对象
var d1 = new Date();
console.log(d1);
console.log(typeof d1);
console.log(d1.toLocaleString());
console.log(typeof d1.toLocaleString());
// 生成指定时间的Date对象
var d2 = new Date("2019/1/29 11:22");
console.log(d2.toLocaleString()); // 转成字符串格式的本地时间
console.log(d2.toUTCString()); // 转成字符串格式的UTC时间
console.log(d2.getDate());// 获取那一天(多少号)
console.log(d2.getDay());// 获取那一天(星期几)
console.log(d2.getMonth());// 获取月份
console.log(d2.getFullYear());// 获取完整年份
console.log(d2.getHours());// 获取小时
console.log(d2.getMinutes());// 获取分钟
console.log(d2.getSeconds());// 获取秒
console.log(d2.getTime());// 获取时间戳
// 编写代码,将当前日期按“2017-12-27 11:11 星期三”格式输出。

// Json对象
console.log("==================");
var s = '{"name":"xiaoqiang","age":18}';
// 把字符串转换成JS内部的对象
var ret = JSON.parse(s);
console.log(ret);
console.log(typeof ret);
// 把JS内部的对象转换成字符串
var s2 = JSON.stringify(ret);
console.log(s2);
console.log(typeof s2);

// RegExp对象 --> Python re模块
// 生成 RegExp对象
var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$");
var regexpRet1 = reg1.test('xiaoqiang');
console.log(regexpRet1);
var regexpRet2 = reg1.test('1xiaoqiang');
console.log(regexpRet2);
// 另一种 生成RegExp方法
// 坑1(正则表达式中间一定不可以有空格)
console.log("==================");
console.log(/^[a-zA-Z][a-zA-Z0-9_]{5,11}$/.test("xiaoqiang"));
console.log(/^[a-zA-Z][a-zA-Z0-9_]{5,11}$/.test("1xiaoqiang"));
// 坑2
// test()不传值相当于传一个undefined进去
// 然后test()就把这个undefined当成是"undefined"来判断
console.log("==================");
console.log(/^[a-zA-Z][a-zA-Z0-9_]{5,11}$/.test("undefined"));
console.log(/^[0-9a-zA-Z][a-zA-Z0-9_]{5,11}$/.test(undefined));
console.log(/^[0-9][a-zA-Z0-9_]{5,11}$/.test(undefined));
console.log(/^[0-9][a-zA-Z0-9_]{5,11}$/.test("undefined"));
// JS正则的两种模式
// 1.g表示全局
// 2.i忽略大小写
var ss = "Alexdashuaibi";
var s3 = ss.replace(/a/gi,"哈哈哈");
//g全局替换,i忽略大小写
console.log(s3);
// 替换 不是改变默认的字符串,而是生成了一个新的字符串
// 坑3
// 当正则表达式使用了全局模式(g)的时候,并且你还让它去检测一个字符串,此时会引出来一个lastIndex会记住上一次匹配成功的位置,并把下一次要开始校验的位置记住
console.log("========================");
var r = /alex/g;
console.log(/^a[a-zA-Z]{2}$/g.test("ale"));
console.log(/^a[a-zA-Z]{2}$/g.test("ale"));
console.log(r.test("alex")); // true
console.log(r.lastIndex);
//lastIndex会记住上一次匹配成功的位置
console.log(r.test("1234alex")); // true
console.log(r.lastIndex);
console.log(r.test("alex")); // true
console.log(r.lastIndex);
console.log(r.test("alex")); // false
// Math对象
var n = -5;
Math.abs(n); // 绝对值 5
Math.floor(6.9); // 对数进行舍入6
Math.max(11, 20); // 最大值 20
Math.min(11, 20); // 最小值 11
Math.pow(10, 2); // 幂运算 100
Math.random(); // 随机小数
Math.round(5.6); // 四舍五入取整
alert("登入可访问"); // 警告框
confirm("你年满十八了?"); // 确认框
prompt("请在下方输入","你的答案"); // 回答框

内置对象和方法

BOM和DOM

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Bom相关内容</title>
</head>
<body>
<script>
    // 多少秒之后做什么事
    var t1 = setTimeout("alert(123);", 3000);
    // 三秒后显示警告框
    clearTimeout(t1);
    // 清除定时器
    function foo() {
        console.log("呵呵");
    }
    var t2 = setTimeout(foo, 3000);
    // 三秒后调用函数foo
    // 每隔多少秒做什么事
    var t3 = setInterval(foo, 1000);
    // 每个1000毫秒执行一次foo函数
    clearInterval(t3);
    // 清除上面的定时器
    //比较重要的只有location
    console.log(location.href);//获取当前的URL
    console.log(location.href = "http://www.sogo.com"); // 跳转到指定网址
    console.log(location.reload()); //重新加载当前页面
</script>
</body>
</html>

BOM的示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>DOM查询相关操作</title>
</head>
<body>
<div id="d1">div</div>
<p class="c1">p标签</p>
<p class="c1">p标签2</p>
<p class="c2">第二个p标签</p>

<div id="d2">
    <div id="d3">d2里面的d3</div>
    <div id="d4">d2里面的d4</div>
    <div id="d5">d2里面的d5</div>
</div>
<script>
    console.log(document.getElementById("d1"));
    // 按照id找到所属标签
    console.log(document.getElementsByClassName("c1"));
    // 按照类名找到所属标签
    console.log(document.getElementsByTagName("p"));
    // 按照标签找到所属的标签
    var d3Ele = document.getElementById("d3");
    // 找到d3标签的所在位置
    console.log(d3Ele.parentElement);
    // 找到d3的父标签 id = "d2"
    var d2Ele = document.getElementById("d2");
    console.log(d2Ele.children);
    // 找到d2下的所有子标签
    console.log(d2Ele.firstElementChild);
    // 找到d2下面的第一个子标签
    console.log(d2Ele.lastElementChild);
    // 找到d2下面的最后一个子标签
    var d4Ele = document.getElementById("d4");
    console.log(d4.nextElementSibling);
    // 找下一个兄弟标签
    console.log(d4.previousElementSibling);
    // 找上一个兄弟标签
    var imgEle = document.createElement("img");
    // 创建一个新的img标签
    var d1Ele = document.getElementById("d1");
    // 找到d1标签
    console.log(d1Ele.appendChild(imgEle));
    // d1下面添加一个子标签,将img标签添加到进去
    console.log(imgEle.src = "http://pic27.nipic.com/20130225/4746571_081826094000_2.jpg");
    // 给img标签添加src属性
    var aEle = document.createElement("a");
    // 创建一个新的a标签
    console.log(d2Ele.insertBefore(aEle, d3Ele));
    // 在d2Ele的内部,d3Ele的前面插入一个新的aEle
    console.log(aEle.innerText = "点我进入搜狗");
    // 给a标签设置文本内容
    console.log(aEle.href = "http://www.sogo.com");
    // 给a标签设置href属性
    console.log(d2Ele.innerText);
    // 获取d2标签内的所有文本内容
    console.log(d2Ele.innerHTML);
    // 获取d2标签内的所有标签
    console.log(d2Ele.innerHTML = "<p>我是d2内部的p标签</p>")
    // 快速添加简单的标签
    var sonPEle = d2Ele.firstElementChild;
    // console.log(d2Ele.removeChild(sonPEle));
    // 从d2Ele的内部把sonPEle删掉
    console.log(d2Ele.replaceChild(aEle,sonPEle));
    // 从d2Ele的内部用aEle替换sonPEle
</script>
</body>
</html>

DOM查询相关操作

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>获取值相关</title>
</head>
<body>
<form action="">
    <label>用户名
        <input name="username" id="i1" type="text">
    </label>
    <label>男
        <input name="gender" value="1" type="radio">
    </label>
    <label>女
        <input name="gender" value="0" type="radio">
    </label>
    <label> <select name="from" id="s1">
        <option value="010">北京</option>
        <option value="021">上海</option>
        <option value="023">重庆</option>
        <option value="022">天津</option>
    </select>
        <textarea id="t1" name="memo" cols="30" rows="10">
    </textarea>
    </label>
</form>
<script>
    var i1Ele = document.getElementById("i1");
    console.log(i1Ele.value);
    //   获取文本输入的内容
    var redioEle = document.getElementsByName("gender");
    console.log(redioEle.values());
    // 获取复选框选择的内容
    var selectEle = document.getElementById("s1");
    console.log(selectEle.value);
    // 获取下拉选择的内容
    var tEle = document.getElementById("t1");
    console.log(tEle.value);
    // 获取大文本框的内容
</script>
</body>
</html>

获取值相关

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>class相关操作</title>
    <style>
        .c1 {
            height: 200px;
            width: 200px;
            border-radius: 50%;
            background-color: grey;
        }
        .c2 {
            background-color: yellow;
        }
    </style>
</head>
<body>
<div class="c1 c2 c3" onclick="change(this);">div</div>
<div class="c1 c2 c3">div</div>
<div class="c1 c2 c3">div</div>
<div class="c1 c2 c3">div</div>
<script>
    function change(ths) {
        ths.classList.toggle("c2");
    }
//    第二种绑定事件的方式
    var divEles = document.getElementsByTagName("div");
    for (var i=0;i<divEles.length;i++){
        divEles[i].onclick=function () {
            this.classList.toggle("c2");
        }
    }
</script>
</body>
</html>

class相关操作

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>定时器事件</title>
</head>
<body>
<label>
    <input id="i1" type="text">
    <input id="start" type="button" value="开始">
    <input id="stop" type="button" value="结束">
</label>
<script>
    var t;
    // 声明一个全局的t,给它绑定事件
    function foo() {
        //在input框里显示当前时间
        //1.获取当前时间
        var now = new Date();
        var nowstr = now.toLocaleString();
        //2.把时间字符串填到input里
        var i1Ele = document.getElementById("i1");
        i1Ele.value = nowstr;
    }

    //    点开始让时间动起来
    //    每隔一秒钟执行foo
    var startButton = document.getElementById("start");
    startButton.onclick = function () {
        foo();
        if (t === undefined) {
            t = setInterval(foo, 1000);// 把定时器的ID复制给全局变量
        }
    };
    // 点停止
    // 找到停止按钮,给它绑定事件
    var stopButton = document.getElementById("stop");
    stopButton.onclick = function () {
        //    清除之前设置的定时器
        clearInterval(t);// 清除t对应的定时器但是t的值还在
        console.log(t);
        t = undefined;
    }
</script>
</body>
</html>

定时器事件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>搜索框示例</title>
</head>
<body>
<label>
    <input type="text" id="i1" value="对子哈特">
    <input type="button" value="搜索">
</label>
<script>
    // 找到input框
    var i1Ele = document.getElementById("i1");
    i1Ele.onfocus=function () {
    //    把value清空
        this.value="";
    };
    i1Ele.onblur=function () {
    //  失去焦点之后把如果值为空就填回去
        if (!this.value.trim()){
            this.value="年货节食品";
        }
    };
</script>
</body>
</html>

搜索框示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>select联动</title>
</head>
<body>
<label>
    <select id="s1">
        <option value="0">--请选择--</option>
        <option value="1">北京</option>
        <option value="">上海</option>
    </select>
    <select id="s2">

    </select>
</label>
<script>
    var data = {1: ["昌平区", "朝阳区", "海淀区"], 2: ["静安区", "闵行区", "浦东区"]};
    // 给第一个select绑定事件,绑定的是onchange事件;
    var s1Ele = document.getElementById("s1");
    s1Ele.onchange = function () {
        //    取到你选的是哪一个市
        console.log(this.value);
        //    把对应的区镇到第二个select框里面
        var areas = data[this.value];// 取到市对应的区
        // 找到s2
        var s2Ele = document.getElementById("s2");
        // 清空之前的
        s2Ele.innerHTML="";
        //    生成option标签
        for (var i = 0; i < areas.length; i++) {
            var opEle = document.createElement("option");
            opEle.innerText = areas[i];
            //    添加到select内部
            s2Ele.appendChild(opEle);
        }
    }
</script>
</body>
</html>

select联动

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>内容回顾补充示例</title>
    <script>
        alert(123);
    </script>
</head>
<body>

<div id="d1" onclick="showText(this)">d1</div>
<hr>
<div id="d2" onclick="showText(this)">d2</div>

<script>
//    var d1Ele = document.getElementById("d1");
//    console.log(d1Ele.innerText);
    // 形参ths
    function showText(xiaodongbei) {
        console.log(xiaodongbei.innerText);
        xiaodongbei.style.color="green";
    }
    // 找要绑定事件的标签
    var divEles = document.getElementsByTagName("div");
    for (var i=0;i<divEles.length;i++) {
        divEles[i].ondblclick=function () {
            alert(this.innerText + "666");
        }
    }
</script>
</body>
</html>

事件的补充示例

jQuery

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>jQuery初识</title>
</head>
<body>

<div id="d1">d1</div>
<div class="c1">.c1</div>
<p class="c2">p</p>
<a class="c2" href="">a标签</a>

<!--筛选器-->
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>

<!--not-->
<div id="d2">
    <p class="c1">div</p>
    <p class="c1">div</p>
    <p class="c2">div</p>
    <p class="c2">div</p>
</div>

<!--:has-->
<div id="d3">
    <div style="background-color: green">
        <p>div中的p标签</p>
    </div>

    <div style="background-color: red">
        <a href="">div中的a标签</a>
    </div>
</div>

<!--属性选择器-->
<form action="" id="f1">
    <label>用户名:
        <input name="username" type="text" disabled>
    </label>

    <label>密码:
        <input name="pwd" type="password">
    </label>

    <label>篮球:
        <input name="hobby" value="basketball" type="checkbox">
    </label>

    <label>足球:
        <input name="hobby" value="football" type="checkbox">
    </label>

    <label>男
        <input name="gender" value="1" type="radio">
    </label>

    <label>女:
        <input name="gender" value="0" type="radio">
    </label>

</form>
<script src="jquery-3.2.1.min.js"></script>
<script>
    // 基本选择器的方法
    console.log($("#d1"));
    // 根据id查找
    console.log($(".c1"));
    // 根据类查找
    console.log($("div"));
    // 根据标签查找
    console.log($("*"));
    // 查找全部标签
    console.log($(".c1,a"));
    // 组合查找,c1标签和a标签
    // 筛选器的方法
    console.log($("ul li:first"));
    // 筛选第一个li标签
    console.log($("ul li:last"));
    // 筛选最后一个li标签
    console.log($("ul li:eq(2)"));
    // eq根据索引查找中间的li标签
    console.log($("ul li:eq(-2)"));
    // 可以倒着索引
    console.log($("ul li:even"));
    // 根据索引值为偶数的筛选
    console.log($("ul li:odd"));
    // 根据索引值为奇数的筛选
    console.log($("ul li:gt(3)"));
    // 根据大于索引值的筛选
    console.log($("ul li:lt(3)"));
    // 根据小于索引值的筛选
    console.log($("#d2 p:not(.c2)"));
    // 根据not把c2样式类的筛选掉
    console.log($("#d3 div:has(a)"));
    // 根据has查找含有a标签的div
    // 属性选择器
    console.log($("input[name='hobby']"));
    // 根据name="hobby"属性 找爱好这一组
    console.log($("input[name='gender']"));
    // 根据name="gender"属性 找到男女这一组
    console.log($(":text"));
    // 找文本属性
    console.log($(":password"));
    // 找密码属性
    console.log($(":disabled"));
    // 找被禁用的属性
    console.log($(":checked"));
    // 找到被选中的属性
</script>
</body>
</html>

初识jQuery

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>筛选器示例</title>
</head>
<body>
<!--筛选器-->
<ul>
    <li id="l0">l0</li>
    <li>l1</li>
    <li>l2</li>
    <li id="l3">l3</li>
    <li>l4</li>
    <li>l5</li>
</ul>

<!--父标签-->
<div id="d1">div-1
    <div id="d2">div-2
        <div id="d3">div-3
            <a href="">a标签</a>
        </div>
    </div>
</div>

<!--兄弟和儿子-->

<div id="dd">
    <p>p0</p>
    <p>p1</p>
    <p id="p2">p2</p>
    <p>p3</p>
</div>
<script src="jquery-3.2.1.min.js"></script>
<script>
    console.log($("#l3").prev());
    // 找l3上一个标签
    console.log($("#l3").next());
    // 找l3下一个标签
    console.log($("#l3").prevAll());
    // 找l3上所有标签
    console.log($("#l3").nextAll());
    // 找l3下所有标签
    console.log($("#l0").nextUntil("#l3"));
    // 找l0下所有标签到l3为止
    console.log($("#l3").prevUntil("#l0"));
    // 找l3上所有标签到l0为止

    // 根据父标签查找
    console.log($("a").parent().parent());
    // 根据a标签找父标签,可以链式操作
    console.log($("a").parents());
    // 根据a标签找所有父标签(全部找出来)
    console.log($("a").parents("body"));
    // 可以指定到什么位置为止

    // 根据儿子标签查找
    console.log($("#dd").children());
    // 找到dd标签下的所有子标签

    // 根据兄弟标签查找
    console.log($("#p2").siblings());
    // 找到p2标签的上下标签

    // 查找元素
    var $c1Ele = $(".c1");
    console.log($($c1Ele).find("div"));
    // find可以根据各种选择器配合使用,一般用于别人传给你的参数

    // 操作标签
    console.log($("div").first());
    // 与:first一样
    console.log($("div").last());
    // 与:last一样
    console.log($("#p2").addClass("c1"));
    // 给标签添加一个类
    console.log($("#p2").addClass("c2"));
    console.log($("#p2").removeClass("c2"));
    // 删除c2类
    console.log($("#p2").hasClass("c2"));
    // 查看是否有c1类标签
</script>
</body>
</html>

筛选器的示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>样式操作示例</title>
    <style>
        .c1 {
            height: 200px;
            width: 200px;
            border-radius: 50%;
            background-color: red;
        }
        .c2 {
            background-color: green;
        }
    </style>
</head>
<body>
<div class="c1"></div>
<script src="jquery-3.2.1.min.js"></script>
<script>
    // 找标签
    $("div.c1").click(function () {
        // console.log(this);  // this是DOM对象
        $(this).toggleClass("c2"); // 有就删掉 没有就加上
    })
</script>
</body>
</html>

样式操作示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>jQuery选择器筛选器练习</title>
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <style>

        .my-padding {
            padding: 10px 0;
        }

        .my-dark {
            background-color: #f5f5f5;
        }

        .footer {
            background: #111;
            font-size: 0.9em;
            position: relative;
            clear: both;
        }

        .my-white {
            color: #ffffff;
        }

        body {
            margin: 0;
        }

        #progress {
            height: 2px;
            background-color: #b91f1f;
            transition: opacity 500ms linear;
        }

        #progress.done {
            opacity: 0;
        }
    </style>
</head>
<body>
<div id="progress"></div>
<!--导航栏开始-->
<nav class="navbar navbar-inverse my-nav">
    <div class="container">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="http://www.oldboyedu.com/"><strong>OldBoy Edu</strong></a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li><a href="#">Python学院<span class="sr-only">(current)</span></a></li>
                <li><a href="#">Linux学院</a></li>
                <li><a href="http://luffy.oldboyedu.com">路飞学城</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">好好学习</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">联系我们<span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Rain</a></li>
                        <li><a href="#">Egon</a></li>
                        <li><a href="#">Yuan</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">Q1mi</a></li>
                    </ul>
                </li>
            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>
<!--导航栏结束-->

<div class="container">

    <div class="jumbotron">
        <div id="j1" class="container">
            <h1 class="c1">沙河前端小王子</h1>
            <h1 class="c1">带你学习jQuery</h1>
            <p id="p1"><a class="btn btn-primary btn-lg" href="https://q1mi.github.io/Blog/2017/07/10/about_jQuery/"
                          role="button">查看更多</a></p></div>
    </div>
    <hr>
    <div class="row">
        <div class="col-md-12">
            <table class="table table-bordered table-striped">
                <thead>
                <tr>
                    <th>#</th>
                    <th>姓名</th>
                    <th>爱好</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    <th>1</th>
                    <td>Eva_J</td>
                    <td>茶道</td>
                    <td>
                        <button class="btn btn-warning">编辑</button>
                        <button class="btn btn-danger">删除</button>
                    </td>
                </tr>
                <tr>
                    <th>2</th>
                    <td>Yuan</td>
                    <td>日天</td>
                    <td>
                        <button class="btn btn-warning">编辑</button>
                        <button class="btn btn-danger">删除</button>
                    </td>
                </tr>
                <tr id="tr3">
                    <th>3</th>
                    <td>Alex</td>
                    <td>吹牛逼</td>
                    <td>
                        <button class="btn btn-warning">编辑</button>
                        <button class="btn btn-danger">删除</button>
                    </td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>

    <hr>
    <div class="row">
        <div class="col-md-12">
            <form id="f1">
                <div class="form-group">
                    <label for="exampleInputEmail1">邮箱</label>
                    <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
                </div>
                <div class="form-group">
                    <label for="exampleInputPassword1">密码</label>
                    <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
                </div>
                <div class="form-group">
                    <label for="exampleInputFile">上传头像</label>
                    <input type="file" id="exampleInputFile">
                    <p class="help-block">只支持img格式。</p>
                </div>
                <button id="btnSubmit" type="submit" class="btn btn-default">提交</button>
            </form>
        </div>
    </div>

    <hr>

    <div class="row">
        <div class="col-md-12">
            <div class="checkbox-wrapper">
                <div class="panel panel-info">
                    <div class="panel-heading">jQuery学习指南</div>
                    <div id="my-checkbox" class="panel-body">
                        <div class="checkbox">
                            <label>
                                <input type="checkbox" value="0">
                                jQuery一点都不难
                            </label>
                        </div>
                        <div class="checkbox">
                            <label>
                                <input type="checkbox" value="1" checked>
                                jQuery一学就会
                            </label>
                        </div>
                        <div class="checkbox">
                            <label>
                                <input type="checkbox" value="2">
                                jQuery就要多练
                            </label>
                        </div>

                        <div class="checkbox">
                            <label>
                                <input type="checkbox" value="3" disabled>
                                jQuery学不好
                            </label>
                        </div>
                    </div>
                </div>
            </div>
            <hr>
            <div class="radio-wrapper">

                <div class="panel panel-info">
                    <div class="panel-heading">我来老男孩之后...</div>
                    <div class="panel-body">
                        <div class="radio">
                            <label>
                                <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
                                我的心中只有学习
                            </label>
                        </div>
                        <div class="radio">
                            <label>
                                <input type="radio" name="optionsRadios" id="optionsRadios2" value="option2">
                                学习真的太TM有意思了
                            </label>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <hr>

    <div>
        <i class="fa fa-hand-pointer-o fa-lg fa-rotate-90" aria-hidden="true"></i>
        <a class="btn btn-success" href="http://jquery.cuishifeng.cn/">jQuery中文API指南</a>
    </div>

    <hr>

    <div class="row">
        <div class="col-md-12">
            <h2>练习题:</h2>
            <ol id="o1">
                <li>找到本页面中id是<code>i1</code>的标签</li>
                <li>找到本页面中所有的<code>h2</code>标签</li>
                <li>找到本页面中所有的<code>input</code>标签</li>
                <li>找到本页面所有样式类中有<code>c1</code>的标签</li>
                <li>找到本页面所有样式类中有<code>btn-default</code>的标签</li>
                <li>找到本页面所有样式类中有<code>c1</code>的标签和所有<code>h2</code>标签</li>
                <li>找到本页面所有样式类中有<code>c1</code>的标签和id是<code>p3</code>的标签</li>
                <li>找到本页面所有样式类中有<code>c1</code>的标签和所有样式类中有<code>btn</code>的标签</li>
                <p id="p2" class="divider"></p>
                <li>找到本页面中<code>form</code>标签中的所有<code>input</code>标签</li>
                <li>找到本页面中被包裹在<code>label</code>标签内的<code>input</code>标签</li>
                <li>找到本页面中紧挨在<code>label</code>标签后面的<code>input</code>标签</li>
                <li>找到本页面中id为<code>p2</code>的标签后面所有和它同级的<code>li</code>标签</li>
                <p id="p3" class="divider"></p>
                <li>找到id值为<code>f1</code>的标签内部的第一个input标签</li>
                <li>找到id值为<code>my-checkbox</code>的标签内部最后一个input标签</li>
                <li>找到id值为<code>my-checkbox</code>的标签内部没有被选中的那个input标签</li>
                <li>找到所有含有<code>input</code>标签的<code>label</code>标签</li>
            </ol>
        </div>
    </div>
</div>

<div class="my-dark my-padding">
    <div class="container">
        <div class="col-sm-8 my-center">
            <p>写很少的代码,做很多的事。</p>
            <h4>所以说</h4>
            <p>学好jQuery真的很重要,学好jQuery真的很重要,学好jQuery真的很重要。</p>
        </div>
    </div>
</div>

<div class="footer">
    <div class="row">
        <div class="col-md-12 text-center">
            <span class="my-white">&copy;2018 沙河前端小王子</span>
        </div>
    </div>
</div>

<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
    // 1.找到本页面中id是i1
    console.log($("#i1")); // 根据ID查找对应的标签
    // 2.找到本页面中所有的h2标签
    console.log($("h2")); // 根据标签查找对应的标签
    // 3.找到本页面中所有的input标签
    console.log($("input"));
    // 4.找到本页面所有样式类中有c1的标签
    console.log($(".c1")); // 根据类标签查找对应的标签
    // 5.找到本页面所有样式类中有btn-default的标签
    console.log($(".btn-default"));
    // 6.找到本页面所有样式类中有c1的标签和所有h2标签
    console.log($(".c1,h2")); // 组合查找对应类标签和普通标签
    // 7.到本页面所有样式类中有c1的标签和id是p3的标签
    console.log($(".c1,#p3")); // 组合查找对应类标签和id标签
    // 8.找到本页面所有样式类中有c1的标签和所有样式类中有btn的标签
    console.log($(".c1,.btn")); // 组合查找对应的两个类标签
    // 9.找到本页面中form标签中的所有input标签
    console.log($("form input")); // 后代选择器查找form标签下所有input标签
    // 10.找到本页面中被包裹在label标签内的input标签
    console.log($("label>input")); // 儿子选择器查找label标签内的input标签
    // 11.找到本页面中紧挨在label标签后面的input标签
    console.log($("label+input")); // 毗邻选择器查找label标签后面的第一个input标签
    // 12.找到本页面中id为p2的标签后面所有和它同级的li标签
    console.log($("#p2~li")); // 弟弟选择器查找id为p2的同级li标签
    // 13.找到id值为f1的标签内部的第一个input标签
    console.log($("#f1 input:first"));
    // 14.找到id值为my-checkbox的标签内部最后一个input标签
    console.log($("#my-checkbox input:last"));
    // 15.找到id值为my-checkbox的标签内部没有被选中的那个input标签
    console.log($("#my-checkbox:not(input)"));
    // 16.找到所有含有input标签的label标签
    console.log($("label:has(input)"));
    // 补充DOM和jQuery的互相转换
    document.getElementById("p3");
    // console.log($("#p3").html());
    // console.log($("#p3")[0].innerHTML);
    var pEle = document.getElementById("p3");
    $(pEle);// DOM转换jQuery
    var $pEle = $("#p3"); // 定义jQuery变量要在前面加个$符号
</script>
</body>
</html>

jQuery选择器筛选器练习

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>左侧菜单作业分解</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            list-style-type: none;
        }
        .hide {
            display: none;
        }
        .left-menu{
            background-color: #111111;
            width: 15%;
            height: 1000px;
        }
        .menu-title{
            font-size: 24px;
            color: white;
            background-color: #666666;
            text-align: center;
            border: 1px white solid;
        }
        .menu-items{
            font-size: 20px;
        }
        a{
            text-decoration: none;
            color: white;
        }
        a:hover{
            color: pink;
        }
        li{
            border: 1px solid white;
            text-align: center;
        }
    </style>
</head>
<body>

<div class="left-menu">
    <div class="menu-title ">菜单一</div>
    <div class="menu-items hide ">
        <ul>
            <li><a href="">111</a></li>
            <li><a href="">222</a></li>
            <li><a href="">333</a></li>
        </ul>
    </div>
    <div class="menu-title">菜单二</div>
    <div class="menu-items hide">
        <ul>
            <li><a href="">111</a></li>
            <li><a href="">222</a></li>
            <li><a href="">333</a></li>
        </ul>
    </div>
    <div class="menu-title">菜单三</div>
    <div class="menu-items hide">
        <ul>
            <li><a href="">111</a></li>
            <li><a href="">222</a></li>
            <li><a href="">333</a></li>
        </ul>
    </div>
</div>

<script src="jquery-3.2.1.min.js"></script>
<script>
    // 需求分析
    // 找到所有的.menu-title标签,绑定点击事件
    $(".menu-title").click(function () {
        // 点击事件具体要做的事儿
        // 1. 找到当前点击菜单下面的.menu-items,把它显示出来(移除hide类)
        $(this).next().toggleClass("hide");
        // 2. 把其他的.menu-items隐藏,添加hide类
        $(this).next().siblings(".menu-items").addClass("hide");
    });
    // var $first = $(".menu-items").first();
    // $first.siblings(".menu-items").removeClass("hide");
    // $(".menu-title").click(function () {
    //     // 1. 找到所有的.menu-items, 隐藏
    //     var $currMenuitems = $(this).next();
    //     $(".menu-items").not($currMenuitems).addClass("hide"); // 所有二级菜单都是隐藏的
    //     // 2. 找到当前点击菜单下面的.menu-items,把它显示出来(移除hide类)
    //     $(this).next().toggleClass("hide");
    // });
</script>
</body>
</html>

左侧菜单作业


"""
Python模拟链式操作示例
"""
class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def wang(self):
        print("旺旺~")
        return self
    def run(self):
        print("哒哒~哒哒~")
        return self
f = Foo("大黄", 9000)
# 链式操作
f.wang().run()
# f2 = f.wang()
# f2.run()
f.run()

python链式操作示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>模态框的示例</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .cover {
            background-color: rgba(0, 0, 0, 0.4);
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
            z-index: 998;
        }
        .modal {
            width: 600px;
            height: 400px;
            background-color: white;
            position: absolute;
            left: 50%;
            top: 50%;
            margin-left: -300px;
            margin-top: -200px;
            z-index: 1000;
        }

        .hide {
            display: none;
        }
    </style>
</head>
<body>
<input type="button" id="b1" value="屠龙宝刀,点击即送">
<div class="cover hide"></div>
<div class="modal hide ">
    <p>
        <label>用户名:
            <input type="text" name="username">
        </label>
    </p>
    <p>
        <label>密码:
            <input type="password" name="password">
        </label>
    </p>

    <p>
        <label>
            <input type="submit" value="登录">
        </label>
        <label>
            <input id="b2" type="button" value="取消">
        </label>
    </p>
</div>
<script src="../jquery-3.2.1.min.js"></script>
<script>
    $("#b1").click(function () {
        $(".cover").removeClass("hide");
        $(".modal").removeClass("hide");
    // 移除背景色和模态框的hide把模态框展示出来
    });
    $("#b2").click(function () {
        $(".cover").addClass("hide");
        $(".modal").addClass("hide");
    // 添加背景色和模态框的hide把模态框隐藏起来
    })
</script>
</body>
</html>

jQuery模态框示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>小强</p>
<p>二哥</p>
<div>div</div>
<script src="../jquery-3.2.1.min.js"></script>
<script>
    $("p").click(function () {
        $(this).css({"color": "red", "font-size": "24px"});
        // 用jQuery给p标签添加多个样式,样式之间用字典表示
    });
    $("div").css({"background": "green", "width": "100px", "height": "100px","color":"white","font-size":"48px"})
        // 用jQuery给div添加多个样式,样式之间用字典表示
</script>
</body>
</html>

jQuery修改css样式

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>位置相关的方法</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .c1,
        .c2,
        .c3 {
            background: #FF0000;
            position: relative;
            width: 100px;
            height: 100px;
        }

        .c2 {
            position: relative;
            top: 200px;
            left: 200px;
        }

        .c3 {
            position: absolute;
            top:100px;
            left: 100px;
            background-color: blue;
        }
    </style>
</head>
<body>
<div class="c1">我是c1类的div标签</div>
<div class="c2">我是c2类的div标签
    <div class="div c3">我是c3类的div标签</div>
</div>
<script src="../jquery-3.2.1.min.js"></script>
<script>
    var $c1Eles = $(".c1");
    var $c2Eles = $(".c2");
    var $c3Eles = $(".c3");
    console.log($c1Eles.offset()); // left:0,top:0
    console.log($c2Eles.offset()); // left:200,top:300
    console.log($c3Eles.offset()); // left:300,top:400
    console.log($c2Eles.offset({left:100,top:100})); // 修改位置
    // 这个获取的位置是从绝对定位获取的值
    console.log($c2Eles.offset()); // left:100,top:100
    // 这个获取的位置是从相对定位获取的值
    console.log($c3Eles.position()) // left:100,top:100
</script>
</body>
</html>

jQuery位置相关操作

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .c1{
            width: 100px;
            height: 200px;
            background-color: red;
        }
        .c2{
            height: 50px;
            width: 50px;
            position: fixed;
            bottom: 15px;
            right: 15px;
            background-color: #2b669a;
        }
        .hide{
            display: none;
        }
        .c3{
            height: 100px
        }
    </style>
</head>
<body>
<button id="b1" class="btn btn-default">点我</button>
<div class="c1"></div>
<div class="c3">1</div>
<div class="c3">2</div>
<div class="c3">3</div>
<div class="c3">4</div>
<div class="c3">5</div>
<div class="c3">6</div>
<div class="c3">7</div>
<div class="c3">8</div>
<div class="c3">9</div>
<div class="c3">10</div>
<div class="c3">11</div>
<div class="c3">12</div>
<div class="c3">13</div>
<div class="c3">14</div>
<div class="c3">15</div>
<div class="c3">16</div>
<div class="c3">17</div>
<div class="c3">18</div>
<div class="c3">19</div>
<div class="c3">20</div>
<div class="c3">21</div>
<div class="c3">22</div>
<div class="c3">23</div>
<div class="c3">24</div>
<div class="c3">25</div>
<div class="c3">26</div>
<div class="c3">27</div>
<div class="c3">28</div>
<div class="c3">29</div>
<div class="c3">30</div>
<div class="c3">31</div>
<div class="c3">32</div>
<div class="c3">33</div>
<div class="c3">34</div>
<div class="c3">35</div>
<div class="c3">36</div>
<div class="c3">37</div>
<div class="c3">38</div>
<div class="c3">39</div>
<div class="c3">40</div>
<div class="c3">41</div>
<div class="c3">42</div>
<div class="c3">43</div>
<div class="c3">44</div>
<div class="c3">45</div>
<div class="c3">46</div>
<div class="c3">47</div>
<div class="c3">48</div>
<div class="c3">49</div>
<div class="c3">50</div>
<div class="c3">51</div>
<div class="c3">52</div>
<div class="c3">53</div>
<div class="c3">54</div>
<div class="c3">55</div>
<div class="c3">56</div>
<div class="c3">57</div>
<div class="c3">58</div>
<div class="c3">59</div>
<div class="c3">60</div>
<div class="c3">61</div>
<div class="c3">62</div>
<div class="c3">63</div>
<div class="c3">64</div>
<div class="c3">65</div>
<div class="c3">66</div>
<div class="c3">67</div>
<div class="c3">68</div>
<div class="c3">69</div>
<div class="c3">70</div>
<div class="c3">71</div>
<div class="c3">72</div>
<div class="c3">73</div>
<div class="c3">74</div>
<div class="c3">75</div>
<div class="c3">76</div>
<div class="c3">77</div>
<div class="c3">78</div>
<div class="c3">79</div>
<div class="c3">80</div>
<div class="c3">81</div>
<div class="c3">82</div>
<div class="c3">83</div>
<div class="c3">84</div>
<div class="c3">85</div>
<div class="c3">86</div>
<div class="c3">87</div>
<div class="c3">88</div>
<div class="c3">89</div>
<div class="c3">90</div>
<div class="c3">91</div>
<div class="c3">92</div>
<div class="c3">93</div>
<div class="c3">94</div>
<div class="c3">95</div>
<div class="c3">96</div>
<div class="c3">97</div>
<div class="c3">98</div>
<div class="c3">99</div>
<div class="c3">100</div>
<button id="b2" class="btn btn-default c2 hide">返回顶部</button>
<script src="jquery-3.2.1.min.js"></script>
<script>
    $("#b1").on("click",function () {
        $(".c1").offset({left:200,top:200});
    });
    $(window).scroll(function () {
    if ($(window).scrollTop()>100){
        $("#b2").removeClass("hide")
    }
    else {
        $("#b2").addClass("hide")
    }
    });
    $("#b2").on("click",function () {
        $(window).scrollTop(0);
    })
//    scrollTop顶部位置
</script>
</body>
</html>

jQuery返回顶部的示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>尺寸示例</title>
    <style>
        .c1 {
            background-color: red;
            height: 100px;
            width: 200px;
            padding: 10px;
            margin: 20px;
            border: 5px solid green;
        }
    </style>
</head>
<body>
<div>
    <div class="c1">div</div>
</div>
<script src="jquery-3.2.1.min.js"></script>
<script>
    var $c1Eles = $(".c1");
    console.log($c1Eles.width());// 获得宽度尺寸
    console.log($c1Eles.height());// 获得高度尺寸
    console.log($c1Eles.innerWidth());// 获取宽度+padding(内边距)的尺寸
    console.log($c1Eles.innerHeight());// 获取高度+padding(内边距)的尺寸
    console.log($c1Eles.outerWidth());// 获取宽度+padding+border的尺寸
    console.log($c1Eles.outerHeight());// 获取高度+padding+border的尺寸
</script>
</body>
</html>

jQuery尺寸的示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>文档操作</title>
    <style>
        .error {
            color: red;
        }
    </style>
</head>
<body>
<div id="d1">
    <p><span>span</span></p>
    <div>div</div>
</div>

<form action="">
    <p>
        <label>用户名:
            <input class="need" name="username" type="text">
            <span class="error"></span>
        </label>
    </p>
    <p>
        <label>密码:
            <input name="password" class="need" type="password">
            <span class="error"></span>
        </label>
    </p>
    <p>
        <label>性别:
            <input name="gender" value="1" type="radio">男
        </label>
        <label>
            <input name="gender" value="0" type="radio">女
        </label>
        <label>
            <input name="gender" value="2" type="radio">保密
        </label>
    </p>
    <p>
        <label>爱好:
            <input name="hobby" value="basketball" type="checkbox">篮球
        </label>
        <label>
            <input name="hobby" value="football" type="checkbox">足球
        </label>
        <label>
            <input name="hobby" value="doublecolorball" type="checkbox">双色球
        </label>
    </p>
    <p>
        <label for="s1">请输入地址
            <select name="from" id="s1" multiple>
                <option value="010">北京</option>
                <option value="021">上海</option>
                <option value="020">广州</option>
                <option value="0755">深圳</option>
            </select>
        </label>
    </p>
    <p>
        <label for="t1">个人简介 </label>
        <textarea name="memo" id="t1" cols="30" rows="10"></textarea>
    </p>
    <p>
        <input id="b1" type="submit" value="登录">
        <input type="button" value="取消">
    </p>
</form>
<script src="jquery-3.2.1.min.js"></script>
<script>
    // 原生DOC的文本操作
    var d1Ele = document.getElementById("d1");
    console.log(d1Ele.innerText);
    console.log(d1Ele.innerHTML);
    // jQuery的文本操作
    var $d1Ele = $("#d1");
    console.log($d1Ele.text());
    console.log($d1Ele.html("<a href='http://www.sogo.com'>搜狗</a>"));
    // html可在添加标签
    console.log($(":text").val());
    // 取值text中的值
    var $checkedEles = $(":checkbox:checked");
    console.log($checkedEles.val());
    // checkbox直接val()只能取到第一个被选中的值
    for (var i = 0; i < $checkedEles.length; i++) {
        console.log($($checkedEles[i]).val())
    }
    // 循环遍历checkbox就取到所有被选中的值,这里$($checkedEles[i])
    console.log($(":radio:checked").val());
    // 取被选择中radio框
    console.log($("#s1").val(["010", "0755"]));
    // 取被选中的select值,val(设置被选中的值)
    console.log($("#t1").val());
    // 获取被textarea中的值

    //需求分析
    //点击登录按钮验证用户名和密码是否为空
    //为空在对应的input标签下面显示一个错误提示信息
    //1.给登录按钮绑定点击事件
    //2.点击事件要做的事儿
    //2.1 找input标签 --> 取值 --> 判断是否为空 --> .length是否为0
    //2.2 如果不为空,则什么都不做
    //2.2.1 如果为空,要做几件事儿
    //2.2.2 在当前这个input标签的下面 添加一个新的标签,内容为xx不能为空
    $("#b1").click(function () {
        var $needEles = $(".need");
        for (var i = 0; i < $needEles.length; i++) {
            if ($($needEles[i]).val().trim().length === 0) {
                var labelName = $($needEles[i]).parent().text().trim().slice(0, -1);
                $($needEles[i]).next().text(labelName + "不能为空!")
            }
        }
        return false;
    });
</script>
</body>
</html>

jQuery文本操作示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<img src="http://www.pptok.com/wp-content/uploads/2012/08/xunguang-4.jpg" alt="">
<input type="button" id="b1" value="下一张">
<label for="c1"></label>
<label for="c2"></label>
<input checked type="checkbox" id="c1">
<input type="checkbox" id="c2">
<script src="jquery-3.2.1.min.js"></script>
<script>
    var newURL = "http://img4.imgtn.bdimg.com/it/u=4118960086,2125569760&fm=26&gp=0.jpg";
    // 将新的URL地址赋值
    // var $imgEles = $("img");
    // console.log($imgEles.attr("src"));
    // // 获取img的src地址
    // console.log($imgEles.attr({
    //     "src": "http://img4.imgtn.bdimg.com/it/u=4118960086,2125569760&fm=26&gp=0.jpg",
    //     "title": "显示文字"
    // }));
    // 设置多个属性值
    // console.log($imgEles.removeAttr("title"));
    // 删除属性值
    var $c1Eles = $("#c1");
    $c1Eles.prop("checked");
    // 获取属性,返回bool值
    $c1Eles.prop("checked", false);
    // 获取属性,改变为false;
    $c1Eles.prop("checked", true);
    // 获取属性,改变为true
    $c1Eles.removeProp("checked");
    $("#b1").click(function () {
        // 修改img标签的src属性
        var $imgEles = $("img");
        // 将找到的img标签保存在内存中
        oldURL = $imgEles.attr("src");
        // 获取img的src地址并赋值
        $imgEles.attr("src", newURL);
        // 修改img的src地址为新的url地址
        newURL = oldURL
        // 将新的地址在赋值回老的地址 实现切换下一个效果
    });
</script>
</body>
</html>

jQuery属性操作示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>作业解析</title>
</head>
<body>
<table border="1">
    <thead>
    <tr align="center">
        <th>序号</th>
        <th>姓名</th>
        <th>职位</th>
    </tr>
    </thead>
    <tbody>
    <tr align="center">
        <td>
            <label>
                <input type="checkbox" class="c1">
            </label>
        </td>
        <td>阿浩</td>
        <td>二人转演员</td>
    </tr>
    <tr align="center">
        <td>
            <label>
                <input type="checkbox" class="c1">
            </label>
        </td>
        <td>阿星</td>
        <td>龙套演员</td>
    </tr>
    <tr align="center">
        <td>
            <label>
                <input type="checkbox" class="c1">
            </label>
        </td>
        <td>阿晶</td>
        <td>二流导演</td>
    </tr>
    </tbody>
</table>
<label>
    <input type="button" id="b1" value="全选">
</label>
<label>
    <input type="button" id="b2" value="反选">
</label>
<label>
    <input type="button" id="b3" value="取消">
</label>
<script src="jquery-3.2.1.min.js"></script>
<script>
    $("#b1").click(function () {
        var $checkboxEles = $(":checkbox");
        $($checkboxEles).prop("checked", true)
    });
    // 点击全选操作
    $("#b2").click(function () {
        var $checkboxEles = $(":checkbox");
        for (i = 0; i < $checkboxEles.length; i++) {
            var $tmp = $($checkboxEles[i]);
            if ($tmp.prop("checked")) {
                $tmp.prop("checked", false)
            }
            else {
                $tmp.prop("checked", true)
            }
        }
    });
    // 点击反选操作
    $("#b3").click(function () {
        var $checkboxEles = $(":checkbox");
        $($checkboxEles).prop("checked", false)
    });
    // 点击取消操作
</script>
</body>
</html>

全选反选作业示例


<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>文档处理</title>
</head>
<body>
<ul id="u1">
    <li id="l1">1</li>
    <li>2</li>
    <li>3</li>
</ul>
<script src="jquery-3.2.1.min.js"></script>
<script>
    var u1Eles = $("#u1");
    var liEle1 = document.createElement("li");
    liEle1.innerText = 4;
    u1Eles.append(liEle1);// 添加元素到元素内部最后一个
    $(liEle1).appendTo(u1Eles); // 反向添加 效果一样
    var liEle2 = document.createElement("li");
    liEle2.innerText = 0;
    u1Eles.prepend(liEle2); // 添加元素到元素内部第一个
    $(liEle2).prependTo(u1Eles); // 反向添加 效果一样
    var l1Eles = $("#l1");
    var liEle3 = document.createElement("li");
    liEle3.innerText = "1.5";
    l1Eles.after(liEle3); // 添加元素到元素外部后面
    $(liEle3).insertAfter(l1Eles); // 反向添加 效果一样
    var liEle4 = document.createElement("li");
    liEle4.innerText = "0.5";
    l1Eles.before(liEle4);// 添加元素到元素外部前面
    $(liEle4).insertBefore(l1Eles); // 反向添加 效果一样
    // u1Eles.remove(); // 清除u1标签
    // u1Eles.empty() // 清除u1标签内容
</script>
</body>
</html>

文档处理

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>点击在表格最后添加一条记录</title>
</head>
<body>
<table border="1" id="t1">
    <thead>
    <tr>
        <th>#</th>
        <th>姓名</th>
        <th>爱好</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>1</td>
        <td>小强</td>
        <td>吃冰淇淋</td>
        <td>
            <button class="delete">删除</button>
        </td>
    </tr>
    <tr>
        <td>2</td>
        <td>二哥</td>
        <td>Girl</td>
        <td>
            <button class="delete">删除</button>
        </td>
    </tr>
    </tbody>
</table>
<button id="b1">添加一行数据</button>
<script src="jquery-3.2.1.min.js"></script>
<script>
    // 绑定事件
    $("#b1").click(function () {
        var trEle = document.createElement("tr");
        // 生成要添加的tr标签及数据
        $(trEle).html("<td>3</td><td>小东北</td><td>社会摇</td><td><button class='delete'>删除</button></td>");
        // 把生成的tr插入到表格中
        $("#t1 tbody").append(trEle);
    });
    // 每一行的=删除按钮绑定事件
    $(".delete").click(function () {
       $(this).parent().parent().remove();
    });
</script>
</body>
</html>

点击在表格最后添加一条记录

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>替换操作示例</title>
</head>
<body>
<p><a href="http://www.sogo.com">aaa</a></p>
<p><a href="">bbb</a></p>
<p><a href="">ccc</a></p>
<button id="b1">点我</button>
<script src="jquery-3.2.1.min.js"></script>
<script>
    $("#b1").click(function () {
        var imgEle = document.createElement("img")
        $(imgEle).attr("src", "http://www.pptok.com/wp-content/uploads/2012/08/xunguang-4.jpg");
        // $("a").replaceWith(imgEle); // 将a标签替换img标签
        $(imgEle).replaceAll("a"); // 用img标签替换所有a标签
    });
</script>
</body>
</html>

替换操作

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>克隆示例</title>
</head>
<body>
<button class="b1">屠龙宝刀,点击就送</button>
<script src="jquery-3.2.1.min.js"></script>
<script>
    $(".b1").click(function () {
        $(this).clone(true).insertAfter(this);
    }); // clone不加参数只复制标签,如果添加true参数就把整个标签和事件全部克隆
</script>
</body>
</html>

克隆操作

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>点击在表格最后添加一条记录</title>
</head>
<body>
<table border="1" id="t1">
    <thead>
    <tr>
        <th>#</th>
        <th>姓名</th>
        <th>爱好</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>1</td>
        <td>小强</td>
        <td>吃冰淇淋</td>
        <td>
            <button class="delete">删除</button>
        </td>
    </tr>
    <tr>
        <td>2</td>
        <td>二哥</td>
        <td>Girl</td>
        <td>
            <button class="delete">删除</button>
        </td>
    </tr>
    </tbody>
</table>
<button id="b1">添加一行数据</button>
<script src="jquery-3.2.1.min.js"></script>
<script>
    // 绑定事件
    $("#b1").on("click",function () {
        var trEle = document.createElement("tr");
        // 生成要添加的tr标签及数据
        $(trEle).html("<td>3</td><td>小东北</td><td>社会摇</td><td><button class='delete'>删除</button></td>");
        // 把生成的tr插入到表格中
        $("#t1 tbody").append(trEle);
    });
    // 每一行的=删除按钮绑定事件
    $("#t1").on("click",".delete",function () {
        console.log(this);
       $(this).parent().parent().remove();
    });
// 适用于 给未来的元素(页面生成的时候还没有的标签) 绑定事件 (事件委托)
//  事件冒泡和事件捕获
// 事件.on(一个参数(事件) 第二个参数(未来的选择器) 第三个参数function事件处理)
</script>
</body>
</html>

on绑定事件 在表格最后添加一条记录

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>登录校验完整版</title>
    <style>
        .error {
            color: red;
        }
    </style>
</head>
<body>
<form action="">
    <p>
        <label>用户名:
            <input class="need" name="username" type="text">
            <span class="error"></span>
        </label>
    </p>
    <p>
        <label>密码:
            <input name="password" class="need" type="password">
            <span class="error"></span>
        </label>
    </p>
    <p>
        <label>性别:
            <input name="gender" value="1" type="radio">男
        </label>
        <label>
            <input name="gender" value="0" type="radio">女
        </label>
        <label>
            <input name="gender" value="2" type="radio">保密
        </label>
    </p>
    <p>
        <label>爱好:
            <input name="hobby" value="basketball" type="checkbox">篮球
        </label>
        <label>
            <input name="hobby" value="football" type="checkbox">足球
        </label>
        <label>
            <input name="hobby" value="doublecolorball" type="checkbox">双色球
        </label>
    </p>
    <p>
        <label for="s1">请输入地址
            <select name="from" id="s1" multiple>
                <option value="010">北京</option>
                <option value="021">上海</option>
                <option value="020">广州</option>
                <option value="0755">深圳</option>
            </select>
        </label>
    </p>
    <p>
        <label for="t1">个人简介 </label>
        <textarea name="memo" id="t1" cols="30" rows="10"></textarea>
    </p>
    <p>
        <input id="b1" type="submit" value="登录">
        <input type="button" value="取消">
    </p>
</form>
<script src="jquery-3.2.1.min.js"></script>
<script>
    // 获取被textarea中的值
    //需求分析
    //点击登录按钮验证用户名和密码是否为空
    //为空在对应的input标签下面显示一个错误提示信息
    //1.给登录按钮绑定点击事件
    //2.点击事件要做的事儿
    //2.1 找input标签 --> 取值 --> 判断是否为空 --> .length是否为0
    //2.2 如果不为空,则什么都不做
    //2.2.1 如果为空,要做几件事儿
    //2.2.2 在当前这个input标签的下面 添加一个新的标签,内容为xx不能为空
    $("#b1").click(function () {
        var $needEles = $(".need");
        // 定位一个标志位
        var flag = true;
        for (var i = 0; i < $needEles.length; i++) {
            // 如果有错误
            if ($($needEles[i]).val().trim().length === 0) {
                var labelName = $($needEles[i]).parent().text().trim().slice(0, -1);
                $($needEles[i]).next().text(labelName + "不能为空!");
                // 将标志位置为false
                flag = false;
            }
        }
        return flag;
    });
//    事件之间
//    1.阻止后续事件的执行
//        return false;
//    2.for循环,退出当前循环 用 break
</script>
</body>
</html>

登录校验示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>键盘相关操作</title>
</head>
<body>
<table border="1" id="t1">
    <thead>
    <tr>
        <th>#</th>
        <th>姓名</th>
        <th>爱好</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td><input type="checkbox"></td>
        <td>小强</td>
        <td>吃冰淇淋</td>
        <td>
            <select>
                <option value="0">下线</option>
                <option value="1">上线</option>
                <option value="2">离线</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox"></td>
        <td>二哥</td>
        <td>Girl</td>
        <td>
            <select>
                <option value="0">下线</option>
                <option value="1">上线</option>
                <option value="2">离线</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox"></td>
        <td>二哥</td>
        <td>Girl</td>
        <td>
            <select>
                <option value="0">下线</option>
                <option value="1">上线</option>
                <option value="2">离线</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox"></td>
        <td>二哥</td>
        <td>Girl</td>
        <td>
            <select>
                <option value="0">下线</option>
                <option value="1">上线</option>
                <option value="2">离线</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox"></td>
        <td>二哥</td>
        <td>Girl</td>
        <td>
            <select>
                <option value="0">下线</option>
                <option value="1">上线</option>
                <option value="2">离线</option>
            </select>
        </td>
    </tr>
    </tbody>
</table>
<script src="jquery-3.2.1.min.js"></script>
<script>
    // 确保绑定事件的时候DOM是生成好的
    $(document).ready(function () {
        var mode = false;
        var $bodyEle = $("body");
        // 给文档绑定 键盘某个按键被按下去的事件
        $bodyEle.on("keydown", function (event) {
            // keydown 键盘按下的操作
            // console.log(event.keyCode);
            if (event.keyCode === 17) {
                // 进入批量操作模式
                mode = true;
            }
        });
        // 按键抬起来的时候,退出批量操作模式
        $bodyEle.on("keyup", function (event) {
            // keyCode键盘对应的位置检测
            // keyup 键盘抬起的操作
            // console.log(event.keyCode);
            if (event.keyCode === 17) {
                // 进入批量操作模式
                mode = false;
            }
        });
        $("select").on("change", function () {
            // 取到当前select标签的值
            var value = $(this).val();
            var $thisCheckbox = $(this).parent().siblings().first().find(":checkbox");
            // 判断checkbox有没有被选中
            if ($thisCheckbox.prop("checked") && mode) {
                // 真正进入批量操作模式
                var $checkedEles = $("input[type='checkbox']:checked");
                for (var i = 0; i < $checkedEles.length; i++) {
                    // 找到同一行的select
                    $($checkedEles[i]).parent().siblings().last().find("select").val(value);
                }
            }
        });
    })
</script>
</body>
</html>

键盘批量控制操作

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>点赞动画示例</title>
  <style>
    div {
      position: relative;
      display: inline-block;
    }
    div>i {
      display: inline-block;
      color: red;
      position: absolute;
      right: -16px;
      top: -5px;
      opacity: 1;
    }
  </style>
</head>
<body>
<div id="d1">点赞</div>
<script src="jquery-3.2.1.min.js"></script>
<script>
  $("#d1").on("click", function () {
    var newI = document.createElement("i");
    newI.innerText = "+1";
    $(this).append(newI);
    $(this).children("i").animate({
      opacity: 0
    }, 1000)
  })
</script>
</body>
</html>

自定义动画效果示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<script src="jquery-3.2.1.min.js"></script>
<script>
    var $divEles = $("div");
    // 原生的for循环方法
    for (var i=0;i<$divEles.length;i++){
        console.log($divEles[i].innerText)
    }
    // each方法更简单的循环方法
    $divEles.each(function () {
        console.log(this.innerText)
    });
    //注意this指的是每次循环的标签(DOM标签),.innerText获取标签的文本内容
    var a1 = [11,22,33,44];
    $.each(a1,function (k,v) {
        if (v===22){
            // 退出当前这一次循环
            return;
            // 跳过这个循环,类似于continue
        }
        console.log(k+":"+v);
        // if (v===22){
        //     // 后续的each循环就不进行了
        //     return false;
        //     // 终止each循环,固定写法 不能用break
        }
    );
</script>
</body>
</html>

each循环示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>data示例</title>
</head>
<body>
<div id="d1">我是div</div>
<img width="400" src="http://www.pptok.com/wp-content/uploads/2012/08/xunguang-4.jpg" alt="">
<script src="../day55/jquery-3.2.1.min.js"></script>
<script>
    var $d1Eles = $("#d1");
    $d1Eles.data("s9", "好");
    $d1Eles.data("age", 9000);
    var $imgEles = $("img");
    $d1Eles.data("img",$imgEles);
    console.log($d1Eles.data("img"));
    console.log($d1Eles.data("img").attr("src","http://img4.imgtn.bdimg.com/it/u=4118960086,2125569760&fm=26&gp=0.jpg"));

</script>
</body>
</html>

data示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>周末作业讲解</title>
    <style>
        .cover {
            position: fixed;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            background-color: #616161;
            opacity: 0.4;
            z-index: 998;
        }

        .modal {
            height: 200px;
            width: 300px;
            background-color: white;
            position: absolute;
            margin-top: -100px;
            margin-left: -150px;
            top: 50%;
            left: 50%;
            z-index: 1000;
        }

        .hide {
            display: none;
        }
    </style>
</head>
<body>

<button id="add">新增</button>
<table border="1">
    <thead>
    <tr>
        <th>#</th>
        <th>姓名</th>
        <th>爱好</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>1</td>
        <td>Egon</td>
        <td>街舞</td>
        <td>
            <button class="edit-btn">编辑</button>
            <button class="delete-btn">删除</button>
        </td>
    </tr>
    <tr>
        <td>2</td>
        <td>Alex</td>
        <td>烫头</td>
        <td>
            <button class="edit-btn">编辑</button>
            <button class="delete-btn">删除</button>
        </td>
    </tr>
    <tr>
        <td>3</td>
        <td>苑局</td>
        <td>日天</td>
        <td>
            <button class="edit-btn">编辑</button>
            <button class="delete-btn">删除</button>
        </td>
    </tr>
    </tbody>
</table>

<div id="myCover" class="cover hide"></div>
<div id="myModal" class="modal hide">
    <div>
        <p>
            <label for="modal-name">姓名</label>
            <input type="text" id="modal-name">
        </p>
        <p>
            <label for="modal-hobby">爱好</label>
            <input type="text" id="modal-hobby">
        </p>
        <p>
            <button id="modal-submit">提交</button>
            <button id="modal-cancel">取消</button>
        </p>
    </div>
</div>
<script src="./jquery-3.2.1.min.js"></script>
<script>

    // 定义一个弹出模态框的函数
    function showModal() {
        $("#myCover,#myModal").removeClass("hide");
    }

    // 关闭模态框
    function closeModal() {
        // 1. 清空模态框中的input
        $("#myModal").find("input").val("");
        $("#myCover,#myModal").addClass("hide");
    }

    // 给新增按钮绑定事件
    $("#add").on("click", function () {
        // 把模态框弹出!
//        $("#myCover").removeClass("hide");
//        $("#myModal").removeClass("hide");
        showModal()
    });

    // 模态框中的取消按钮绑定事件
    $("#modal-cancel").on("click", function () {
        // 2. 隐藏模态框
        closeModal();

    });

    // 模态框中的提交按钮绑定事件
    $("#modal-submit").on("click", function () {
        // 1. 取到 用户 填写的 input框的值
        var name = $("#modal-name").val();  // 把用户在模态框里输入的姓名获取到,保存在name变量中
        var hobby = $("#modal-hobby").val();  // 把用户在模态框里输入的爱好获取到,保存在hobby变量中

        var $myModalEle = $("#myModal");
        // 判断,按需操作
        var $currentTrEle = $myModalEle.data("currentTr");
        if ($currentTrEle !== undefined) {
            // 说明是编辑状态
            $currentTrEle.children().eq(1).text(name);
            $currentTrEle.children().eq(2).text(hobby);

            // 清空之前保存的当前行
            $myModalEle.removeData();
        } else {
            // 创建tr标签把数据填进去
            var trEle = document.createElement("tr");
            var number = $("tr").length;
            $(trEle).html("<td>" + number + "</td>" +
                "<td>" + name + "</td>" +
                "<td>" + hobby + "</td>" +
                '<td><button class="edit-btn">编辑</button> <button class="delete-btn">删除</button></td>'
            );
            // 把创建好的tr添加到tbody中
            $("tbody").append(trEle);
        }
        // 隐藏模态框
        closeModal();
    });

    // 2. 根据是编辑 还是新增 做不同的操作
    // 2.1 如果是新增操作,就生成一条新的tr,加到table的最后
    // 2.2 如果是编辑操作, 根据先前 编辑 按钮那一行
    // 难点在于 如何确定 编辑的是哪一行?  --> 利用data()可以存具体的jQuery对象

    // 给每一行的编辑按钮绑定事件
    // 要使用事件委托,基于已经存在的元素(页面加载完之后存在的标签)绑定事件
    $("tbody").on("click", ".edit-btn", function () {
        // 把模态框弹出来
        showModal();
        // 把原来的数据填写到模态框中的input
        var $currentTrEle = $(this).parent().parent();

        // 把当前行的jQuery对象保存起来
        $("#myModal").data("currentTr", $currentTrEle);

        var name = $currentTrEle.children().eq(1).text();
        var hobby = $currentTrEle.children().eq(2).text();

        // 填
        $("#modal-name").val(name);
        $("#modal-hobby").val(hobby);
    });

    // 给每一行的删除按钮绑定事件
    $("tbody").on("click", ".delete-btn", function () {
        // 删除被点击的删除按钮的那一行
        var $currentTrEle = $(this).parent().parent();
        // 更新序号
        // 找到当前行后面所有的tr,依次更新序号
        $currentTrEle.nextAll().each(function () {
            // 取到原来的序号
            var oldNumber = $(this).children().first().text();
            // 将原来的序号-1,再赋值回去
            $(this).children().first().text(oldNumber - 1);
        });
        $currentTrEle.remove();
    });
</script>
</body>
</html>

模态框新增修改删除作业

python网络进阶篇的更多相关文章

  1. Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)

    Python开发[第七篇]:面向对象   详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇)   上一篇<Python 面向对象(初级篇)> ...

  2. 第六篇:Python函数进阶篇

    在了解完了 Python函数基础篇之后,本篇的存在其实是为了整合知识,由于该篇的知识是否杂乱,故大家可以通过点开点连接直接进入其详细介绍,该篇主要大致的介绍一下几个知识点:  一.Python的迭代器 ...

  3. python Django 进阶篇

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

  4. Python网络编程篇之socketserver

    1.socketserver模块和类 socketserver是标准库中的一个高级模块,目标是简化很多样板代码(创建网络客户端和服务器所必须的代码) 这个模块封装了socket编程所需要的各种各样的类 ...

  5. Python网络编程篇之socket

    1 socket 插座?呵呵,想多了,翻译过来意思是套接字! A network socket is an internal endpoint for sending or receiving dat ...

  6. Python 面向对象 (进阶篇)

    <Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可 ...

  7. Python网络编程篇之select和epoll

    1. select 原理 在多路复⽤的模型中, ⽐较常⽤的有select模型和epoll模型. 这两个都是系统接⼝, 由操作系统提供. 当然, Python的select模块进⾏了更⾼级的封装. ⽹络 ...

  8. python 网络编程篇

    基础模拟通话网络程序: #客户端 import socket client = socket.socket() client.connect(('localhost',6969)) client.se ...

  9. Python—函数进阶篇

    lambda表达式(匿名函数表达式) 作用:创建一个匿名函数对象.同def类似,但不提供函数名. 语法:lambda [形参1,形参2,...] : 表达式 语法说明 lambda 只是一个表达式,它 ...

随机推荐

  1. 什么样的IT业务适合外包?

    很多公司都应该遇到过这样的问题,什么样的IT业务才适合外包呢? 百度大家都可以百度的到一些信息,比如: 针对这样的推荐答案,是否也需要认真思考一下,我需要外包的业务是什么样的业务?是不是真的适合外包? ...

  2. 【单例模式】java实现

    概述:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 关键点: 构造函数不对外开放,一般为private. 通过一个静态方法或者枚举返回单例类对象. 确保单例类的对象有且只有一个,尤 ...

  3. 线段树(区间树)之区间染色和4n推导过程

    前言 线段树(区间树)是什么呢?有了二叉树.二分搜索树,线段树又是干什么的呢?最经典的线段树问题:区间染色:正如它的名字而言,主要解决区间的问题 一.线段树说明 1.什么是线段树? 线段树首先是二叉树 ...

  4. groupcache源码解析-概览

    接下来讲什么 今天开始讲groupcache! Memcached大家应该都不陌生,官网的介绍是: Free & open source, high-performance, distribu ...

  5. Java多线程概念简介 多线程中篇(一)

    Java的线程与操作系统的线程   在线程的相关介绍中,有讲到“线程的实现”分为三种:内核支持,用户级以及两者混合.(这只是一种简要的分类) Java线程在JDK1.2之前,是用户线程实现的 而在JD ...

  6. 用TensorFlow教你手写字识别

    博主原文链接:用TensorFlow教你做手写字识别(准确率94.09%) 如需转载,请备注出处及链接,谢谢. 2012 年,Alex Krizhevsky, Geoff Hinton, and Il ...

  7. SpringCloud系列——Eureka 服务注册与发现

    前言 Eureka是一种基于REST(具像状态传输)的服务,主要用于AWS云中定位服务,以实现中间层服务器的负载平衡和故障转移.本文记录一个简单的服务注册与发现实例. GitHub地址:https:/ ...

  8. .Net语言 APP开发平台——Smobiler学习日志:获取或存储图像路径设置

    ResourcePath属性 一.属性介绍 获取或设置图像存储路径,默认设置为“image”,表示的ResourcePath是在程序运行路径下的Image文件夹(bin\Debug\Image): 该 ...

  9. 第35章 秘密(secrets) - Identity Server 4 中文文档(v1.0.0)

    在某些情况下,客户端需要使用身份服务器进行身份验证,例如 在令牌端点请求令牌的机密应用程序(也称为客户端) API在内省端点验证引用令牌 为此,您可以将秘密列表分配给客户端或API资源. 秘密解析和验 ...

  10. CentOS 7 源码编译安装 NodeJS

    1.安装 gcc.gcc-c++ yum -y install gcc gcc-c++ kernel-devel 2.下载源码 wget https://nodejs.org/dist/v8.11.3 ...