一、獲取元素方法(JS選擇器)
1.1概述
得到id元素的方法
document.getElementById() |
得到一個元素。事實上,還有一個方法可以得到標籤元素,並且得到的是多個元素:
document.getElementsByTagName(); |
全線瀏覽器相容的,得到元素的方法,就這兩個:
document.getElementById() 通過id得到元素
document.getElementsByTagName(); 通過標籤名得到元素們
還有更多的得到元素的方法:
document.getElementsByClassName();通過類名得到元素
document.querySelector(); 通過選擇器得到元素
document.querySelectorAll();通過選擇器得到元素,得到的是一組元素
document.getElementsByName(name) 通nama屬性名獲取元素
這些不是全線瀏覽器相容,IE8以上開始相容。
1.2 getElementsByTagName
getElementsByTagName就是通過標籤名得到元素,得到的是頁面上所有的該標籤元素,得到的是陣列。陣列有下標,下標0開始,最後一項length-1。通過標籤名獲得所有標籤名這個標籤。類似於css中的標籤選擇器。選擇的是一組元素。
get 得到
elements 元素們
By 通過
TagName 標籤名字
var ops = document.getElementsByTagName("p"); console.log(ops); // ops.style.backgroundColor = "skyblue"; //錯誤寫法,因為得到的是一根陣列,必須用下標獲取元素 ops[0].style.backgroundColor = "skyblue";//獲取下標為1的標籤 ops[1].style.backgroundColor = "skyblue";//獲取下標為2的標籤 ops[2].style.backgroundColor = "skyblue";//獲取下標為3的標籤 ops[3].style.backgroundColor = "skyblue";//獲取下標為4的標籤 ops[4].style.backgroundColor = "skyblue";//獲取下標為5的標籤 ops[ops.length-1].style.backgroundColor = "skyblue";//獲取最後的標籤
既然是陣列,就可以通過迴圈語句批量控制。
var ops = document.getElementsByTagName("p"); //迴圈給所有p標籤 for(var i = 0;i < ops.length;i++){ console.log(i) ops[i].style.backgroundColor = "skyblue"; }
HTML標籤從上到下執行,依次是0,1,2,3,4
<div> <div> <p>0</p> <div> <p>1</p> </div> <p>2</p> </div> <p>3</p> </div> <p>4</p> //頁面上只有一個p標籤,也必須用陣列[]得到 document.getElementsByTagName('p')[2].style.color = "red";
1.3連續打點呼叫get
先去選擇一個HTML標籤,然後選擇這個HTML標籤中所有的p元素
連續打點呼叫get方法,控制範圍,選中父親下的什麼什麼元素。
document.getElementsByTagName('div')[0].getElementsByTagName('p')[1].style.color = "red"; |
錯誤寫法:不要多寫document,只要開頭有一個就可以了。
document.getElementsByTagName('div')[0].document.getElementsByTagName('p')[1].style.color = "red"; |
實際應用:先用id名去縮小範圍,內部的多選擇使用標籤選擇器。
document.getElementById('box').getElementsByTagName('p')[1].getElementsByTagName('span')[1].style.color = 'red'; |
表格隔行變色:
var tr = document.getElementById("table").getElementsByTagName('tr'); //不管個數是多少,編號從0開始 for(var i = 0;i < tr.length;i += 2){ //從0開始,每次加2,所以都是偶數 tr[i].style.backgroundColor = "pink"; } for(var i = 1;i < tr.length;i += 2){ //從1開始,每次加2,所以都是奇數 tr[i].style.backgroundColor = "skyblue"; }
1.4批量新增事件新增
如果一些相同的元素,新增相同事件,事件函式內部的程式碼幾乎相同,可以批量選擇元素新增事件。
注意:找出陣列中每一項,定義事件函式,用for迴圈中的變數。閉包可能會程式造成影響。
迴圈給所有p標籤新增事件,並且彈出對應的編號:
var ops = document.getElementsByTagName('p'); for(var i = 0;i < ops.length;i++){ ops[i].onclick = function(){ alert(i); //迴圈結束後都還執行函式,所以值 } }
但是,對編號的影響,閉包的影響又出現了。
所以每個盒子點選後都是5,而不是0,1,2,3,4。
閉包的影響:匿名函式定義時,都已經記住了自己認識i,但是認識i不是表示把i的值複製一份儲存,所以匿名函式執行時(就是事件觸發時),i的值變為迴圈結束的值了。
解決方法1:使用IIFE關住當時定義時的作用域,點選事件發生時,執行對應的事件函式,事件函式會去找自己定義時的作用域。定義時a已經被傳遞了引數,值就已經儲存起來了。
var ops = document.getElementsByTagName('p'); for(var i = 0;i < ops.length;i++){ (function(a){ ops[a].onclick = function(){ alert(a); } })(i); //把每次迴圈i的值傳遞給函式區域性變數a }
解決方法2:獲取的元素,本身封裝了大量的屬性和方法,還能自定義一些新屬性並賦值,自定義屬性後可以打點呼叫。
任何物件都可以自定義屬性,並賦值:
Math.aaa = 9999; window.aaa = 8888; Array.bbb = 12345; console.log(Math.aaa) console.log(window.aaa) console.log(Array.bbb)
var ops = document.getElementsByTagName('p'); for(var i = 0;i < ops.length;i++){ ops[i].index = i; //自定義屬性,並且把迴圈i的值賦值儲存到屬性中,名稱自定義的 ops[i].onclick = function(){ alert(this.index); //this關鍵字就代表事件源本身 } }
解決方式:每個元素物件新增一個自定義屬性,用屬性儲存迴圈變數,在事件函式內部與都有一個特殊關鍵字,叫this,this會指向事件源本身,它能完全替代事件觸發的那個事件源物件。
事件源:誰觸發事件,誰就是事件源(誰就是this)
1.5對應和排他思想
保留自己排除別人。
實際運用到程式碼中,批量控制給所有人新增一個相同樣式,然後再給被操作的元素新增特殊樣式。
做到了先排除所有人,然後再保留自己的特殊樣式。
對應模型:點選第一排p,第二排對用編號的p變色。
// 方法1:編號,迴圈新增事件監聽,給第一排所有p並且繫結點選事件 for(var i = 0;i < box1.length;i++){ box1[i].index = i; box1[i].onclick = function(){ console.log(this.index) box2[this.index].style.backgroundColor = "red"; } }
//方法2:IIFE for(var i = 0;i < box1.length;i++){ (function(i){ // console.log(i) box1[i].onclick = function(){ box2[i].style.backgroundColor = "red"; } })(i); }
排他思想:點選p的時候,就自己變紅色,其他所有o都變灰色
var aps = document.getElementById('box').getElementsByTagName("p"); var biaoti = document.getElementById("biaoti"); //迴圈新增監聽 for(var i = 0;i < aps.length;i++){ aps[i].index = i; //自定義編號 aps[i].onclick = function(){ //每點選一個p並且,實際上兩件事 //第一件事:讓所有人(包括自己)都變灰色 for(var j = 0;j < aps.length;j++){ //aps[j].style.backgroundColor = "#ccc"; aps[j].className = ""; //清空型別 } //第二件事:讓自己都變紅色 //this.style.backgroundColor = "#f40"; this.className = "current"; //新增類名 } }
輪播圖:
var imgList = document.getElementById('imgList').getElementsByTagName('li'); var navList = document.getElementById('navList').getElementsByTagName('li'); var leftBtn = document.getElementById('btn1'); var rightBtn = document.getElementById('btn2'); var index = 0; //全域性訊號量,是ul的li下標,下標為幾,就顯示第幾個li //右按鈕 rightBtn.onclick = function(){ index++;//訊號量自加 //後驗收 if(index > imgList.length-1){ index = 0; //回到第一張 } slide();//呼叫函式 } //左按鈕 leftBtn.onclick = function(){ index--;//訊號量自減 //後驗收 if(index < 0){ index = imgList.length-1; //回到第一張 } slide();//呼叫函式 } //封裝函式 function slide(){ //排他:將所有人的隱藏(類名清空),再讓自己加current類名(誰有類名誰就顯示) for(var i = 0;i < imgList.length; i++){ //第一步:讓所有圖片li標籤隱藏 imgList[i].className = ""; //讓所有ol的li都清空 navList[i].className = ""; } //讓自己顯示,其他li隱藏 //給當前編號的ul的li新增類名,顯示圖片 imgList[index].className = "current"; //給當前編號的ol的li新增類名,顯示小圓點 navList[index].className = "current"; } //下面小圓點如果點選,應該讓index對應的發生變化 for(var i = 0;i < navList.length;i++){ navList[i].index = i; //自定義屬性 navList[i].onclick = function(){ index = this.index; //把當前被點選的li編號重新賦值給全域性變數(修改全域性) // index得到後,執行函式 slide(); //呼叫函式 } }
選項卡:
var tab_li = document.getElementById('tab-hd').getElementsByTagName("li"); var tab_ul = document.getElementById('tab-bd').getElementsByTagName("ul"); //批量給li新增滑鼠移入事件 for(var i = 0; i < tab_li.length;i++){ tab_li[i].index = i; //自定義屬性,儲存i的值 tab_li[i].onmouseenter = function(){ //排他思想: //第一步:先清空所有li元素的類名 for(var j = 0; j < tab_li.length;j++){ tab_li[j].className = ""; //清空li的類名 tab_ul[j].className = ""; //清空ul的類名 } //第二步再給自己新增類名 this.className = "current"; //給當前滑鼠移入的li新增類名 tab_ul[this.index].className = "current"; //給對應編號的ul新增類名 } }
二、得到計算後的樣式
2.1高階瀏覽器和低階瀏覽器的不同寫法
現在我們只能得到行內的樣式,事實上DOM提供了可靠的API,得到計算後的樣式(內嵌式和外鏈式)。
W3C制定的標準API,所有現代瀏覽器(包括IE9,但不包括之前的版本)支援window.getComputedStyle()方法,該方法接收一個要進行樣式計算的元素,並返回一個樣式物件。樣式物件提供了getPropertyValue()的方法,用於檢索特定CSS樣式屬性的計算樣式。getPropertyValue()方法接收css屬性名稱,而不是駝峰式的名稱。getPropertyValue()可以不寫,直接用[]方括號來代替檢索屬性也可以。
get得到,computed計算後,style樣式
get得到,property屬性,vaule值
這種方式獲取和設定的都是行內樣式,無法獲取內嵌和外鏈的CSS樣式:
console.log(oBox.style.width); |
window.getComputedStyle(oBox); //得到當前div元素所有的CSS樣式 window.getComputedStyle(oBox).getPropertyValue("width"); //獲取計算後的樣式 |
所有的window物件的方法,都可以不寫window
window.alert(); |
等價於:
alert(); |
得到計算後的樣式,可以直接使用getComputedStyle()方法,不用寫window。
還要注意,引號裡面是CSS屬性,不是駝峰命名法。
getComputedStyle(oBox).getPropertyValue("padding-left") |
getPropertyValue()方法看著就不爽,所以可以用“[]”來代替它
getComputedStyle(oBox)["padding-left"]; |
計算後的綜合結果,就是這個元素此時的狀態:
getComputedStyle(oBox)["background"]; getComputedStyle(oBox)["background-color"]; //樣式計算後結果是得到rgb的值 getComputedStyle(oBox)["background-image"]; getComputedStyle(oBox)["border"];
上面的方法IE6、7、8一律不相容!!!
DOM提供給JS的非常牛,一個元素此時的狀態,可以完全被得到,好用的屬性,但是不相容。所以IE6、7、8不相容getComputedStyle()方法,寫另外一套寫法:附加在元素身上的currentStyle屬性,它和style點語法一樣,使用駝峰命名法。
IE6、7、8支援以下寫法:
注意:currentStyle得到樣式,必須用駝峰命名法,寫法和oBox.style.width這種一樣
oBox.currentStyle.paddingLeft |
可以不寫點語法,使用“[]”,但是也必須是駝峰命名。
oBox.currentStyle['paddingLeft'] |
alert(oBox.currentStyle.width); alert(oBox.currentStyle.height); //不寫高度得到的是auto,不能獲取被內容撐開的高度 alert(oBox.currentStyle.backgroundColor); //顏色值會原樣輸出,pink
顏色值在高階瀏覽器中是rgb(),低版本瀏覽器是原樣輸出
總結: 高階瀏覽器: window.getComputedStyle(oBox).getPropertyValue("padding-left"); getComputedStyle(oBox).getPropertyValue("padding-left"); getComputedStyle(oBox)["padding-left"]; IE6/7/8瀏覽器 oBox.currentStyle.paddingLeft oBox.currentStyle["paddingLeft"];
2.2相容寫法
IE6、7、8低階瀏覽器,不認識getComputedStyle視為錯誤
Chrome等高階瀏覽器,不認識currentStyle視為錯誤
所以,現在就要進行一個相容性寫法,新玩家會認為,要檢測瀏覽器版本,如果版本是IE6、7、8那麼……。
實際上,老司機都不這麼做。我們不關心你的瀏覽器版本是什麼,我只關心你瀏覽器的能力。
所以要進行能力檢測,可以在不同瀏覽器中得到相容性的寫法,輸出CSS屬性的值:
如果能使用這個方法,方法作為if語句的判斷條件就會返回true,不能使用就返回false。
if(window.getComputedStyle){ //條件滿足為真,說明當前瀏覽器認識getComputedStyle()方法 alert(getComputedStyle(oBox)["background-color"]); }else{ //條件不滿足,說明當前瀏覽器不認識getComputedStyle()方法,認識currentStyle alert(oBox.currentStyle.backgroundColor); }
封裝一個相容性的函式獲取一個元素某個CSS屬性值的方法。
API:傳入兩個引數,第一個是元素物件,第二個是CSS屬性名
返回值:是這個傳入元素物件的CSS屬性值
function getStyle(obj,property){ if(window.getComputedStyle){ //高階連起來,要把使用者輸入的CSS屬性中檢測一下是否為駝峰,如果是就轉為連字元寫法 //強制把使用者輸入的大寫字母,變為小寫字母加“-” // paddingLeft 替換 padding-left // 正則替換: property = property.replace(/([A-Z])/g,function(match,$1){ return "-" + $1.toLowerCase(); }) //返回計算後的樣式 return getComputedStyle(obj)[property]; }else{ //IE只認識駝峰,要防止用輸入短橫,如果輸入短橫,要把短橫改為大寫字母 //padding-left替換paddingLeft property = property.replace(/-([a-z])/g,function(match,$1){ return $1.toUpperCase(); }) //返回計算後的樣式 return obj.currentStyle[property]; } } alert(getStyle(oBox,"padding-left")); alert(getStyle(oBox,"backgroundColor"));
2.3關於opacity
opactiy取值0.0~1.0,而濾鏡取值0~100。
儘管IE8和早期版本不支援opacity,通過style.opacity或者ele.currentStyle.opacity屬性取值時,返回的依然是opacity值,即使瀏覽器完全忽略了opatity值。這是一個好事兒,當我們能夠保證opactiy、filter中設定的屬性是一致的,則JavaScript讀取opactiy值就算是相容的。
支援opacity的瀏覽器,總會將.6這種寫法規範為0.6 。 而不支援opacity的瀏覽器則會返回原有的形式.5。這是一個小坑,進行比較的時候需要注意。
設定opacity的時候,我們需要同時設定filter屬性,filter中的數值是opacity的100倍。
查了100倍
var oBox = document.getElementById("box"); // alert(oBox.style.opacity); //JS沒有相容性問題 // alert(oBox.currentStyle.opacity); //低版本沒有相容性問題 var opacity = 0.5; oBox.style.opacity = opacity; oBox.style.filter = "alpha(opacity="+(opacity * 100)+")";