前端筆記知識點整合之JavaScript(八)關於元素&計算後的樣式

来源:https://www.cnblogs.com/rope/archive/2019/03/26/10601634.html
-Advertisement-
Play Games

一、獲取元素方法(JS選擇器) 1.1概述 得到id元素的方法 document.getElementById() 得到一個元素。事實上,還有一個方法可以得到標簽元素,並且得到的是多個元素: document.getElementsByTagName(); 全線瀏覽器相容的,得到元素的方法,就這兩個 ...


一、獲取元素方法(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)+")";

 

ps:儘量讓它越來越規範,前期的文章都是本人的學習時的筆記整理,希望看完後可以指點一二,提提意見多多交流; 

筆記流程:html>css>javascript>jquery>html5/css3>移動端>ajax>面向對象>canvas>nodejs>es678>vue>react>小程式>面試問題

意見請留言,郵箱:[email protected]


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在前端開發中,許多新手常會遇見一個問題,參考的網頁上有類似下圖的圖標,但在資源里卻找不到對應的文件,這是因為這些網頁使用了圖標庫。這裡介紹一種常見的圖標庫——FontAwesome的使用。 1.登錄Font Awesome官網,下載Font Awesome安裝包,最好下載最新版本的,因為最新版本中的 ...
  • 一、問題描述 問題是這樣的,後臺傳了xArr = [x1, x2,...,xn]和yArr = [y1, y2, ..yn]兩個數組,前端要渲染出表格並且可以填寫每個單元格的值,然後按照一定數據結構保存並傳給後臺,並且再次獲取這個數據結構和數組xArr、yArr可以自己渲染出這個表?實現新增和修改的 ...
  • usually.js 是一個面向現代 Web 開發的 JavaScript 函數庫,基於 ES6 開發。最新版本2.4.1,最新版本usually.js增加管道函數—— pipe 函數。什麼是管道函數?管道函數,其作用是將前一步的結果直接傳參給下一步的函數,從而省略了中間的賦值步驟,可以大量減少記憶體... ...
  • 一、快捷位置和尺寸屬性 DOM已經提供給我們計算後的樣式,但是還是覺得不方便,因為計算後的樣式屬性值都是字元串類型。 不能直接參与運算。 所以DOM又提供了一些API:得到的就是number類型的數據,不需要parseInt(),直接可以參與運算。 offsetLeft和offsetTop offs ...
  • 一、單例模式: 所謂單例模式,即保證一個類只有一個實例,並提供一個訪問它的全局訪問點。 單例模式實現彈出層: 二、觀察者模式: 所謂觀察者模式,即(發佈-訂閱模式):其定義對象間一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都將得到通知。 觀察者模式常見面試題: 三、組合模式: ...
  • Layui 分為單頁版和iframe版 單頁版 通過將單頁代碼輸出到div,不如要完整的html代碼。 刷新頁面後,依然能夠記錄上一次的頁面。 此種方式不易於調試前端代碼。 Iframe版 通過iframe的方式將載入另一個頁面。需要完整的html代碼,包括js代碼。 屬性頁面後,不能夠記錄上一次的 ...
  • 在學習表格時我們會遇到一些既跨行又跨列合併的情況,此時可以用下麵這種方法來實現。 但是需要特別指出的是,如果一個單元格既跨行又跨列合併了,那麼最好不要再讓相鄰單元格也跨行或跨列合併了。 此時會出現如下所示的錯誤效果,可以看到單元格與單元格的尺寸不再一致了。 ...
  • 大家好 !! 又見面了, 今天我們來搞一搞 H5的新增API FileReader 真是一個超級超級方便的API呢!!!很多場景都可以使用.......... 我們先不贅述MDN文檔里的內容, 我們從 1 到 0, 從 一個 小Demo 入手 開始 瞭解 它; 請開始你的表演: 是不是簡單又炫酷, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...