前端筆記之JavaScript(八)關於元素&計算后的樣式


一、獲取元素方法(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關鍵字就代表事件源本身
    }
}

解決方式:每個元素對象添加一個自定義屬性,用屬性存儲循環變量,在事件函數內部與都有一個特殊關鍵字,叫thisthis會指向事件源本身,它能完全替代事件觸發的那個事件源對象。

事件源:誰觸發事件,誰就是事件源(誰就是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"];

上面的方法IE678一律不兼容!!!

DOM提供給JS的非常牛,一個元素此時的狀態,可以完全被得到,好用的屬性,但是不兼容。所以IE678不兼容getComputedStyle()方法,寫另外一套寫法:附加在元素身上的currentStyle屬性,它和style點語法一樣,使用駝峰命名法。

 

IE678支持以下寫法:

注意: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兼容寫法

IE678低級瀏覽器,不認識getComputedStyle視為錯誤

Chrome等高級瀏覽器,不認識currentStyle視為錯誤

所以,現在就要進行一個兼容性寫法,新玩家會認為,要檢測瀏覽器版本,如果版本是IE678那么……。

實際上,老司機都不這么做。我們不關心你的瀏覽器版本是什么,我只關心你瀏覽器的能力。

 

所以要進行能力檢測,可以在不同瀏覽器中得到兼容性的寫法,輸出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值。這是一個好事兒,當我們能夠保證opactiyfilter中設置的屬性是一致的,則JavaScript讀取opactiy值就算是兼容的。

支持opacity的瀏覽器,總會將.6這種寫法規范為0.6 。 而不支持opacity的瀏覽器則會返回原有的形式.5。這是一個小坑,進行比較的時候需要注意。

設置opacity的時候,我們需要同時設置filter屬性,filter中的數值是opacity100倍。

 

查了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)+")";

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM