banner
Jrenc

Jrenc

There’s a million things I haven’t done。
x
github
email
bilibili

JS如何作用於Html

document 和 window 的區別?#

就是簡而言之,dom 是一個對象,win 也是一個對象。他們都是 Web API 裡的一個不同角色。

window 對象#

  • window 對象
    window 就是窗口嗎,它代表瀏覽器的一個窗口或標籤頁,並且是 JavaScript 中的全局對象。它提供了許多控制瀏覽器窗口的方法和屬性。
    作用域:window 是最頂層的對象,在瀏覽器中的任何 JavaScript 代碼中都可以直接訪問 window 及其屬性和方法,無需任何限定前綴。
    功能:window 對象包含了瀏覽器窗口的屬性,如窗口的大小、位置等,同時也提供了一些方法來控制瀏覽器窗口的行為,如打開新窗口、定時器函數(setTimeout、setInterval)、瀏覽器歷史控制等。此外,它還是所有全局變量和全局函數的宿主

document 對象#

  • document 對象
    定義:document 對象是 window 對象的一個屬性,它代表了加載在窗口中的 HTML 文檔,是 Document Object Model(DOM)的入口點。
    作用域:document 對象專門用於操作和訪問文檔的內容,比如 HTML 元素、CSS 樣式等。
    功能:document 對象提供了許多方法來訪問和修改文檔內容,如獲取和設置元素的內容、創建新的 HTML 元素、查詢選擇器等。通過 document 對象,可以實現對頁面內容的動態修改和交互。

總的來說,window 對象代表了瀏覽器窗口本身,是所有全局 JavaScript 對象、函數和變量的父級對象,而 document 對象代表了窗口中加載的文檔,是所有 HTML 文檔元素的容器。在實際開發中,根據需要操作的是瀏覽器窗口本身還是窗口中的文檔內容,來決定使用 window 還是 document。
就簡單而言,dom 對象操控的是文檔的內容,而 window 對象操控的是瀏覽器窗口的屬性和方法。所以,如果你想開定時器,監控窗口的變化你需要用到的是 windows 對象,如果你想要改變文檔的內容那你則需要使用 document 對象。
所以當時其實甘特圖最主要的問題是,我不知道 windows API 和 document API 的區別。我不懂原生的 html,當這塊知識缺失了自然是不會去設計這個邏輯的
所以本質上就是會用封裝好的 API。

Dom 流 API 學習#

如何獲取元素#

