- cat 284.py > 100.py:将284文件重定向到100,相当于复制到100
- cat 284.py 456.py > 100.py:将284,456何必后重定向100
- grep '000' 101.py:查找101文件中的‘000’
- grep -n '^abcd' 101.py :带行数的搜索
- 支持正则表达式
- grep查找文件中的内容
- find ./ -name 284.py:在当前目录找名字是284.py文件
- find /tmp -size +2M :找大于2M的文件,-是小于
- find ./ -name '*.sh' :可以按照正则的方式查找
- cp 284.py test/:将284文件复制到test目录下
- cp test test2/ -r:将test目录整个拷贝到test2目录下,-r是递归的方式
- mv 100.py test:相当于剪切,
- mv test2/ test/:将test2文件夹,全部移动到test文件夹下
- mv 284.py 284-2.py:可以利用mv进行重命名
- tar -zcvf 压缩打包文件名 文件1 文件2 文件3:将文件1,文件2,文件3,进行打包压缩
- tar -zxcf 压缩打包文件名:解压
- tar -zxcf 压缩打包文件名 -C 解压路径:解压
- cal:日历
- date:时间
- ps:查看进程信息
- -aux 显示所有进程的详细进程
- kill 进程号:杀死进程
- kill -9 进程号:强制干掉进程
- reboot:重启
- shutdown:关机
- top:现在当前资源率情况,资源管理器
- df -lh:查看当前占用空间
- du -lh:查看当前目录的使用情况
- ifcofig:查看网络情况,类似ipcofig
- ping 114.114.114.114:网络是否连通
- Fiddler
- 配置
- 定位到composer
- 将右边访问的网页拖过来
- 可以得到我们向网页发送了什么信息
- 定位到composer
- 配置
- 爬虫去重策略
- 1.将访问过的URl保存在数据库中
- 2.将访问过的URL保存在set中(保存到内存中),o(1)的代价查询url
- 3.url经过MD5等方法哈希后保存到set中,降低了几倍的内存
- 4.用bitmap方法,将访问过的url通过hash函数映射到某一位(降低几倍内存,但是冲突太高)
- 5.bloomfilter对bitmap进行改进,多次hash函数降低冲突
- 多任务
- 操作系统可以同时运⾏多个任务。
-
进程
-
优点:同时利用多个CPU,能够同时进行多个操作
-
缺点:耗费资源(需要重新开辟空间)
-
from multiprocessing import Process import time import os #继承Process类 class Process_Class(Process): #因为Process类本身也有__init__⽅法,这个⼦类相当于重写了这个⽅法, #我们并没有完全的初始化⼀个Process类,所以就不能使⽤从这个类继承的⼀些⽅法和属性, #最好的⽅法就是将继承类本身传递给Process.__init__⽅法,完成这些初始化操作 def __init__(self,interval): Process.__init__(self) self.interval = interval #重写了Process类的run()⽅法 def run(self): print("⼦进程(%s) 开始执⾏,⽗进程为(%s)"%(os.getpid(),os.getppid())) t_start = time.time() time.sleep(self.interval) t_stop = time.time() print("(%s)执⾏结束,耗时%0.2f秒"%(os.getpid(),t_stop-t_start)) if __name__=="__main__": t_start = time.time() print("当前程序进程(%s)"%os.getpid()) p1 = Process_Class(2) #对⼀个不包含target属性的Process类执⾏start()⽅法,就会运⾏这个类中的run()⽅法,所以这⾥会执⾏ p1.run() p1.start() p1.join() t_stop = time.time() print("(%s)执⾏结束,耗时%0.2f"%(os.getpid(),t_stop-t_start))
- 进程池
-
from multiprocessing import Pool import os,time,random def worker(msg): t_start = time.time() print("%s开始执⾏,进程号为%d"%(msg,os.getpid())) #random.random()随机⽣成0~1之间的浮点数 time.sleep(random.random()*2) t_stop = time.time() print(msg,"执⾏完毕,耗时%0.2f"%(t_stop-t_start)) po=Pool(3) #定义⼀个进程池,最⼤进程数3 for i in range(0,10): #Pool.apply_async(要调⽤的⽬标,(传递给⽬标的参数元祖,)) #每次循环将会⽤空闲出来的⼦进程去调⽤⽬标 po.apply_async(worker,(i,)) print("----start----") po.close() #关闭进程池,关闭后po不再接收新的请求 po.join() #等待po中所有⼦进程执⾏完成,必须放在close语句之后 print("-----end-----")
-
- 进程间的通信
-
from multiprocessing import Process, Queue import os, time, random # 写数据进程执⾏的代码: def write(q): for value in ['A', 'B', 'C']: print('Put %s to queue...' % value) q.put(value) time.sleep(random.random()) # 读数据进程执⾏的代码: def read(q): while True: if not q.empty(): value = q.get(True) print('Get %s from queue.' % value) time.sleep(random.random()) else: break if __name__ == '__main__': # ⽗进程创建Queue,并传给各个⼦进程: q = Queue() pw = Process(target=write, args=(q,)) pr = Process(target=read, args=(q,)) # 启动⼦进程pw,写⼊: pw.start() # 等待pw结束: pw.join() # 启动⼦进程pr,读取: pr.start() pr.join() # pr进程⾥是死循环,⽆法等待其结束,只能强⾏终⽌: print('') print('所有数据都写⼊并且读完')
-
-
线程
-
优点:共享内存,IO操作的时候,创造并发操作
-
缺点:抢占资源--同时修改一个变量
-
- 异步
-
from multiprocessing import Pool import time import os def test(): print("---进程池中的进程---pid=%d,ppid=%d--" % (os.getpid(), os.getppid())) for i in range(3): print("----%d---" % i) time.sleep(1) return "hahah" def test2(args): time.sleep(1) print("---callback func--pid=%d" % os.getpid()) print("---callback func--args=%s" % args) # def test3(): # print("---callback func--pid=%d" % os.getpid()) if __name__ == '__main__': pool = Pool(3) # callback回调异常 pool.apply_async(func=test, callback=test2) # 异步执行 time.sleep(5) print("----主进程-pid=%d----" % os.getpid())
-
-
GIL:全局解释器锁
- 多线程因为GIL是伪线程,实际上还是单线程的
- 多进程是真的多进程
-
协程
-
等待途中保存位置去做其他的事,直到得到结果在去保存的位置继续做这件事
-
from greenlet import greenlet # 12 -> 34 -> 56 -> 78 def test1(): print("12") gr2.switch() print("34") gr2.switch() def test2(): print("56") gr1.switch() print("78") gr1 = greenlet(test1) gr2 = greenlet(test2) gr1.switch()
- 协程正式版
-
from gevent import monkey; monkey.patch_all() import gevent import urllib2 def f(url): print('GET: %s' % url) resp = urllib2.urlopen(url) data = resp.read() print('%d bytes received from %s.' % (len(data), url)) gevent.joinall([ gevent.spawn(f, 'https://www.python.org/'), gevent.spawn(f, 'https://www.yahoo.com/'), gevent.spawn(f, 'https://github.com/'), ])
-
-
- 深浅拷贝
- 引用
- a=b
- 只拷贝指针(内存地址),不拷贝内容
- 深拷贝
- copy.deepcopy()
- 拷贝内容,指针(内存地址)不同,递归拷贝,里面的引用也拷贝
- 拷贝
- copy.copy()
- 只拷贝第一层,引用不拷贝
- 引用
- 生成器
- ⽣成器是这样⼀个函数,它记住上⼀次返回时在函数体中的位置。
- 生成器保存的是算法,⽣成器不仅“记住”了它数据状态;⽣成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。
- yield
- 特点
- 节约内存
- 迭代到下⼀次的调⽤时,所使⽤的参数都是第⼀次所保留下的,即是说,在整个所有函数调⽤的参数都是第⼀次所调⽤时保留的,⽽不是新创建的
- jquery
- 1.寻找元素
- 选择器
-
1.基本选择器
$("#id") //ID选择器 $("div") //元素选择器 $(".classname") //类选择器 $(".classname,.classname1,#id1") //组合选择器 2.层次选择器
$("#id>.classname ") //子元素选择器 $("#id .classname ") //后代元素选择器 $("#id + .classname ") //紧邻下一个元素选择器 $("#id ~ .classname ") //兄弟元素选择器 3.过滤选择器(重点)
$("li:first") //第一个li $("li:last") //最后一个li $("li:even") //挑选下标为偶数的li $("li:odd") //挑选下标为奇数的li $("li:eq(4)") //下标等于 4 的li(第五个 li 元素) $("li:gt(2)") //下标大于 2 的li $("li:lt(2)") //下标小于 2 的li $("li:not(#runoob)") //挑选除 id="runoob" 以外的所有li 3.2内容过滤选择器
$("div:contains('Runob')") // 包含 Runob文本的元素 $("td:empty") //不包含子元素或者文本的空元素 $("div:has(selector)") //含有选择器所匹配的元素 $("td:parent") //含有子元素或者文本的元素 3.3可见性过滤选择器 $("li:hidden") //匹配所有不可见元素,或type为hidden的元素 $("li:visible") //匹配所有可见元素 3.4属性过滤选择器 $("div[id]") //所有含有 id 属性的 div 元素 $("div[id='123']") // id属性值为123的div 元素 $("div[id!='123']") // id属性值不等于123的div 元素 $("div[id^='qq']") // id属性值以qq开头的div 元素 $("div[id$='zz']") // id属性值以zz结尾的div 元素 $("div[id*='bb']") // id属性值包含bb的div 元素 $("input[id][name$='man']") //多属性选过滤,同时满足两个属性的条件的元素 3.5状态过滤选择器 $("input:enabled") // 匹配可用的 input $("input:disabled") // 匹配不可用的 input $("input:checked") // 匹配选中的 input $("option:selected") // 匹配选中的 option 4.表单选择器
$(":input") //匹配所有 input, textarea, select 和 button 元素 $(":text") //所有的单行文本框,$(":text") 等价于$("[type=text]"),推荐使用$("input:text")效率更高,下同 $(":password") //所有密码框 $(":radio") //所有单选按钮 $(":checkbox") //所有复选框 $(":submit") //所有提交按钮 $(":reset") //所有重置按钮 $(":button") //所有button按钮 $(":file") //所有文件域
-
- 筛选器
- 选择器
- 2.操作元素
- CSS操作
- 属性操作
- 文档处理
- 3.事件
- 4.Jquery扩展
- 5.ajax
- 1.寻找元素
- 协议
- 为了解决不同种族⼈之间的语⾔沟通障碍,现规定国际通⽤语⾔是英语,这就是⼀个规定,这就是协议
- 端口
- 相当于房间的门牌号,用来区分不同的进程
- 0-65535 2的16次方65536个
- 知名端口
- 0-1023 大家都知道的端口,一般做固定的事情,比如百度的端口,80
- 动态端口
- 1024-65535 不固定分配某种服务,这种端口随便用
- netstat 查询端口
- IP地址
- 子网掩码
-
就是将某个IP地址划分成⽹络地址和主机地址两部分⼦⽹掩码的设定必须遵循⼀定的规则。
-
- UDP和TCP
- 4层解决什么问题
- 应用层:解决需要传递什么数据,理解为需要发送的快件。主要通过协议规定,ftp,ssh,smtp,pop3,HTTP等
- 传输层:解决如何传输数据,TCP,UDP,可以理解快递公司
- 网络层:IP,理解为快件需要发送的地址,地理位置坐标
- 链路层:具体的工具
- 时间复杂度的几条基本计算规则
- 1.基本操作,即只有常数项,认为其时间复杂度为O(1)
- 2.顺序结构,时间复杂度按加法进行计算
- 3.循环结构,时间复杂度按乘法进行计算
- 4.分支结构,时间复杂度取最大值
- 5.判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
- 6.在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度
- 常见时间复杂度之间的关系
- list内置操作的时间复杂度
-
dict内置操作的时间复杂度
- 顺序表
- 在Python的官方实现中,list就是一种采用分离式技术实现的动态顺序表。这就是为什么用list.append(x) (或 list.insert(len(list), x),即尾部插入)比在指定位置插入元素效率高的原因。
- 在Python的官方实现中,list实现采用了如下的策略:在建立空表(或者很小的表)时,系统分配一块能容纳8个元素的存储区;在执行插入操作(insert或append)时,如果元素存储区满就换一块4倍大的存储区。但如果此时的表已经很大(目前的阀值为50000),则改变策略,采用加一倍的方法。引入这种改变策略的方式,是为了避免出现过多空闲的存储位置。
- 链表
- 单向链表
- 节点实现
-
class SingleNode(object): """单链表的结点""" def __init__(self,item): # _item存放数据元素 self.item = item # _next是下一个节点的标识 self.next = None
-
-
链表的全部方法
-
class SingleNode(object): """单链表的结点""" def __init__(self, item): # _item存放数据元素 self.item = item # _next是下一个节点的标识 self.next = None class SingleLinkList(object): """单链表""" def __init__(self): self._head = None def is_empty(self): """判断链表是否为空""" return self._head == None def length(self): """链表长度""" # cur初始时指向头节点 cur = self._head count = 0 # 尾节点指向None,当未到达尾部时 while cur != None: count += 1 # 将cur后移一个节点 cur = cur.next return count def travel(self): """遍历链表""" cur = self._head while cur != None: print(cur.item) cur = cur.next print("") def add(self, item): """头部添加元素""" # 先创建一个保存item值的节点 node = SingleNode(item) # 将新节点的链接域next指向头节点,即_head指向的位置 node.next = self._head # 将链表的头_head指向新节点 self._head = node def append(self, item): """尾部添加元素""" node = SingleNode(item) # 先判断链表是否为空,若是空链表,则将_head指向新节点 if self.is_empty(): self._head = node # 若不为空,则找到尾部,将尾节点的next指向新节点 else: cur = self._head while cur.next != None: cur = cur.next # 遍历到尾部,然后node链接到尾部 cur.next = node def insert(self, pos, item): """指定位置添加元素""" # 若指定位置pos为第一个元素之前,则执行头部插入 if pos <= 0: self.add(item) # 若指定位置超过链表尾部,则执行尾部插入 elif pos > (self.length() - 1): self.append(item) # 找到指定位置 else: node = SingleNode(item) count = 0 # pre用来指向指定位置pos的前一个位置pos-1,初始从头节点开始移动到指定位置 pre = self._head while count < (pos - 1): count += 1 pre = pre.next # 先将新节点node的next指向插入位置的节点 node.next = pre.next # 将插入位置的前一个节点的next指向新节点 pre.next = node def remove(self, item): """删除节点""" cur = self._head pre = None while cur != None: # 找到了指定元素 if cur.item == item: # 如果第一个就是删除的节点 if not pre: # 将头指针指向头节点的后一个节点 self._head = cur.next else: # 将删除位置前一个节点的next指向删除位置的后一个节点 pre.next = cur.next break else: # 继续按链表后移节点 pre = cur cur = cur.next def search(self, item): """链表查找节点是否存在,并返回True或者False""" cur = self._head while cur != None: if cur.item == item: return True cur = cur.next return False if __name__ == "__main__": ll = SingleLinkList() print(ll.is_empty()) ll.add(1) ll.add(2) ll.append(3) ll.insert(2, 4) print("length:", ll.length()) ll.travel() print(ll.search(3)) print(ll.search(5)) ll.remove(1) print("length:", ll.length()) ll.travel()
-
- 节点实现
-
双向链表
-
只多了一个prev,存储前一个节点的地址
-
全部实现
-
class Node(object): """双向链表节点""" def __init__(self, item): self.item = item self.next = None self.prev = None class DLinkList(object): """双向链表""" def __init__(self): self._head = None def is_empty(self): """判断链表是否为空""" return self._head == None def length(self): """返回链表的长度""" cur = self._head count = 0 while cur != None: count += 1 cur = cur.next return count def travel(self): """遍历链表""" cur = self._head while cur != None: print(cur.item, end="") cur = cur.next print("") def add(self, item): """头部插入元素""" node = Node(item) if self.is_empty(): # 如果是空链表,将_head指向node self._head = node else: # 将node的next指向_head的头节点 node.next = self._head # 将_head的头节点的prev指向node self._head.prev = node # 将_head 指向node self._head = node def append(self, item): """尾部插入元素""" node = Node(item) if self.is_empty(): # 如果是空链表,将_head指向node self._head = node else: # 移动到链表尾部 cur = self._head while cur.next != None: cur = cur.next # 将尾节点cur的next指向node cur.next = node # 将node的prev指向cur node.prev = cur def search(self, item): """查找元素是否存在""" cur = self._head while cur != None: if cur.item == item: return True cur = cur.next return False def insert(self, pos, item): """在指定位置添加节点""" if pos <= 0: self.add(item) elif pos > (self.length() - 1): self.append(item) else: node = Node(item) cur = self._head count = 0 # 移动到指定位置的前一个位置 while count < (pos - 1): count += 1 cur = cur.next # 将node的prev指向cur node.prev = cur # 将node的next指向cur的下一个节点 node.next = cur.next # 将cur的下一个节点的prev指向node cur.next.prev = node # 将cur的next指向node cur.next = node def remove(self, item): """删除元素""" if self.is_empty(): return else: cur = self._head if cur.item == item: # 如果首节点的元素即是要删除的元素 if cur.next == None: # 如果链表只有这一个节点 self._head = None else: # 将第二个节点的prev设置为None cur.next.prev = None # 将_head指向第二个节点 self._head = cur.next return while cur != None: if cur.item == item: # 将cur的前一个节点的next指向cur的后一个节点 cur.prev.next = cur.next # 将cur的后一个节点的prev指向cur的前一个节点 cur.next.prev = cur.prev break cur = cur.next if __name__ == "__main__": ll = DLinkList() ll.add(1) ll.add(2) ll.append(3) ll.insert(2, 4) ll.insert(4, 5) ll.insert(0, 6) print("length:", ll.length()) ll.travel() print(ll.search(3)) print(ll.search(4)) ll.remove(1) print("length:", ll.length())
-
-
-
单向循环链表
-
全部实现、
-
class Node(object): """节点""" def __init__(self, item): self.item = item self.next = None class SinCycLinkedlist(object): """单向循环链表""" def __init__(self): self._head = None def is_empty(self): """判断链表是否为空""" return self._head == None def length(self): """返回链表的长度""" # 如果链表为空,返回长度0 if self.is_empty(): return 0 count = 1 cur = self._head while cur.next != self._head: count += 1 cur = cur.next return count def travel(self): """遍历链表""" if self.is_empty(): return cur = self._head print(cur.item,end="") while cur.next != self._head: cur = cur.next print(cur.item) print("") def add(self, item): """头部添加节点""" node = Node(item) if self.is_empty(): self._head = node node.next = self._head else: #添加的节点指向_head node.next = self._head # 移到链表尾部,将尾部节点的next指向node cur = self._head while cur.next != self._head: cur = cur.next cur.next = node #_head指向添加node的 self._head = node def append(self, item): """尾部添加节点""" node = Node(item) if self.is_empty(): self._head = node node.next = self._head else: # 移到链表尾部 cur = self._head while cur.next != self._head: cur = cur.next # 将尾节点指向node cur.next = node # 将node指向头节点_head node.next = self._head def insert(self, pos, item): """在指定位置添加节点""" if pos <= 0: self.add(item) elif pos > (self.length()-1): self.append(item) else: node = Node(item) cur = self._head count = 0 # 移动到指定位置的前一个位置 while count < (pos-1): count += 1 cur = cur.next node.next = cur.next cur.next = node def remove(self, item): """删除一个节点""" # 若链表为空,则直接返回 if self.is_empty(): return # 将cur指向头节点 cur = self._head pre = None # 若头节点的元素就是要查找的元素item if cur.item == item: # 如果链表不止一个节点 if cur.next != self._head: # 先找到尾节点,将尾节点的next指向第二个节点 while cur.next != self._head: cur = cur.next # cur指向了尾节点 cur.next = self._head.next self._head = self._head.next else: # 链表只有一个节点 self._head = None else: pre = self._head # 第一个节点不是要删除的 while cur.next != self._head: # 找到了要删除的元素 if cur.item == item: # 删除 pre.next = cur.next return else: pre = cur cur = cur.next # cur 指向尾节点 if cur.item == item: # 尾部删除 pre.next = cur.next def search(self, item): """查找节点是否存在""" if self.is_empty(): return False cur = self._head if cur.item == item: return True while cur.next != self._head: cur = cur.next if cur.item == item: return True return False if __name__ == "__main__": ll = SinCycLinkedlist() ll.add(1) ll.add(2) ll.append(3) ll.insert(2, 4) ll.insert(4, 5) ll.insert(0, 6) print("length:",ll.length()) ll.travel() print(ll.search(3)) print(ll.search(7)) ll.remove(1) print("length:",ll.length()) ll.travel()
-
- 单向链表
-
栈
-
可以利用顺序表,链表等都能构成栈,实现栈的功能
-
顺序表实现栈
-
class Stack(object): """栈--顺序表模式""" def __init__(self): self.items = [] def is_empty(self): """判断是否为空""" return self.items == [] def push(self, item): """加入元素""" self.items.append(item) def pop(self): """弹出元素""" return self.items.pop() def peek(self): """返回栈顶元素--最后一个元素""" return self.items[len(self.items)-1] def size(self): """返回栈的大小""" return len(self.items) if __name__ == "__main__": stack = Stack() stack.push("hello") stack.push("world") stack.push("itcast") print(stack.peek()) print(stack.pop()) print(stack.pop()) print(stack.pop())
-
-
队列
-
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
-
顺序表实现队列
-
class Queue(object): """队列""" def __init__(self): self.items = [] def is_empty(self): return self.items == [] def enqueue(self, item): """进队列""" self.items.insert(0, item) def dequeue(self): """出队列""" return self.items.pop() def size(self): """返回大小""" return len(self.items) if __name__ == "__main__": q = Queue() q.enqueue("hello") q.enqueue("world") q.enqueue("itcast") print(q.size()) print(q.dequeue()) print(q.dequeue()) print(q.dequeue())
-
-
双端队列
-
双端队列可以在队列任意一端入队和出队。
-
顺序表实现队列
-
class Deque(object): """双端队列""" def __init__(self): self.items = [] def is_empty(self): """判断队列是否为空""" return self.items == [] def add_front(self, item): """在队头添加元素""" self.items.insert(0,item) def add_rear(self, item): """在队尾添加元素""" self.items.append(item) def remove_front(self): """从队头删除元素""" return self.items.pop(0) def remove_rear(self): """从队尾删除元素""" return self.items.pop() def size(self): """返回队列大小""" return len(self.items) if __name__ == "__main__": deque = Deque() deque.add_front(1) deque.add_front(2) deque.add_rear(3) deque.add_rear(4) print(deque.size()) print(deque.remove_front()) print(deque.remove_front()) print(deque.remove_rear()) print(deque.remove_rear())
-
-
-
-
排序和搜索
-
排序算法的稳定性:排序之后子序列的排列顺序和子序列在原序列时的相同即为稳定
-
冒泡排序
-
代码实现
-
def bubble_sort(alist): for j in range(len(alist)-1,0,-1): # j表示每次遍历需要比较的次数,是逐渐减小的 for i in range(j): if alist[i] > alist[i+1]: alist[i], alist[i+1] = alist[i+1], alist[i] li = [54,26,93,17,77,31,44,55,20] bubble_sort(li) print(li)
-
-
- 最优时间复杂度:O(n) (表示遍历一次发现没有任何可以交换的元素,排序结束。)
- 最坏时间复杂度:O(n2)
- 稳定性:稳定
- 选择排序:找出最小---找出最小,放在固定位置
- 代码实现
-
def selection_sort(alist): n = len(alist) # 需要进行n-1次选择操作 for i in range(n-1): # 记录最小位置 min_index = i # 从i+1位置到末尾选择出最小数据 for j in range(i+1, n): if alist[j] < alist[min_index]: min_index = j # 如果选择出的数据不在正确位置,进行交换 if min_index != i: alist[i], alist[min_index] = alist[min_index], alist[i] alist = [54,226,93,17,77,31,44,55,20] selection_sort(alist) print(alist)
-
-
- 最优时间复杂度:O(n2)
- 最坏时间复杂度:O(n2)
- 稳定性:不稳定(考虑升序每次选择最大的情况)
- 代码实现
- 插入排序:前面有序,后面插入有序的合适位置-----插入是认为前面有序,然后进行插入
- 代码实现
-
def insert_sort(alist): # 从第二个位置,即下标为1的元素开始向前插入 for i in range(1, len(alist)): # 从第i个元素开始向前比较,如果小于前一个元素,交换位置 for j in range(i, 0, -1): if alist[j] < alist[j-1]: alist[j], alist[j-1] = alist[j-1], alist[j] alist = [54,26,93,17,77,31,44,55,20] insert_sort(alist) print(alist)
-
-
- 最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
- 最坏时间复杂度:O(n2)
- 稳定性:稳定
- 代码实现
- 希尔排序---插入排序的改进版
- 取一个gap,分段插入,更改gap,重复
- 代码实现
-
def shell_sort(alist): n = len(alist) # 初始步长 gap = n // 2 while gap > 0: # 按步长进行插入排序 for i in range(gap, n): j = i # 插入排序 while j >= gap and alist[j - gap] > alist[j]: alist[j - gap], alist[j] = alist[j], alist[j - gap] j -= gap # 得到新的步长 gap = gap // 2 alist = [54, 26, 93, 17, 77, 31, 44, 55, 20] shell_sort(alist) print(alist)
-
-
- 最优时间复杂度:根据步长序列的不同而不同
- 最坏时间复杂度:O(n2)
- 稳定想:不稳定
- 快速排序:选一个基准,左边都比他小,右边都比他大---双游标
- 从数列中挑出一个元素,称为"基准"(pivot),
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
- 代码实现
-
def quick_sort(alist, start, end): """快速排序""" # 递归的退出条件 if start >= end: return # 设定起始元素为要寻找位置的基准元素 mid = alist[start] # low为序列左边的由左向右移动的游标 low = start # high为序列右边的由右向左移动的游标 high = end while low < high: # 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动 while low < high and alist[high] >= mid: high -= 1 # 将high指向的元素放到low的位置上 alist[low] = alist[high] # 如果low与high未重合,low指向的元素比基准元素小,则low向右移动 while low < high and alist[low] < mid: low += 1 # 将low指向的元素放到high的位置上 alist[high] = alist[low] # 退出循环后,low与high重合,此时所指位置为基准元素的正确位置 # 将基准元素放到该位置 alist[low] = mid # 对基准元素左边的子序列进行快速排序 quick_sort(alist, start, low-1) # 对基准元素右边的子序列进行快速排序 quick_sort(alist, low+1, end) alist = [54,26,93,17,77,31,44,55,20] quick_sort(alist,0,len(alist)-1) print(alist)
-
-
- 最优时间复杂度:O(nlogn)
- 最坏时间复杂度:O(n2)
- 稳定性:不稳定
- 归并排序
-
归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。
将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。
- 代码实现
-
def merge_sort(alist):
if len(alist) <= 1:
return alist
# 二分分解
num = len(alist)//2
left = merge_sort(alist[:num])
right = merge_sort(alist[num:])
# 合并
return merge(left,right)
def merge(left, right):
'''合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组'''
#left与right的下标指针
l, r = 0, 0
result = []
while l<len(left) and r<len(right):
if left[l] < right[r]:
result.append(left[l])
l += 1
else:
result.append(right[r])
r += 1
result += left[l:]
result += right[r:]
return result
alist = [54,26,93,17,77,31,44,55,20]
sorted_alist = merge_sort(alist)
print(sorted_alist)
-
-
- 最优时间复杂度:O(nlogn)
- 最坏时间复杂度:O(nlogn)
- 稳定性:稳定
-
- 搜索--二分查找
- 递归实现
-
def binary_search(alist, item): if len(alist) == 0: return False else: midpoint = len(alist)//2 if alist[midpoint]==item: return True else: if item<alist[midpoint]: return binary_search(alist[:midpoint],item) else: return binary_search(alist[midpoint+1:],item) testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,] print(binary_search(testlist, 3)) print(binary_search(testlist, 13))
-
- 非递归实现
-
def binary_search(alist, item): first = 0 last = len(alist) - 1 while first <= last: midpoint = (first + last) // 2 if alist[midpoint] == item: return True elif item < alist[midpoint]: last = midpoint - 1 else: first = midpoint + 1 return False testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42, ] print(binary_search(testlist, 3)) print(binary_search(testlist, 13))
-
-
- 最优时间复杂度:O(1)
- 最坏时间复杂度:O(logn)
- 递归实现
- 树
- 树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。
- 特点
- 每个节点有零个或多个子节点;
- 没有父节点的节点称为根节点;
- 每一个非根节点有且只有一个父节点;
- 除了根节点外,每个子节点可以分为多个不相交的子树;
- 术语
- 节点的度:一个节点含有的子树的个数称为该节点的度;
- 树的度:一棵树中,最大的节点的度称为树的度;
- 叶节点或终端节点:度为零的节点;
- 父亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
- 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
- 兄弟节点:具有相同父节点的节点互称为兄弟节点;
- 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
- 树的高度或深度:树中节点的最大层次;
- 堂兄弟节点:父节点在同一层的节点互为堂兄弟;
- 节点的祖先:从根到该节点所经分支上的所有节点;
- 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
- 森林:由m(m>=0)棵互不相交的树的集合称为森林;
- 树的种类
- 无序树:树中任意节点的子节点之间没有顺序关系,这种树称为无序树,也称为自由树;
- 有序树:树中任意节点的子节点之间有顺序关系,这种树称为有序树;
- 二叉树:每个节点最多含有两个子树的树称为二叉树;
- 完全二叉树:对于一颗二叉树,假设其深度为d(d>1)。除了第d层外,其它各层的节点数目均已达最大值,且第d层所有节点从左向右连续地紧密排列,这样的二叉树被称为完全二叉树,其中满二叉树的定义是所有叶节点都在最底层的完全二叉树;
- 平衡二叉树(AVL树):当且仅当任何节点的两棵子树的高度差不大于1的二叉树;
- 排序二叉树(二叉查找树(英语:Binary Search Tree),也称二叉搜索树、有序二叉树);
- 霍夫曼树(用于信息编码):带权路径最短的二叉树称为哈夫曼树或最优二叉树;
- B树:一种对读写操作进行优化的自平衡的二叉查找树,能够保持数据有序,拥有多余两个子树。
- 二叉树:每个节点最多含有两个子树的树称为二叉树;
- 存储方式
- 顺序存储:将数据结构存储在固定的数组中,然在遍历速度上有一定的优势,但因所占空间比较大,是非主流二叉树。二叉树通常以链式存储。
- 链式存储
- 顺序存储:将数据结构存储在固定的数组中,然在遍历速度上有一定的优势,但因所占空间比较大,是非主流二叉树。二叉树通常以链式存储。
- 应用场景
- 1.xml,html等,那么编写这些东西的解析器的时候,不可避免用到树
2.路由协议就是使用了树的算法
3.mysql数据库索引
4.文件系统的目录结构
5.所以很多经典的AI算法其实都是树搜索,此外机器学习中的decision tree也是树结构
- 1.xml,html等,那么编写这些东西的解析器的时候,不可避免用到树
- 二叉树
- 性质1: 在二叉树的第i层上至多有2^(i-1)个结点(i>0)
性质2: 深度为k的二叉树至多有2^k - 1个结点(k>0)
性质3: 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
性质4:具有n个结点的完全二叉树的深度必为 log2(n+1)
性质5:对完全二叉树,若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必为i/2(i=1 时为根,除外) - 代码实现
-
# 通过使用Node类中定义三个属性,分别为elem本身的值,还有lchild左孩子和rchild右孩子 class Node(object): """节点类""" def __init__(self, elem=-1, lchild=None, rchild=None): # 数据 self.elem = elem self.lchild = lchild self.rchild = rchild # 树的创建,创建一个树的类,并给一个root根节点,一开始为空,随后添加节点 class Tree(object): """树类""" def __init__(self, root=None): # 首节点,根节点 self.root = root def add(self, elem): """为树添加节点""" node = Node(elem) # 如果树是空的,则对根节点赋值 if self.root == None: self.root = node else: # 利用队列实现,广度优先的遍历 queue = [] queue.append(self.root) # 对已有的节点进行层次遍历 while queue: # 弹出队列的第一个元素 cur = queue.pop(0) if cur.lchild == None: cur.lchild = node return elif cur.rchild == None: cur.rchild = node return else: # 如果左右子树都不为空,加入队列继续判断 queue.append(cur.lchild) queue.append(cur.rchild)
-
- 二叉树的遍历,代码实现
-
# 通过使用Node类中定义三个属性,分别为elem本身的值,还有lchild左孩子和rchild右孩子 class Node(object): """节点类""" def __init__(self, elem=-1, lchild=None, rchild=None): # 数据 self.elem = elem self.lchild = lchild self.rchild = rchild # 树的创建,创建一个树的类,并给一个root根节点,一开始为空,随后添加节点 class Tree(object): """树类""" def __init__(self, root=None): # 首节点,根节点 self.root = root def add(self, elem): """为树添加节点""" node = Node(elem) # 如果树是空的,则对根节点赋值 if self.root == None: self.root = node else: # 利用队列实现,广度优先的遍历 queue = [] queue.append(self.root) # 对已有的节点进行层次遍历 while queue: # 弹出队列的第一个元素 cur = queue.pop(0) if cur.lchild == None: cur.lchild = node return elif cur.rchild == None: cur.rchild = node return else: # 如果左右子树都不为空,加入队列继续判断 queue.append(cur.lchild) queue.append(cur.rchild) def breadth_travel(self): """利用队列实现树的层次遍历""" if self.root == None: return queue = [] queue.append(self.root) while queue: node = queue.pop(0) print(node.elem, end=" ") if node.lchild != None: queue.append(node.lchild) if node.rchild != None: queue.append(node.rchild) def preorder(self, node): """递归实现先序遍历---中左右""" if node == None: return print(node.elem,end=" ") self.preorder(node.lchild) self.preorder(node.rchild) def inorder(self,root): """递归实现中序遍历----左中右""" if root == None: return self.inorder(root.lchild) print(root.elem,end=" ") self.inorder(root.rchild) def postorder(self,root): """递归实现后续遍历---左右中""" if root == None: return self.postorder(root.lchild) self.postorder(root.rchild) print(root.elem, end=" ") if __name__ == '__main__': tree = Tree() tree.add(0) tree.add(1) tree.add(2) tree.add(3) tree.add(4) tree.add(5) tree.add(6) tree.add(7) tree.add(8) tree.add(9) tree.breadth_travel() print(end=" ") tree.preorder(tree.root) print(end=" ") tree.inorder(tree.root) print(end=" ") tree.postorder(tree.root)
-
0 1 2 3 4 5 6 7 8 9 0 1 3 7 8 4 9 2 5 6 7 3 8 1 9 4 0 5 2 6 7 8 3 9 4 1 5 6 2 0
-
- 性质1: 在二叉树的第i层上至多有2^(i-1)个结点(i>0)
-
-
MySql
-
数据库命令: 创建create database 数据库名 charset=utf8; 删除drop database 数据库名; 查看所有数据库:show databases; 使用数据库:use 数据库名; ---------------------------------------- 表命令: create table 表名(列...); 唯一标识的要求:id 类型:int unsigned 约束1:not null 约束2:primary key 约束3:auto_increment 列的格式:列的名称 类型 约束 create table stu( -> id int not null primary key auto_increment, -> name varchar(10) not null, -> gender bit default 1, -> birthday datetime, -> isDelete bit default 0, -> ); 查看表show tables; 查看表结构desc 表名; 修改表:alter table 表名 add|modify|drop 列名 类型 约束; alter table stu modify column isDelete bit not null default 0; 删除表:drop table 表名; ---------------------------------------- 数据命令: 添加数据:insert into 表名(列名) values(值),(值)...; 修改数据:update 表名 set 列1=值1,... where ...; 删除数据:delete from 表名 where ...; 逻辑删除:update .... 备份:mysqldump > 恢复:mysql < --------------------------------------- 数据库、表、字段、行 问:查询姓黄或洪的男生 分析:数据从哪来,哪个表stu 条件:姓黄或洪name or and 男生gender 答:select * from stu where gender=1 and (name like '黄%' or name like '洪%') distinct 条件:where 字段 运算符 常量 分组聚合:group by ... having ... 关系的存储方案 1:1-》存储在任何一个表中 1:n-》存储在n的表中,新增一个字段 m:n-》新建表 成绩表:id,成绩,学生,科目 关系,第三范式,外键 问题:两个表之间有关系吗?分析的依据是当前系统的业务,够用就行 怎么存储这个关系?参照“关系的存储方案” 关系字段的类型是什么?根据第三范式,引用主键,所以主键的类型,就是这个字段的类型 关系字段的数据有效性怎么保证?外键 create table sco( id int not null auto_increment primary key, stu_id int, sub_id int, score int(3), foreign key(stu_id) references stu(id), foreign key(sub_id) references sub(id) ); insert into sco values(0,1,1,100); ---------------------------------- select distinct * from 表名 where ... group by ... having ... order by ... limit ... 关系的问题 (1)是什么样的对应关系 (2)存储关系的字段,使用什么类型 (3)存入数据时错了怎么办? 查:学生姓名及所在的班级名称 分析:stu,class stu.class_id=class.id 答:select * from stu inner join class on stu.class_id=class.id 查询学生的姓名、平均分 分析:姓名->stu 平均分->先sco查分数,再聚合avg 需要从两张表中获取数据,所以需要连接 连接的条件:stu.id=sco.stu_id 实现一:获取所有的原始数据 select name,score from stu inner join sco on stu.id=sco.stu_id 继续分析:对每个学生求平均分 让姓名相同的信息,分成一组 select name,avg(score) from stu inner join sco on stu.id=sco.stu_id group by name 查询男生的姓名、总分 分析:姓名->stu 男生->stu 总分->sum(),分数->sco 连接条件:stu.id=sco.stu_id 实现一:select * from sco inner join stu on stu.id=sco.stu_id where gender=1 实现二:分组 。。。 group by name 查询科目的名称、平均分 sub.title->sub avg(),score->sco sub.id=sco.sub_id 查询学生姓名、科目名称、分数 stu sub sco 查询省的名称为“山西省”的所有城市 select * from areas where title='山西省' 查询‘广州市’的所有区县 #select * from areas where title='淄博市' #370300 #select * from areas where pid='370300' #370301 #select * from areas where pid='370301' #areas as shi where shi.title='广州市' #areas as qu on qu.pid=shi.id #areas as qu1 on qu1.pid=qu.id select qu.*,qu1.* from areas as shi inner join areas as qu on qu.pid=shi.id left join areas as qu1 on qu1.pid=qu.id where shi.title='淄博市' 子查询 #查询广州市、淄博市的所有区 #select id from areas where title='广州市' or title='淄博市' select * from areas where pid in(select id from areas where title='广州市' or title='淄博市') 源码安装:python setup.py install ----------------------------------- MySQLdb Connection Cursor 查询:fetchone(),fetchall() 封装:将数据库操作的代码封装到一个类中,helper 用户的登录注册成功 hashlib sha1() update() hexdigest()
-
-
PS
-
常见图片格式
-
psd
-
photoshop的专用格式,UI设计师使用photoshop设计效果图,最后会将psd格式的效果图交付给前端工程师,这种格式是不压缩的,而且保留了图层、透明和半透明等图片信息,所以这种图片格式的容量相对来说是很大的,前端工程师使用这种格式的效果图来切图制作网页,但是网页中不会使用这个格式的图片,它的作用一是保存图片的原始数据,二是方便图片的修改。
-
-
jpg
-
jpg是一种有损压缩格式,压缩效率高,容量相对来说最小,网络传输速度快,它不能存为透明背景,在网页中应用最广,一般在不需要透明背景的时候就使用这种图片。
-
-
gif
- gif是一种无损压缩格式的图片,最多只有256种颜色,颜色丰富的图片转化为这种格式会颜色失真。它的背景可以是透明的,但不能是半透明的,透明背景中的图像,如果边缘轮廓是曲线的,会产生锯齿,它还可以保存为动画格式。
- png
- png的目的是为了代替gif图片,无损压缩,背景可以是透明或者半透明的,透明图像边缘光滑,没有锯齿,网页中需要透明或者半透明背景的图片,首选是png图片。
- webp
- 由谷歌于2010年推出的新一代图片格式,在压缩方面比当前jpg格式更优越,在质量相同的情况下,WebP格式图像的体积要比jpg格式图像小40%,不过这种图片还没有得到广泛的浏览器支持,仅在Chrome和Opera上支持
- 位图和矢量图
- 位图也叫点阵图,是由一个个的方形的像素点排列在一起拼接而成的,位图在放大时,图像会失真。上面讲的5种图像都属于位图。
矢量图和位图组成图像的原理不同,它的图像轮廓是由函数曲线生成的,当放大图像时,实际的原理就是将曲线乘以一个倍数,图像可以轻易地放大,而且不会出现像素块,图像边缘也不会出现锯齿。
- 位图也叫点阵图,是由一个个的方形的像素点排列在一起拼接而成的,位图在放大时,图像会失真。上面讲的5种图像都属于位图。
- svg
- svg是一种矢量二维图形格式,它是基于xml标记语言描述的,可以通过任何文本编辑器创建。它的优点是文件容量小,放大不失真,而且背景也可以是透明的。目前大量使用这种格式来制作网页图标或者网页地图,由于它是矢量的,所以在不同终端屏幕上(pc、手机)都有很好的显示效果。
- flash
- flash是一种矢量动画文件格式,曾经在网络上风靡一时,如今已逐渐退出历史舞台,原因是它的技术更新跟不上发展,这种格式既可以是静态的图形,还可以是多媒体动画,还可以加入用户交互和数据,这是它曾经很流行的原因,这种格式名为swf,flash是对它的统称。这种格式在网页中已经很少使用了,它的很多优秀特性,可以用HTML5取代。swf文件中衍生出一种视频格式flv,它是一种流媒体视频格式,由于它有文件容量小,可以边下载,边观看等优点,目前广泛应用在视频网站中。
-
- 基本操作
- ctrl + +:放大
- ctrl + - :缩小
- 空格+鼠标:平移
-
photoshop批量切图
-
1、使用psd格式并且带有图层的图像切图
2、在图像上用切片工具切出需要的小图
3、双击切片,给切片命名
4、执行菜单命令 存储为web所用格式
5、点选切片,设置切片的图片格式
6、存储切片,选择“所有用户切片”,点存储(多个切片会存到所选文件夹中的images文件夹中)
-
-
Photoshop制作雪碧图
-
雪碧图,就是将网页制作中使用的多个小图片合并成一个图片,使用css技术将这张合成的图片应用在网页不同的地方,雪碧图可以减少网页加载时的http请求数,优化网页性能。
步骤:
1、使用Photoshop新建一张背景透明的图片
2、将小图片复制到此图片中,排列好每个图像的位置,图片幅面不够可以用画布大小调整大小
3、按照所有小图片的范围裁剪图片,存为透明背景的png图片
-
-
-
JS---原生的JS
-
前端三大块
1、HTML:页面结构
2、CSS:页面表现:元素大小、颜色、位置、隐藏或显示、部分动画效果
3、JavaScript:页面行为:部分动画效果、页面与用户的交互、页面功能 -
JQuery是JS人性化的库,基本使用也是Jquery
-
嵌入页面
-
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>JS的嵌入</title> </head> <body> <!--第一种,行间事件--不推荐使用--> <input type="button" value="弹框" onclick="alert('hello world')"> <!--第二种,页面script标签嵌入---常用--> <script type="text/javascript"> var a = '你好!'; alert(a); </script> <!--第三种,外部引入--> <script type="text/javascript" src="hello.js"></script> </body> </html>
-
-
结尾:一条javascript语句应该以“;”结尾
-
注释
-
<script type="text/javascript"> // 单行注释 var a = 123; /* 多行注释 1、... 2、... */ var b = 'str'; </script>
-
-
变量:声明var
-
变量类型
-
基本数据类型
-
number、string、boolean、undefined、null
- undefined(未定义)
- 声明或定义的时候,没有给值,会自动变成未定义类型
- 变量定义,值未定义
-
-
复合类型
-
object
-
-
-
-
获取元素(标签)
-
getElementById
-
var oDiv = document.getElementById('div1');
oDiv.title = "找到你了!"
-
window.onload = function(){ var oDiv = document.getElementById('div1');
-
当整个文档加载完之后,在执行这个JS操作
-
-
getElementsByTagName
-
window.onload = function () { // 得到的是一个列表,数组 var ali = document.getElementsByTagName('li'); //alert(ali.length) ali[1].style.backgroundColor = 'gold'
-
-
-
操作元素(标签)属性
-
操作属性的方法
-
“.” 操作
-
var oA = document.getElementById('link1'); //写属性值 oA.href="http://www.baidu.com/"; oA.title = "去到百度网"; //读属性值 alert(oA.id)
-
1、html的属性和js里面属性写法一样
-
2、“class” 属性写成 “className”
-
3、“style” 属性里面的属性,有横杠的改成驼峰式,比如:“font-size”,改成”style.fontSize”
-
-
“[ ]”操作:可以写变量
-
var color1 = "color"; oA.style[color1] = 'yellow';
-
- innerHTML可以读取或者写入标签包裹的内容
-
//读取标签包括的内容 var txt = oA.innerHTML; alert(txt);
-
-
- 函数
- 函数定义与执行
-
<script type="text/javascript"> // 函数定义 function aa(){ alert('hello!'); } // 函数执行 aa(); </script>
-
- 在html行间调用的事件可以提取到javascript中调用,从而做到结构与行为分离。
-
<!-- 提取行间事件 --> <script type="text/javascript"> window.onload = function(){ var oBtn = document.getElementById('btn1'); oBtn.onclick = myalert; function myalert(){ alert('ok!'); } } </script> ...... <input type="button" name="" value="弹出" id="btn1">
-
- 匿名函数
-
// 直接将匿名函数赋值给绑定的事件 oBtn.onclick = function (){ alert('ok!'); }
-
- JavaScript解析过程分为两个阶段,先是编译阶段,然后执行阶段,在编译阶段会将function定义的函数提前,并且将var定义的变量声明提前,将它赋值为undefined。
- 函数穿参
-
<script type="text/javascript"> function add(a, b) { var c = a + b; return c; alert('here!'); } var d = add(3, 4); alert(d); //弹出7 </script>
-
function changestyle(styl,val) { oA.style[styl] = 'val'; } changestyle('color','gold'); changestyle('background','red');
-
- 条件语句
- &&(而且)、||(或者)、!(否)
- if ...else
-
var a = 6; if(a==1) { alert('语文'); } else if(a==2) { alert('数学'); } else if(a==3) { alert('英语'); } else if(a==4) { alert('美术'); } else if(a==5) { alert('舞蹈'); } else { alert('不补习'); }
-
- switch
-
var a = 6; switch (a){ case 1: alert('语文'); break; case 2: alert('数学'); break; case 3: alert('英语'); break; case 4: alert('美术'); break; case 5: alert('舞蹈'); break; default: alert('不补习'); }
-
- 数组及操作方法
- 创建数组
-
//对象的实例创建 var aList = new Array(1,2,3); //直接量创建 var aList2 = [1,2,3,'asd'];
-
-
数组中的方法
-
<script type="text/javascript"> //多维数组 var aList2 = [[1,2,3],['a','b','c']]; alert(aList2[0][1]); //弹出2; // 数组长度 var aList = [1,2,3,4]; alert(aList.length); // 弹出4 // 下标获取值 alert(aList[0]); // 弹出1 // join alert(aList.join('-')); // 弹出 1-2-3-4 // 尾部增加元素append aList.push(5); // pop 尾部删除 aList.pop(); // 前面增加元素 aList.unshift(5); // 前面删除元素 aList.shift(); // 数组反转 aList.reverse(); // 第一次出现时的索引 alert(aList.indexOf(1)); // 删除和增加元素 aList.splice(2,1,7,8,9); //从第2个元素开始,删除1个元素,然后在此位置增加'7,8,9'三个元素 alert(aList); //弹出 1,2,7,8,9,4 </script>
-
-
循环语句
-
for
-
for(var i=0;i<len;i++) { ...... }
-
-
while
-
var i=0; while(i<8){ ...... i++; }
-
-
数组去重
-
var aList = [1,2,3,4,4,3,2,1,2,3,4,5,6,5,5,3,3,4,2,1]; var aList2 = []; for(var i=0;i<aList.length;i++) { if(aList.indexOf(aList[i])==i) { aList2.push(aList[i]); } } alert(aList2);
-
-
- 创建数组
-
Javascript组成
-
1、ECMAscript javascript的语法(变量、函数、循环语句等语法)
2、DOM 文档对象模型 操作html和css的方法
3、BOM 浏览器对象模型 操作浏览器的一些方法
-
-
字符串处理方法
-
<script type="text/javascript"> var str = 'asdfj12jlsdkf098'; // + 字符串拼接 var name = 'xiaohei'; var age = 19; alert('名字是'+name+',年龄是'+age); // int() parseInt(); // float() parseFloat(); // split() var str2 = str.split('').reverse().join(''); // 第一次出现的索引 str.indexOf(a); // 根据索引找值 str.charAt(0); // 切片 str.substring(1,-1); // 小写转大写 str.toUpperCase(); // 大写转小写 str.toLowerCase() ; alert(str2); </script>
-
-
调试程序的方法
-
1、alert
2、console.log
3、document.title
-
-
计算器
-
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>计算器</title> </head> <body> <h1>计算器</h1> <input type="text" id="input1"> <select id="fuhao"> <option value="0">+</option> <option value="1">-</option> <option value="2">*</option> <option value="3">/</option> </select> <input type="text" id="input2"> <input type="button" value="计算" id="btn"> <script type="text/javascript"> window.onload = function () { var oInput01 = document.getElementById("input1"); var oInput02 = document.getElementById("input2"); var oFuhao = document.getElementById("fuhao"); var oBtn = document.getElementById("btn"); // oBtn绑定事件 oBtn.onclick = function () { var num01 = oInput01.value; var num02 = oInput02.value; var fuhao = oFuhao.value; if (num01 == '' || num02 == ''){ alert("输出框不能为空!"); return } if(isNaN(num01) || isNaN(num02)){ alert("输入的不是一个数字,请输入数字") return } switch (fuhao) { case "0": alert((parseFloat(num01) * 100 + parseFloat(num02) * 100) / 100); break; case "1": alert((parseFloat(num01) * 100 - parseFloat(num02) * 100) / 100); break; case "2": alert((parseFloat(num01) * 100 * parseFloat(num02) * 100) / 100); break; case "3": alert((parseFloat(num01) * 100 / parseFloat(num02) * 100) / 100); break; } }; }; </script> </body> </html>
-
- 类型转换
- 1、直接转换 parseInt() 与 parseFloat()
- 2、隐式转换 “==” 和 “-”
- 3、NaN 和 isNaN
- NaN非数字
- isNaN判断非数字
- 定时器
- 作用
- 1、制作动画
2、异步操作
3、函数缓冲与节流
- 1、制作动画
- 定时器类型
-
setTimeout();
只执行一次的定时器
-
// 2个参数函数,x毫秒 ---延迟3000毫秒,执行函数 setTimeout(showpop,3000); function showpop() { oPop.style.display = 'block'; }
-
弹窗的例子
-
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>定时器</title> <style type="text/css"> .pop_con{ display: none; } .pop{ 400px; height: 300px; background-color: white; border: 1px solid #000000; position: fixed; left: 50%; top: 50%; margin-left: -200px; margin-top: -150px; /*层级*/ z-index: 9999; } .mask { /*针对浏览器窗口定位*/ position: fixed; 100%; height: 100%; background-color: black; left: 0; top: 0; /*透明度*/ opacity: 0.3; /*针对IE的透明度*/ filter: alpha(opacity=30); z-index: 9990; } </style> </head> <body> <h1>首页标题</h1> <p>页面内容</p> <div class="pop_con" id="pop"> <div class="pop"> <h3>提示信息!</h3> <a href="#" id="shutoff">关闭提示</a> </div> <div class="mask"></div> </div> <script type="text/javascript"> window.onload = function () { var oPop = document.getElementById("pop"); var oShut = document.getElementById("shutoff"); // 2个参数函数,x毫秒 ---延迟3000毫秒,执行函数 setTimeout(showpop,3000); function showpop() { oPop.style.display = 'block'; } // 控制关闭弹窗 oShut.onclick = function () { oPop.style.display = 'none'; // clearTimeout() } }; function myalert() { alert("hello world") } // myalert(); </script> </body> </html>
-
-
-
关闭定时器
-
var timer=setTimeout(function() { alert("hello"); },3000); // 关闭定时器 clearTimeout(timer);
-
-
- setInterval 反复执行的定时器
-
//一直执行的定时器 var timer2=setInterval(function() { alert("hi"); },2000); // 关闭定时器 clearInterval(timer2);
-
- 定时器做动画的基本原理
-
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>动画</title> <style type="text/css"> .box{ 100px; height: 100px; background-color: gold; position: fixed; left: 20px; top: 20px; } </style> </head> <body> <div class="box" id="box"> </div> <script type="text/javascript"> window.onload = function () { var oBox = document.getElementById('box'); var left = 20; var timer =setInterval(function () { left+=2; oBox.style.left = left + 'px'; // 到700停止 if(left>700){ clearInterval(timer); } },30); }; </script> </body> </html>
-
- 定时器做时钟
-
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>时钟</title> </head> <body> <div id="div1"></div> <script type="text/javascript"> window.onload = function(){ var oDiv = document.getElementById('div1'); function timego(){ // 内置对象 Date() // now :Mon Jun 08 2020 23:06:44 GMT+0800 (中国标准时间) var now = new Date(); // alert(now); var year = now.getFullYear(); var month = now.getMonth()+1; var date = now.getDate(); var week = now.getDay(); var hour = now.getHours(); var minute = now.getMinutes(); var second = now.getSeconds(); var str = '当前时间是:'+ year + '年'+month+'月'+date+'日 '+toweek(week)+' '+todou(hour)+':'+todou(minute)+':'+todou(second); oDiv.innerHTML = str; } // 先执行一次,没有间隔时间 timego(); setInterval(timego,1000); }; function toweek(n){ if(n==0) { return '星期日'; } else if(n==1) { return '星期一'; } else if(n==2) { return '星期二'; } else if(n==3) { return '星期三'; } else if(n==4) { return '星期四'; } else if(n==5) { return '星期五'; } else { return '星期六'; } } function todou(n){ if(n<10) { return '0'+n; } else { return n; } } </script> </body> </html>
-
- 定时器做倒计时
-
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>倒计时</title> </head> <body> <div id="div1"></div> <script type="text/javascript"> window.onload = function(){ var oDiv = document.getElementById('div1'); function timeleft(){ // 实际开发从服务器获取 var now = new Date(); var future = new Date(2020,10,1,24,0,0); var lefts = parseInt((future-now)/1000); var day = parseInt(lefts/86400); var hour = parseInt(lefts%86400/3600); var min = parseInt(lefts%86400%3600/60); var sec = lefts%60; alert(lefts); // 当时间到达,跳转页面 if(lefts<1){ window.location.href = "http://www.baidu.com" } str = '距离2020年10月1日晚24点还剩下'+day+'天'+hour+'时'+min+'分'+sec+'秒'; oDiv.innerHTML = str; } timeleft(); setInterval(timeleft,1000); } </script> </body> </html>
-
- 作用
- 变量作用域
- 全局变量
- 局部变量
- 封闭函数
- 定义的变量不会影响到全局
- 增加功能,不影响全局
-
/* function f() { var str = "欢迎"; alert(str); } f(); */ // 上面函数的简写形式 (function() { var str = "欢迎1"; alert(str); })(); // 封闭函数的其他写法 !function () { var str = "欢迎2"; alert(str); }(); ~function () { var str = "欢迎3"; alert(str); }();
-
- 闭包
- 闭包的本质就是函数嵌套--内部函数可以引用外部函数的参数和变量,不会被垃圾回收机制回收
-
function aaa(a){ var b = 5; function bbb(){ a++; b++; alert(a); alert(b); } return bbb; } var ccc = aaa(2); ccc(); ccc();
-
- 用封闭函数写
-
var ccc = (function(a){ var b = 5; function bbb(){ a++; b++; alert(a); alert(b); } return bbb; })(2); ccc(); ccc();
-
- 闭包的用途
- 将一个变量长期驻扎在内存当中,可用于循环中存索引值
-
<script type="text/javascript"> window.onload = function(){ var aLi = document.getElementsByTagName('li'); for(var i=0;i<aLi.length;i++) { (function(i){ aLi[i].onclick = function(){ alert(i); } })(i); } } </script> ...... <ul> <li>111</li> <li>222</li> <li>333</li> <li>444</li> <li>555</li> </ul>
-
- 私有变量计数器,外部无法访问,避免全局变量的污染
-
<script type="text/javascript"> var count = (function(){ var a = 0; function add(){ a++; return a; } return add; })() count(); count(); var nowcount = count(); alert(nowcount); </script>
-
- 将一个变量长期驻扎在内存当中,可用于循环中存索引值
- 闭包的本质就是函数嵌套--内部函数可以引用外部函数的参数和变量,不会被垃圾回收机制回收
- 内置对象
-
1、document
-
document.referrer //获取上一个跳转页面的地址(需要服务器环境)
-
-
2、location
-
window.location.href //获取或者重定url地址
-
window.location.search //获取地址参数部分
-
window.location.hash //获取页面锚点或者叫哈希值
-
-
3、Math
-
Math.random 获取0-1的随机数
-
Math.ceil 向上取整
-
Math.floor 向下取整
-
-
-
面向对象
-
1、面向过程:所有的工作都是现写现用。
-
2、面向对象:是一种编程思想,许多功能事先已经编写好了,在使用时,只需要关注功能的运用,而不需要这个功能的具体实现过程。
-
-
新增选择器
-
1、document.querySlector()
- 类似jquery的写法.class等
-
2、document.querySlectorAll()
-
选中多个
-
-
- 函数定义与执行
-
-
-
jquery
-
jQuery是目前使用最广泛的javascript函数库。实际开发都使用这个,不使用原生的JS
-
口号:Write Less, Do More(写得少,做得多)
-
引入
-
<script type="text/javascript" src="jquery-3.3.1.js"></script>
-
-
初步使用,ready比原生的onload快
-
<script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript" > // 所有节点加载完就执行,不等渲染 $(document).ready(function () { var $div = $('.div1'); // 打印div包括的文字 alert($div.html()); }); // 简写 $(function () { var $div = $('.div1'); // 打印div包括的文字 alert($div.html()+'jquery'); }) </script>
-
-
jquery选择器:先选择,在操作
- 选择器
-
$(document) //选择整个文档对象 $('li') //选择所有的li元素 $('#myId') //选择id为myId的网页元素 $('.myClass') // 选择class为myClass的元素 $('input[name=first]') // 选择name属性等于first的input元素 $('#ul1 li span') //选择id为为ul1元素下的所有li下的span元素
-
-
对选择集进行修饰过滤
-
$('#ul1 li:first') //选择id为ul1元素下的第一个li $('#ul1 li:odd') //选择id为ul1元素下的li的奇数行 $('#ul1 li:eq(2)') //选择id为ul1元素下的第3个li $('#ul1 li:gt(2)') // 选择id为ul1元素下的前三个之后的li $('#myForm :input') // 选择表单中的input元素 $('div:visible') //选择可见的div元素
-
-
对选择集进行函数过滤
-
$('div').has('p'); // 选择包含p元素的div元素 $('div').not('.myClass'); //选择class不等于myClass的div元素 $('div').filter('.myClass'); //选择class等于myClass的div元素 $('div').first(); //选择第1个div元素 $('div').eq(5); //选择第6个div元素
-
-
选择集转移
-
$('div').prev('p'); //选择div元素前面的第一个p元素 $('div').next('p'); //选择div元素后面的第一个p元素 $('div').closest('form'); //选择离div最近的那个form父元素 $('div').parent(); //选择div的父元素 $('div').children(); //选择div的所有子元素 $('div').siblings(); //选择div的同级元素 $('div').find('.myClass'); //选择div内的class等于myClass的元素
-
- 选择器
-
样式操作
-
操作行间样式
-
// 获取div的样式 $("div").css("width"); $("div").css("color"); //设置div的样式 $("div").css("width","30px"); $("div").css("height","30px"); $("div").css({fontSize:"30px",color:"red"});
-
-
操作样式类名
-
$("#div1").addClass("divClass2") //为id为div1的对象追加样式divClass2 $("#div1").removeClass("divClass") //移除id为div1的对象的class名为divClass的样式 $("#div1").removeClass("divClass divClass2") //移除多个样式 $("#div1").toggleClass("anotherClass") //重复切换anotherClass样式
-
-
-
绑定click事件
-
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> <style type="text/css"> .box{ 200px; height: 200px; background-color: gold; } .sty{ background-color: green; } </style> </head> <body> <div class="div1">这是一个div元素</div> <input type="button" value="切换" id="btn"> <div class="box"></div> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript" > // 样式切换与点击事件的绑定 $(function () { $('#btn').click(function () { $('.box').toggleClass('sty'); }); }) </script> </body> </html>
-
-
jquery做选项卡
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .btns{ 500px; height:50px; } .btns input{ 100px; height:50px; background-color:#ddd; color:#666; border:0px; } .btns input.cur{ background-color:gold; } .contents div{ 500px; height:300px; background-color: gold; display:none; line-height:300px; text-align:center; } .contents div.active{ display: block; } </style> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ $('#btns input').click(function() { // this是原生的对象 // 上面的切换效果,自己增加cur,兄弟去掉cur $(this).addClass('cur').siblings().removeClass('cur'); //$(this).index() 获取当前按钮所在层级范围的索引值 $('#contents div').eq($(this).index()).addClass('active').siblings().removeClass('active'); }); }) </script> </head> <body> <div class="btns" id="btns"> <input type="button" value="tab01" class="cur"> <input type="button" value="tab02"> <input type="button" value="tab03"> </div> <div class="contents" id="contents"> <div class="active">tab文字内容一</div> <div>tab文字内容二</div> <div>tab文字内容三</div> </div> </body> </html>
-
-
jquery求索引值
-
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> <style type="text/css"> .list li{ height: 30px; margin-bottom: 20px ; background-color: gold; } </style> </head> <body> <ul class="list"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> </ul> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function () { $('.list li').click(function () { alert($(this).index()); }); }) </script> </body> </html>
-
-
jquery特殊效果---固定动画
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ 200px; height:200px; background-color: gold; } </style> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ $('#btn1').click(function() { //淡入淡出 $('.box').fadeToggle(); }); $('#btn2').click(function() { // 展开和卷起 $('.box').slideToggle(); }); $('#btn3').click(function() { // 显示和隐藏 $('.box').toggle(); }); }) </script> </head> <body> <input type="button" name="" value="效果1" id="btn1"> <input type="button" name="" value="效果2" id="btn2"> <input type="button" name="" value="效果3" id="btn3"> <div class="box"></div> </body> </html>
-
-
jquery链式调用:jquery对象的方法会在执行完后返回这个jquery对象,所有jquery对象的方法可以连起来写
-
$('#div1') // id为div1的元素 .children('ul') //该元素下面的ul子元素 .slideDown('fast') //高度从零变到实际高度来显示ul元素 .parent() //跳到ul的父元素,也就是id为div1的元素 .siblings() //跳到div1元素平级的所有兄弟元素 .children('ul') //这些兄弟元素中的ul子元素 .slideUp('fast'); //高度实际高度变换到零来隐藏ul元素
-
-
jquery动画
-
层级菜单
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>层级菜单</title> <style type="text/css"> body{ font-family:'Microsoft Yahei'; } body,ul{ margin:0px; padding:0px; } ul{list-style:none;} .menu{ 200px; margin:20px auto 0; } .menu .level1,.menu li ul a{ display:block; 200px; height:30px; line-height:30px; text-decoration:none; background-color:#3366cc; color:#fff; font-size:16px; text-indent:10px; } .menu .level1{ border-bottom:1px solid #afc6f6; } .menu li ul a{ font-size:14px; text-indent:20px; background-color:#7aa1ef; } .menu li ul li{ border-bottom:1px solid #afc6f6; } .menu li ul{ display:none; } .menu li ul.current{ display:block; } .menu li ul li a:hover{ background-color:#f6b544; } </style> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ // 层级菜单的显示和隐藏 /* $('.level1').click(function() { $(this).next().toggleClass('current'); }); */ // 向上,向下展开 /* $('.level1').click(function() { $(this).next().slideToggle(); }); */ $('.level1').click(function() { // a-li-剩下的li-ul--关闭 $(this).next().slideDown().parent().siblings().children('ul').slideUp(); }); }); </script> </head> <body> <ul class="menu"> <li> <a href="#" class="level1">水果</a> <ul class="current"> <li><a href="#">苹果</a></li> <li><a href="#">梨子</a></li> <li><a href="#">葡萄</a></li> <li><a href="#">火龙果</a></li> </ul> </li> <li> <a href="#" class="level1">海鲜</a> <ul> <li><a href="#">蛏子</a></li> <li><a href="#">扇贝</a></li> <li><a href="#">龙虾</a></li> <li><a href="#">象拔蚌</a></li> </ul> </li> <li> <a href="#" class="level1">肉类</a> <ul> <li><a href="#">内蒙古羊肉</a></li> <li><a href="#">进口牛肉</a></li> <li><a href="#">野猪肉</a></li> </ul> </li> <li> <a href="#" class="level1">蔬菜</a> <ul> <li><a href="#">娃娃菜</a></li> <li><a href="#">西红柿</a></li> <li><a href="#">西芹</a></li> <li><a href="#">胡萝卜</a></li> </ul> </li> <li> <a href="#" class="level1">速冻</a> <ul> <li><a href="#">冰淇淋</a></li> <li><a href="#">湾仔码头</a></li> <li><a href="#">海参</a></li> <li><a href="#">牛肉丸</a></li> </ul> </li> </ul> </body> </html>
-
-
简单的动画实现
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>jquery 动画</title> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ /* 参数: 1、属性设置{param1: value1, param2: value2}--最后的结果 2、speed 时间 ms --动画的快慢 3、swing 默认值 开始和结束慢速,中间快速 linear 匀速 4、回调函数 ---动画完成之后干嘛 */ $('#div1').animate({200,height:200},1000,'linear',function(){ // alert('动画完了!'); $(this).animate({marginLeft:500},1000,function(){ $(this).animate({marginTop:500},1000,function() { $(this).animate({marginLeft:1000},1000,function () { $(this).animate({marginTop:0},1000,function () { $(this).animate({marginLeft:0},1000,function () { $(this).animate({100,height:100},1000,'linear') }); }); }); }); }); }); }) </script> <style type="text/css"> .box{ 100px; height:100px; background-color: gold; } </style> </head> <body> <div id="div1" class="box"></div> </body> </html>
-
-
手风琴效果实现
-
<!doctype html> <html> <head> <meta charset="utf-8"> <script type="text/javascript" src="jquery-3.3.1.js"></script> <style> *{margin:0;padding:0;} body{font-size:12px;} #accordion{727px; height:350px; margin:100px auto 0 auto; position:relative; overflow:hidden; border:1px solid #CCC;} #accordion ul{list-style:none;} #accordion ul li{643px;height:350px; position:absolute; background:#FFF;} #accordion ul li span{display:block;20px; height:350px; float:left; text-align:center; color:#FFF; padding-top:5px; cursor:pointer;} #accordion ul li img{display:block; float:right;} .bar01{left:0px;} .bar02{left:643px;} .bar03{left:664px;} .bar04{left:685px;} .bar05{left:706px;} .bar01 span{background:#09E0B5;} .bar02 span{background:#3D7FBB;} .bar03 span{background:#5CA716;} .bar04 span{background:#F28B24;} .bar05 span{background:#7C0070;} </style> <script type="text/javascript"> $(function(){ $('#accordion li').click(function() { // 第一个卷轴 $(this).animate({left:$(this).index()*21}); // each相当于for循环,将前面所有的都先移动过去 $(this).prevAll().each(function(){ // 分别移的元素 $(this).animate({left:$(this).index()*21}); }); // 往回移 $(this).nextAll().each(function(){ $(this).animate({left:(727-(5-$(this).index())*21)}); }); }); }) </script> <title>手风琴效果</title> </head> <body> <div id="accordion"> <ul> <li class="bar01"><span>神无月01</span><img src="images/001.jpg" width="622" height="350"/></li> <li class="bar02"><span>神无月02</span><img src="images/002.jpg" width="622" height="350"/></li> <li class="bar03"><span>神无月03</span><img src="images/003.jpg" width="622" height="350"/></li> <li class="bar04"><span>神无月04</span><img src="images/004.jpg" width="622" height="350"/></li> <li class="bar05"><span>神无月05</span><img src="images/005.jpg" width="622" height="350"/></li> </ul> </div> </body> </html>
-
-
-
尺寸相关,滚动事件
-
提示信息显示-定位
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>元素绝对位置</title> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ // 获取第三个盒子 var $pos = $('.pos'); // 获取位置 返回left top // pos.left pos.top var pos =$pos.offset(); // 提示信息的宽高 var w = $pos.outerWidth(); var h = $pos.outerHeight(); // 提示信息定位 $('.pop').css({left:pos.left+w,top:pos.top}); // 鼠标进入,显示 $pos.mouseover(function(){ $('.pop').show(); }); // 鼠标离开,隐藏 $pos.mouseout(function(){ $('.pop').hide(); }); }); </script> <style type="text/css"> .con{ 600px; height:600px; margin:50px auto 0; } .box{ 100px; height:100px; background-color:gold; margin-bottom:10px; } .pos{ margin-left:500px; } .pop{ 100px; height:100px; background-color:red; position:fixed; left:0; top:0; display:none; } </style> </head> <body> <div class="con"> <div class="box"></div> <div class="box"></div> <div class="box pos"></div> <div class="box"></div> </div> <!--鼠标移动上去显示提示信息--> <div class="pop"> 提示信息! </div> </body> </html>
-
-
1、获取和设置元素的尺寸
-
width()、height() 获取元素width和height innerWidth()、innerHeight() 包括padding的width和height outerWidth()、outerHeight() 包括padding和border的width和height outerWidth(true)、outerHeight(true) 包括padding和border以及margin的width和height
-
-
2、获取元素相对页面的绝对位置
-
offse()
-
-
3、获取可视区高度---页面显示高度,不是实际页面高度
-
$(window).height();
-
-
4、获取页面高度
-
$(document).height();
-
-
5、获取页面滚动距离
-
$(document).scrollTop(); $(document).scrollLeft();
-
-
6、页面滚动事件
-
$(window).scroll(function(){ ...... })
-
-
置顶菜单和回到顶部
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>置顶菜单</title> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ // 滚动事件 $(window).scroll(function() { // 滚动距离 var nowTop = $(document).scrollTop(); // 当top滚动超过200,就固定定位 if(nowTop>200){ $('.menu').css({ position:'fixed', left:'50%', top:0, marginLeft:-480 }); $('.menu_pos').show(); } // 不定位 else{ $('.menu').css({ position:'static', marginLeft:'auto' }); // 用来顶替,menu脱离文档流的时候 $('.menu_pos').hide(); } // 回到顶部 大于400的时候显示 if(nowTop>400){ $('.totop').fadeIn(); } // 小于400的时候隐藏 else{ $('.totop').fadeOut(); } }); // 回到顶部 $('.totop').click(function() { $('html,body').animate({'scrollTop':0}); }); }) </script> <style type="text/css"> body{margin:0px;} .logo_bar{ 960px; height:200px; background-color:#f0f0f0; margin:0 auto; } .menu,.menu_pos{ 960px; height:50px; margin:0 auto; background-color:gold; text-align:center; line-height:50px; } .menu_pos{ display:none; } .down_con{ 960px; height:1800px; margin:0 auto; } .down_con p{ margin-top:100px; text-align:center; } .totop{ 50px; height:50px; background:url(images/01.jpg) center center no-repeat #000; border-radius:50%; position:fixed; right:50px; bottom:50px; display:none; } </style> </head> <body> <div class="logo_bar">顶部logo</div> <div class="menu">置顶菜单</div> <div class="menu_pos"></div> <div class="down_con"> <p style="color:red">网站主内容</p> <p>网站主内容</p> <p>网站主内容</p> <p>网站主内容</p> <p>网站主内容</p> </div> <a href="javascript:;" class="totop"></a> </body> </html>
-
-
无缝滚动
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>无缝滚动</title> <style type="text/css"> body,ul,li{margin:0;padding:0} ul{list-style:none;} .slide{ 500px; height:100px; border:1px solid #ddd; margin:20px auto 0; position:relative; overflow:hidden; } .slide ul{ position:absolute; 1000px; height:100px; left:0; top:0; } .slide ul li{ 90px; height:90px; margin:5px; background-color:#ccc; line-height:90px; text-align: center; font-size:30px; float:left; } .btns{ 500px; height:50px; margin:10px auto 0; } </style> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ // 选择ul var $ul = $('#slide ul'); var left = 0; var deraction = 2; // 10个li在塞回给自己 $ul.html($ul.html()+$ul.html()); // 定时器,30ms东易成 var timer = setInterval(move,30); function move(){ // 刚开始向左移动 left-=deraction; // 等于-500,复位 if(left<-500){ left = 0; } //大于0,制为-500.-500-500又值 if(left>0){ left=-500; } //设定left $ul.css({left:left}); } // 左右滚动切换 $('#btn1').click(function(){ deraction = 2; }); $('#btn2').click(function(){ deraction = -2; }); // 鼠标覆盖就去掉定时器 $('#slide').mouseover(function(){ clearInterval(timer); }); //鼠标离开,继续启动定时器 $('#slide').mouseout(function(){ timer = setInterval(move,30); }) }) </script> </head> <body> <div class="btns"> <input type="button" name="" value="向左" id="btn1"> <input type="button" name="" value="向右" id="btn2"> </div> <div class="slide" id="slide"> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> </div> </body> </html>
-
-
-
jquery事件
-
鼠标的移入移出
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ /* 进入子元素时会触发 $('#div1').mouseover(function(){ $(this).animate({marginTop:50}); }); $('#div1').mouseout(function(){ $(this).animate({marginTop:100}); }); */ /* 进入子元素时不会触发 $('#div1').mouseenter(function(){ $(this).stop().animate({marginTop:50}); }); $('#div1').mouseleave(function(){ $(this).stop().animate({marginTop:100}); }); */ /* 通过hover简写 */ $('#div1').hover(function(){ $(this).stop().animate({marginTop:50}); },function(){ $(this).stop().animate({marginTop:100}); }); }) </script> <style type="text/css"> .box{ 200px; height:200px; background-color:gold; margin:100px auto 0; } .son{ 100px; height:100px; background-color:green; } </style> </head> <body> <div id="div1" class="box"> <div class="son"></div> </div> </body> </html>
-
-
事件
-
blur() 元素失去焦点 focus() 元素获得焦点 change() 表单元素的值发生变化 click() 鼠标单击 dblclick() 鼠标双击 mouseover() 鼠标进入(进入子元素也触发) mouseout() 鼠标离开(离开子元素也触发) mouseenter() 鼠标进入(进入子元素不触发) mouseleave() 鼠标离开(离开子元素不触发) hover() 同时为mouseenter和mouseleave事件指定处理函数 mouseup() 松开鼠标 mousedown() 按下鼠标 mousemove() 鼠标在元素内部移动 keydown() 按下键盘 keypress() 按下键盘 keyup() 松开键盘 load() 元素加载完毕 ready() DOM加载完成 resize() 浏览器窗口的大小发生改变 scroll() 滚动条的位置发生变化 select() 用户选中文本框中的内容 submit() 用户递交表单 toggle() 根据鼠标点击的次数,依次运行多个函数 unload() 用户离开页面
-
-
input事件
-
<script type="text/javascript"> $(function(){ //$('#txt01').focus(); // 获取焦点的时候-有光标的时候 $('#txt01').focus(function() { //alert('foucus'); }); // 失去焦点-光标离开的时候 $('#txt01').blur(function() { //alert('blur'); }); /* 输入框内的内容发生变化,失去焦点后触发 */ $('#txt01').change(function() { alert('change'); }); //按键松开后就触发 /* $('#txt01').keyup(function() { alert('keyup'); }); */ }) </script>
-
-
绑定事件的方式
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ $('#btn').bind('click mouseover',function(){ alert('hello!'); // 取消绑定 $(this).unbind('mouseover'); }) }) </script> </head> <body> <input type="button" name="" value="按钮" id="btn"> </body> </html>
-
-
自定义事件
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>自定义事件</title> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ // 绑定hello事件 $('#btn').bind('hello',function(){ alert('hello!'); }); // 绑定点击事件 $('#btn').bind('click',function(){ alert('click'); }); // 用按钮2触发绑定的hello事件 $('#btn2').click(function() { $('#btn').trigger('hello'); $('#btn').trigger('click'); }); }) </script> </head> <body> <input type="button" name="" value="按钮" id="btn"> <input type="button" name="" value="按钮2" id="btn2"> </body> </html>
-
- 主动触发
可使用jquery对象上的trigger方法来触发对象上绑定的事件。
事件冒泡
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .grandfather{ 300px; height:300px; background-color:green; position:relative; } .father{ 200px; height:200px; background-color:gold; } .son{ 100px; height:100px; background-color:red; position:absolute; left:0; top:400px; } </style> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ $('body').click(function() { alert(4); }); $('.grandfather').click(function() { alert(3); }); $('.father').click(function() { alert(2); }); $('.son').click(function(ev) { alert(1); //ev.stopPropagation(); //console.log(ev); //点击的坐标 //alert(ev.clientX); // 阻止冒泡 阻止默认事件 return false; }); // 阻止右键 阻止冒泡 $(document).contextmenu(function(event) { //event.preventDefault(); return false; }); }); </script> </head> <body> <div class="grandfather"> <div class="father"> <div class="son"></div> </div> </div> </body> </html>
-
阻止冒泡
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .pop_con{ display:none; } .pop{ 400px; height:300px; background-color:#fff; border:1px solid #000; position:fixed; left:50%; top:50%; margin-left:-200px; margin-top:-150px; z-index:9999; } .mask{ position:fixed; 100%; height:100%; background-color:#000; left:0; top:0; opacity:0.3; filter:alpha(opacity=30); z-index:9990; } </style> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ // 去掉冒泡 $('#btn').click(function() { $('#pop').show(); return false; }); $('#shutoff').click(function() { $('#pop').hide(); }); // 点其他地方也让弹框消失, $(document).click(function(event) { $('#pop').hide(); }); // 去掉冒泡事件 $('.pop').click(function() { return false; }); }) </script> </head> <body> <h1>首页标题</h1> <p>页面内容</p> <input type="button" name="" value="弹出" id="btn"> <div class="pop_con" id="pop"> <div class="pop"> <h3>提示信息!</h3> <a href="#" id="shutoff">关闭</a> <input type="text" name=""> </div> <div class="mask"></div> </div> </body> </html>
-
事件委托
事件委托就是利用冒泡的原理,把事件加到父级上,通过判断事件来源的子集,执行相应的操作,事件委托首先可以极大减少事件绑定次数,提高性能;其次可以让新加入的子元素也可以拥有相同的操作。
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件委托</title> <style type="text/css"> .list{ list-style:none; } .list li{ height:30px; background-color:green; margin-bottom:10px; color:#fff; } </style> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ /*$('.list li').click(function(){ alert($(this).html()); }) */ /* 事件委托的写法 */ // 父级下面的什么元素 // 什么事件 // 子集发生的事件 $('.list').delegate('li', 'click', function() { alert($(this).html()); //取消委托 //$('.list').undelegate(); }); }) </script> </head> <body> <ul class="list"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> </ul> </body> </html>
-
节点操作
创建节点--创建标签
-
var $div = $('<div>'); var $div2 = $('<div>这是一个div元素</div>');
-
插入节点 (标签)
-
1、append()和appendTo():在现存元素的内部,从后面插入元素 var $span = $('<span>这是一个span元素</span>'); $('#div1').append($span); ...... <div id="div1"></div> 2、prepend()和prependTo():在现存元素的内部,从前面插入元素 3、after()和insertAfter():在现存元素的外部,从后面插入元素 4、before()和insertBefore():在现存元素的外部,从前面插入元素
-
删除节点(标签)
-
$('#div1').remove();
-
实例
-
<script type="text/javascript"> $(function(){ var $span = $('<span>span元素</span>'); var $p = $('<p>p段落元素</p>'); var $h = $('<h1>页面标题</h1>'); /* $('#div1').append($span); $('#div1').append($p); */ $span.appendTo('#div1'); $p.appendTo('#div1'); //$('#div1').before($h); $h.insertBefore('#div1'); $p.remove(); }) </script>
-
to do list
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>todolist</title> <style type="text/css"> .list_con{ 400px; margin:50px auto 0; } .inputtxt{ 350px; height:30px; border:1px solid #ccc; padding:0px; text-indent:10px; } .inputbtn{ 40px; height:32px; padding:0px; border:1px solid #ccc; } .list{ margin:0; padding:0; list-style:none; margin-top:20px; } .list li{ height:30px; line-height:30px; border-bottom:1px solid #ccc; } .list li span{ float:left; } .list li a{ float:right; text-decoration:none; margin:0 10px; } </style> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript"> $(function(){ $('#btn1').click(function(){ var txt = $('#txt1').val(); $('#txt1').val(''); if(txt==''){ alert('请输入内容!'); return; } // 增加标签 $li = $('<li><span>'+ txt +'</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li>'); $li.appendTo('#list'); }); /* $('.del').click(function() { $(this).parent().remove(); }); */ $('#list').delegate('a', 'click', function() { var handler = $(this).attr('class'); if(handler=='del'){ $(this).parent().remove(); } if(handler=='up'){ if($(this).parent().prev().length==0) { alert('到顶了!'); return; } $(this).parent().insertBefore($(this).parent().prev()); } if(handler=='down'){ if($(this).parent().next().length==0) { alert('到底了!'); return; } $(this).parent().insertAfter($(this).parent().next()); } }); }) </script> </head> <body> <div class="list_con"> <h2>To do list</h2> <input type="text" name="" id="txt1" class="inputtxt"> <input type="button" name="" value="增加" id="btn1" class="inputbtn"> <ul id="list" class="list"> <li><span>学习html</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li> <li><span>学习css</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li> <li><span>学习javascript</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li> </ul> </div> </body> </html>
-
-
整屏滚动
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>整页滚动</title> <!--<link rel="stylesheet" type="text/css" href="test.css">--> <style type="text/css"> ul { list-style: none; } .pages_con { position: fixed; left: 0; top: 0; 100%; overflow: hidden; } .pages { height: 600px; position: relative; } .page1 { background-color: orange; } .page2 { background-color: lightgreen; } .page3 { background-color: cyan; } .page4 { background-color: pink; } .page5 { background-color: lightblue; } .points { 16px; height: 176px; position: fixed; right: 20px; top: 50%; margin-top: -88px; } .points li { 13px; height: 13px; margin: 16px 0; border-radius: 50%; border: 1px solid #666; cursor: pointer; } .points li.active { background-color: #666; } </style> <script type="text/javascript" src="jquery-3.3.1.js"></script> <script type="text/javascript" src="jquery.mousewheel.js"></script> <script type="text/javascript"> $(function () { // 获取显示区的高度 var $h = $(window).height(); var $pages = $('.pages'); // 把高度设置成得到的高度 $pages.css({height: $h}); var $points = $('.points li'); var nowscreen = 0; var timer = null; $pages.eq(0).addClass('moving'); $(window).mousewheel(function (ev, dat) { // dat的值向下滑动是-1.向上滑动是1 clearTimeout(timer); timer = setTimeout(function () { if (dat == -1) { nowscreen++; } else { nowscreen--; } if (nowscreen < 0) { nowscreen = 0; } if (nowscreen > 4) { nowscreen = 4 } $('.pages_con').animate({top: -nowscreen * $h}, 300); // 点和page的移动 $pages.eq(nowscreen).addClass('moving').siblings().removeClass('moving'); $points.eq(nowscreen).addClass('active').siblings().removeClass('active'); }, 200) }); $points.click(function (event) { var nowindex = $(this).index(); $('.pages_con').animate({top: -nowindex * $h}, 300); $pages.eq(nowindex).addClass('moving').siblings().removeClass('moving'); $points.eq(nowindex).addClass('active').siblings().removeClass('active'); }); }) </script> </head> <body> <div class="pages_con"> <div class="pages page1"> <div class="main_con"> <div class="left_img"><img src="images/001.jpg" height="722"></div> <div class="right_info"> Web前端开发是从网页制作演变而来的,名称上有很明显的时代特征。在互联网的演化进程中,网页制作是Web1.0时代的产物,那时网站的主要内容都是静态的,用户使用网站的行为也以浏览为主。 </div> </div> </div> <div class="pages page2"> <div class="main_con"> <div class="right_img"><img src="images/002.jpg" height="722"></div> <div class="left_info"> 2005年以后,互联网进入Web2.0时代,各种类似桌面软件的Web应用大量涌现,网站的前端由此发生了翻天覆地的变化。网页不再只是承载单一的文字和图片,各种富媒体让网页的内容更加生动,网页上软件化的交互形式为用户提供了更好的使用体验,这些都是基于前端技术实现的。 </div> </div> </div> <div class="pages page3"> <div class="main_con"> <div class="left_img"><img src="images/003.jpg" height="652"></div> <div class="right_info"> 以前会Photoshop和Dreamweaver就可以制作网页,现在只掌握这些已经远远不够了。无论是开发难度上,还是开发方式上,现在的网页制作都更接近传统的网站后台开发,所以现在不再叫网页制作,而是叫Web前端开发。 </div> </div> </div> <div class="pages page4"> <div class="main_con"> <div class="left_img"><img src="images/004.jpg" height="652"></div> <div class="right_info"> Web前端开发在产品开发环节中的作用变得越来越重要,而且需要专业的前端工程师才能做好,这方面的专业人才近几年来备受青睐。Web前端开发是一项很特殊的工作,涵盖的知识面非常广,既有具体的技术,又有抽象的理念。简单地说,它的主要职能就是把网站的界面更好地呈现给用户。 </div> </div> </div> <div class="pages page5"> <div class="main_con"> <div class="center_img"><img src="images/005.jpg"></div> </div> </div> </div> <ul class="points"> <li class="active"></li> <li></li> <li></li> <li></li> <li></li> </ul> </body> </html>
-
- 幻灯片
- json:JavaScript Object Notation
- 键值对
- ajax
- ajax技术的目的是让javascript发送http请求,与后台通信,获取数据和信息。ajax技术的原理是实例化xmlhttp对象,使用此对象与后台通信。ajax通信的过程不会影响后续javascript的执行,从而实现异步。
- jsonp:ajax只能请求同一个域下的数据或资源,有时候需要跨域请求数据,就需要用到jsonp技术,jsonp可以跨域请求数据,它的原理主要是利用了script标签可以跨域链接资源的特性。
-
<script type="text/javascript"> function aa(dat){ alert(dat.name); } </script> <script type="text/javascript" src="....../js/data.js"></script>
-
- 正则表达式
- 表单验证
- 前端调用js文件进行表单验证,降低服务器压力
- 本地存储
- 本地存储分为cookie,以及新增的localStorage和sessionStorage
- cookie
- 存储在本地,容量最大4k
- localStorage
- 存储在本地,容量为5M或者更大,不会在请求时候携带传递
- sessionStorage
- 存储在本地,容量为5M或者更大,不会在请求时候携带传递,在同源的当前窗口关闭前有效。
-
bootstrap
-
简单、直观、强悍的前端开发框架,让web开发更迅速、简单。
-
bootstrap 容器 container-fluid 流体 container 1170 970 750 100% bootstrap 栅格系统 bootstrap将页面横向分为12等分,按照12等分定义了适应不同宽度等分的样式类,这些样式类组成了一套响应式、移动设备优先的流式栅格系统: 1、col-lg- 2、col-md- 3、col-sm- 4、col-xs- bootstrap响应式查询区间: 1、大于等于768 2、大于等于992 3、大于等于1200 bootstrap 表单 1、form 声明一个表单域 2、form-inline 内联表单域 3、form-horizontal 水平排列表单域 4、form-group 表单组、包括表单文字和表单控件 5、form-control 文本输入框、下拉列表控件样式 6、checkbox checkbox-inline 多选框样式 7、radio radio-inline 单选框样式 8、input-group 表单控件组 9、input-group-addon 表单控件组物件样式 10、input-group-btn 表单控件组物件为按钮的样式 10、form-group-lg 大尺寸表单 11、form-group-sm 小尺寸表单 bootstrap 按钮 1、btn 声明按钮 2、btn-default 默认按钮样式 3、btn-primay 4、btn-success 5、btn-info 6、btn-warning 7、btn-danger 8、btn-link 9、btn-lg 10、btn-md 11、btn-xs 12、btn-block 宽度是父级宽100%的按钮 13、active 14、disabled 15、btn-group 定义按钮组 bootstrap 图片 img-responsive 声明响应式图片 bootstrap 隐藏类 1、hidden-xs 2、hidden-sm 3、hidden-md 4、hidden-lg bootstrap 字体图标 通过字体代替图标,font文件夹需要和css文件夹在同一目录 bootstrap 下拉菜单 1、dropdown-toggle 2、dropdown-menu bootstrap 选项卡 1、nav 2、nav-tabs 3、nav-pills 4、tab-content bootstrap 导航条 1、navbar 声明导航条 2、navbar-default 声明默认的导航条样式 3、navbar-inverse 声明反白的导航条样式 4、navbar-static-top 去掉导航条的圆角 5、navbar-fixed-top 固定到顶部的导航条 6、navbar-fixed-bottom 固定到底部的导航条 7、navbar-header 申明logo的容器 8、navbar-brand 针对logo等固定内容的样式 11、nav navbar-nav 定义导航条中的菜单 12、navbar-form 定义导航条中的表单 13、navbar-btn 定义导航条中的按钮 14、navbar-text 定义导航条中的文本 9、navbar-left 菜单靠左 10、navbar-right 菜单靠右 bootstrap 模态框 1、modal 声明一个模态框 2、modal-dialog 定义模态框尺寸 3、modal-lg 定义大尺寸模态框 4、modal-sm 定义小尺寸模态框 5、modal-header 6、modal-body 7、modal-footer
-
-
-
-
小米商城
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>mi.com</title> <link href="https://cdn.bootcss.com/normalize/8.0.0/normalize.min.css" rel="stylesheet"> <link rel="stylesheet" href="./css/mi.css"> </head> <body> <!-- 顶部导航栏 start --> <div class="nav"> <div class="container"> <ul class="nav-left"> <li> <a href="">玉米商城</a> </li> <li> <a href="">链接A</a> </li> <li> <a href="">链接B</a> </li> <li> <a href="">链接C</a> </li> <li> <a href="">链接D</a> </li> </ul> <ul class="nav-right fr"> <li> <a href="">登录</a> </li> <li> <a href="">注册</a> </li> <li> <a href="">消息</a> </li> <li> <a href="">购物车</a> </li> </ul> </div> </div> <!-- 顶部导航栏 end --> <!-- 首屏 开始 --> <div class="main"> <!-- 目录导航 开始 --> <div class="main-header"> <div class="logo fl"> <img src="./img/logo.png" alt=""> <img src="./img/logo_r.png" alt=""> </div> <ul class="top-menu fl"> <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="">社区</a> </li> </ul> <div class="main-search fr"> <input type="text"> <button>搜索</button> </div> </div> <!-- 目录导航 结束 --> <!-- 菜单+轮播 开始 --> <div class="menu clearfix"> <div class="sidebar fl"> <ul class="item-list"> <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="">移动电源 插线板</a> </li> <li> <a href="">耳机 音箱</a> </li> <li> <a href="">生活 米兔</a> </li> </ul> </div> <div class="carousel fr"> <img src="./img/carousel.png" alt=""> </div> </div> <!-- 菜单+轮播 结束 --> <!-- 副广告区 开始 --> <div class="main-down clearfix"> <div class="fl"> <a class="pic"> <img src="./img/pic0.png" alt=""> </a> </div> <div class="fr"> <a class="pic-item first"> <img src="./img/pic1.png" alt=""> </a> <a class="pic-item"> <img src="./img/pic2.png" alt=""> </a> <a class="pic-item"> <img src="./img/pic3.png" alt=""> </a> </div> </div> <!-- 副广告区 结束 --> <!-- 闪购 开始 --> <div class="flash-sale"> <h1>限时闪购</h1> <div class="flash-list clearfix"> <div class="flash-left fl"> <a class="flash-item first" href=""> <img src="./img/flash0.png" alt=""> </a> </div> <div class="flash-right fr"> <a class="flash-item" href=""> <img src="./img/flash1.png" alt=""> </a> <a class="flash-item" href=""> <img src="./img/flash2.png" alt=""> </a> <a class="flash-item" href=""> <img src="./img/flash1.png" alt=""> </a> <a class="flash-item" href=""> <img src="./img/flash2.png" alt=""> </a> </div> </div> </div> <!-- 闪购 结束 --> </div> <!-- 首屏 结束 --> <!-- 商品展示 开始 --> <div class="goods"> <div class="container"> <div class="goods-box clearfix"> <h2>家电</h2> <div class="goods-box-left fl"> <img src="./img/goods-left0.png" alt=""> </div> <div class="goods-box-right fr"> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item1.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item2.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item3.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item4.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item4.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item3.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item2.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item1.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> <!-- <div class="item-memo"> <a href="">我真的是个天才,哈哈哈哈</a> </div> --> </div> </div> </div> <div class="goods-box clearfix"> <h2>智能</h2> <div class="goods-box-left fl"> <a class="left-item first" href=""> <img src="./img/goods-left1.png" alt=""> </a> <a class="left-item" href=""> <img src="./img/goods-left1.png" alt=""> </a> </div> <div class="goods-box-right fr"> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item1.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item2.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item3.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item4.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item4.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item3.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item2.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> <div class="goods-item fl"> <div class="item-img"> <a href=""> <img src="./img/item1.png" alt=""> </a> </div> <p class="item-title"> <a href="">商品名称</a> </p> <p class="item-price">1999元</p> </div> </div> </div> <!-- 热评产品 开始 --> <div class="goods-box clearfix"> <h2>热评商品</h2> <div class="hot-goods-list"> <div class="hot-goods first fl"> <p class="hot-goods-img"> <a href=""> <img src="./img/item11.png" alt=""> </a> </p> <p class="hot-goods-msg"> <a>东西真心不错,用过最好用的插线板,做工外观没得挑剔,3个USB接口很实用,充电快,建议不包邮的应该在...</a> </p> <p class="hot-goods-author"> <a href="">来源于水军1号的评价</a> </p> <div class="hot-goods-info"> <h3 class="title">玉米插线板</h3> <span>|</span> <p class="price">49元</p> </div> </div> <div class="hot-goods fl"> <p class="hot-goods-img"> <a href=""> <img src="./img/item12.png" alt=""> </a> </p> <p class="hot-goods-msg"> <a>东西真心不错,用过最好用的插线板,做工外观没得挑剔,3个USB接口很实用,充电快,建议不包邮的应该在...</a> </p> <p class="hot-goods-author"> <a href="">来源于水军1号的评价</a> </p> <div class="hot-goods-info"> <h3 class="title">玉米插线板</h3> <span>|</span> <p class="price">49元</p> </div> </div> <div class="hot-goods fl"> <p class="hot-goods-img"> <a href=""> <img src="./img/item11.png" alt=""> </a> </p> <p class="hot-goods-msg"> <a>东西真心不错,用过最好用的插线板,做工外观没得挑剔,3个USB接口很实用,充电快,建议不包邮的应该在...</a> </p> <p class="hot-goods-author"> <a href="">来源于水军1号的评价</a> </p> <div class="hot-goods-info"> <h3 class="title">玉米插线板</h3> <span>|</span> <p class="price">49元</p> </div> </div> <div class="hot-goods fl"> <p class="hot-goods-img"> <a href=""> <img src="./img/item12.png" alt=""> </a> </p> <p class="hot-goods-msg"> <a>东西真心不错,用过最好用的插线板,做工外观没得挑剔,3个USB接口很实用,充电快,建议不包邮的应该在...</a> </p> <p class="hot-goods-author"> <a href="">来源于水军1号的评价</a> </p> <div class="hot-goods-info"> <h3 class="title">玉米插线板</h3> <span>|</span> <p class="price">49元</p> </div> </div> </div> </div> <!-- 热评商品 结束 --> </div> </div> <!-- 商品展示 结束 --> <!-- 底部 开始 --> <div class="footer"> <div class="container"> <ul class="service-info clearfix"> <li class="service-item first"> <a href="">预约维修</a> </li> <li class="service-item"> <a href="">7天无理由退货</a> </li> <li class="service-item"> <a href="">15天免费换货</a> </li> <li class="service-item"> <a href="">满150元包邮</a> </li> <li class="service-item"> <a href="">520余家售后网点</a> </li> </ul> </div> <div class="slogan"> ©为发骚而生 </div> </div> <!-- 底部 结束 --> </body> </html>
-
css
-
a { text-decoration: none; } ul { list-style-type: none; } .fr { float: right } .fl { float: left; } .clearfix:before, .clearfix:after { content: ""; display: block; clear: both; } .container { 1226px; margin: 0 auto; } /* 导航条样式 */ .nav { background-color: #333; height: 40px; line-height: 40px; 100%; position: fixed; top: 0; } .nav-left, .nav-right, .top-menu, .item-list, .service-info { margin: 0; padding: 0; } .nav-left li { float: left; padding-right: 15px; } .nav-right li { float: left; padding-left: 15px; } .nav a { color: #b0b0b0; } .nav a:hover { color: #fff; } /* main区 样式 */ .main { 1226px; margin: 40px auto; background-color: white; } .logo>* { margin-right: 15px; } .main-header { height: 55px; line-height: 55px; } .top-menu a { color: #3d3d3d; } .top-menu a:hover { color: #ff6700; } .top-menu li { float: left; padding: 0 10px; } .main-search { 300px; height: 50px; margin-top: 15px; } .main-search input { border: 1px solid #e0e0e0; 80%; } .main-search button { border: 1px solid #e0e0e0; 19%; } .main-search input, .main-search button { padding: 10px 0; display: block; float: left; } /* 左侧菜单和轮播carousel */ .menu { margin-bottom: 30px; } .menu > .sidebar { 234px; background-color: #0a3651; } .item-list { padding: 20px 0; } .item-list a { color: white; display: block; height: 42px; line-height: 42px; padding: 0 25px; } .item-list a:hover { background-color: tomato; } .menu > .carousel { 992px; } /* 目录下 二级广告区 */ .pic-item { margin-left: 8px; } .pic.first{ margin-left: 0; } /* 闪购 */ .flash-item { margin-left: 8px; } .flash-item.first { margin-left: 0px; } /* 商品列表 */ .goods { background-color: #f5f5f5; padding-bottom: 60px; } .goods-box { padding-top: 20px; } .goods-box-left { 234px; } .left-item { display: block; } .left-item.first { margin-bottom: 10px; } .goods-box-right { 992px; } .goods-item { height: 246px; 234px; padding: 34px 0 20px; background-color: white; margin-left: 14px; margin-bottom: 14px; } .item-img { 150px; height: 150px; margin: 0 auto 18px; } .item-img>a { display: block; } .item-price { text-align: center; color: red; } .item-title { text-align: center; } .item-title>a { color: #3d3d3d; } .item-memo>a { display: block; padding: 8px 30px; } /* 热评商品 */ .hot-goods { 296px; height: 415px; background-color: white; margin-left: 14px; } .hot-goods.first { margin-left: 0px; } .hot-goods-img { margin: 0 0 28px; } .hot-goods-msg { padding: 0 28px; color: #333; } .hot-goods-author { height: 18px; margin: 0 28px 8px; padding: 0 10px 0 0; font-size: 12px; } .hot-goods-author>a { color: #b0b0b0; } .hot-goods-info { margin: 0 30px; } .hot-goods-info>* { display: inline; } .price { color: red } /* 页脚 */ .footer { background-color: white; } .service-info { padding: 27px 0; border-bottom: 1px solid #e0e0e0; } .service-item { float: left; 19%; height: 25px; border-left: 1px solid #e0e0e0; font-size: 16px; line-height: 25px; text-align: center; } .service-item.first { border-left: none; } .service-item>a { color: #616161; } .service-item>a:hover{ color: #ff6700; } .slogan { padding: 5px 0; text-align: center; color: #616161; background-color: #f5f5f5; }
-
-
images
-
链接:https://pan.baidu.com/s/1KCMXEVDW1aZzqZulGSwCfQ 提取码:ily9
-
-
- Scrapy-redis 分布式爬虫
- Scrapy 是一个通用的爬虫框架,但是不支持分布式,Scrapy-redis是为了更方便地实现Scrapy分布式爬取,而提供了一些以redis为基础的组件(仅有组件)。
-
Scrapy-redis提供了下面四种组件(components):(四种组件意味着这四个模块都要做相应的修改)
-
Scheduler----调度器
-
Scrapy改造了python本来的collection.deque(双向队列)形成了自己的Scrapy queue,,但是Scrapy多个spider不能共享待爬取队列Scrapy queue, 即Scrapy本身不支持爬虫分布式,scrapy-redis 的解决是把这个Scrapy queue换成redis数据库(也是指redis队列),从同一个redis-server存放要爬取的request,便能让多个spider去同一个数据库里读取。
- Scrapy中跟“待爬队列”直接相关的就是调度器
Scheduler
,它负责对新的request进行入列操作(加入Scrapy queue),取出下一个要爬取的request(从Scrapy queue中取出)等操作。它把待爬队列按照优先级建立了一个字典结构,比如:-
{ 优先级0 : 队列0 优先级1 : 队列1 优先级2 : 队列2 }
- 然后根据request中的优先级,来决定该入哪个队列,出列时则按优先级较小的优先出列。
-
-
-
Duplication Filter----去重---断掉还可以续传
- Scrapy中用集合实现这个request去重功能,Scrapy中把已经发送的request指纹放入到一个集合中,把下一个request的指纹拿到集合中比对,如果该指纹存在于集合中,说明这个request发送过了,如果没有则继续操作。这个核心的判重功能是这样实现的:
-
def request_seen(self, request): # self.request_figerprints就是一个指纹集合 fp = self.request_fingerprint(request) # 这就是判重的核心操作 if fp in self.fingerprints: return True self.fingerprints.add(fp) if self.file: self.file.write(fp + os.linesep)
- 在scrapy-redis中去重是由
Duplication Filter
组件来实现的,它通过redis的set 不重复的特性,巧妙的实现了Duplication Filter去重。
-
- Scrapy中用集合实现这个request去重功能,Scrapy中把已经发送的request指纹放入到一个集合中,把下一个request的指纹拿到集合中比对,如果该指纹存在于集合中,说明这个request发送过了,如果没有则继续操作。这个核心的判重功能是这样实现的:
-
Item Pipeline----管道文件--不给管道,给redis数据库
-
引擎将(Spider返回的)爬取到的Item给Item Pipeline,scrapy-redis 的Item Pipeline将爬取到的 Item 存⼊redis的 items queue。
-
修改过
Item Pipeline
可以很方便的根据 key 从 items queue 提取item,从⽽实现items processes
集群。
-
-
Base Spider----改变爬虫类--改成以redis为核心的爬虫类
- 不在使用scrapy原有的Spider类,重写的
RedisSpider
继承了Spider和RedisMixin这两个类,RedisMixin是用来从redis读取url的类。---类前面加个redis
- 不在使用scrapy原有的Spider类,重写的
-
- 从0搭建scrapy-redis分布式爬虫
-
假设有四台电脑:Windows 10、Mac OS X、Ubuntu 16.04、CentOS 7.2,任意一台电脑都可以作为 Master端 或 Slaver端,比如:
-
Master端
(核心服务器) :使用 Windows 10,搭建一个Redis数据库,不负责爬取,只负责url指纹判重、Request的分配,以及数据的存储 -
Slaver端
(爬虫程序执行端) :使用 Mac OS X 、Ubuntu 16.04、CentOS 7.2,负责执行爬虫程序,运行过程中提交新的Request给Master -
首先Slaver端从Master端拿任务(Request、url)进行数据抓取,Slaver抓取数据的同时,产生新任务的Request便提交给 Master 处理;
-
Master端只有一个Redis数据库,负责将未处理的Request去重和任务分配,将处理后的Request加入待爬队列,并且存储爬取的数据。
-
- Scrapy-Redis默认使用的就是这种策略,我们实现起来很简单,因为任务调度等工作Scrapy-Redis都已经帮我们做好了,我们只需要继承RedisSpider、指定redis_key就行了.
- 公司用一个带宽,没有把分布式利用到极致,需要多个带宽去进行分布式爬取
-
-
- 安装redis
-
$ wget http://download.redis.io/releases/redis-6.0.5.tar.gz $ tar xzf redis-6.0.5.tar.gz $ cd redis-6.0.5 $ make
-
-