1.for in
對象中有多少組鍵值對,我們的FOR IN 循環就遍歷多少次(不一定)
每一次循環KEY這個變量存儲的都是當前循環這組鍵對值的屬性名
1、KEY存儲的值都是字符串格式的(不管屬性名是否為數字)
2、在FOR IN 循環遍歷的時候,大部分瀏覽器都是先把對象中的鍵值對進行排序(把數字屬性名的排在前面,并且排列的時候按照數字由小到大排列),其次再把非數字的屬性名按照之前編寫的順序排列,循環的時候按照重新排列的順序依次遍歷(小數算作字母不算作數字)for (var key in obj) {
console.log(typeof key) "string"
console.log(obj.key)
console.log(obj[key]);每一次循環把key變量存儲的值(當前遍歷的屬性名)獲取到放在中括號中,獲取OBJ對應屬性的屬性值
'key':字符串key
key:變量key,代表的是存儲的值
}obj['key'] obj.key 屬性名是key
obj[key] 屬性名不是key 而是key變量存儲的值
復制代碼
2. 數據類型轉換
2.1 把其他數據類型轉換為number類型
A) isNaN 、Number、parseInt、parseFloat
true --> 1 false --> 0 '' --> 0 '12'-->12 '12px' --> NaN/12 '帥哥' --> NaN
null --> 0 undefined --> NaN
{} /$/ function() {} --> NaN
[]
通過toString方法把數組轉化為字符串,然后再調用Number把字符串轉換為數字
[] --> '' -->0 [12] --> '12' -->12 [12,23] --> '12,23' --> NaNB)在進行加減乘除數學運算的時候
1、加減乘除
2、除了加法有特殊性,其余的運算符都是數學運算,也就是遇到非數字類型,需要把其轉換為number再進行運算
1- '1' = 0 10 * null = 0 10/undefined = NaN . 10 * [10] = 100
加法的特殊性:
在遇到字符串的時候 + 不是數學運算 而是字符串拼接 只要不遇到字符串就是數學運算
1+ '1' = '11' null + '1' = 'null1'
字符串拼接:把其他值轉為字符串然后再拼接 (toString)
其他數據類型的toString是直接把值用單(雙)引號包起來即可,只有對象的有特殊性,對象.toString =' [object object]'
(1).toString --> '1' (true).toString ---> "true" null undefined 都有toString() 方法 但是瀏覽器不讓用
[12,23].toString() "12,23" /^$/.toString() "/^$/" (function() {}).toString() "function() {}"
({name:"hou"}).toString() "[object object]"1+ null + undefined + [] +'hou' + null + undefined + [] + 101 +null ---> 1 1 + true --->2 2 + undefined ---> NaN
NaN + [] --->NaN + '' --->"NaN"
"NaN" + 'hou' + 'null' + 'undefined' + '' + '10'---> "NaNhounullundefined10"復制代碼
2.2 將其他數據類型轉換為布爾類型
Boolean ! !!
條件判斷,也是轉換為布爾類型,然后判斷真假
只有 0 NaN null undefined 空字符串 五個轉換為false 其余都是true
[] ---> true -1 ---> trueif (box) {首先把box 變量存儲的值獲取到,轉化為布爾類型,如果轉化為true條件成立 反之不成立
}if(3 +'3px') {
}if(3- '3px') {
}
復制代碼
2.3 使用"=="進行比較
在使用"=="進行比較的時候,如果左右兩邊數據類型不相同,瀏覽器會默認轉換為相同的類型,然后再比較("==="不會這樣操作)
對象和對象:比較的是空間地址,不是相同的空間,結果肯定是false
[] == [] false var a = {} var b = a ; a==b true
對象和數字:把對象轉換為數字
[] == 0 true
({}) == NaN false NaN和自己不相等和其他任何值都不相等
對象和字符串:把兩邊都轉換為數字比較的
[] == '' true
對象和布爾:把兩邊都轉換為數字
[] == true 0==1 false
[] == false 0 ==0 true
![] == false --> 把數組變為布爾再取反 = false --> false == false --> true字符串和數字:字符串轉換為數字
字符串和布爾:都轉化為數字
布爾和數字: 布爾轉換為數字規律:兩個等于號比較,左右兩邊數據值的類型不一樣,瀏覽器會把兩邊的類型都轉換為數字然后再比較,但是null 和undefined除外
null == undefined --> true
null === undefined ---> false
null以及undefined 和其他任何值都不相等
復制代碼
3.Math中的常用方法:
數學函數:但是它是對象數據類型的 typeof Math 'object'
Math對象中給我們提供了很多常用操作數字的方法
abs 取絕對值
ceil 向上取整
floor 向下取整
round 四舍五入 Math.round(12.3) -->12 Math(12.5) ---> 13 正數中5包含在向上
Math.round(-12.3) ---> -12 Math.round(-12.5) ---> -12 負數5 包含在向下 Math.round(-12.51) -13
random 獲取[0,1)之間的隨機小數 很難獲取到0
獲取[0,10]之間的隨機整數 Math.round(Math.random()*10)
獲取[3,15]之間的隨機整數 Math.round(Math.random()*12 + 3)
獲取[n,m]之間的隨機整數 Math.round(Math.random()*(m-n) + n)
max/min 獲取一組值中的最大值和最小值
PI 獲取圓周率
pow 獲取一個值的多少次冪 Math.pow(10,2) --> 100
sqrt 開平方 Math.sqrt(100) ---> 10
復制代碼
4.字符串常用方法:
Jstr.charAt(索引):返回指定索引位置的字符,和str[索引]的區別在于,當指定的索引不存在的時候,中括號的方式獲取的是undefined,而charAt獲取的是空字符串
str.charCodeAt(索引):在charAt基礎上,把獲取的字符變為unicode編碼值(對應ASCII碼表)
48-57: 0-9
65-90: A-Z
97-122: a-z
str.fromCharCode(十進制的unicode值):把值按照ASCII碼表中的信息,轉換為原有的字符,和charCodeAt正好對應
substr && substring && slice
實現字符串截取的三個辦法
str.substr(n,m):從索引n開始 截取m個字符
str.substring(n,m):從索引n開始,截取到索引為m處(不包含m 即 m-1)把找到的部分截取
str.slice(n,m):和substring語法一樣,區別在于slice支持以負數做索引
當索引是負數的時候,瀏覽器在處理的時候,是用字符串的總長度加上負數索引,然后按照正數處理操作
str.slice(-7,-3) ===> str.slice(str.length-7,str.length-3)
細節:
1、如果只傳遞了n(str.substr(n)/str.substring(n)),相當于從索引n開始一直截取到字符串的末尾
2、如果傳遞的索引超出最大限制,也是把能截取的部分截取掉即可
3、如果一個參數都不傳遞,相當于把整個字符串都截取(字符串的克隆)
str.toUpperCase:把字母全局大寫
str.toLowerCase:把字母全局小寫
indexOf && lastIndexOf
str.indexOf:獲取當前字符在字符串中第一次出現位置的索引
str.lastIndexOf:獲取的是當前字符最后一次出現位置的索引
如果當前字符在字符串中沒有出現過,結果是-1 :我們根據這個規律可以驗證一下當前字符串是否包含某個字符
if(str.indexOf('?') === -1) {
}if(str.indexOf('?') >=0) {
}
str.split:按照某一個字符把字符串拆分成數組中的某一項,和數組的join方法是對應的
var str = 'name=shuaige&age=8'
str.split('=')
["name","shuaige&age","8"]
str.split(/=|&/g);
["name","shuaige","age","8"]
str.split('')
["n", "a", "m", "e", "=", "s", "h", "u", "a", "i", "g", "e", "&", "a", "g", "e", "=", "8"]
str.split(' ') 不太一樣 后邊這個有空格 ["name=shuaige&age=8"]
var ary = [12,34,32]
ary.join('+') "12+34+32"
"12+34+32".split('+') ==> ["12","34","32"] ary 的元素是數字 變成了字符串
str.replace:實現字符的替換
執行一次replace 只能替換一次 如果我們有好幾個需要替換,在不使用正則的情況下我們需要執行很多次replace
有些需求即使執行很多次replace也實現不了,此時需要使用正則處理,真實項目中replace一般都是和正則搭配使用的
trim && trimLeft && trimRight
str.trimLeft:去除字符串開始的空格
str.trimRight:去除字符串結尾的空格
str.trim:去除字符串首尾的空格字符串應用之queryURLParameter
var url = "https://www.baidu.com/s?wd=node&rsv_spt=1&issp=1"
目標:把問號傳遞的參數值分別的解析出來
var obj ={wd:'javascript',rsv_spt:1,issp:1}
方案一:
function queryURLParameter(url) {var quesIndex = url.indexOf('?')var obj = {};if(quesIndex === -1) {return obj;}url = url.substr(quesIndex+1);var ary = url.split('&');for(var i = 0; i < ary.length; i++) {var curAry = ary[i].split('='); obj[curAry[0]] = curAry[1];}return obj;
}方案二:待分析
String.prototype.myQueryURLParameter = function myQueryURLParameter() {var obj = {},reg = /([^=?&]+)=([^=?&]+)/g;this.replace(reg,function() {var arg = arguments;obj[arg[1]] = arg[2];});return obj;
}真實項目中的驗證碼:
真實項目中的驗證碼一般都是后臺處理的,后臺返回給客戶端展示的是一個圖片(圖片中包含了驗證碼)
1、字母+ 數字
2、問答
3、12306 選擇圖片
4、成語填空
5、圖片拼圖
6、滑動拖拽letter-spacing:5px 文本字體之間的間距
cursor:pointer;
函數操作
var codeBox = document.getElementById('codeBox');
==>生成4位隨機驗證碼
var areaStr = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
var result = '';
for(var i = 0; i < 4; i++) {var ran = Math.round(Math.random()*61);var char = areaStr.charAt(ran);if(result.toLowerCase().indexOf(char.toLowerCase())>-1) {i--; continue;}result+=char;
}
codeBox.innerHTML = result;點擊盒子生成4個隨機驗證碼
function queryCode() {.....codeBox.onclick = queryCode;禁止用戶選中文字 ==》-webkit-user-select: none
復制代碼
5.節點操作
DOM: document object model 文檔對象模型,提供一些屬性和方法可以讓我們去操作DOM元素
獲取DOM元素的方法
document.getElementById 一個元素對象
[context].getElementsByTagName 元素集合
[context].getElementsByClassName 通過元素類名獲取元素集合
document.getElementsByName 通過name屬性值獲取節點集合
document ===>說明上下文不能發生變化
[context] ===> 說明上下文可以發生變化
document.documentElement 獲取整個HTML對象
document.body 獲取整個BODY對象
document.head 獲取整個HEAD對象
[context].querySelector 通過選擇器獲取一個元素對象
[context].querySelectorAll 通過選擇器獲取元素集合getElementById ==> 此方法的上下文只能是document
一個HTML頁面中元素的ID理論上是不能重復的
1、如果頁面中的ID重復了,我們獲取的結果是第一個ID對應的元素對象
2、在IE7及更低版本瀏覽器中,會把表單元素的name值當作id來識別使用(項目中盡量不要讓表單的name和其他元素的id相同)
3、如果我們把JS放在結構的下面,我們可以直接使用ID值來獲取這個元素(不需要通過getElementsById獲取),而且這種方式會把頁面中所有ID是他的元素都獲取到(元素對象/元素集合) ===> 不推薦
獲取頁面中ID值為#box1的所有元素標簽
var allList = document.getElementsByTagName('*');
var result = [];
for(var i = 0 ; i < allList.length; i ++) {
var item = allList[i];
item.id === 'box1' ? result.push(item):null;
}getElementsByTagName
上下文可以自己來指定
獲取到的結果是一個元素集合(類數組集合)
1、獲取的結果是集合,哪怕集合中只有一項,我們想要操作這一項(元素對象),需要先從集合中獲取出來,然后再操作
var bodyBox = document.getElementsByTagName('body');
bodyBox[0].getElementsByTagName('div');
2、在指定的上下文中,獲取所有子子孫孫元素中標簽名叫做這個的(后代篩選)getElementsByClassName
上下文也可以隨意指定
獲取的結果也是一個元素集合(類數組集合)
1、真實項目中我們經常會通過樣式類名來獲取元素,getElementsByClassName這個方法在IE6-8瀏覽器中是不兼容的
getElementsByName
通過元素的Name屬性值獲取一組元素(類數組:節點集合NodeLIst)
它的上下文也只能是document
IE瀏覽器只能識別表單元素的name屬性值,所以我們這個方法一般都是用來操作表單元素的document.documentElement/document.body
獲取HTML或者BODY(一個元素對象)
document.documentElement.clientWidth || document.body.clientWidth//獲取當前瀏覽器窗口可視區域的寬度(當前頁面一屏幕的寬度)
clientHeight是獲取高度querySelector /querySelectorAll ---->性能沒有這么好
在IE6-8下不兼容,而且也沒有什么特別好的辦法處理它的兼容,所以這兩個方法一般多用于移動端開發使用
querySelector:獲取一個元素對象
querySelectorAll :獲取的是一個元素集合
只要是css支持的選擇器,這里大部分都支持document.querySelectorAll('#div1');//根據ID獲取所有的元素
document.querySelectorAll('.box');//根絕className獲取元素集合
document.querySelectorAll('div');//根據標簽獲取元素集合
document.querySelectorAll('body>div');//子代選擇器 body下的 div
document.querySelectorAll('#box2 li');//后代選擇器
document.querySelectorAll('div [name=xxxxx]');DOM的節點
node:節點,瀏覽器認為一個HTML頁面中的所有內容都是節點(包括標簽、注釋、文字文本等)
元素節點:HTML標簽
文本節點:文字內容(高版本瀏覽器會把空格和換行也當作文本節點)
注釋節點:注釋內容
document文檔節點元素節點
nodeType:1
nodeName: 大寫標簽名(在部分瀏覽器的怪異模式下,我們寫的標簽名是小寫,它獲取的就是小寫)
nodeValue: null
[curEle].tagName:獲取當前元素的標簽名(獲取的標簽名一般都是大寫)文本節點 --- 空格 換行 屬于文本 節點
nodeType:3
nodeName: #text
nodeValue:文本內容注釋節點
nodeType:8
nodeName: #comment
nodeValue:注釋內容文檔節點
nodeType:9
nodeName: #document
nodeValue:nulldocument.body.childNodes節點:用來描述頁面中每一部分之間關系的,只要我可以獲取頁面中的一個節點,那么我就可以通過相關的屬性和方法獲取頁面中的所有節點
childNodes:獲取當前元素所有子節點(節點集合:類數組)
注:不僅僅是元素子節點,文本、注釋等都會包含在內;
子節點說明只是在兒子輩分中查找children:獲取所有的元素子節點(元素集合) 在IE6-8下獲取的結果和標準瀏覽器中有區別(IE6-8中會把注釋節點當作元素節點獲取到)
parentNode:獲取當前元素的父節點(元素對象)
previousSibling nextSibling
previousSibling:獲取當前節點的上一個哥哥節點(不一定是元素節點也可能文本或者注釋)
nextSibling:獲取當前節點的下一個弟弟節點previousElementSibling nextElementSibling
previousElementSibling:獲取當前節點的上一個哥哥元素節點(IE6-8不兼容)
nextElementSibling:獲取當前節點的下一個弟弟元素節點(IE6-8不兼容)firstChild lastChild
firstChild:當前元素所有子節點中的第一個(也不一定是元素節點,可能是文本和注釋)
lastChild:當前元素所有子節點中的最后一個firstElementChild lastElementChild(IE6-8不兼容)DOM的增刪改
真實項目中,我們偶爾會在JS中動態創建一些HTML標簽,然后把其增加到頁面中
document.createElement
在JS中動態創建一個HTML標簽
容器.appentChild(新元素)
把當前創建的新元素增加到容器的末尾位置
insertBefore
容器.insertBefore(新元素,老元素)
在當前容器中,把新創建的元素增加到老元素之前//真實項目中很多需求是通過動態創建元素來完成的,其中有一個需求:解析一個URL地址每一部分的信息(包含問號傳遞的參數)
1、純字符串拆分截取
2、編寫強大的正則,捕獲到需要的結果
3、通過動態創建一個A標簽,利用A標簽的一些內置屬性來分別獲取每一部分的內容
var link = document.createElement('a');
link.herf = 'http://www.zhufengpeixun.cn/stu/?name=zxt&age=27#teacher';
//此處地址就是我們需要解析的URL
hash:存儲的是哈希值 '#teacher'
hostname:存儲的是域名 'www.zhufengpeixun.cn'
pathname:存儲的是請求資源的路徑名稱'/stu/'
protocol:協議'http:'
search:存儲的是問號傳遞的參數值,沒有傳遞是空字符串'' ===>'?name=zxt&age=27'function queryURLParameter(url) {
var link = document.createElement('a');
link.href = url;var search = link.search,
obj = {};
if(search.lenght === 0) return;
search = search.substr(1).split(/&|=/g);
//拆分完之后 奇數項是key 偶數項是value ["name","zxt","age","27"]
for(var i = 0; i < search.length; i +=2) {
var key = search[i];
value = search[i+1];
obj[key] = value;
}
link = null;
return obj;
}removeChild
容器.removeChild(元素)
在當前容器中把某一個元素移除掉
replaceChild
容器.replaceChild(新元素,老元素)
在當前容器中,拿新元素替換老元素
cloneNode
元素.cloneNode(false/true)
把原有的元素克隆一份一模一樣的
false:只克隆當前元素本身
true:深度克隆,把當前元素本身以及元素的所有后代都進行克隆
[set/get/remove] Attribute
給當前元素設置/獲取/移除 屬性的(一般操作的都是它的自定義屬性)box.setAttribute('myIndex',0);
box.getAttribute('myIndex');
box.removeAttribute('myIndex');使用xxx.index 和xxx.setAttribute('index',0)這兩種設置自定義屬性的區別
xxx.index:是把當前操作的元素當作一個普通對象,為其設置一個屬性名(和頁面中的HTML標簽沒關系)
xxx.setAttribute:把元素當作特殊的對象來處理,設置的自定義屬性是和頁面結構中的DOM元素映射在一起的JS中獲取的元素對象,我們可以把它理解為兩種角色:
與頁面HTML結構無關的普通對象
與頁面HTML結構存在映射關系的元素對象元素對象中的內置屬性,大部門都和頁面的標簽存在映射關系:
xxx.style.backgroundColor = 'xxx' 此時不僅把JS中對象對應的屬性值改變了,而且也會映射到頁面的HTML標簽上(標簽中有一個style行內樣式、元素的樣式改變了)xxx.className='xxx' 此時不僅是把JS對象中的屬性值改了,而且頁面中的標簽增加了class樣式類(可以看見的)元素對象的自定義屬性:xxx.index = 0
僅僅是把JS對象中增加了一個屬性名(自定義的),和頁面中的HTML沒啥關系(在結構上看不見)
xxx.setAttribute:通過這種方式設置的自定義屬性和之前提到的內置屬性差不多,都是和HTML結構存在映射關系的(設置的自定義屬性可以呈現在結構上)獲取當前元素的上一個哥哥元素節點
首先獲取當前元素的上一個哥哥節點,判斷當前獲取的節點是否為元素節點(nodeType ===1),如果不是,基于當前獲取的節點,找他的上一個哥哥節點。。。(找幾次不知道)一直到找到的節點是元素節點為止,
如果在查找過程中,發現沒有上一個哥哥節點了(找到頭了),則不再繼續查找
function pre(curEle) {
var p = curEle.previousSibling;
//p 為null 結束 p的nodeType ===1 結束
while(p && p.nodeType !==1) {
p = p.previousSibling;//p: p!=null
}
return p;
}
//擴展
next:獲取下一個弟弟元素節點
function next(curEle) {
var p = curEle.nextSibling;
//p 為null 結束 p的nodeType ===1 結束
while(p && p.nodeType !==1) {
p = p.nextSibling;//p: p!=null
}
return p;
}prevAll:獲取所有的哥哥元素節點
function prevAll(curEle) {
var arr = [];
var p = curEle.previousSibling;
//p 為null 結束
while(p) {
// 如果是元素節點 放到數組中
if(p.nodeType ===1) {
arr.push(p);
}
p = p.previousSibling;//p: p!=null
}
return arr;
}nextAll:獲取所有的弟弟元素節點
function nextAll(curEle) {
var arr = [];
var p = curEle.nextSibling;
//p 為null 結束 說明找到了盡頭
while(p ) {
if(p.nodeType ===1) {
arr.push(p);
}
p = p.nextSibling;//p: p!=null
}
return arr;
}
siblings:獲取所有的兄弟元素節點
//既要往前找 又要往后找
function siblings(curEle) {
var arr = [];
var p = curEle.previousSibling;
var n = curEle.nextSinling;
while(p) {
// 如果是元素節點 放到數組中
if(p.nodeType ===1) {
arr.push(p);
}
p = p.previousSibling;//p: p!=null
}while(n ) {
if(n.nodeType ===1) {
arr.push(n);
}
n = n.nextSibling;//p: p!=null
}
return arr;}
index:獲取當前元素在兄弟中的排名索引function index() {
var arr = [];
var index = 0;
var p = curEle.previousSibling;
//p 為null 結束
while(p) {
// 如果是元素節點 放到數組中
arr.push(p);
p = p.previousSibling;//p: p!=null
}
index = arr.length;
return index;}
復制代碼
6.日期操作
Date:日期類,通過它可以對時間進行處理
var time = new Date()
獲取的結果是一個日期格式的對象
typeof new Date() --->'object'
time.getFullYear() 獲取四位整年數
time.getMonth() 獲取月(0-11 代表1-12月)
time.getDate() 獲取日
time.getDay() 獲取星期(0-6 代表周日到周六)
time.getHours() 獲取小時
time.getMinutes() 獲取分鐘
time.getSeconds() 獲取秒
time.getMilliseconds() 獲取毫秒
time.getTime() 獲取當前日期距離"1970-01-01 00:00:00"的毫秒差var time = new Date('2017-10-22');
當new Date中傳遞了一個時間格式的字符串,相當于把這個字符串轉換為標準的時間對象格式(轉換完成后 就可以調取上面我們講的那些方法了)
時間格式的字符串
"2017-10-22"(IE下識別不了)
"2017/10/22"
"2017/10/22 16:15:34"
1508659621314 ===>傳遞的距離1970的那個毫秒差 (數字格式 不能是字符串)var timeBox = document.getElementById('timeBox');
function computed() {
var nowTime = new Date();
var targeTime = new Date("2017/10/22 17:00:00");
var spanTime = targeTime - nowTime;
if(spanTime <=0) {
timeBox.innerHTML = '開始考試';
window.clearInterval(timer);
return;
}
var hour = Math.floor(spanTime/(1000*60*60));
spanTime -= hour*60*1000;
var minute = Math.floor(spanTime/(1000*60));
spanTime -= minute*60*1000;
var second = Math.floor(spanTime/1000);
hour < 10 ? hour = '0'+ hour:null;
minute<10?minute = '0'+ minute :null;
second < 10 ?second = '0' + second :null;timeBox.innerHTML = hour + ':' + minute + ':' + second;
}
var timer = window.setInterval(computed,1000);
復制代碼
- 動力: 這是我的學習筆記(來源于視頻或者查閱文檔),您能從中得到收獲和進步,是我分享的動力,幫助別人,自己也會更快樂
- 期望: 不喜勿噴,謝謝合作!如果涉及版權請及時聯系我,馬上刪除!