在 DOM 中獲取元素主要涉及以下幾個 API:

  1. getElementById()

    • 通過元素的 ID 獲取單個元素。ID 在一個 HTML 文檔中應該是唯一的。
    let element = document.getElementById('elementId'); // 通過ID獲取元素
    
  2. getElementsByClassName()

    • 通過元素的類名獲取一個元素集合。這個方法返回的是一個類數組對象,包含所有匹配指定類名的元素。
    let elements = document.getElementsByClassName('className'); // 通過類名獲取元素集合
    
  3. getElementsByTagName()

    • 通過元素的標籤名(如div, p, a等)獲取元素集合。同樣返回一個類數組對象,包含所有匹配指定標籤名的元素。
    let elements = document.getElementsByTagName('tagName'); // 通過標籤名獲取元素集合
    
  4. querySelector()

    • 使用 CSS 選擇器獲取第一個匹配的元素。這是一個非常強大的方法,可以使用複雜的 CSS 選擇器來定位元素。
    let element = document.querySelector('.className'); // 通過CSS選擇器獲取第一個匹配的元素
    
  5. querySelectorAll()

    • 使用 CSS 選擇器獲取所有匹配的元素集合。這個方法返回的是一個NodeList對象,包含所有匹配指定 CSS 選擇器的元素
    let elements = document.querySelectorAll('.className'); // 通過CSS選擇器獲取所有匹配的元素
    
  6. closest()

    • 從元素本身開始,在其祖先元素中(包括自己),找到第一個匹配給定 CSS 選擇器的元素。這個方法對於尋找元素的最近父級匹配非常有用。自下向上尋找。
    let closestElement = element.closest('.className'); // 在元素的祖先中找到最近的匹配給定選擇器的元素
    
  7. children

    • 獲取一個元素的子元素集合,不包括文本和註釋節點。這是一個元素對象的屬性,返回直接子元素的 HTML 集合。
    let childElements = parentElement.children; // 獲取parentElement的所有直接子元素
    
  8. childNodes

    • 獲取一個元素的所有子節點,包括元素節點、文本節點和註釋節點。這同樣是元素對象的一個屬性,返回一個節點列表。
    let childNodes = parentElement.childNodes; // 獲取parentElement的所有子節點,包括文本和註釋
    
  9. parentElementparentNode

    • 通過一個元素獲取其父元素。parentElement 返回父級元素節點,而 parentNode 可以返回任何類型的父節點,包括文本節點和註釋節點。
    let parent = childElement.parentElement; // 獲取childElement的父元素
    let parentNode = childElement.parentNode; // 獲取childElement的父節點
    
  10. nextSiblingpreviousSibling

    • 分別獲取元素的下一個和上一個同級節點。這兩個屬性返回的可以是任何類型的節點,包括元素節點、文本節點和註釋節點。
    let nextNode = element.nextSibling; // 獲取element的下一個同級節點
    let prevNode = element.previousSibling; // 獲取element的上一個同級節點
    
  11. nextElementSiblingpreviousElementSibling

    • 類似於 nextSiblingpreviousSibling,但這兩個屬性只返回元素節點,忽略文本節點和註釋節點。
    let nextElement = element.nextElementSibling; // 獲取element的下一個同級元素
    let prevElement = element.previousElementSibling; // 獲取element的上一個同級元素
    
  12. firstChildlastChild

    • 分別獲取元素的第一個和最後一個子節點。這些子節點可以是任何類型的節點,包括元素節點、文本節點和註釋節點。
    let first = parentElement.firstChild; // 獲取parentElement的第一個子節點
    let last = parentElement.lastChild; // 獲取parentElement的最後一個子節點
    
  13. firstElementChildlastElementChild

    • 類似於 firstChildlastChild,但這兩個屬性只返回元素節點,忽略文本節點和註釋節點。
    let firstElement = parentElement.firstElementChild; // 獲取parentElement的第一個子元素
    let lastElement = parentElement.lastElementChild; // 獲取parentElement的最後一個子元素
    

通過綜合運用這些 API,可以有效地遍歷和操作 DOM 樹,實現對頁面結構的靈活控制。

通過這些 API,可以根據不同的條件和需求,在 DOM 樹中靈活地獲取單個或多個元素。


如何創建元素#

創建元素#

document.createElement('tag')

創建文本節點#

document.createTextNode('text')

什麼是文本節點?
文本節點就是 html 中的文本,比如 p 標籤中的文本,a 標籤中的文本等等。
createTextNode 怎麼使用?

var text = document.createTextNode('text')

這是什麼效果?

<p>text</p>

text 在這裡面是它文字的內容。


如何添加元素#

添加元素#

parent.appendChild(child)

什麼效果?

<div>
  <p>text</p>
</div>

插入元素#

parent.insertBefore(newNode, referenceNode)

舉個例子

var parent = document.getElementById('parent')
var newNode = document.createElement('p')
var referenceNode = document.getElementById('reference')
parent.insertBefore(newNode, referenceNode)

這個效果是什麼?

<div id="parent">
  <p>newNode</p>
  <p id="reference">referenceNode</p>
</div>

referenceNode 起了什麼作用?
referenceNode 是一個參考節點,它的作用是在參考節點之前插入新的節點。

如何刪除元素#

刪除元素#

parent.removeChild(child)

舉個例子

var parent = document.getElementById('parent')
var child = document.getElementById('child')
parent.removeChild(child)

這個效果是什麼?給出對比

<div id="parent">
  <p id="child">child</p>
</div>
<div id="parent">
</div>

如何修改元素內容?#

