Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产片一区二区三区,在线观看亚洲网站,精品成人在线观看

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          大神的Javascript基礎(chǔ)總結(jié),還不收藏起來?

          者:HXGNMSL來源:CSDN原文:https://blog.csdn.net/HXGNMSL/article/details/89076476

          Javascript的歷史來源

          94年網(wǎng)景公司 研發(fā)出世界上第一款瀏覽器。

          95年 sun公司 java語言誕生

          網(wǎng)景公司和sun合作。

          Javascript ===> javascript

          JavaScript和ECMAScript的關(guān)系

          簡(jiǎn)單來說ECMAScript不是一門語言,而是一個(gè)標(biāo)準(zhǔn)。符合這個(gè)標(biāo)準(zhǔn)的比較常見的有:JavaScript、Action Script(Flash中用的語言)

          JavaScript的基本結(jié)構(gòu):

          JavaScript的語法:

          JavaScript的基礎(chǔ)語法

          變量的聲明及使用

          數(shù)據(jù)類型

          運(yùn)算符

          邏輯控制語句

          注釋

          語法規(guī)則

          變量的聲明語法:

          var變量名;

          例如:

          Var num;

          然后進(jìn)行賦值:num = 10;也可以聲明時(shí)直接賦值:

          Var num =10;

          在JavaScript中,提供了常用的基本數(shù)據(jù)類型:

          undefined 未定義;

          null 空;

          string 字符串類型;

          boolean 布爾類型;

          number 數(shù)值類型;

          運(yùn)算符:

          算數(shù)運(yùn)算符:+、-、*、/、%、++、–;

          比較運(yùn)算符:>、<、> =、< =、==、!=;

          邏輯運(yùn)算符:&&、||、!;

          賦值運(yùn)算符:=;

          邏輯控制語句:

          JavaScript的邏輯控制語句也分為兩類:條件結(jié)構(gòu)和循環(huán)機(jī)構(gòu)。

          條件結(jié)構(gòu)

          條件機(jī)構(gòu)分為if結(jié)構(gòu)和switch結(jié)構(gòu):

          If…else

          Switch

          循環(huán)結(jié)構(gòu)

          JavaScript的循環(huán)結(jié)構(gòu)的執(zhí)行順序與Java類似,主要包括以下幾種結(jié)構(gòu):

          for循環(huán)

          while循環(huán)

          do…while循環(huán)

          for…inx循環(huán)

          示例:

          for(var i=0;i<10;i++){

          Document.write(“*”);

          }

          輸出結(jié)果:**********

          循環(huán)中斷:

          用于循環(huán)中斷的語句有以下兩種:

          break.

          continue.

          與Java用法一樣,break是跳出循環(huán),continue是跳入下一次循環(huán)。

          函數(shù)

          函數(shù)有兩種:一種是系統(tǒng)函數(shù),一種是自定義函數(shù)

          常用的系統(tǒng)函數(shù)包括:

          parseInt():轉(zhuǎn)換為整數(shù)。

          parseFloat():轉(zhuǎn)換為浮點(diǎn)型。

          isNaN():判斷非數(shù)字。

          Eval():計(jì)算表達(dá)式值。

          自定義函數(shù):

          自定義函數(shù)的語法

          function 函數(shù)名(參數(shù)1,參數(shù)2,…){

          …//語句

          Return 返回值;//可選

          }

          函數(shù)的調(diào)用:

          函數(shù)的調(diào)用方式有以下兩種

          事件名=函數(shù)名(傳遞的實(shí)參值),例如:

          “函數(shù)名()”

          直接使用函數(shù)名(傳遞的實(shí)參值),例如:

          var recult = add(2,3);

          匿名函數(shù)

          匿名函數(shù)的語法

          var sumFun=function(num1,num2){

          return(nun1,num2);

          } ;

          在語法中:

          var sunFun=function(num1,num2)表示聲明一個(gè)變量等于某個(gè)函數(shù)體。

          {…};是把整個(gè)函數(shù)體放在變量的后面,并把末尾添加一個(gè)分號(hào)。

          匿名函數(shù)的調(diào)用:

          由于匿名函數(shù)定義的整個(gè)語句,可以像賦值一樣賦給一個(gè)變量進(jìn)行保存,所以可以使用如下方式調(diào)用語法中的匿名函數(shù):

          var sum=sumFun(2,3)

          BOM概述

          使用BOM可以移動(dòng)窗口,改變狀態(tài)欄中的文本,執(zhí)行其他與頁(yè)面內(nèi)容不直接相關(guān)的動(dòng)作。它包含的對(duì)象主要有以下幾種;

          Window對(duì)象

          Window對(duì)象是指整個(gè)窗口對(duì)象,可以通過操作Window對(duì)象的屬性和方法控制窗口,例如,打開或關(guān)閉一個(gè)窗口。

          History對(duì)象

          瀏覽器訪問過的歷史頁(yè)面對(duì)應(yīng)History對(duì)象,通過History對(duì)象的屬性和方法實(shí)現(xiàn)瀏覽器的前進(jìn)或后退的功能。

          Location對(duì)象

          瀏覽器的地址欄對(duì)應(yīng)Location對(duì)象,通過Location對(duì)象的屬性和方法控制頁(yè)面跳轉(zhuǎn)。

          Document對(duì)象

          瀏覽器內(nèi)的網(wǎng)頁(yè)內(nèi)容對(duì)應(yīng)Document對(duì)象,通過Document對(duì)象的屬性和方法,控制頁(yè)面元素。

          Window常用的屬性有:

          history:有關(guān)客戶訪問過的URL的信息。

          location:有關(guān)當(dāng)前URL的信息。

          Screen: 有關(guān)客戶端的屏幕和顯示性能的信息。

          Window對(duì)象常用的方法:

          prompt():顯示可提示用戶輸入的對(duì)話框。

          alert():顯示帶有一段消息和一個(gè)人“確認(rèn)”按鈕的警告框。

          confirm():顯示帶有一段消息以及“確認(rèn)”按鈕“取消”按鈕的對(duì)話框。

          close():關(guān)閉瀏覽器窗口。

          open():打開一個(gè)新的瀏覽器窗口,加載給定URL所指定的文檔。

          setTimeout():用于在指定(以毫秒計(jì))后調(diào)用函數(shù)或計(jì)算表達(dá)式。

          setTneerval():按照指定的周期 (以毫秒計(jì))數(shù)來調(diào)用函數(shù)或計(jì)算表達(dá)式。

          Window對(duì)象常用窗口特征屬性

          height、width:窗口文檔顯示區(qū)的高度、寬度,以像素計(jì)。

          left、top:窗口的x坐標(biāo)y坐標(biāo),以像素計(jì)。

          toolbar:yes|no|1|0:是否顯示瀏覽器的工具欄,默認(rèn)是yes。

          scrollbars =yes|no|1|0:是否顯示滾動(dòng)條,默認(rèn)是yes。

          locationyes|no|1|0:是否顯示地址欄,默認(rèn)是yes。

          status|no|1|0:是否添加地址欄,默認(rèn)是yes。

          menubar|no|1|0:是否顯示菜單欄,默認(rèn)是yes。

          resizable|no|1|0:窗口是否可調(diào)節(jié)尺寸,默認(rèn)是yes。

          Window對(duì)象的常用事件:

          onload:一個(gè)頁(yè)面或一副圖像完成加載。

          onmouseover:鼠標(biāo)指針移到某元素之上。

          onclick:單擊某個(gè)對(duì)象。

          onkeydown:某個(gè)鍵盤按鍵被按下。

          onchange:域的內(nèi)容被改變。

          History對(duì)象的方法:

          back():加載History對(duì)象列表中的上一個(gè)URL。

          forward():加載History對(duì)象列表中的下一個(gè)URL。

          go():加載History對(duì)象列表中的某個(gè)具體URL。

          Location對(duì)象的屬性:

          host:設(shè)置或返回主機(jī)名和當(dāng)前URL的端口號(hào)。

          hostname:設(shè)置或返回當(dāng)前URL的主機(jī)名。

          href:設(shè)置或返回完整的URL。

          Location對(duì)象的方法:

          reload():重新加載當(dāng)前文檔。

          replace():用新的文檔替換當(dāng)前文檔。

          Document對(duì)象常用的屬性:

          referrer:返回載入當(dāng)前文檔的URL。

          URL:返回當(dāng)前文檔的URL。

          Document對(duì)象的常用方法:

          getElementById():返回對(duì)擁有指定id的第一個(gè)對(duì)象的引用。

          getElementsByName():返回帶有指定名稱的對(duì)象的集合。

          getElementsByTagName():返回帶有指定標(biāo)簽名的對(duì)象的集合。

          write():向文檔寫文本、HTML表達(dá)式代碼。

          內(nèi)置對(duì)象

          系統(tǒng)的內(nèi)置對(duì)象有Date對(duì)象、Array對(duì)象、String對(duì)象和Math對(duì)象等。

          Date:用于操作日期和時(shí)間。

          Array:用于在單獨(dú)的變量名中儲(chǔ)存一系列的值。

          String:用于支持對(duì)字符串的處理。

          Math:用于執(zhí)行數(shù)學(xué)任務(wù),包含了若干數(shù)字常量和函數(shù)。

          Date對(duì)象:

          1:創(chuàng)建日期對(duì)象

          Date對(duì)象包含日期和時(shí)間兩個(gè)信息,創(chuàng)建日期對(duì)象的基本語法有兩種:

          創(chuàng)建日期的基本語法1: var 日期實(shí)例化=new Date(參數(shù));

          創(chuàng)建日期的基本語法2: var 日期實(shí)例化=new Date();

          Date對(duì)象的常用方法:

          getDate():從Date對(duì)象返回一個(gè)月中的某一天,其值介于1到31之間。

          getDay():從Date對(duì)象返回星期中的某一天,其值介于0到6之間。

          getHours():返回Date對(duì)象的小時(shí),其值介于0到23之間。

          getMinutes():返回Date對(duì)象的分鐘,其值介于0到59之間。

          getSeconds():返回Date對(duì)象的秒數(shù),其值介于0到59之間。

          getMonth():返回Date對(duì)象的月份,其值介于0到11之間。

          getFullYear():返回Date對(duì)象的年份,其值為4位數(shù)。

          getTime():返回自某一時(shí)刻(2010年1月1日)以來的毫秒數(shù)。

          DOM概述

          什么是DOM

          DOM是文檔對(duì)象的縮寫,和語言無關(guān)。它提供了訪問、動(dòng)態(tài)修改結(jié)構(gòu)文檔的接口,W3C制定了DOM規(guī)范,主流瀏覽器都支持。

          使用Core DOM操作節(jié)點(diǎn)

          訪問節(jié)點(diǎn):

          使用getElement系列方法訪問指定節(jié)點(diǎn)。

          getElementById():返回對(duì)擁有指定id的第一個(gè)對(duì)象的引用。

          getElementsByName():返回帶有指定名稱的對(duì)象的集合。

          getElementsByTagName():返回帶有指定標(biāo)簽名的對(duì)象的集合。

          使用層次關(guān)系訪問節(jié)點(diǎn)。

          parenNode:返回節(jié)點(diǎn)的父節(jié)點(diǎn)。

          firstChild:返回節(jié)點(diǎn)的首個(gè)節(jié)點(diǎn)。文本和屬性節(jié)點(diǎn)沒有父節(jié)點(diǎn),會(huì)返回一個(gè)空數(shù)組,對(duì)于元素節(jié)點(diǎn),若是沒有子節(jié)點(diǎn)會(huì)返回null。

          lastChild:返回節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn),返回值同firstChild。

          操作節(jié)點(diǎn)屬性值

          CoreDOM的標(biāo)準(zhǔn)方法包括以下兩種:

          getAttribute(“屬性名”):獲取屬性值。

          getAttribute(“屬性名”,“屬性值”):設(shè)置屬性值

          創(chuàng)建和增加節(jié)點(diǎn):

          創(chuàng)建節(jié)點(diǎn)

          createElement(tagName):按照給定的標(biāo)簽名稱創(chuàng)建一個(gè)新的元素節(jié)點(diǎn)

          appendChild(nodeName):向以存在節(jié)點(diǎn)列表的末尾添加新的節(jié)點(diǎn)。

          inserBefore(newNode,oldNode):向指定的節(jié)點(diǎn)之前插入一個(gè)新的子節(jié)點(diǎn)。

          cloneNode(deep):復(fù)制某個(gè)指定的節(jié)點(diǎn)。

          刪除和替換節(jié)點(diǎn)

          removeChild(node):刪除指定的節(jié)點(diǎn)。

          replaceChild(newNode,oldNode):用其他的節(jié)點(diǎn)替換指定的節(jié)點(diǎn)。

          Table對(duì)象的屬性和方法

          屬性:

          rows[]:返回包含表格中所有行的一個(gè)數(shù)組。

          rows[]用于返回表格中所有行的一個(gè)數(shù)組。

          方法:

          inserRow():在表格中插入一個(gè)新行。

          deleteRow():從表格中刪除一行。

          數(shù)組

          數(shù)組是具有相同數(shù)據(jù)類型的一個(gè)或多個(gè)值得集合

          創(chuàng)建數(shù)組的語法:

          var 數(shù)組名稱=new Array(size);

          數(shù)組的賦值的兩種方式:

          先聲明在賦值

          var province = new Array(4);

          province[0]=“河北省”;

          province[1]=“河南省”;

          索引也可以使用標(biāo)識(shí)(字符串),例如:

          var province=new Array(4);

          province[‘河北省’]=“河北省”;

          province[‘河南省’]=“河南省”;

          聲明時(shí)同時(shí)初始化

          var province=new Array(“河北省”,“河南省”,“湖北省”,“廣東省”);

          Array對(duì)象的常用屬性和方法:

          屬性:

          length:設(shè)置或返回?cái)?shù)組中元素的數(shù)目。

          方法:

          join():把數(shù)組的所有元素放入一個(gè)字符串,通過一個(gè)分隔符進(jìn)行分割。

          sort():對(duì)數(shù)組的元素進(jìn)行排序。

          理 | 屠敏
          出品 | CSDN(ID:CSDNnews)

          一直以來,操作系統(tǒng)的「時(shí)間、日期、時(shí)區(qū)」,是讓很多程序員在開發(fā)程序時(shí)比較敏感與特別關(guān)注的問題。

          • 還記得即將步入 2000 年的“千年蟲”(Year 2000 Problem,簡(jiǎn)稱“Y2K”)事件,由于早期的計(jì)算機(jī)配置比較低,那時(shí)為了節(jié)省空間就把年份只用后兩位數(shù)表示,如 1999 就表示為 99,導(dǎo)致新千年時(shí)電腦把 2000 年認(rèn)為是 1900 年,出現(xiàn) Bug,進(jìn)而引發(fā)各種各樣的系統(tǒng)功能紊亂甚至崩潰。

          • 2012 年,有用戶發(fā)現(xiàn)低內(nèi)核版 Linux 開啟 NTP 服務(wù)器會(huì)遇到閏秒 Bug,導(dǎo)致服務(wù)器重啟。

          • 2016 年,很多網(wǎng)友“作了一把”,將 iPhone 的日期設(shè)置到 1970 年 1 月 1 日,無意中觸發(fā)系統(tǒng) Bug,一時(shí)間導(dǎo)致 iPhone 重啟失敗,手機(jī)直接變板磚。

          就在近日,一個(gè)新的關(guān)于時(shí)間 Bug 出現(xiàn)在 Windows 系統(tǒng)中。據(jù) Ars Technica 報(bào)道,有一位挪威數(shù)據(jù)中心的工程師 Simen 遇到了一個(gè)令人費(fèi)解的時(shí)間 Bug, 它會(huì)導(dǎo)致 Windows Server 突然將系統(tǒng)時(shí)鐘重置到未來 55 天。

          時(shí)間 Bug 帶來的混亂

          事實(shí)上,這并不是 Simen 第一次遇到這個(gè)問題。

          在去年 8 月,Simen 曾遇到過類似的錯(cuò)誤,當(dāng)時(shí)一臺(tái)運(yùn)行 Windows Server 2019 的機(jī)器將時(shí)鐘重置到了 2023 年 1 月,但過了沒多久又自動(dòng)跳回來了。

          后來,直到事件日志被清除后才發(fā)現(xiàn)這一問題,但那時(shí)無法分析具體是什么原因?qū)е碌摹?/span>

          現(xiàn)在,他又在一臺(tái)運(yùn)行 Windows Server 2016 的機(jī)器上遇到了這個(gè)問題。

          對(duì)于普通用戶而言,時(shí)間的錯(cuò)亂帶來的短暫影響也許可以忽略不計(jì)。但是對(duì)于工程師而言,卻是一個(gè)讓人崩潰的存在。

          Simen 的主要工作是在 Windows Server 維護(hù)一個(gè)路由表(存儲(chǔ)在聯(lián)網(wǎng)計(jì)算機(jī)中的電子表格(文件)或類數(shù)據(jù)庫(kù)),這個(gè)路由表實(shí)時(shí)跟蹤手機(jī)號(hào)碼從一個(gè)運(yùn)營(yíng)商轉(zhuǎn)到另一個(gè)運(yùn)營(yíng)商的過程。

          當(dāng)服務(wù)器出現(xiàn)時(shí)間 Bug 時(shí),系統(tǒng)時(shí)鐘跳到八周后,這就帶來一個(gè)不可估量的后果,譬如,此前尚未遷移的號(hào)碼被列入已經(jīng)遷移、已經(jīng)轉(zhuǎn)移的號(hào)碼被列為待處理狀態(tài),整個(gè)都亂掉了。

          無獨(dú)有偶

          本來以為這只是一個(gè)特例,但是搜索一下,網(wǎng)絡(luò)上遇到這個(gè)問題的工程師不在少數(shù)。

          去年,有一位名叫 Ken 的工程師也發(fā)現(xiàn)了類似的“時(shí)間跳躍”現(xiàn)象,當(dāng)時(shí)在 2-3 臺(tái)服務(wù)器上,時(shí)鐘時(shí)不時(shí)會(huì)跳躍到幾周后,甚至有一次直接跳到了 2159 年。

          據(jù) Ars Technica 披露,Ken 在一封郵件中寫道:“受此影響的服務(wù)器呈指數(shù)增長(zhǎng),越來越多。在 5000 臺(tái)服務(wù)器(虛擬機(jī))中,我們總共有 20 臺(tái)左右的服務(wù)器(虛擬機(jī))遇到過這種情況。這種情況通常發(fā)生在數(shù)據(jù)庫(kù)服務(wù)器上。當(dāng)數(shù)據(jù)庫(kù)服務(wù)器在時(shí)間上發(fā)生跳躍時(shí),就會(huì)造成嚴(yán)重破壞,只要服務(wù)器在時(shí)間上有如此大的偏移,備份也就無法運(yùn)行。對(duì)于我們的客戶來說,這一點(diǎn)至關(guān)重要。”

          除了 Simen 和 Ken 之外,追溯到 2017 年,一位 Reddit 用戶 zanatwo 發(fā)帖稱他在一所大學(xué)工作,某一天,其發(fā)現(xiàn)校園內(nèi)的幾臺(tái) Windows 10 計(jì)算機(jī)開始出現(xiàn)錯(cuò)誤的時(shí)間。這些計(jì)算機(jī)上顯示的時(shí)間 Bug 完全是隨機(jī)的,在某些情況下,他的設(shè)備時(shí)間直接跳到了 31 個(gè)小時(shí)之前。

          通過深入分析,當(dāng)時(shí) Reddit 用戶發(fā)現(xiàn),時(shí)間變化與 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\SecureTimeLimits 中的 Windows 注冊(cè)表鍵相關(guān)。進(jìn)一步的調(diào)查顯示,當(dāng)一些人試圖訪問大學(xué)網(wǎng)站時(shí),這些錯(cuò)誤報(bào)告稱網(wǎng)站使用的有效 SSL 證書無效。

          Windows 官方發(fā)布的功能惹了禍?

          經(jīng)過排查之后,以上幾位工程師將罪魁禍?zhǔn)捉y(tǒng)一定位到了 Windows 上一個(gè)鮮為人知的功能—— Secure Time Seeding(簡(jiǎn)稱 STS)中。

          這是微軟在 2016 年引入 Windows 的功能,主要作用就是在 Windows 設(shè)備無法通過安全連接與時(shí)間服務(wù)器通信的情況下,改進(jìn)對(duì)正確時(shí)間的記錄。簡(jiǎn)單來看,這也是設(shè)備在斷電情況下也能保證準(zhǔn)確的時(shí)間。默認(rèn)情況下,這一功能在 Windows 系統(tǒng)及服務(wù)器下是打開的。

          從工作原理來看,為確定當(dāng)前時(shí)間,STS 會(huì)調(diào)用 SSL(Secure Sockets Layer)握手過程中包含的一組元數(shù)據(jù)。具體來說,這些數(shù)據(jù)包括:

          • ServerUnixTime,日期和時(shí)間表示法,顯示自 1970 年 1 月 1 日 00:00:00 UTC 時(shí)起已過去的秒數(shù)。

          • 從遠(yuǎn)程服務(wù)器 SSL 證書中獲取的加密簽名數(shù)據(jù),顯示該證書是否已根據(jù)所謂的 "在線證書狀態(tài)協(xié)議 "機(jī)制被撤銷。

          在發(fā)布這一功能時(shí),微軟工程師在官方文檔中寫道,他們使用 ServerUnixTime 數(shù)據(jù)是 "假定它在一定程度上是準(zhǔn)確的",但在同一句話中又承認(rèn)它 "也可能是不正確的"。

          為了防止 STS 根據(jù)單個(gè)不同步遠(yuǎn)程服務(wù)器提供的數(shù)據(jù)重置系統(tǒng)時(shí)鐘,STS 會(huì)隨機(jī)穿插 SSL 連接到多個(gè)服務(wù)器,以得出當(dāng)前時(shí)間的可靠范圍。

          然后,該機(jī)制會(huì)將 ServerUnixTime 與 OCSP(Online Certificate Status Protocol,在線證書狀態(tài)協(xié)議 )有效期合并,以產(chǎn)生盡可能小的時(shí)間范圍,并為其分配置信度分?jǐn)?shù)。

          當(dāng)分?jǐn)?shù)達(dá)到足夠高的閾值時(shí),Windows 就會(huì)將數(shù)據(jù)歸類為 STSHC(Secure Time Seed of High Confidence,高置信度安全時(shí)間種子)。然后,STSHC 用于監(jiān)控系統(tǒng)時(shí)鐘是否存在 "嚴(yán)重錯(cuò)誤",并對(duì)其進(jìn)行糾正。

          盡管 STS 內(nèi)建了檢查和平衡機(jī)制,以確保其提供準(zhǔn)確的時(shí)間估計(jì),但長(zhǎng)期以來工程師遇到的“時(shí)間跳躍”事件表明,該功能有時(shí)會(huì)做出誤差數(shù)天、數(shù)周、數(shù)月甚至數(shù)年的胡亂猜測(cè)。

          Ars Technica 報(bào)道的文章中,其分享了來自工程師 Ken 遇到時(shí)間跳躍時(shí)的具體截圖。

          第一張圖片中的選定行上方的 "預(yù)計(jì)安全時(shí)間 "條目顯示,Windows 預(yù)計(jì)當(dāng)前日期為 2023 年 10 月 20 日,比系統(tǒng)時(shí)鐘顯示的時(shí)間晚四個(gè)多月。然后,STS 會(huì)更改系統(tǒng)時(shí)鐘,使其與"目標(biāo)系統(tǒng)時(shí)間 "中顯示的錯(cuò)誤的預(yù)計(jì)安全時(shí)間相匹配。

          第二張圖片顯示了類似的情況,其中 STS 將日期從 2023 年 6 月 10 日改為 2023 年 7 月 5 日。

          在遇到這一問題后,Ken 和 Simen 都向微軟進(jìn)行了反饋,遺憾的是,他們并沒有得到實(shí)質(zhì)性的回應(yīng)與解決方案。

          微軟工程師個(gè)人曾發(fā)出警告:主動(dòng)關(guān)閉 STS 功能

          那要問有沒有解決方法,其實(shí)去年一位微軟 Windows 高級(jí)工程師 Ryan Ries 發(fā)過推文提供過用戶,其寫到“大家好,如果你們管理 Active Directory 域控制器,我想給你們一些非官方的建議,這完全是我的個(gè)人意見:在您的 DC 上禁用 w32time 的 STS。”

          當(dāng)有網(wǎng)友進(jìn)一步詢問原因時(shí),Ryan Ries 表示,「因?yàn)樵谒愕钠ü芍埃@只是一個(gè)時(shí)間問題」。

          這也不禁讓人好奇,連微軟自家工程師都覺得這個(gè)功能有問題,為什么官方還有做保留。

          就在眾人存疑時(shí),微軟在給 Ars Technica 的一份聲明中寫道:

          STS 功能是一種基于啟發(fā)式的計(jì)時(shí)方法,在某些軟件/固件/硬件計(jì)時(shí)失效的情況下也有助于校正系統(tǒng)時(shí)間。該功能已在所有默認(rèn) Windows 配置中默認(rèn)啟用,并已證明在默認(rèn)配置中發(fā)揮了預(yù)期功能。

          每次部署的時(shí)間分配都是獨(dú)一無二的,客戶通常會(huì)根據(jù)自己的特殊需求來配置機(jī)器。鑒于 "STS"的啟發(fā)式性質(zhì)以及客戶可能使用的各種部署,我們提供了禁用該功能的選項(xiàng),以滿足客戶的需求。我們的理解是,在客戶遇到 STS 問題的部署中,很可能存在獨(dú)特、專有、復(fù)雜的因素,而這些客戶并不能從目前實(shí)施的這一功能中受益。在這些個(gè)別情況下,我們只能建議在部署中禁用該功能。

          具體來看,要禁用 STS,可以在受影響的機(jī)器上設(shè)置一個(gè)注冊(cè)表項(xiàng)。這是 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config 目錄中的 UtilizeSslTimeData 密鑰,其類型為 REG_DWORD。如果設(shè)置為 0,則停用 STS。如果設(shè)置為 1,則可以重新激活該功能。

          STS 的異常,有沒有解決方案?

          截至目前,似乎除了關(guān)閉此功能之外,并沒有太過合適的解決方案,因此,很多人對(duì)于微軟的回應(yīng)并不買賬。在 HN 上,網(wǎng)友也展開了激烈的討論,甚至有人吐槽:是時(shí)候應(yīng)該買塊手表來核對(duì)服務(wù)器上的時(shí)間了!

          另外,有網(wǎng)友 @theqmann 分析認(rèn)為,「這聽起來像是一種統(tǒng)計(jì)方法,如果在給定時(shí)間內(nèi)收到 N 個(gè)時(shí)間戳相似的數(shù)據(jù)包/連接,就會(huì)改變時(shí)鐘。我可以看到這樣一個(gè)問題:一臺(tái) Windows Server 每分鐘全天候提供數(shù)千或數(shù)百萬個(gè) OpenSSL 數(shù)據(jù)包,而它恰好隨機(jī)接收到 N 個(gè)數(shù)據(jù)包,這些數(shù)據(jù)包彼此非常接近,足以滿足統(tǒng)計(jì)閾值的要求。通過隨機(jī)跳轉(zhuǎn),連續(xù)跳轉(zhuǎn)十多次時(shí)間都是有可能的」。

          @jmuguy 則表示:

          在我做 IT 人員的這些年里,Windows Time 是我處理過的最煩人的事情之一。注冊(cè)和取消注冊(cè) w32time,嘗試不同的 NTP 服務(wù)器。試圖弄明白為什么域系統(tǒng)無法從 DC 獲取時(shí)間。這總讓人感覺很......愚蠢。在設(shè)備上設(shè)置正確的時(shí)間肯定沒那么復(fù)雜。事實(shí)證明,并不復(fù)雜,除非你使用的是 Windows 系統(tǒng)。有點(diǎn)諷刺的是,如今我唯一需要處理的 Windows 系統(tǒng)就是我的游戲電腦。它拒絕與 time.windows.com 同步。

          除了 Windows 系統(tǒng)之外,還有人稱在 Linux 中也遇到了同樣的問題。

          @nicolaslem 表示:

          我的 Linux 筆記本電腦有時(shí)也會(huì)遇到類似的問題,把電腦從睡眠中喚醒時(shí),時(shí)間會(huì)跳到 2077 年。我猜這是硬件故障,因?yàn)樗⒉唤?jīng)常發(fā)生,但一旦發(fā)生就會(huì)造成很大影響。我無法想象在生產(chǎn)服務(wù)器上發(fā)生類似情況會(huì)有多大影響。

          你是否遇到過類似的問題?

          參考:

          https://arstechnica.com/security/2023/08/windows-feature-that-resets-system-clocks-based-on-random-data-is-wreaking-havoc/

          https://news.ycombinator.com/item?id=37151220

          https://www.reddit.com/r/sysadmin/comments/61o8p0/system_time_jumping_back_on_windows_10_caused_by/

          ouseout和mouseleave的區(qū)別

          二者都是鼠標(biāo)移出。mouseout冒泡。 mouseleave不冒泡。(出去冒泡,離開不冒泡)

          mouseout對(duì)應(yīng)上面的mouseover ,mouseleave對(duì)應(yīng)上面的mouseenter。

          注冊(cè)事件的第二種方法(監(jiān)聽法)

          就是誰發(fā)生、怎么發(fā)生、發(fā)生了什么 的第二種表達(dá)方式。

          誰發(fā)生.addEventListener(怎么發(fā)生,發(fā)生了什么的函數(shù))
        1. 怎么發(fā)生:這里的觸發(fā)事件不帶on,比如click
        2. 發(fā)什么了什么的函數(shù): function() { 要發(fā)生的事情 };
        3. //例如上面的唐伯虎點(diǎn)秋香例子
          btn.addEventListener('click', function() {
          	alert('點(diǎn)秋香');
          })

          節(jié)點(diǎn)操作01

          • 改變?cè)貎?nèi)容
          element.innerText
          //從起始位置到終止位置的內(nèi)容。但它去除html標(biāo)簽,同時(shí)空格和換行也會(huì)去掉
          element.innerHTML
          //起始位置到終止位置的全部?jī)?nèi)容,包括html標(biāo)簽,同時(shí)保留空格和換行

          innerText 和 innerHTML的區(qū)別

          1. innerText 不識(shí)別html標(biāo)簽 非標(biāo)準(zhǔn) 去除空格和換行
          2. innerHTML 識(shí)別html標(biāo)簽 按照W3C標(biāo)準(zhǔn) 保留空格和換行
          3. 這兩個(gè)屬性都是可讀寫的,可以獲取元素里面的內(nèi)容。例如:
          <p>2333</p>
          <script>
          	var p = document.getElementByTagName('p');
          	console.log(p.innerText);
          	console.log(p.innerHTML);
          </script>

          常見元素的屬性操作

          三種操作情況:

          innerText 、innerHTML 改變?cè)貎?nèi)容

          src、 href

          id、alt、title

          表單元素的屬性操作

          利用DOM可以操作如下表單元素的屬性:

          type , value , checked , selected , disabled

          <body>
          	<button>按鈕</button>
          	<input type="text" value="輸入內(nèi)容" />
          	<script>
          		//1,獲取元素
          		var btn = document.querySelector('button');
          		var inp = document.querySelector('input');
          		//2,注冊(cè)事件--誰發(fā)生 怎么發(fā)生 發(fā)生什么
          		btn.addEventListener('click', function() {
          		//inp.innerHTML = '被點(diǎn)擊了'; 這個(gè)是 普通盒子 比如div標(biāo)簽里面的內(nèi)容被修改,不是value里的內(nèi)容被改變
          		//表單里面的值 文字內(nèi)容是通過valve來修改的
          			inp.value = '我被點(diǎn)擊了';
          		//如果想要某個(gè)表單被禁用,不能重復(fù)點(diǎn)擊disabled 我們想要這個(gè)按鈕 button禁用
          		//btn.disbled = true; 這樣就被禁用了
          		this.disabled = true;//這里的this就是btn,因?yàn)槭莃tn發(fā)生的,這里的this就特指btn了。
          		//this指向的是發(fā)生的那個(gè)元素 btn
          		})
          	</script>
          </body>

          案例:京東登陸界面的密碼表單輸入密碼時(shí),默認(rèn)不顯示密碼。點(diǎn)擊小眼睛圖標(biāo)時(shí),顯示密碼。再點(diǎn)擊又不顯示密碼。


          //2,注冊(cè)事件 誰發(fā)生 怎么發(fā)生 發(fā)生什么
          var flag = 0;
          eye.addEventListener('click', function() {
          	//每次點(diǎn)擊 flag一定要變化
          	if(flag == 0) {
          		pwd.type = 'text';
          		eye.src = '---';
          		flag = 1;//這里就是要變化了。原來是0,這里就要變成1
          	} else {
          			pwd.type = 'password';
          			eye.src = '---';
          			flag = 0;//這里又變化了。原來是1,點(diǎn)過一次就變成0了
          		}
          })

          樣式屬性操作

          我們可以通過JS修改元素的大小、顏色、位置等樣式。

          element.style = ’ ';行內(nèi)樣式操作

          element.className 類名樣式操作

          注意:

          JS 里面的樣式采取駝峰命名法 比如 fontSize , backgroundColor 。注意,這里沒有連接的 - 了。

          JS修改style 樣式操作,產(chǎn)生的是行內(nèi)樣式,css權(quán)重比較高。

          className 會(huì)直接更改元素的類名,會(huì)覆蓋原先的類名。

          第3條里,如果原來的類名還想保留,那就可以這樣做,假如原來的類名是class=‘first’ ,現(xiàn)在要用的是class='change’并且不想把原來的first類型替換掉,那就寫成 元素.className = ‘first change’ 就闊以了。

          <body>
          	<div></div>
          	<script>
          		//1,獲取元素
          		var div = document.querySelector('div');
          		//2,注冊(cè)事件。誰發(fā)生 怎么發(fā)生 發(fā)生什么
          		div.onclick = function() {
          			//div.style里面的屬性  采取駝峰命名法
          			this.style.backgroundColor = 'purple';
          			this.style.width = '200px';
          		}
          	</script>
          </body>

          這里是this是指向函數(shù)的調(diào)用者,即div在調(diào)用這個(gè)函數(shù)。 相當(dāng)于div.style (如上圖的div)

          如果調(diào)用者不是當(dāng)前的元素,就不能用this了。(如下圖function里的box.style 就不能寫成this.style)

          因?yàn)槭莃tn在調(diào)用函數(shù),然后讓box產(chǎn)生變化。 如果用了this,就是指btn在發(fā)生變化了。所以這里不能用this。

          當(dāng)一個(gè)元素需要更改的樣式較多時(shí),適合用element.className來完成。

          <head>
          <style>
          .change {
          	background-color: purple;
          	color: #fff;
          	font-size: 25px;
          	margin-top: 100px;
          }
          </style>
          </head>
          
          <body>
          	<div>文本</div>
          	<script>
          		//當(dāng)元素樣式較多或者功能復(fù)雜的情況下,
          		//使用element.className獲得修改元素樣式,
          		var div = document.querySelector('div');
          		div.onclick = function() {
          			this.className = 'change';
          		}
          	</script>
          </body>

          JS排他思想

          如果有同一組元素,我們想要其中一個(gè)元素實(shí)現(xiàn)某種樣式的情況下,不想讓其他同樣的元素跟著實(shí)現(xiàn)這種樣式,就需要用到循環(huán)的排他思想算法:

          1. 所有元素全部清除樣式(干掉其他人)
          2. 給當(dāng)前元素設(shè)置樣式(留下我自己)
          3. 注意順序不能顛倒。首先干掉其他人,再設(shè)置自己。
          <ul class='baidu'>
          	<li><img src='1' /></li>
          	<li><img src='1' /></li>
          	<li><img src='1' /></li>
          </ul>
          <script>
          	//1,獲取元素 
          	var imgs = document.querySelector('.baidu').querySelectorAll('img');
          	//console.log(imgs);
          	//2,循環(huán)注冊(cè)事件
          	for(var i = 0; i < imgs.length; i++) {
          		imgs[i].onclick = function() {
          		//this.src 就是我們點(diǎn)擊的圖片的路徑
          		//console.log(this.src);
          		//把這個(gè)路徑this.src給body就可以了
          			document.body.style.backgroundImage = 'url(' + this.src + ')';
          		}
          	}
          </script>

          說白了,就是先讓包括自己的所有人都不顯示,然后再讓自己顯示。 這樣在自己顯示的時(shí)候,別人就不顯示了。

          全選反選案例

          <script>
          	//1,全選和取消全選的做法: 
          	//讓下面所有復(fù)選框的checked屬性(選中狀態(tài)) 跟隨 全選按鈕即可
          	//獲取元素
          	var j_acAll = document.getElementById('j_cbAll');
          	var j_tbs = document.getElementById('j_tb').getElementByTagName('input');
          	//即 選出下面所有的復(fù)選框
          	//注冊(cè)時(shí)間 誰發(fā)生 怎么發(fā)生 發(fā)生什么
          	j_cbAll.onclick = function() {
          		//this.checked 它可以得到當(dāng)前復(fù)選框的選中狀態(tài) 
          		//如果是true 就是選中, 如果是false 就是未選中
          		console.log(this.checked);
          		for(var i = 0; i < j_tbs.length; i++) {
          			j_tbs[i].checked = this.checked;
          		}
          	}
          	//2,下面的復(fù)選框需要全部選中,上面全選才能選中做法:
          	//給下面所有復(fù)選框綁定點(diǎn)擊事件,每次點(diǎn)擊,都要循環(huán)看是否都選中了
          	for(var i = 0; i < j_tbs.length; i++) {
          		j_tbs[i].onclick = function() {
          			//flag控制全選按鈕是否選中
          			var flag = true;
          			//每次點(diǎn)擊下面的復(fù)選框都要循環(huán)檢查這4個(gè)小按鈕是否全被選中
          			for(var i = 0; i < j_tbs.length; i++) {
          				if( !j_tbs[i].checked) {
          					flag = false;
          					break;
          				//退出for循環(huán) 這樣可以提高運(yùn)行效率
          				//因?yàn)橹灰粋€(gè)沒有選中,剩下的就無需再循環(huán)判斷了
          				}
          			}
          			j_cbAll.checked = flag;
          		}
          	}
          </script>
          //每次點(diǎn)擊,都要循環(huán)

          操作屬性

          自定義屬性的操作

          獲取屬性值

          • element.屬性 獲取屬性值
          • 作用:獲取內(nèi)置屬性值,即元素本身自帶的屬性
          • element.getAttribute(‘屬性’);
          • 作用:可以獲得原有屬性值,也可以獲得自定義的元素值。主要獲取自定義的屬性 (標(biāo)準(zhǔn)) 我們程序員自定義的屬性。

          獲取、設(shè)置、移除元素屬性的應(yīng)用例子:

          <body>
          	<div id="demo" index="1"></div>
          	<script>
          		var div = document.querySelector('div');
          		//1,獲取元素的屬性值
          		//(1)element.屬性
          		console.log(div.id);//demo
          		//(2)element.getAttribute('屬性')
          		//程序員自己添加的屬性,我們稱為自定義屬性,比如這里的 index
          		console.log(div.getAttribute('id'));//demo
          		console.log(div.getAttribute('index'));//1
          		//2,設(shè)置元素的屬性值
          		//(1)element.屬性 = ‘值’;
          		div.id = 'test';
          		div.className = 'navs';
          		//(2)element.setAttribute('屬性','值');
          		//主要針對(duì)自定義屬性
          		div.setAttribute('index', 2);
          		div.setAttribute('class', 'footer');
          		//class特殊 這里寫的就是class 不是className
          		//3,移除屬性 element.removeAttribute('屬性');
          		div.removeAttribute('index');
          	</script>
          </body>

          屬性操作案例(必須會(huì)寫)

          <script>
          	//獲取元素
          	var tab_list = document.querySelector('.tab_list');
          	var lis = tab_list.querySelectorAll('li');
          	var items = document.querySelectorAll('.item');
          	//for循環(huán)綁定點(diǎn)擊事件
          	for(var i = 0; i < lis.length; i++) {
          		//開始給5個(gè)小li設(shè)置索引號(hào)index
          		lis[i].setAttribute('index',i);
          		lis[i].onclick = function() {
          			//1,上面的模塊選項(xiàng)卡,點(diǎn)擊某一個(gè),當(dāng)前這個(gè)底色會(huì)是紅色,其他選項(xiàng)卡不變色。
          			//所以用到排他思想。干掉所有人,其余的li清除class這個(gè)類
          			for(var i = 0; i < lis.length; i++) {         		
          				lis[i].className = '';		
          			}
          			//留下我自己
          			this.className = 'current';
          			//2,下面的顯示內(nèi)容模塊
          			var index = this.getAttribute('index');
          			console.log(index);
          			//干掉所有人 讓其余的item 這些div 隱藏
          			for(var i = 0; i < items.length; i++) {
          				items[i].style.display = 'none';
          			}
          			//留下我自己 讓對(duì)應(yīng)的item顯示出來
          			items[index].style.display = 'block';
          		}
          	}
          </script>

          關(guān)于自定義屬性

          H5自定義屬性

          自定義屬性目的:是為了保存并使用數(shù)據(jù)。有些數(shù)據(jù)可以保存到頁(yè)面中而不用保存到數(shù)據(jù)庫(kù)中。

          1.設(shè)置H5自定義屬性

          H5規(guī)定自定義屬性data- 開頭做為屬性名并且賦值。說白了就是,自定義屬性要用data- 做開頭。比如:

          <div data-index="1"></div>

          或者使用JS設(shè)置:

          element.setAttribute('data-index', 2)

          2.獲取H5自定義屬性

          1,element.getAttribute(‘data-index’) 兼容性好

          2,H5新增 element.dataset.index 或者element.dataset[‘index’] , ie11才開始支持,而且只能取data- 開頭的自定義元素屬性。

          如果自定義屬性里有多個(gè) - 連接的單詞,我們獲取的時(shí)候,采取駝峰命名法。如 div.dataset.listName 或 div.dataset[‘listName’]

          節(jié)點(diǎn)操作02

          網(wǎng)頁(yè)中的所有內(nèi)容都是節(jié)點(diǎn)(標(biāo)簽,屬性,文本,注釋,空格等),在DOM中,節(jié)點(diǎn)使用node來表示。

          HTML DOM樹中的所有節(jié)點(diǎn)均可通過JS進(jìn)行訪問,所有HTML元素(節(jié)點(diǎn))均可被修改,也可以創(chuàng)建或刪除。

          一般地,節(jié)點(diǎn)至少擁有nodeType(節(jié)點(diǎn)類型),nodeName(節(jié)點(diǎn)名稱)和nodeValue(節(jié)點(diǎn)值)這三個(gè)基本屬性。

          • 元素節(jié)點(diǎn) nodeType 為1
          • 屬性節(jié)點(diǎn) nodeType 為2
          • 文本節(jié)點(diǎn) nodeType 為3(文本節(jié)點(diǎn)包含文字,空格,換行等)

          我們實(shí)際開發(fā)中,節(jié)點(diǎn)操作主要操作的是元素節(jié)點(diǎn)。

          節(jié)點(diǎn)層級(jí)

          利用DOM樹可以把節(jié)點(diǎn)劃分為不同的層級(jí)關(guān)系,常見的是父子兄弟層級(jí)關(guān)系。

          1,父級(jí)節(jié)點(diǎn)

          node.parentNode
        4. parentNode屬性可返回某節(jié)點(diǎn)的父節(jié)點(diǎn),注意是最近的一個(gè)父節(jié)點(diǎn)(親爸爸)
        5. 如果指定的節(jié)點(diǎn)沒有父節(jié)點(diǎn),則返回null。
        6. <div class="demo">
          	<div class="box">
          		<span class="erweima">X</span>
          	</div>
          </div>
          
          <script>
          	//1,父節(jié)點(diǎn)parentNode
          	var erweima = document.querySelector('.erweima');
          	//var box = document.querySelector('.box');
          	//得到的是離元素最近的父級(jí)節(jié)點(diǎn)(親爸爸)
          	//如果找不到父節(jié)點(diǎn),就返回null
          	console.log(erweima.parentNode);
          </script>

          2,子節(jié)點(diǎn)

          有兩種獲得方式,標(biāo)準(zhǔn)和非標(biāo)準(zhǔn)。

          第一種: parentNode.childNodes(標(biāo)準(zhǔn))
          //雖然是標(biāo)準(zhǔn)的,但是不提倡使用

          parentNode.childNodes 返回包含指定節(jié)點(diǎn)的子節(jié)點(diǎn)的集合。該集合為即時(shí)更新的集合。

          注意:返回值里面包含了所有的子節(jié)點(diǎn),包括元素節(jié)點(diǎn),文本節(jié)點(diǎn)(文字,空格,換行等)等。

          如果只想要獲得里面的元素節(jié)點(diǎn),則需要專門處理。所以我們**一般不提倡使用childNodes** 。 專門處理需要的代碼:

          var ul = document.querySelector('ul');
          for(var i = 0; i < ul.childNodes.length; i++) {
          	if(ul.childNodes[i].nodeType == 1) {
          		//即 ul.childNodes[i]是元素節(jié)點(diǎn)
          		console.log(ul.childNodes[i];
          	}
          }
          第二種: parentNode.children(非標(biāo)準(zhǔn))
          //雖然是非標(biāo)準(zhǔn),但是可以得到我們想要的元素節(jié)點(diǎn),
          //所以推薦使用這個(gè)

          parentNode.children是一個(gè)只讀屬性,返回所有子元素節(jié)點(diǎn),其余節(jié)點(diǎn)不返回。所以重點(diǎn)掌握這個(gè)方法。

          獲取 第一個(gè)子元素和最后一個(gè)子元素

          實(shí)際開發(fā)中,firstChild 和 lastChild 包含其他節(jié)點(diǎn),操作不方便,而firstElementChild 和 lastElementChild又有兼容性問題。那么我們?nèi)绾潍@取第一個(gè)子元素節(jié)點(diǎn)或最后一個(gè)子元素節(jié)點(diǎn)呢?

          解決方案:

          1.獲取第一個(gè)子元素節(jié)點(diǎn), parentNode.children[0];

          2,獲取最后一個(gè)子元素節(jié)點(diǎn),

          parentNode.children[parentNode.children.length - 1]

          這樣既可以獲得想要的元素節(jié)點(diǎn),又不存在兼容性問題。

          節(jié)點(diǎn)操作案例:


          <script>
          	//1,獲取元素
          	var nav = document.querySelector('.nav');
          	var lis = nav.children;//得到4個(gè)小li
          	//2,注冊(cè)循環(huán)事件 點(diǎn)誰誰發(fā)生
          	for(var i = 0; i < lis.length; i++) {
          		lis[i].onmouseover = function() {
          			this.children[i].style.display = 'block';
          		}
          		lis[i].onmouseout = function() {
          			this.children[i].style.display = 'none';
          		}
          	}
          </script>

          節(jié)點(diǎn)層級(jí)--兄弟節(jié)點(diǎn)

          1. node.nextSibling返回當(dāng)前元素的下一個(gè)兄弟節(jié)點(diǎn),找不到則返回null 。同樣,也是包含所有的節(jié)點(diǎn)。
          2. node.previousSibling返回當(dāng)前元素上一個(gè)兄弟節(jié)點(diǎn),找不到則返回null。同樣,也包含所有的節(jié)點(diǎn)。
          3. node.nextElementSibling返回當(dāng)前元素下一個(gè)兄弟元素節(jié)點(diǎn),找不到則返回null。
          4. node.previousElementSibling返回當(dāng)前元素的上一個(gè)兄弟元素節(jié)點(diǎn),找不到則返回null。

          1和2 取兄弟節(jié)點(diǎn)的時(shí)候,會(huì)把空格文本節(jié)點(diǎn)也取到。不適合用。

          3和4取出來的確實(shí)是想要的兄弟節(jié)點(diǎn),但是會(huì)有兼容性問題。

          如何解決兼容性問題?

          需要自己封裝一個(gè)函數(shù)。

          function getNextElementSibling(element) {
          	var el = element;
          	while(el == el.nextSibling) {
          		if(el.nodeType === 1) {
          			return el;
          		}
          	}
          	return null;
          }

          不過兄弟節(jié)點(diǎn)用的較少。

          創(chuàng)建元素節(jié)點(diǎn)

          document.createElement('tagName');

          創(chuàng)建 由tagName指定的HTML元素。因?yàn)檫@些元素原先不存在,是根據(jù)我們的需求 動(dòng)態(tài)生成的,所以我們也稱為動(dòng)態(tài)創(chuàng)建元素節(jié)點(diǎn)。

          添加節(jié)點(diǎn):先創(chuàng)建,后添加

          1. node.appendChild(child)將一個(gè)節(jié)點(diǎn)添加到指定父節(jié)點(diǎn)的子節(jié)點(diǎn)列表末尾。類似于css里面的after偽元素。node是父節(jié)點(diǎn),child是子級(jí)。
          2. node.insertBefore(child,指定元素)將一個(gè)節(jié)點(diǎn)添加到父節(jié)點(diǎn)的指定子節(jié)點(diǎn)前面。類似于css里面的before偽元素。
          <body>
          	<ul>
          		<li>2333</li>
          	</ul>
          	<script>
          		//1,創(chuàng)建元素節(jié)點(diǎn)
          		var li = document.createElement('li');
          		//2,添加后節(jié)點(diǎn) node.appendChild(child)
          		var ul = document.querySelector('ul');
          		ul.appendChild(li);
          		//添加前節(jié)點(diǎn) node.insertBefore(child,指定元素);
          		var lili = document.creatrElement('li');
          		ul.insertBefore(lili,ul.children[0]);
          	</script>
          </body>

          發(fā)布留言板案例:

          <body>
          	<textarea name="" id=""></textarea>
          	<button>發(fā)布</button>
          	<ul>
          	</ul>
          	<script>
          		//1,獲取元素
          		var btn = document.querySelector('button');
          		var text = document.querySelector('textarea');
          		var ul = document.querySelector('ul');
          		//2,注冊(cè)事件 誰發(fā)生 怎么發(fā)生 發(fā)生什么
          		btn.onclick = function() {
          			if(text.value == "") {
          				alert('內(nèi)容不能為空!');
          				return false;
          			} else {
          					//(1)創(chuàng)建元素節(jié)點(diǎn)
          					var li = document.createElement('li');
          					//先創(chuàng)建li 才能賦值
          					li.innerHTML = text.value;
          					//(2)添加節(jié)點(diǎn)
          					ul.insertBefore(li,ul.children[0]);
          				}
          		}
          	</script>
          </body>

          刪除子節(jié)點(diǎn)

          node.removeChild(child)
          //舉例:
          ul.removeChild(ul.children[0]);

          從DOM中刪除一個(gè)子節(jié)點(diǎn),返回刪除的節(jié)點(diǎn)。

          復(fù)制(克隆)節(jié)點(diǎn):先克隆,再添加

          node.cloneNode()
          //返回調(diào)用該方法的節(jié)點(diǎn)的一個(gè)副本。
          //這里的node是要被克隆的那個(gè)元素節(jié)點(diǎn)

          注意:

          1. 如果括號(hào)參數(shù)為空或者false,則是淺克隆,即只克隆節(jié)點(diǎn)本身,不克隆里面的子節(jié)點(diǎn)。
          2. 如果括號(hào)里面的參數(shù)為true,則是深克隆,會(huì)復(fù)制節(jié)點(diǎn)本身以及里面所有的子節(jié)點(diǎn)。
          <body>

          三種動(dòng)態(tài)創(chuàng)建元素的區(qū)別

          1. document.write()
          2. element.innerHTML
          3. document.createElement()

          區(qū)別:

          • document.write()是直接將內(nèi)容寫入頁(yè)面的內(nèi)容流,但是文檔流執(zhí)行完畢,它會(huì)導(dǎo)致頁(yè)面全部重繪。
          • innerHTML是將內(nèi)容寫入某個(gè)DOM節(jié)點(diǎn),不會(huì)導(dǎo)致頁(yè)面全部重繪。
          • innerHTML創(chuàng)建多個(gè)元素效率更高,不需要拼接字符串,采取數(shù)組形式拼接,結(jié)構(gòu)稍微復(fù)雜。
          • createElement()創(chuàng)建多個(gè)元素效率稍微低一點(diǎn)點(diǎn),但是結(jié)構(gòu)更清晰。
          <!DOCTYPE html>
          <html>
          	<head>
          		<meta charset="uft-8" />
          	</head>
          	<body>
          		<button>點(diǎn)擊</button>
          		<div class="inner"></div>
          		<ul class="create"></ul>
          		<script>
          			//1,document.write()創(chuàng)建元素
          				var btn = document.querySelector('button');
          				btn.onclick = function() {
          					document.write('<div>2333</div>');
          				}
          				//2,innerHTML 創(chuàng)建元素
          				var inner = document.querySelector('.inner');
          				var arr = [];
          				for(var i = 0; i <= 10; i++) {
          					arr.push('<a href="">233</a>');
          				}
          				inner.innerHTML = arr.join(' ');
          				//3,document.createElement()創(chuàng)建元素
          				var create = document.querySelector('.create');
          				for (var i = 0; i <= 10; i++) {
          					var li = document.createElement('li');
          					create.appendChild(li);
          				}
          		</script>
          	</body>
          </html>

          DOM事件流

          • 事件流描述的是從頁(yè)面中接收事件的順序。
          • 事件發(fā)生時(shí),會(huì)在元素節(jié)點(diǎn)之間按照特定的順序傳播,這個(gè)傳播過程就是DOM事件流。

          事件冒泡:IE最早提出,事件開始時(shí)由最具體的元素接收,然后逐級(jí)向上傳播到DOM最頂層節(jié)點(diǎn)的過程。

          事件捕獲:網(wǎng)景最早提出,由DOM最頂層節(jié)點(diǎn)開始,然后逐級(jí)向下傳播到最具體的元素接收的過程。

          注意:

          1,JS代碼中只能執(zhí)行捕獲或者冒泡其中的一個(gè)階段。二者只能選其一。

          2,onclick和attachEvent只能得到冒泡階段。

          3,addEventListener()中function()后面的參數(shù),如果是true,表示在事件捕獲階段條用事件處理程序;如果是不寫參數(shù)或者參數(shù)是false,表示在事件冒泡階段調(diào)用事件處理程序。

          4,實(shí)際開發(fā)中我們很少使用事件捕獲,我們更關(guān)注事件冒泡。

          5,有些事件是沒有冒泡的,比如 onblur,onfocus,onmouseenter,onmouseleave。

          事件對(duì)象

          什么是事件對(duì)象?

          eventTarget.onclick = function(event) { };
          或
          eventTarget.addEventListener('click', function(event) { })
          //這個(gè)event就是事件對(duì)象。可以寫成e或者evt。
          //這個(gè)參數(shù)在前面學(xué)習(xí)中是沒有寫出來的。

          官方解釋:event對(duì)象代表事件的狀態(tài),比如鍵盤按鍵的狀態(tài),鼠標(biāo)的位置,鼠標(biāo)按鈕的狀態(tài)。

          簡(jiǎn)單理解:事件發(fā)生后,跟事件相關(guān)的一系列信息數(shù)據(jù)的集合都放到這個(gè)對(duì)象里面,這個(gè)對(duì)象就是事件對(duì)象event,它有很多屬性和方法。

          比如:

          1,誰綁定了這個(gè)事件。

          2,鼠標(biāo)觸發(fā)事件的話,會(huì)得到鼠標(biāo)的相關(guān)信息,如鼠標(biāo)位置。

          3,鍵盤觸發(fā)事件的話,會(huì)得到鍵盤的相關(guān)信息,如按了哪個(gè)鍵。

          這個(gè)event是個(gè)形參,系統(tǒng)幫我們?cè)O(shè)定為事件對(duì)象,不需要傳遞實(shí)參過去。

          當(dāng)我們注冊(cè)事件時(shí),event對(duì)象就會(huì)被系統(tǒng)自動(dòng)創(chuàng)建,并依次傳遞給事件監(jiān)聽器(即事件處理函數(shù))。

          兼容性問題

          事件對(duì)象的兼容性方案

          事件對(duì)象本身的獲取存在兼容性問題:

          1,標(biāo)準(zhǔn)瀏覽器中是瀏覽器給方法傳遞的參數(shù),只需要定義形參3 就可以獲得到。 2,在IE6~8中,瀏覽器不會(huì)給方法傳遞參數(shù),如果需要的話,需要到window.event中獲取查找。

          解決:

          e = e || window.event;


          阻止事件冒泡的兩種方式

          事件冒泡:開始時(shí)由最具體的元素接收,然后逐級(jí)向上傳播到DOM最頂層節(jié)點(diǎn)。

          事件冒泡本身的特性,會(huì)帶來壞處,也會(huì)帶來好處,需要我們靈活掌握。

          阻止事件冒泡

          • 標(biāo)準(zhǔn)寫法:利用事件對(duì)象里面的e.stopPropagation()方法
          • 非標(biāo)準(zhǔn)寫法:IE6-8使用。 利用事件對(duì)象cancelBubble屬性。

          常用的是標(biāo)準(zhǔn)寫法。IE瀏覽器因?yàn)榧嫒輪栴},不經(jīng)常用。如果用了非標(biāo)準(zhǔn)寫法,可以調(diào)試一下兼容性:

          if(e && e.stopPropagation) {
          	e.stopPropagation();
          } else {
          	window.event.cancelBubble = true;	
          }

          用法:

          <body>
          	<div class="father">
          		<div class="son">son兒子</div>
          	</div>
          	<script>
          		//常見事件對(duì)象的屬性和方法
          		//阻止冒泡 dom 推薦的標(biāo)準(zhǔn) stopPropagation()
          		var son = document.querySelector('.son');
          		son.addEventListener('click', function(e) {
          		alert('son');
          		e.stopPropagation();//停止傳播
          		e.canselBubble = true;//非標(biāo)準(zhǔn) 取消泡泡
          },false);
          var father = document.querySelector('.father');
          father.addEventListener('click', function() {
          	alert('father');	
          },false);
          document.addEventListener('click', function() {
          	alert('document');
          }
          	</script>
          </body>

          事件委托

          事件委托也稱為事件代理,在jQuery里面稱為事件委派。

          事件委托的原理

          不是每個(gè)子節(jié)點(diǎn)單獨(dú)設(shè)置事件監(jiān)聽器,而是事件監(jiān)聽器在其父節(jié)點(diǎn)上,然后利用冒泡原理影響設(shè)置每個(gè)子節(jié)點(diǎn)。

          比如,給ul注冊(cè)點(diǎn)擊事件,然后利用事件對(duì)象的target來找到當(dāng)前點(diǎn)擊的li,因?yàn)辄c(diǎn)擊li,事件會(huì)冒泡到ul上,ul有注冊(cè)事件,就會(huì)觸發(fā)事件監(jiān)聽器。

          事件委托的作用

          我們只操作了依次DOM,提高了程序的性能。

          <body>
          	<ul>
          		<li>2333</li>
          		<li>2333</li>
          		<li>2333</li>
          		<li>2333</li>
          	</ul>
          	<script>
          		//事件委托的核心原理:給父節(jié)點(diǎn)添加監(jiān)聽器,
          		//利用事件冒泡影響每一個(gè)子節(jié)點(diǎn)。
          		var ul = document.querySelector('ul');
          		ul.addEventListener('click', function(e) {
          			//alert('2333');
          			//e.target 可以得到我們點(diǎn)擊的對(duì)象
          			e.target.style.backgroundColor = 'pink';
          		})
          	</script>
          </body>

          鼠標(biāo)事件對(duì)象

          event對(duì)象代表事件的狀態(tài),跟事件相關(guān)的一系列信息的集合。現(xiàn)階段我們主要是用鼠標(biāo)事件對(duì)象mouseevent和鍵盤事件對(duì)象keyboardevent。


          <style>
          	img {
          		position: absolute;
          		top: 2px;
          	}
          </style>
          <body>
          	<img src=''>
          	<script>
          		var pic = document.querySelector('img');
          		document.addEventListener('mousemove', function(e) {
          		var x = e.pageX;
          		var y = e.pageY;
          		console.log(x, y);//輸出x 和 y坐標(biāo)
          		//千萬不要忘記給left和top添加px單位!
          		pic.style.left = x + 'px';
          		pic.style.top = y + 'px';
          		});
          	</script>
          </body>

          常用的鍵盤事件

          注意:

          1,如果使用addEventListener,就不需要加on

          2,三個(gè)事件的執(zhí)行順序是: keydown-keypress-keyup


          鍵盤事件對(duì)象


          注意:onkeydown和onkeyup不區(qū)分字母大小寫,onkeypress區(qū)分字母大小寫。

          在我們實(shí)際開發(fā)中,我們更多的使用keydown和keyup,它能識(shí)別所有的鍵(包括功能鍵)

          Keypress不識(shí)別功能鍵,但是keyCode屬性能區(qū)分大小寫,返回不同的ASCII值。

          注意:keydown和keyup在文本框里面的特點(diǎn):他們兩個(gè)事件觸發(fā)的時(shí)候,文字還沒有落入文本框中。keyup事件觸發(fā)的時(shí)候,文字已經(jīng)落入文本框里面了。因?yàn)殒I已經(jīng)松開了。

          案例:按下s鍵,搜索框獲得焦點(diǎn)

          <body>
          	<input type="text">
          	<script>
          		//核心思路:檢測(cè)用戶是否按下了s鍵。
          		//如果按下了s鍵,就把光標(biāo)定位到搜索框里面。
          		//使用鍵盤事件對(duì)象里面的keyCode,
          		//判斷用戶按下的是否是s鍵。
          		//搜索框獲得焦點(diǎn):使用js里面的focus()方法
          		var sch = document.querySelector('input');
          		document.addEventListener('keyup', function(e) {
          			if(e.keyCode == 83) {
          				sch.focus();
          			}
          		})
          	</script>
          </body>

          --------------------DOM---end------------------------

          BOM瀏覽器對(duì)象模型

          什么是BOM?

          BOM(Brower Object Model)即瀏覽器對(duì)象模型。它提供了獨(dú)立于內(nèi)容而與瀏覽器窗口進(jìn)行交互的對(duì)象,其核心對(duì)象是window 。

          BOM由一系列相關(guān)的對(duì)象構(gòu)成,并且每個(gè)對(duì)象都提供了很多方法和屬性。

          BOM缺乏標(biāo)準(zhǔn),JS語法的標(biāo)準(zhǔn)化阻止是ECMA,DOM的標(biāo)準(zhǔn)化組織是W3C,BOM最初是Netscape(就是網(wǎng)景公司)瀏覽器標(biāo)準(zhǔn)的一部分。

          BOM構(gòu)成

          BOM比DOM更大,它包含DOM。

          window對(duì)象是瀏覽器的頂級(jí)對(duì)象。它具有雙重角色。

          1,它是JS訪問瀏覽器窗口的一個(gè)接口。

          2,它是一個(gè)全局對(duì)象。定于在全局作用域中的變量和函數(shù)都會(huì)變成window對(duì)象的屬性和方法。

          在調(diào)用的時(shí)候可以省略window,前面學(xué)習(xí)的對(duì)話框都屬于window對(duì)象方法,比如alert() ,prompt()等。

          注意:window下的一個(gè)特殊屬性 window.name

          window對(duì)象的常用事件

          窗口加載事件

          這樣就可以把js放在任何一個(gè)地方了,js代碼都會(huì)執(zhí)行了。

          window.onload = function() { }
          或者
          window.addEventListener('load', function() { })(推薦使用,因?yàn)闆]有次數(shù)限制)

          window.onload是窗口(頁(yè)面)加載事件,當(dāng)文檔內(nèi)容完全加載完成時(shí)會(huì)觸發(fā)該事件(包括圖像,腳本文件,css文件等),就會(huì)調(diào)用處理函數(shù)。

          注意:

          1,有了window.onload就闊以把JS代碼寫在頁(yè)面元素的上方,因?yàn)閛nload是等頁(yè)面內(nèi)容全部加載完畢,再去執(zhí)行處理函數(shù)的。

          2,window.onload傳統(tǒng)注冊(cè)事件方式只能寫一次,如果有多個(gè),會(huì)以最后一個(gè)window.onload為準(zhǔn)。

          3,如果使用window.addEventListener則沒有限制。

          另一種情況:(加載較慢的情況)

          document.addEventListener('DOMContenLoaded', function() { })

          DOMContentLoaded事件觸發(fā)時(shí),僅當(dāng)DOM加載完成時(shí),不包括樣式表,圖片,flash等等。

          IE9以上才支持。

          如果頁(yè)面的圖片很多的話,從用戶訪問到onload觸發(fā)可能需要較長(zhǎng)的事件,交互效果就不能實(shí)現(xiàn),必然影響用戶的體驗(yàn),此時(shí)用DOMContentLoaded事件比較合適。

          調(diào)整窗口大小事件

          window.onresize = function() {}
          window.addEventListener('resize', function() {})

          window.onresize是調(diào)整窗口大小加載事件,當(dāng)觸發(fā)時(shí)就調(diào)用的處理函數(shù)。注意:1,只要窗口大小發(fā)生像素變化,就會(huì)觸發(fā)這個(gè)事件。2,我們經(jīng)常利用這個(gè)事件完成響應(yīng)式布局。window.innerWidth是當(dāng)前屏幕的寬度。

          兩種定時(shí)器

          第一種定時(shí)器:setTimeout()定時(shí)器

          window.setTimeout(調(diào)用函數(shù),延遲的毫秒數(shù));

          setTimeout()方法用于設(shè)置一個(gè)定時(shí)器,該定時(shí)器在定時(shí)器到期后執(zhí)行調(diào)用函數(shù)。

          注意:

          1,window可以省略。

          2,這個(gè)調(diào)用函數(shù)可以直接寫函數(shù),或者寫函數(shù)名, 或者 '函數(shù)名()'三種形式。但是不推薦最后一種寫法。

          3,延遲的毫秒數(shù)可以省略,默認(rèn)是0,如果寫,必須是毫秒數(shù)。不需要帶單位。

          4,因?yàn)槎〞r(shí)器可能有很多,所以我們經(jīng)常給定時(shí)器賦值一個(gè)標(biāo)識(shí)符。

          //語法規(guī)范: window.setTimeout(調(diào)用函數(shù),延遲時(shí)間);
          //setTimeout(function() {
          //	console.log('午時(shí)已到');
          //}, 2000);
          function callback() {
          	console.log('立即斬首');
          }
          setTimeout(callback, 3000);

          回調(diào)函數(shù) callback

          window.setTimeout(調(diào)用函數(shù),延遲的毫秒數(shù));

          setTimeout()這個(gè)調(diào)用函數(shù),我們也稱為回調(diào)函數(shù)callback。

          普通函數(shù)是按照代碼順序直接調(diào)用。

          而這個(gè)函數(shù),需要等待時(shí)間,時(shí)間到了才能取調(diào)用這個(gè)函數(shù),因此我們稱為回調(diào)函數(shù)。

          簡(jiǎn)單理解:回調(diào),就是回頭調(diào)用的意思。上一件事干完,再回頭調(diào)用這個(gè)函數(shù)。

          以前講的element.onclick = function() {}或者element.addEventListener(‘click’, fn);里面的函數(shù)也是回調(diào)函數(shù)。

          停止定時(shí)器(讓定時(shí)器停下來,別執(zhí)行函數(shù)里的程序了)

          clearTimeout(定時(shí)器名字);

          window.clearTimeout(timeout ID)

          注意:1,window可以省略。2,里面的參數(shù)就是定時(shí)器的標(biāo)識(shí)符。

          第二種定時(shí)器 setInterval()

          window.setInterval(回調(diào)函數(shù),間隔的毫秒數(shù));

          setInterval()方法重復(fù)調(diào)用一個(gè)函數(shù),每隔這個(gè)時(shí)間,就去調(diào)用一次回調(diào)函數(shù)。

          這是與setTimeout()最大的不同。setTimeout()定時(shí)器只調(diào)用一次回調(diào)函數(shù)。

          注意:

          1,window可以省略。

          2,這個(gè)調(diào)用函數(shù)可以直接寫函數(shù),或者函數(shù)名或者采用字符串 ’ 函數(shù)名() ’ 三種形式。

          3,間隔的毫秒數(shù)可以省略,默認(rèn)是0,如果寫,必須是毫秒數(shù),不用帶單位。

          4,因?yàn)槎〞r(shí)器可能有很多,所以我們經(jīng)常給定時(shí)器賦值一個(gè)標(biāo)識(shí)符。

          案例:自動(dòng)倒計(jì)時(shí)

          <body>
          	<div>
          		<span class="hour">1</span>
          		<span class="minute">2</span>
          		<span class="second">3</span>
          	</div>
          	<script>
          		//1,獲取元素
          		var hour = document.querySelector('.hour');
          		var minute = document.querySelector('.minute');
          		var second = document.querySelector('.second');
          		var inputTime = +new Date('2019-5-1 18:00:00');//用戶輸入時(shí)間總的毫秒數(shù)
          		countDown();//現(xiàn)調(diào)用一次函數(shù),防止第一次刷新頁(yè)面出現(xiàn)空白
          		//2,開啟定時(shí)器
          		setInterval(countDown, 1000);
          		function countDown() {
          			var nowTime = +new Date();
          			//返回的是當(dāng)前時(shí)間總的毫秒數(shù)
          			var times = (inputTime - nowTime) / 1000;
          			//times是剩余需要倒計(jì)時(shí)的總的秒數(shù)
          			var h = parseInt(times / 60 / 60 / % 24);//小時(shí)
          			h = h < 10 ? '0' + h: h;
          			//格式搞的好看一點(diǎn)
          			hour.innerHTML = h ;
          			//把倒計(jì)時(shí)的小時(shí)數(shù)給小時(shí)盒子
          			var m = parseInt(times / 60 % 60);//分鐘
          			m = m < 10 ? '0' + m: m;
          			minute.innerHTML = m;
          			var s = parseInt(times % 60);//秒
          			s = s < 10 ? '0' + s: s;
          			second.innerHTML = s;
          		}
          	</script>
          </body>

          案例:發(fā)送短信驗(yàn)證


          JS執(zhí)行機(jī)制

          JS是單線程:同一時(shí)間只做一件事。代碼是從上到下一行一行的執(zhí)行。

          同步和異步: 最新的js可以創(chuàng)建多個(gè)任務(wù)了。

          為了解決這個(gè)問題,利用多核CPU的計(jì)算能力,HTML5提出Web Worker 標(biāo)準(zhǔn),允許JS腳本創(chuàng)建多個(gè)線程。于是,JS中 出現(xiàn)了同步和異步。

          同步

          前一個(gè)任務(wù)結(jié)束后再執(zhí)行后一個(gè)任務(wù),程序的執(zhí)行順序與任務(wù)排列順序是一直的,同步的。比如做飯的同步做法:我們要燒水煮飯,等水開了(10分鐘后),再去切菜,炒菜。

          異步

          在做一件事情時(shí),因?yàn)檫@件事情會(huì)話費(fèi)很長(zhǎng)時(shí)間。在做這件事情的同時(shí),還可以去處理其他事情。比如做飯的異步做法,在燒開水的同時(shí),利用這10分鐘,去切菜,炒菜。

          同步任務(wù)

          同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行線。

          異步任務(wù)

          JS的異步是通過回調(diào)函數(shù)實(shí)現(xiàn)的。 一般而言,異步任務(wù)有以下三種類型: 1,普通事件,如click,resize等 2,資源加載,如load,error等 3,定時(shí)器,包括setTimeout,setInterval等。

          異步任務(wù)相關(guān)回調(diào)函數(shù)添加到任務(wù)隊(duì)列中,任務(wù)隊(duì)列也稱為消息隊(duì)列。

          執(zhí)行機(jī)制:任務(wù)分成同步任務(wù)和異步任務(wù)。先執(zhí)行完同步任務(wù),再去執(zhí)行異步任務(wù)。

          1,先執(zhí)行執(zhí)行棧中的同步任務(wù)。

          2,異步任務(wù)(回調(diào)函數(shù))放入任務(wù)隊(duì)列中。

          3,一旦執(zhí)行棧中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)按照次序讀取任務(wù)隊(duì)列中的異步任務(wù),于是被讀取的異步任務(wù)結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。

          由于主線程不斷的重復(fù)獲得任務(wù)、執(zhí)行任務(wù)、再獲取任務(wù)、再執(zhí)行,所以這種機(jī)制被稱為事件循環(huán)(event loop)。

          location對(duì)象

          URL

          統(tǒng)一資源定位符(Uniform Resource Locator,URL)是互聯(lián)網(wǎng)上標(biāo)準(zhǔn)資源的地址。互聯(lián)網(wǎng)上的每個(gè)文件都有一個(gè)唯一的URL,它包含的信息指出文件的位置以及瀏覽器應(yīng)該怎么處理它。

          URL的一般語法格式為:

          protocol://host[:port]/path/[?query]#fragment
          如:
          http://www.itcast.cn/index.html?name=andy&age=18#link


          location對(duì)象的屬性

          案例:獲取URL參數(shù)數(shù)據(jù):數(shù)據(jù)在不同網(wǎng)頁(yè)中傳遞

          第一個(gè)頁(yè)面:輸入信息的界面

          <body>
          	<form action="index.html">
          		用戶名:<input type="text" name="uname">
          		<input type="submit" value="登錄" />
          	</form>
          </body>

          第二個(gè)頁(yè)面:接收信息的界面

          <body>
          	<div></div>
          	<script>
          		console.log(location.search);//?uname=andy
          		//1,先去掉? substr('起始位置', 截取幾個(gè)字符);
          		var params = location.search.substr(1);//uname=andy
          		//2,利用 = 號(hào)把字符串分割為數(shù)組 split('=');
          		var arr = params.split('=');
          		console.log(arr);//["uname", "ANDY"]
          		var div = document.querySelector('div');
          		//3,把數(shù)據(jù)寫入div中
          		div.innerHTML = arr[1] + "歡迎您";
          	</script>
          </body>

          location對(duì)象的方法

          navigator對(duì)象:知道用戶用了什么瀏覽器

          navigator對(duì)象包含有關(guān)瀏覽器的信息,它有很多屬性,我們最常用的是userAgent,該屬性可以返回由客戶機(jī)發(fā)送服務(wù)器的user-agent頭部的值。

          下面前端代碼可以判斷用戶哪個(gè)中斷打開的頁(yè)面,實(shí)現(xiàn)跳轉(zhuǎn):

          if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobild|BlackBerry|IEMobild|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
          window.location.href = ""; //手機(jī)
          } else {
          	window.location.href = ""; //電腦
          }
          //把這個(gè)代碼賦值到<script></script>里面就闊以了。
          //要查哪個(gè)網(wǎng)頁(yè)地址,就把地址補(bǔ)齊到href里。

          window對(duì)象給我們提供了一個(gè)history對(duì)象,與瀏覽器歷史紀(jì)錄進(jìn)行交互。該對(duì)象包含用戶(在瀏覽器窗口中)訪問過的URL。

          history.back();history.forward();history.go(1);

          PC網(wǎng)頁(yè)端特效

          知識(shí)點(diǎn):

          1. offset
          2. client
          3. scroll
          4. 封裝簡(jiǎn)單動(dòng)畫函數(shù)
          5. 網(wǎng)頁(yè)輪播圖

          offset系列屬性

          offset翻譯過來就是偏移量,我們使用offset系列相關(guān)屬性可以動(dòng)態(tài)的得到該元素的位置(偏移)、大小等。

          • 獲得元素舉例帶有定位父元素的位置
          • 獲得元素自身的大小(寬度高度)
          • 注意:返回的數(shù)值都不帶單位

          offset系列常用屬性:

          offset翻譯過來就是偏移量,我們使用offset系列相關(guān)屬性可以動(dòng)態(tài)的得到該元素的位置(偏移)、大小等。

          • 獲得元素舉例帶有定位父元素的位置
          • 獲得元素自身的大小(寬度高度)
          • 注意:返回的數(shù)值都不帶單位

          offset系列常用屬性:


          只有上和左,沒有下和右。

          offset和style的區(qū)別

          案例:獲取鼠標(biāo)在盒子內(nèi)的動(dòng)態(tài)位置

          ![在這里插入圖片描述](https://img-blog.csdnimg.cn/20200427005033196.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3R1emkwMDdh,size_16,color_FFFFFF,t_70)

          元素可視區(qū)client系列

          client翻譯過來就是客戶端,我們使用client系列的相關(guān)屬性來獲取元素在可視區(qū)的相關(guān)信息。通過client系列的相關(guān)屬性可以動(dòng)態(tài)的得到該元素的邊框大小、元素大小等。

          注意和offset的區(qū)別。clientWidth是不含邊框的。

          立即執(zhí)行函數(shù)

          <body>
          	<script>
          		//1,立即執(zhí)行函數(shù):不需要調(diào)用,立馬能夠子級(jí)執(zhí)行的函數(shù)
          		function fn() {
          			console.log(1);
          		}
          		fn();
          		//2,寫法也可以傳遞參數(shù)進(jìn)來
          		//(function() {})()或者(function() {}())
          		(function(a, b) {
          			console.log(a + b);
          			var num = 10;
          		})(1, 2);//第二個(gè)小括號(hào)可以看作是調(diào)用函數(shù)
          		(function sun(a, b) {
          			console.log(a + b);
          			var num = 10;//局部變量
          		}(2, 3));
          		//3,立即執(zhí)行函數(shù)最大的作用就是 獨(dú)立創(chuàng)建了一個(gè)作用域,
          		//里面所有的變量都是局部變量,不會(huì)右命名沖突的情況。
          	</script>
          </body>

          元素滾動(dòng)scroll系列

          scroll翻譯過來就是滾動(dòng)的,我們使用scroll系列的相關(guān)屬性可以動(dòng)態(tài)的得到該元素的大小、滾動(dòng)距離等。


          常用的是 element.scrollTop和element.scrollLeft。

          window.pageXOffset 和 window.pageYOffset屬性,返回文檔在窗口左上角水平和垂直方向滾動(dòng)的像素。

          pageXOffset設(shè)置或返回當(dāng)前網(wǎng)頁(yè)相對(duì)于窗口顯示區(qū)左上角的X位置。pageYOffset設(shè)置或返回當(dāng)前頁(yè)面相對(duì)于窗口顯示區(qū)左上角的Y位置。

          pageXOffset 和pageYOffset屬性相當(dāng)于scrollX和scrollY屬性。

          這些屬性是只讀的。

          頁(yè)面被卷去 的頭部兼容性解決方案

          需要注意的是,頁(yè)面被卷去的頭部,有兼容性問題,因此被卷去的頭部通常有如下幾種寫法:

          1. 聲明了DTD,使用document.documentElement.scrollTop
          2. 未聲明DTD,使用document.body.scrollTop
          3. 新方法window.pageYOffset和window.pageXOffset , IE9開始支持。
          function getScroll() {
          	return {
          	left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0,
          	top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0,
          	}
          }
          //使用的時(shí)候 
          getScroll().left

          動(dòng)畫函數(shù)封裝

          動(dòng)畫實(shí)現(xiàn)原理:

          實(shí)現(xiàn)步驟:

          1. 獲得盒子當(dāng)前的位置
          2. 讓盒子在當(dāng)前位置加上1個(gè)移動(dòng)距離
          3. 利用定時(shí)器不斷重復(fù)這個(gè)操作
          4. 加一個(gè)結(jié)束定時(shí)器的條件
          5. 注意:此元素需要添加定位,才能使用element.style.left
            因?yàn)橐尯凶用撾x標(biāo)準(zhǔn)流,所以要添加定位。
            函數(shù)封裝:
          <script>
          	//簡(jiǎn)單動(dòng)畫函數(shù)封裝obj目標(biāo)對(duì)象 target 目標(biāo)位置
          	function animate(obj, target) {
          		var timer = setInterval(function() {
          			if (obj.offsetLeft >= target) {
          			//運(yùn)動(dòng)到一定距離,就停止計(jì)時(shí)器
          				clearInterval(timer);
          			}
          			obj.style.left = obj.offsetLeft + 1 + 'px';
          		}, 200);
          	}
          	var div = document.querySelector('div');
          	//調(diào)用函數(shù)
          	animate(div, 300);
          </script>

          動(dòng)畫函數(shù)給不同元素記錄不同定時(shí)器

          如果多個(gè)元素都使用這個(gè)動(dòng)畫函數(shù),每次都要var聲明定時(shí)器。我們可以給不同元素使用不同的定時(shí)器(自己專門用自己的定時(shí)器)


          核心原理:利用JS是一門動(dòng)態(tài)語言,可以很方便的給當(dāng)前對(duì)象添加屬性。

          <script>
          	//var obj = {};
          	//obj.name = 'andy';
          	//簡(jiǎn)單動(dòng)畫函數(shù)封裝obj是目標(biāo)對(duì)象 target 是目標(biāo)位置
          	//給不同的元素指定了不同的定時(shí)器
          	function animate(obj, target) {
          		obj.timer = setInterval(function() {
          			if(obj.offsetLeft >= target) {
          				clearInterval(obj.timer);
          			}
          				obj.style.left = obj.offsetLeft + 1 + 'px';
          		}, 200);
          	}
          	var div = document.querySelector('div');
          	var span = document.querySelector('span');
          	//調(diào)用函數(shù)
          	animate(div,300);
          	animate(span, 200);
          </script>

          改進(jìn)版:

          <script>
          	//當(dāng)我們不斷的點(diǎn)擊按鈕,這個(gè)元素的速度會(huì)越來越快,因?yàn)殚_啟了太多的定時(shí)器
          	//解決方案就是 讓我們?cè)刂挥幸粋€(gè)定時(shí)器執(zhí)行
          	//先清除以前的定時(shí)器,只保留當(dāng)前一個(gè)定時(shí)器執(zhí)行
          	clearInterval(obj.timer);
          	function animate(obj, target) {
          		obj.timer = setInterval(function() {
          			if(obj.offsetLeft >= target) {
          				clearInterval(obj.timer);
          			}
          				obj.style.left = obj.offsetLeft + 1 + 'px';
          		}, 200);
          	}
          	var div = document.querySelector('div');
          	var span = document.querySelector('span');
          	//調(diào)用函數(shù)
          	animate(div,300);
          	animate(span, 200);
          </script>

          案例:淘寶網(wǎng)頁(yè)輪播圖,也叫焦點(diǎn)圖

          節(jié)流閥

          防止輪播圖按鈕連續(xù)點(diǎn)擊造成播放過快。


          節(jié)流閥目的:當(dāng) 上一個(gè)函數(shù)動(dòng)畫內(nèi)容執(zhí)行完畢,再去執(zhí)行下一個(gè)函數(shù)動(dòng)畫,讓事件無法連續(xù)觸發(fā)。


          核心思路:利用回調(diào)函數(shù),添加要給變量來控制,鎖住函數(shù)和解鎖函數(shù)。

          //開始設(shè)置一個(gè)變量 
          var flag = true;
          if(flag) {
          	flag = false;
          	do something...//關(guān)閉水龍頭
          }
          //利用回調(diào)函數(shù),動(dòng)畫執(zhí)行完畢后,
          flag = true;//打開水龍頭

          案例:淘寶側(cè)邊欄的返回頂部

          window.scroll(x,y) 整個(gè)窗口滾動(dòng)到文檔中的特定位置。

          x是距離文檔左邊的距離,y是距離文檔頂部的距離。x和y都不帶單位。


          主站蜘蛛池模板: 精品亚洲AV无码一区二区三区| 一区二区三区免费精品视频 | 久久婷婷久久一区二区三区| 国产成人亚洲综合一区| 国产一区二区三区精品久久呦| 无码囯产精品一区二区免费| 久99精品视频在线观看婷亚洲片国产一区一级在线 | 在线播放一区二区| 国内偷窥一区二区三区视频| 琪琪see色原网一区二区| 精品国产一区二区三区久| 亚洲日韩一区精品射精| 亚洲av乱码一区二区三区| 福利一区二区三区视频在线观看| 精品国产一区二区三区2021| 国产中文字幕一区| 国产综合精品一区二区| 正在播放国产一区| 午夜一区二区免费视频| 国产在线一区观看| 国产亚洲综合精品一区二区三区| 国产精品视频一区国模私拍| 色一情一乱一伦一区二区三欧美| 亚洲AV日韩综合一区尤物| 亚洲一区二区三区高清不卡 | 国产综合无码一区二区色蜜蜜| 国产精品99精品一区二区三区| 亚洲av色香蕉一区二区三区| 怡红院一区二区三区| 国产一区二区在线观看麻豆| 国产精品乱码一区二区三区 | 呦系列视频一区二区三区| 国产一区二区在线观看| 国产精品一区不卡| 中文字幕在线无码一区| 亚洲爆乳精品无码一区二区三区| 91精品一区二区综合在线| 亚洲av无码一区二区三区天堂| 日本精品视频一区二区三区| 成人国内精品久久久久一区| 亚洲av福利无码无一区二区|