核心要点
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中文网其他相关文章!