在 DOM(文檔對象模型)中修改元素內容主要涉及以下幾個常用的 API:

  1. innerTexttextContent
    這兩個屬性都可以用來獲取或設置一個元素的文本內容。innerText 反映了元素及其子元素的 “渲染” 文本內容,即按照樣式顯示在頁面上的內容,而 textContent 則獲取或設置元素內所有子節點的內容,包括 <script><style> 標籤內的文本。

    element.innerText = '新的文本內容'; // 設置元素的可見文本
    let content = element.innerText; // 獲取元素的可見文本
    
    element.textContent = '新的全部文本內容'; // 設置元素的全部文本,包含所有子節點
    let fullContent = element.textContent; // 獲取元素的全部文本,包含所有子節點
    
  2. innerHTML
    innerHTML 屬性可以用來獲取或設置元素內的 HTML 內容。與 innerTexttextContent 不同,innerHTML 會包含所有的 HTML 標籤。

    element.innerHTML = '<strong>加粗的文本</strong>'; // 設置元素內的HTML內容
    let htmlContent = element.innerHTML; // 獲取元素內的HTML內容
    
  3. outerHTML
    outerHTML 屬性可以獲取或設置包含元素本身及其所有子節點的 HTML。

    element.outerHTML = '<div><strong>新元素及其內容</strong></div>'; // 替換元素及其內容
    
  4. createElementappendChild / replaceChild
    這些方法用於創建新的 DOM 元素並將其插入到文檔中。createElement 用於創建一個新的元素節點,appendChild 用於將創建的節點添加到父節點的子節點列表的末尾,replaceChild 用於替換父節點的一個子節點。

    let newElement = document.createElement('div'); // 創建一個新的div元素
    newElement.innerText = '這是新創建的元素'; // 設置新元素的文本內容
    parentElement.appendChild(newElement); // 將新元素添加為parentElement的子節點
    
    let anotherElement = document.createElement('span'); // 創建另一個元素
    parentElement.replaceChild(anotherElement, newElement); // 替換父元素中的子元素
    

通過這些 API,可以方便地在 DOM 中修改元素的內容和結構。
在 DOM 中修改元素的樣式和屬性主要涉及以下幾個 API:

  1. 修改樣式:style 屬性

    • 每個 DOM 元素都有一個 style 屬性,它允許你通過 JavaScript 直接修改元素的樣式。可以通過設置元素的 style 屬性中的 CSS 屬性來改變樣式。
    element.style.backgroundColor = 'red'; // 直接設置元素的背景顏色為紅色
    element.style.fontSize = '20px'; // 設置元素的字體大小為20像素
    
  2. 修改類:classList 屬性

    • classList 提供了一種簡單的方法來操作元素的類名集合。常用的方法包括 add(), remove(), toggle()contains()
    element.classList.add('new-class'); // 添加一個新的類名
    element.classList.remove('old-class'); // 移除一個類名
    element.classList.toggle('active'); // 如果存在則刪除該類名,不存在則添加
    
  3. 設置和獲取屬性:setAttribute()getAttribute()

    • 這兩個方法分別用於設置和獲取元素的屬性。屬性可以是標準的 HTML 屬性,如 id, src, href 等,也可以是自定義屬性。
    element.setAttribute('data-custom', 'value'); // 設置一個自定義屬性
    let value = element.getAttribute('data-custom'); // 獲取這個自定義屬性的值
    
  4. 直接修改屬性

    • 對於一些常用的 HTML 屬性,如 id, src, href 等,可以直接通過元素對象來獲取和設置。
    element.href = 'https://example.com'; // 直接設置元素的href屬性
    let elementId = element.id; // 直接獲取元素的id屬性
    

通過這些 API,可以方便地在 JavaScript 中修改 DOM 元素的樣式和屬性,以實現動態的頁面效果。

如何替換元素#

替換元素#

在 DOM 操作中,替換元素涉及以下幾個常用的 API:

  1. replaceChild(newChild, oldChild)

    • 這是一個在父節點上調用的方法,用於將父節點中的一個舊子節點替換為一個新的子節點。newChild 是要插入的新節點,而 oldChild 是要被替換的舊節點。
    parentNode.replaceChild(newElement, oldElement); // 將parentNode中的oldElement替換為newElement
    
  2. replaceWith(...)

    • replaceWith() 方法允許你將一個 DOM 節點(或多個節點)替換為指定的節點或者一段 HTML 或文本字符串。這個方法是直接在要被替換的節點上調用的。
    oldElement.replaceWith(newElement); // 將oldElement替換為newElement
    
  3. 使用 insertBefore() 配合 removeChild()remove() 來實現替換

    • 雖然不是直接的替換方法,但可以通過先插入新節點到舊節點之前,然後移除舊節點,達到替換的效果。
    parentNode.insertBefore(newElement, oldElement); // 將newElement插入到oldElement之前
    parentNode.removeChild(oldElement); // 移除oldElement,實現替換效果
    // 或者使用更簡潔的 oldElement.remove(),如果環境支持
    oldElement.remove();
    
  4. 使用 outerHTML

    • 通過設置元素的 outerHTML 屬性,可以直接替換整個元素,包括元素本身及其內容。這種方法不需要先獲取父節點。
    oldElement.outerHTML = '<div id="newElement">新內容</div>'; // 用新的HTML內容替換oldElement,包括元素本身
    

