前端開發者必知的8個冷門卻超實用DOM技巧

身為前端開發者,每天都在與DOM (文件物件模型) 打交道,它就像是網頁的骨架,讓開發者能夠操控頁面上的各種元素。不過,在眾多DOM API中,藏著許多鮮為人知但非常實用的方法。

1. Element.checkVisibility()

這是什麼?

這個方法能夠檢測元素是否「真正可見」,不只是存在於DOM中而已。它考慮了多種因素:

  • CSS遮蓋(被其他元素擋住)
  • 滾動隱藏(元素在可視區域外)
  • 透明度為0(肉眼看不見)

實際應用場景

  • 表單驗證:只對用戶可見的表單欄位進行驗證
  • 廣告曝光統計:確保廣告真正被看到才計算曝光
  • 懶加載優化:精準判斷內容是否進入視野,再觸發加載
// 簡單範例
if (myElement.checkVisibility()) {
  // 元素真的被看到了,執行相應操作
}

2. TreeWalker API

這是什麼?

一種高效能遍歷DOM樹的方式,採用「迭代器模式」設計。想像它就像是一個聰明的導遊,可以按照您的要求有序地帶您參觀DOM樹的各個節點。

為什麼要用它?

相比於 querySelectorAll,TreeWalker在處理超大型DOM樹時更省記憶體,因為它不會一次性把所有匹配的節點都載入記憶體。

// 建立一個只遍歷段落元素的TreeWalker
const walker = document.createTreeWalker(
  document.body,           // 從body開始
  NodeFilter.SHOW_ELEMENT, // 只看元素節點
  {
    acceptNode(node) {
      return node.tagName === 'P' 
        ? NodeFilter.FILTER_ACCEPT 
        : NodeFilter.FILTER_SKIP;
    }
  }
);

// 逐一訪問每個段落元素
let currentNode;
while (currentNode = walker.nextNode()) {
  console.log(currentNode.textContent);
}

3. Node.compareDocumentPosition()

這是什麼?

這個方法能精確判斷兩個節點的「位置關係」,就像是網頁元素的GPS定位系統。

常用位置關係代碼

  • 2 (DOCUMENT_POSITION_PRECEDING): 節點A在B之前
  • 4 (DOCUMENT_POSITION_FOLLOWING): 節點A在B之後
  • 8 (DOCUMENT_POSITION_CONTAINS): A是B的祖先節點
// 實用範例:確定拖放元素的插入位置
function determineDropPosition(draggedElem, targetElem) {
  const position = draggedElem.compareDocumentPosition(targetElem);
  
  if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
    return '目標元素在被拖動元素之後';
  } else if (position & Node.DOCUMENT_POSITION_PRECEDING) {
    return '目標元素在被拖動元素之前';
  }
}

4. scrollIntoViewIfNeeded()

這是什麼?

一個聰明的捲動功能,只有當元素不在視窗中時才會自動捲動,避免不必要的頁面跳動。

與傳統方法的比較

傳統的 scrollIntoView() 會無條件捲動到元素位置,而 scrollIntoViewIfNeeded() 則更加智能,避免了過度捲動帶來的使用體驗問題。

// 使用範例:點擊目錄項時,智能捲動到對應章節
catalogItem.addEventListener('click', () => {
  // 只有當章節不在視窗內時才捲動
  document.getElementById(chapterId).scrollIntoViewIfNeeded();
});

5. insertAdjacentElement()

這是什麼?

這是一個比 appendChild 更靈活的元素插入方法,讓您能精準控制插入的位置。

位置參數選項

  • ‘beforebegin’: 在目標元素前面插入
  • ‘afterbegin’: 在目標元素內部的最前面插入
  • ‘beforeend’: 在目標元素內部的最後面插入
  • ‘afterend’: 在目標元素後面插入
// 實用範例:在表單每個輸入框後加入提示訊息
const helpText = document.createElement('small');
helpText.textContent = '請輸入有效的電子郵件地址';
inputElement.insertAdjacentElement('afterend', helpText);

 

6. Range.surroundContents()

這是什麼?

這是一個處理文字區域的神器,能用指定的元素將選中的內容包裹起來。

實際應用場景

  • rich文件編輯器:快速套用格式如加粗、斜體
  • 文章批註系統:標註並高亮重點段落
  • 搜尋結果高亮:突顯頁面中匹配的搜尋詞
