併發程式設計
程式
作業系統的歷史
# 手工操作 —— 穿孔卡片 # 程式設計師將對應於程式和資料的已穿孔的紙帶(或卡片)裝入輸入機,然後啟動輸入機把程式和資料輸入計算機記憶體,接著通過控制檯開關啟動程式針對資料執行;計算完畢,印表機輸出計算結果;使用者取走結果並卸下紙帶(或卡片)後,才讓下一個使用者上機。 # 手工操作方式兩個特點: # (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()
程式的同步控制
程式鎖
# 火車票的例子 # 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沒買到票 """
訊號量
# 訊號量的操作類似於程式鎖,新增了計數器 # 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執行結束 '''
事件
# 通過一個資訊 來控制 多個程式 同時 執行或者阻塞 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秒內
程式間的通訊
佇列
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)
# 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程式結束 # 主程式中程式碼結束 # 守護程式(消費者的程式)結束
管道
#建立管道的類: 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) # 為了資料安全 必須要加鎖
程式池
# 為什麼會有程式池的概念 # 效率問題 # 每開啟程式,開啟屬於這個程式的記憶體空間 # 暫存器 堆疊 檔案 # 程式過多 作業系統要呼叫程式 # 程式池 # 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 '''
# 簡單的爬蟲 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())有相同的結果。
# 多執行緒簡單實現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()
# 守護程式隨著主執行緒程式碼結束而結束 # 守護執行緒在主執行緒結束之後會等待其他子執行緒結束才結束 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吃麵 """
訊號量
# 訊號量的例項 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 '''
事件
# 事件被建立的時候 # 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()
條件
# 條件 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()
定時器
# 簡單的Timer例項 from threading import Timer import time def func(): print("時間同步") while True: Timer(5,func).start() time.sleep(5)
執行緒之間通訊
佇列
# 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') # 越小越優先
執行緒池
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 '''
協程與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()
#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就切換其他任務
# 爬蟲的例子 # 想要學會爬蟲 正則一定要學會 # 請求過程中的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()
# *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'))
前端
前端的理論知識
<!--前端的理論 前端 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 根據內容決定長度 不能設定長和寬 -->
列表標籤
<!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>
表單標籤
1 <!DOCTYPE html> 2 <html lang="zh-CN"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>form表單示例</title> 6 </head> 7 <body> 8 <!--上傳檔案的固定格式--> 9 <form action="http://127.0.0.1:8000/upload/" method="post" enctype="multipart/form-data" autocomplete="off"> 10 <!--搜尋引擎展示資訊用get請求——要東西--> 11 <!--表單傳送訊息用post請求——給東西--> 12 <!--action路徑,往哪裡提交的--> 13 <p> 14 <label for="i1">使用者名稱:</label> 15 <input name="username" type="text" id="i1" readonly value="小強"> 16 <input name="username" type="text" disabled placeholder="小強"> 17 <!--name往後端提交相當於字典中的鍵--> 18 </p> 19 <p> 20 <label for="i2">密碼:</label> 21 <input id="i2" name="password" type="password"> 22 </p> 23 <p> 24 <label for="i3">郵箱:</label> 25 <input id="i3" name="email" type="email"> 26 </p> 27 <p>隱藏按鈕: 28 <input type="hidden" value="hidden"> 29 </p> 30 <p> 性別: 31 <label for="r1">男</label> 32 <input id="r1" name="gender" type="radio" value="1"> 33 <label for="r2">女</label> 34 <input id="r2" name="gender" type="radio" value="0"> 35 <label for="r3">保密</label> 36 <input id="r3" checked name="gender" type="radio" value="0"> 37 <!--value往後端提交相當於字典中的值--> 38 </p> 39 <p>愛好: 40 <label for="a1">籃球</label> 41 <input id="a1" checked name="hobby" type="checkbox" value="basketball"> 42 <label for="a2">足球</label> 43 <input id="a2" checked name="hobby" type="checkbox" value="football"> 44 <label for="a3">雙色球</label> 45 <input id="a3" checked name="hobby" type="checkbox" value="doublecolorball"> 46 </p> 47 <p> 48 <label for="b1">生日</label> 49 <input id="b1" name="birthday" type="date"> 50 </p> 51 <p>地址: 52 <label> 53 <select name="from1" id="s1"> 54 <option value="bj">北京</option> 55 <option value="sh">上海</option> 56 <option value="sd">山東</option> 57 <option value="sc">四川</option> 58 </select> 59 </label> 60 <label> 61 <select name="from1" id="s2" multiple> 62 <option value="bj">北京</option> 63 <option value="sh" selected>上海</option> 64 <option value="sd">山東</option> 65 <option value="sc">四川</option> 66 </select> 67 </label> 68 <label> 69 <select name="from2" id="s3"> 70 <optgroup label="北京"> 71 <option value="cy">朝陽</option> 72 <option value="cp">昌平</option> 73 <option value="hd">海淀</option> 74 <option value="ft">豐臺</option> 75 </optgroup> 76 <optgroup label="上海"> 77 <option value="pdxq">浦東新區</option> 78 <option value="hpxq">黃埔新區</option> 79 <option value="mhq">閔行區</option> 80 </optgroup> 81 <optgroup label="四川"> 82 <option value="pzh">攀枝花</option> 83 <option value="zg">自貢</option> 84 <option value="my">綿陽</option> 85 </optgroup> 86 </select> 87 </label> 88 </p> 89 <p> 90 <label> 91 <textarea name="info" id="t1" cols="30" rows="10"></textarea> 92 </label> 93 </p> 94 <p> 95 <input name="file" type="file"> 96 </p> 97 <p> 98 <input type="submit" value="提交"> 99 <input type="button" value="button"> 100 <input type="reset" value="重填"> 101 </p> 102 <!-- 103 總結 104 form標籤 建立一個表單 105 input標籤 表單的輸入 106 type 表單的型別 107 text 文字框 108 submit 提交按鈕 109 password 密碼文字框 110 radio 核取方塊 111 name="gender" 單選框 112 email 郵箱 113 checkbox 多選框 114 date 日期 115 datetime 時間 116 file 檔案 117 button 普通按鈕,多用js給它繫結事件 118 reset 重置按鈕 119 hidden 隱藏按鈕 120 select標籤 下拉框 121 122 option標籤 配置下拉框名稱 123 optgroup標籤 分組下拉框 124 textarea標籤 大文字框 125 label標籤 標註,標記標籤 126 標籤的常用屬性 127 label 分組下拉框的名稱 128 name 傳給後端相當於字典中的鍵 必須要新增 129 value 傳給後端相當於字典中的值 HTTP中設定預設值 130 placeholder 設定佔位的內容 131 action 提交表單的位置路徑,一般填寫域名或IP地址 132 autocomplete 開啟和關閉自動補全功能 133 novalldate 規定瀏覽器不驗證表單 134 method 規定在提交表單時所用的HTTP方法(預設GET) 135 enctype 規定被提交資料的編碼 136 input單獨屬性 137 checked 預設選中什麼 138 readonly 只讀模式 配合value值使用 139 disabled 不可用,禁用 140 select單獨屬性 141 multiple 布林屬性,設定後為多選,否則預設單選 142 selected 預設選中該項 143 144 --> 145 </form> 146 </body> 147 </html>
css樣式
css選擇器
1 <!DOCTYPE html> 2 <html lang="zh-CN"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>css引入的示例</title> 6 <!--<style>--> 7 <!--p{--> 8 <!--color: green;--> 9 <!--}--> 10 <!--</style>--> 11 </head> 12 <body> 13 <!--<p style="color: pink">海燕</p>--> 14 <p id="p1">海燕</p> 15 <p id="p2">這個是個黑色的海燕</p> 16 <p class="c1">這個是個黃色的海燕</p> 17 <p class="c1">這個是個黃色的海燕</p> 18 <p class="c1">這個是個黃色的海燕</p> 19 <p class="c1">這個是個黃色的海燕</p> 20 21 <link rel="stylesheet" href="index.css"> 22 <!--index.css 23 /* 24 解釋性的資訊 25 */ 26 27 /*全域性通用的樣式*/ 28 /*例如字型*/ 29 30 31 /*導航條的樣式*/ 32 33 34 /*商品列表的樣式*/ 35 p{ 36 color: red; 37 font-size: 30px; 38 } 39 /*標籤選擇器*/ 40 h1{ 41 color: green; 42 font-size: 60px; 43 } 44 /*ID選擇器*/ 45 #p2{ 46 color: black; 47 } 48 /*類選擇器*/ 49 .c1{ 50 color: yellow; 51 } 52 /*通用選擇器*/ 53 *{ 54 margin-right: auto; 55 } 56 --> 57 <h1>這是一個h1標籤</h1> 58 </body> 59 </html>
<!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>
1 <!DOCTYPE html> 2 <html lang="zh-CN"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>屬性選擇器示例</title> 6 <style> 7 /*屬性選擇器相關樣式*/ 8 [s9] { 9 color: red; 10 } 11 12 [s9="hao"] { 13 color: green; 14 } 15 </style> 16 </head> 17 <body> 18 <p s9="hao">我是一個p標籤</p> 19 <p s9="good">我也是一個p標籤</p> 20 <p>我還是一個p標籤</p> 21 </body> 22 </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>
<!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>
<!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>
<!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>
<!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>
<!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.自定義的模態框示例 -->
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>
<!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(){...}; // 22 // 22 //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中自定義物件 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); // 4 //lastIndex會記住上一次匹配成功的位置 console.log(r.test("1234alex")); // true console.log(r.lastIndex); // 8 console.log(r.test("alex")); // true console.log(r.lastIndex); // 0 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>
<!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>
<!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>
<!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>
<!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>
<!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">©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>
<!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()
<!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>
<!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>
<!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>
<!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>
<!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>
<!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>
<!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>
<!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>
<!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>
<!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>
<!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>