這些 API 提供了靈活的方式來替換 DOM 中的元素,可以根據不同的場景和需求選擇合適的方法。

如何給元素添加事件#

在 DOM 中處理元素事件主要涉及以下幾個 API:

  1. addEventListener(event, handler, [options])

    • 用於在指定元素上添加一個事件監聽器。event 是要監聽的事件類型(如 "click", "mouseover" 等),handler 是事件發生時調用的函數,options 是一個可選的參數,用於指定更詳細的事件監聽行為。
    element.addEventListener('click', function() {
      console.log('元素被點擊了');
    });
    
  2. removeEventListener(event, handler, [options])

    • 用於移除之前通過 addEventListener 添加的事件監聽器。需要注意的是,handler 必須與添加監聽器時使用的是同一個函數引用。
    function handleClick() {
      console.log('元素被點擊了');
    }
    
    element.addEventListener('click', handleClick);
    // 稍後移除監聽器
    element.removeEventListener('click', handleClick);
    
  3. dispatchEvent(event)

    • 用於觸發指定元素上的事件。event 是一個 Event 對象的實例,可以通過 new Event() 來創建。
    let event = new Event('customEvent');
    element.dispatchEvent(event); // 觸發自定義事件
    
  4. 通過屬性直接分配事件處理器

    • 可以直接將事件處理函數分配給元素的事件處理屬性。例如,onclick 對應於點擊事件。
    element.onclick = function() {
      console.log('元素被點擊了');
    };
    
  5. 使用 on 前綴的屬性來設置事件處理函數

    • 除了 onclick,還有許多其他的事件可以通過設置以 on 開頭的屬性來添加處理函數,例如 onmouseoveronkeydown 等。
    element.onmouseover = function() {
      console.log('鼠標懸停在元素上');
    };
    
  6. 使用 Event 對象

    • 事件處理函數中的 event 參數是一個 Event 對象的實例,它提供了關於事件的信息,如觸發事件的元素、事件類型以及其他與特定事件相關的屬性和方法。
    element.addEventListener('click', function(event) {
      console.log('點擊發生在 ' + event.target.tagName + ' 元素上');
    });
    
  7. preventDefault()

    • 事件對象的 preventDefault() 方法用於阻止事件的默認行為。這在處理如點擊鏈接時不希望頁面跳轉,或在提交表單時不希望頁面重新加載等場景下非常有用。
    element.addEventListener('click', function(event) {
      event.preventDefault(); // 阻止鏈接默認的跳轉行為
    });
    
  8. stopPropagation()

    • 用於阻止事件冒泡到父元素。事件冒泡是指事件從最深的節點開始,然後逐級向上傳播到較為淺的節點的過程。
    element.addEventListener('click', function(event) {
      event.stopPropagation(); // 阻止事件繼續冒泡
    });
    
  9. 事件委託

    • 利用事件冒泡的特性,可以將事件監聽器設置在父元素上,而不是每個子元素上。當事件在子元素上觸發並冒泡到父元素時,可以通過檢查事件的 target 屬性來確定是哪些子元素觸發的事件。
    parentElement.addEventListener('click', function(event) {
      if (event.target && event.target.matches('button.child')) {
        console.log('子按鈕被點擊');
      }
    });
    
  10. capture 事件捕獲

    • 在事件處理的第三個參數 options 中,可以設置 capturetrue 來指定事件處理器在捕獲階段而不是冒泡階段執行。事件捕獲是指事件從最外層開始,然後逐級向下傳播到最深的節點的過程。
    element.addEventListener('click', function() {
      console.log('捕獲階段的事件處理');
    }, {capture: true});
    
  11. once 選項

    • addEventListener 的第三個參數中,設置 once: true 可以讓事件處理器只執行一次,然後自動移除。
    element.addEventListener('click', function() {
      console.log('這個事件處理器只會執行一次');
    }, {once: true});
    

