核心要點
cite
屬性自動在塊引用中插入引用鏈接。 幾年前,編寫 HTML 的關鍵技能是掌握足夠的表格技巧,以說服兩個主要的瀏覽器或多或少地按照你的意願執行。現代 Web 則大相徑庭,你的標記質量取決於你如何熟練地使用標題、段落和列表等結構元素來描述你的內容。這種方法的好處已被多次解釋:更易於維護的代碼、更小的文件大小、更好的可訪問性以及能夠從單個樣式表控製網站的外觀和感覺,而不是在跨多個頁面的龐大標記塊中進行修改。一個不太常被討論的優勢是,結構良好的標記為基於客戶端 Web 第三方技術——JavaScript 的額外網站增強打開了大門。本文將探討 JavaScript 和結構良好的標記可以協同工作的兩種方式。第一個示例將展示如何通過連接到其 cite 屬性來增強塊引用。第二個示例將演示一個“最佳實踐”腳本,用於構建鏈接,這些鏈接可切換頁面上可見的面板。
對於我們的第一個示例,讓我們來看一下不起眼的塊引用元素。該元素經常被誤用於應用縮進,但其正確的用法是標記應在視覺上與周圍文本分開的引用。起始塊引用標籤可以帶有一個可選的 cite 屬性,該屬性應包含引文來源頁面的 URL。 cite 屬性的唯一問題是瀏覽器完全忽略它。標記純粹主義者可能會欣賞它,但從純粹的實用角度來看,使用它除了獲得使用正確標記的滿足感外,沒有任何好處。這就是 JavaScript 的用武之地。使用 DOM,可以在具有 cite 屬性的任何塊引用的底部添加指向引文來源的鏈接。以下是執行此操作的函數代碼:
function extractBlockquoteCitations() { var quotes = document.getElementsByTagName('blockquote'); for (var i = 0; i < quotes.length; i++) { var cite = quotes[i].getAttribute('cite'); if (cite) { var a = document.createElement('a'); a.setAttribute('href', cite); a.setAttribute('title', cite); a.appendChild(document.createTextNode('Source')); var p = document.createElement('p'); p.className = 'blockquotesource'; p.appendChild(a); quotes[i].appendChild(p); } } }
讓我們仔細看看函數的主體。
var quotes = document.getElementsByTagName('blockquote');
這行代碼使用 DOM 方法 getElementsByTagName
查找當前頁面中的所有塊引用元素,並將它們賦值給名為 quotes
的數組(實際上是 HTMLCollection,但它是一個行為類似於數組的數據結構)。
for (var i = 0; i < quotes.length; i ) { ... }
現在我們正在遍歷收集到的塊引用節點。每次循環,我們都使用 getAttribute
方法從元素中檢索 cite 屬性。如果已設置 cite 屬性,我們將繼續進行有趣的部分:在引文底部創建一個“來源”鏈接。
var a = document.createElement('a'); a.setAttribute('href', cite); a.setAttribute('title', cite);
當我們想要使用 DOM 動態地向頁面添加新的 HTML 元素時,正確的做法是使用 createElement
方法以編程方式創建這些元素。上面的幾行代碼創建了一個新的 'a' 元素,並為其分配了 href 和 title 屬性,這兩個屬性都設置為引文的 URL。
a.appendChild(document.createTextNode('Source'));
我們希望鏈接元素包含一些用戶可以點擊以激活鏈接的文本。原始文本節點是使用 createTextNode
方法創建的。 DOM 將 HTML 元素視為構成一棵樹,因此要將文本添加到我們新創建的鏈接,我們需要調用其 appendChild
方法。
var p = document.createElement('p'); p.className = 'blockquotesource'; p.appendChild(a);
為了允許我們使用 CSS 靈活地設置新鏈接的樣式,我們可以將其包裝在一個段落元素中。上面的代碼創建了這樣一個元素,將其類設置為“blockquotesource”以提供 CSS 掛鉤,然後使用 appendChild
將鏈接添加到其中。此時,我們構建的新文檔片段等效於以下 HTML:
<code><p> <a href="https://www.php.cn/link/a725c77dfdec0a53250d0709ed36e1fe" title="https://www.php.cn/link/a725c77dfdec0a53250d0709ed36e1fe">Source</a> </p>
Source
目前,我們的片段仍然不可見,因為雖然我們在內存中創建了它,但我們尚未將其附加到我們的文檔中。函數中的最後一行就是這麼做的:
quotes[i].appendChild(p);
quotes[i]
appendChild
是我們當前正在處理的塊引用元素。
還有兩個步驟。首先,我們需要在頁面首次加載時運行上述函數。實現這一點的方法有很多。最簡單的方法是將對該函數的調用添加到文檔主體元素的 onload 屬性中:
這可以正常工作,但我們可以做得更好。由於我們的 JavaScript 函數將託管在外部文件中,那麼外部文件也導致函數運行豈不是更有意義?天真的做法是用下面的 JavaScript 代碼:
window.onload = extractBlockquoteCitations;
//
請注意,我們提供了函數的名稱,但忽略了末尾的 (),這將導致函數執行。 JavaScript 支持函數式編程風格,這意味著函數可以像任何其他數據對像一樣被傳遞作為參數、存儲在數據結構中,甚至可以從其他函數返回。我將在以後的文章中更多地討論這個主題,但結果是將函數賦值給 window.onload
將導致它在頁面加載完成後執行。
然而,此解決方案也存在一個缺點。如果你想在一個給定的頁面上使用多個在頁面加載完成後執行的腳本,那麼最後一個向 window.onload
註冊自身的腳本將是唯一執行的腳本。真正需要的是一種方法,可以在不覆蓋已有的內容的情況下將我們的函數附加到窗口對象的 onload 處理程序。不幸的是,Internet Explorer 和其他瀏覽器在如何處理這種動態事件附加方面有所不同;幸運的是,Scott Andrew 發布了一個可以處理這些差異的函數。以下是該函數:
function extractBlockquoteCitations() { var quotes = document.getElementsByTagName('blockquote'); for (var i = 0; i < quotes.length; i++) { var cite = quotes[i].getAttribute('cite'); if (cite) { var a = document.createElement('a'); a.setAttribute('href', cite); a.setAttribute('title', cite); a.appendChild(document.createTextNode('Source')); var p = document.createElement('p'); p.className = 'blockquotesource'; p.appendChild(a); quotes[i].appendChild(p); } } }
以下是將我們的 blockquotes 函數添加到窗口對象的 load 事件的代碼:
addEvent(window, 'load', extractBlockquoteCitations);
最後一步是用 CSS 設置引文的樣式。這是一個處理塊引用的相對簡單的 CSS 代碼片段:
function addEvent(obj, evType, fn){ if (obj.addEventListener){ obj.addEventListener(evType, fn, false); return true; } else if (obj.attachEvent){ var r = obj.attachEvent("on"+evType, fn); return r; } else { return false; } }
成品可以在這裡查看。
現在,讓我們考慮一個更高級的動態效果——面板切換器。這裡的目標是在頁面上放置多個面板(使用 div 標記),一次只顯示一個面板。一組始終可見的鏈接可用於選擇當前顯示的面板。這對於構建類似於選項卡式界面以瀏覽一系列相關屏幕非常有用,而無需每次選擇選項卡時都刷新頁面。
每當使用 JavaScript 增強頁面時,需要記住一個好規則,即即使禁用 JavaScript,頁面也必須仍然可用。在這種情況下,這意味著理想的解決方案應該在啟用 JavaScript 時按廣告宣傳的那樣工作,但在非 JavaScript 環境中應在頁面上顯示所有面板,每個鏈接都直接鏈接到相關面板,並使用 URL 片段。
那麼,這是可能工作的最簡單的標記:
令人驚訝的是,以上幾乎是我們為了掛鉤一些 JavaScript 以創建所需效果而需要的全部標記。我們可以繼續使用上面的代碼,但是讓我們向鏈接添加一個類,以明確說明我們希望對它們執行特殊操作:
<a href="https://www.php.cn/link/65dfa16ba6de9bdb34ea435c9fe2a425" class="toggle">Panel 1</a> | <a href="https://www.php.cn/link/379d08c7a38df48c777c07ea990a3bcf" class="toggle">Panel 2</a>
//
以下是 JavaScript 的工作方式。當頁面加載時,腳本將掃描頁面上的所有鏈接,查找其類中包含“toggle”的任何鏈接。對於找到的任何鏈接,將檢查 href 屬性,並將其中指定的元素定位並添加到目標元素數組中。除了第一個元素之外,所有其他元素都將“關閉”,因此當頁面加載時,只有第一個面板將保持可見。鏈接本身將附加 JavaScript 事件處理程序,以便在激活它們時,可以顯示其相應的面板。
完整的腳本可以在這裡查看。以下是代碼工作原理的逐步講解。
var et_toggleElements = [];
第一行創建了一個全局空數組,它將保存頁面上面板元素的引用。因為此腳本具有全局變量和許多函數,我們將每個函數都加上前綴“et_”(代表“easy toggle”)——這降低了我們的函數與同一頁面加載的其他腳本發生名稱衝突的可能性。
/* Initialisation */ function et_init() { var i, link, id, target, first; first = true; for (i = 0; (link = document.links[i]); i ) { ... }
到目前為止,我們已經初始化了一些變量,將 first 標誌設置為 true,並開始迭代文檔中的所有鏈接。使用 var
聲明變量非常重要,因為它確保變量對函數是本地的。如果沒有此步驟,它們將是全局可訪問的,並且可能會干擾其他腳本。
if (/btoggleb/.exec(link.className)) { ... }
此條件檢查當前鏈接的類中是否包含“toggle”。我們使用正則表達式,而不是只檢查 link.className == 'toggle'
,因為類屬性可以包含多個類,用空格分隔。 /btoggleb/
是正則表達式;b
部分匹配“單詞邊界”,它可能是空格或字符串的開頭或結尾。
id = link.href.split('#')[1];
如果鏈接的類列表中包含 toggle,我們假設鏈接的目標是 URL 片段。
link.href.split('#')
在 # 標記處拆分鏈接 href——我們知道我們感興趣的部分在 # 之後,因此我們直接使用 [1]
索引結果數組以提取目標 ID。
target = document.getElementById(id); et_toggleElements[et_toggleElements.length] = target;
在這裡,我們做出了另一個假設——鏈接指示的元素確實存在。我們使用 getElementById()
方法獲取該元素,然後通過將其分配給等於數組當前長度的數組索引來將其添加到我們的元素數組中。這是有效的,因為數組從 0 開始索引,但數組長度從 1 開始計數;因此,數組的長度也是數組中下一個空槽的索引。
if (first) { first = false; } else { target.style.display = 'none'; }
這就是我們前面定義的 first 標誌發揮作用的地方。我們希望網站上的第一個面板保持可見,而其他面板使用 JavaScript 等效於 CSS 中的“display: none”來隱藏。該標誌允許我們做到這一點。
link.onclick = et_toggle;
最後,我們將 et_toggle
函數分配給鏈接的 onclick
事件,導致每次激活鏈接時調用該函數。下一步是定義該函數。
function extractBlockquoteCitations() { var quotes = document.getElementsByTagName('blockquote'); for (var i = 0; i < quotes.length; i++) { var cite = quotes[i].getAttribute('cite'); if (cite) { var a = document.createElement('a'); a.setAttribute('href', cite); a.setAttribute('title', cite); a.appendChild(document.createTextNode('Source')); var p = document.createElement('p'); p.className = 'blockquotesource'; p.appendChild(a); quotes[i].appendChild(p); } } }
再次,我們使用 split
方法從鏈接中提取 ID。
現在我們知道要顯示哪個面板了,我們可以遍歷我們的元素數組,關閉除 ID 與所需面板的 ID 匹配的元素之外的所有其他元素。
通過返回 false,我們阻止鏈接在激活時實際被跟隨,這可能會導致在瀏覽器中查看的頁面上出現不希望的跳轉。
最後一步是使用前面描述的 addEvent
函數將 et_init
函數註冊到窗口的 load 事件中。
addEvent(window, 'load', et_init);
你可以在此處查看運行中的完成代碼。
在本文中,我們看到了結構良好的標記可以與 JavaScript 和 W3C DOM 配合使用以實現有用效果的兩種方式。我希望這篇文章能激勵你尋找使用 JavaScript 和智能標記的新方法。
還有許多其他基於結構化標記的 JavaScript 效果的優秀示例。以下是一些值得關注的示例:
JavaScript 中的結構化標記是指使用 HTML 元素來描述 Web 文檔的內容和結構。這些元素包括標題、段落、列表等等。 JavaScript 可以操作這些元素來創建動態和交互式的網頁。例如,JavaScript 可以更改 HTML 元素的內容,更改 HTML 元素的樣式 (CSS),甚至添加新的 HTML 元素。
JavaScript 通過文檔對像模型 (DOM) 與 HTML 元素交互。 DOM 表示網頁的結構,JavaScript 可以操作它。例如,JavaScript 可以使用 document.createTextNode()
方法創建一個新的文本節點,然後將其附加到現有的 HTML 元素。
JavaScript 中的文本節點是一種節點類型,它表示元素或屬性的文本內容。它可以使用 document.createTextNode()
方法創建。此方法創建一個新的文本節點,可以將其附加到現有的 HTML 元素,允許你動態地向網頁添加文本。
可以通過幾種方法將 JavaScript 添加到 HTML。可以使用 <script></script>
標籤直接將其包含在 HTML 文件中,或者可以使用 <script></script>
標籤的 src
屬性鏈接到外部 JavaScript 文件。還可以使用 onclick
或 onload
等事件屬性在發生特定事件時運行 JavaScript 代碼。
document.createTextNode()
方法? document.createTextNode()
方法用於創建一個新的文本節點。首先使用要添加的文本作為參數調用此方法。這將返回一個新的文本節點,然後可以使用 appendChild()
方法將其附加到現有的 HTML 元素。
文檔對像模型 (DOM) 是 HTML 和 XML 文檔的編程接口。它將文檔的結構表示為對象的樹,每個對象代表文檔的一部分。 JavaScript 可以與 DOM 交互以操作網頁的內容和結構。
可以使用 JavaScript 中的 innerHTML
屬性更改 HTML 元素的內容。此屬性可用於獲取或設置元素的 HTML 內容。例如,如果有一個 id 為“myElement”的元素,則可以像這樣更改其內容:document.getElementById('myElement').innerHTML = 'New content';
。
可以使用 JavaScript 中的 style
屬性更改 HTML 元素的樣式。此屬性是一個對象,其中包含元素的所有 CSS 屬性。例如,如果有一個 id 為“myElement”的元素,則可以像這樣更改其顏色:document.getElementById('myElement').style.color = 'red';
。
可以使用 JavaScript 中的 createElement()
方法添加新的 HTML 元素。此方法創建一個新元素,然後可以使用 appendChild()
方法將其附加到現有元素。例如,可以創建一個新的段落並將其添加到文檔的主體中,如下所示:var p = document.createElement('p'); document.body.appendChild(p);
。
JavaScript 中的事件屬性用於定義在發生特定事件時要運行的 JavaScript 代碼。這些事件可能包括單擊按鈕 (onclick
)、頁面加載 (onload
) 或鼠標移到元素上 (onmouseover
) 等。事件的代碼直接在 HTML 元素的屬性中定義。
以上是用JavaScript增強結構標記的詳細內容。更多資訊請關注PHP中文網其他相關文章!