// 實現高亮功能
function highlightText(text) {
  const range = document.createRange();
  const selection = window.getSelection();
  
  if (selection.rangeCount > 0) {
    range.setStart(selection.anchorNode, selection.anchorOffset);
    range.setEnd(selection.focusNode, selection.focusOffset);
    
    const highlight = document.createElement('mark');
    highlight.style.backgroundColor = 'yellow';
    
    try {
      range.surroundContents(highlight);
    } catch(e) {
      console.log('選區跨越多個節點,無法直接包裹');
    }
  }
}

7. Node.isEqualNode()

這是什麼?

這個方法能深度比較兩個節點是否「結構相同」,就像比較兩棵樹的形狀是否一致。

重要注意點

它只比較節點的結構和屬性,不會比較動態綁定的事件處理器等內容。這與 === 比較參考是否相同完全不同。

// 實用範例:檢查模板渲染後結構是否符合預期
const expectedStructure = document.createElement('div');
expectedStructure.innerHTML = '';

預期結構

const renderResult = myTemplateEngine.render(data);

if (expectedStructure.firstChild.isEqualNode(renderResult.firstChild)) {
  console.log('渲染結果符合預期結構!');
}

8. document.createExpression()

這是什麼?

這是XPath表達式的預編譯功能,能大幅提升反覆使用同一XPath查詢的效能。

實際應用場景

  • 大數據量表格的快速篩選查詢
  • 複雜XML文檔的節點訪問
  • 需要重複執行同一查詢的場景
// 預編譯XPath表達式
const compiledXPath = document.createExpression(
  '//table[@id="data-table"]/tbody/tr[position() < 10]'
);

// 多次執行同一查詢而無需重複解析
function updateTable() {
  const result = compiledXPath.evaluate(
    document,
    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
    null
  );
  
  for (let i = 0; i < result.snapshotLength; i++) {
    const row = result.snapshotItem(i);
    // 處理前10行資料
  }
}

小結

這些鮮為人知的DOM API能讓您的前端代碼更加優雅高效。不過在實際應用時,請注意以下幾點:

  • 部分API(如checkVisibility)需要較新的瀏覽器支援(Chrome 106+)
  • 使用前建議檢查Can I Use確認瀏覽器兼容性
  • 適當使用這些API能提升代碼質量,但請避免為了炫技而過度使用冷門API
  • 考慮添加polyfill或fallback方案來處理舊版瀏覽器

掌握這些實用技巧,您的前端開發效率將得到顯著提升!您有用過這些API嗎?歡迎在評論區分享您的經驗和其他實用技巧。

Google Map panto試做

[javascript]
function Move2NextMarker1(){
var marker=markers1[tempMarker1];
map.panTo(markers1[tempMarker1].getPosition());
scontent = ‘<div id="iw-container">’ +
‘<div class="iw-title">’+markers[tempMarker1].title+'</div>’ +
‘<div class="iw-content">’ +markers[tempMarker1].description+
‘</div>’ +
‘<div class="iw-bottom-gradient"></div>’ +
‘</div>’;
infoWindow.setContent(scontent);
infoWindow.open(map,markers1[tempMarker1]);
setTimeout(Move2NextMarker1,5600);
tempMarker1=(tempMarker1+1)%(markers.length);

}
[/javascript]

功能完整的純文字編輯器Notepad++

Notepad++是壽山最常拿來編輯PHP、HTML、CSS、JavaScript的文字編輯器。

這套軟體也算是台灣之光,是由台灣人侯今吾基於Scintilla編輯元件所撰寫出來的!在功能上可以取代系統內附較陽春的記事本(Notepad),也可以解決無法打開超過64K檔案以及支援Unicode,在中文搜尋、取代也做的很好!也提供程式語言上色以及高亮功能。真的是原始碼編輯的好幫手!

延伸閱讀:

Notepad++ 官網

Scintilla

 

強大的jQuery圖表套件- HighCharts

脈博網後台看到很漂亮的圖表,原來是使用 HighCharts這個元件。提供了幾乎所有常用的圖表類型:長條圖圓餅圖、折線圖、散佈圖等….,每種圖表還可以額外的定義,可以輕鬆的打造出專屬的圖表。

記得使用時要搭配 jQuery。

HighCharts
網站:http://www.highcharts.com

範例:http://www.highcharts.com/demo

Highcharts - Interactive JavaScript charts for your webpage

verlet-js蠻炫的JS物理引擎

verlet-js_examples_spiderweb_html

verlet-js是一套開放原始碼的JavaScript物理引擎,擁有粒子系統以及碰撞、關連、拖拉、模擬等特性。

透過Verlet也可以做出 box2d  效果的遊戲唷!在官方網站上,提供了幾個範例程式可以更瞭解物理引擎的用法。

官方網站:http://subprotocol.com/verlet-js/

GitHub:https://github.com/subprotocol/verlet-js