通過這些 API,可以靈活地為 DOM 元素添加、移除和觸發事件,實現豐富的交互效果。

生命週期#

DOM(文檔對象模型)和 Window 對象在 Web 頁面的生命週期中扮演著重要的角色。下面介紹一些與 DOM 和 Window 生命週期相關的 API:

  1. Window 的生命週期事件:

    • load 事件

      • 當整個頁面及所有依賴資源如樣式表和圖片都已完成加載時,window 對象會觸發 load 事件。
      window.addEventListener('load', function() {
          console.log('頁面完全加載完畢');
      });
      
    • DOMContentLoaded 事件

      • 當初始的 HTML 文檔被完全加載和解析完成,不需要等待樣式表、圖片和子框架完成加載,document 對象會觸發 DOMContentLoaded 事件。
      document.addEventListener('DOMContentLoaded', function() {
          console.log('DOM內容加載完畢');
      });
      
    • unload 事件

      • 當用戶離開當前頁面,window 對象會觸發 unload 事件。這個事件可以用於清理工作,如關閉彈出窗口等。
      window.addEventListener('unload', function() {
          console.log('用戶離開頁面');
      });
      
    • beforeunload 事件

      • 在窗口、文檔或其資源即將卸載時觸發。可以用來詢問用戶是否確定離開當前頁面,通常用於提示用戶保存未保存的更改。
      window.addEventListener('beforeunload', function(event) {
          event.returnValue = '您有未保存的更改,確定要離開嗎?';
      });
      
  2. 請求動畫幀(Request Animation Frame):

    • requestAnimationFrame(callback)

      • 提供了一種在瀏覽器重繪之前調用特定代碼的方法,用於執行動畫或頁面重繪等。這個方法比傳統的 setInterval 更高效,可以更平滑地執行動畫。
      function animate() {
          // 動畫代碼
          requestAnimationFrame(animate);
      }
      requestAnimationFrame(animate);
      
  3. 頁面可見性 API(Page Visibility API):

    • 這個 API 提供了visibilitychange事件,以及document.hidden屬性,用於檢測頁面是否對用戶可見。這在優化頁面性能和用戶體驗方面特別有用,比如可以在頁面不可見時暫停視頻播放或停止執行動畫。
    document.addEventListener('visibilitychange', function() {
        if (document.hidden) {
            console.log('頁面不可見');
        } else {
            console.log('頁面可見');
        }
    });
    
  4. 性能監測 API(Performance API):

    • performance對象允許訪問與當前頁面相關的性能數據。例如,可以使用performance.timing來分析不同階段的耗時,如頁面加載、解析等。
    window.addEventListener('load', function() {
        setTimeout(function() {
            const timing = performance.timing;
            const loadTime = timing.loadEventEnd - timing.navigationStart;
            console.log('頁面加載時間:' + loadTime);
        }, 0);
    });
    
  5. resize 事件:

    • 當瀏覽器窗口被調整大小時,window對象會觸發resize事件。可以用來調整頁面佈局或執行其他響應窗口大小變化的操作。
    window.addEventListener('resize', function() {
        console.log('窗口大小變化了');
    });
    
  6. scroll 事件:

    • 當用戶滾動頁面時,會觸發scroll事件。這可以用於實現 “懶加載”(延遲加載圖片等內容),或者動態改變導航條的樣式等。
    window.addEventListener('scroll', function() {
        console.log('頁面被滾動了');
    });
    
  7. focusblur 事件:

    • 當頁面或頁面內的元素獲得或失去焦點時,會觸發focusblur事件。這可以用於改善表單輸入的用戶體驗,或在應用中管理鍵盤快捷鍵。
    window.addEventListener('focus', function() {
        console.log('窗口獲得了焦點');
    });
    
    window.addEventListener('blur', function() {
        console.log('窗口失去了焦點');
    });
    

通過結合使用這些 API,開發者可以更精細地控制和優化 Web 應用的行為和性能,提升用戶的互動體驗。

通過監聽和處理這些生命週期事件,可以更好地控制 Web 頁面的加載、渲染和卸載過程,提高用戶體驗。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。