HTML Dog

跳至导航

Suckerfish :target

作者:Patrick Griffiths 和 Dan Webb

CSS3 带来了一个相当酷的伪类,即 :target,它可以用来高亮显示页面中的目标锚点。


h2:target {
	color: white;
	background: #f60;
}

基本上,以上述为例,如果有人在一个页面中选择了一个链接,其 href"#balloon",并且在该页面中有一个 id 属性为 "balloon"<h2> 元素,那么页面不仅会跳转到该元素,还会应用 h2:target 选择器指定的样式。

Mozilla 系列浏览器已经支持这个伪类。要在 Internet Explorer 中获得相同的结果,这个 Suckerfish 应该会非常有效。


sfTarget = function() {
	var sfEls=document.getElementsByTagName("H2");
	var aEls = document.getElementsByTagName("A");
	document.lastTarget = null;
	for (var i=0; i<sfEls.length; i++) {
		if (sfEls[i].id) {
			if (location.hash==("#" + sfEls[i].id)) {
				sfEls[i].className+=" " + cls;
				document.lastTarget=sfEls[i];
			}
			for (var j=0; j<aEls.length; j++) {
				if (aEls[j].hash==("#" + sfEls[i].id)) aEls[j].targetEl = sfEls[i]; aEls[j].onclick = function() {
					if (document.lastTarget) document.lastTarget.className = document.lastTarget.className.replace(new RegExp(" sftarget\\b"), "");
					if (this.targetEl) this.targetEl.className+=" sftarget"; document.lastTarget=this.targetEl;
					return true;
				}
			}
		}
	}
}
if (window.attachEvent) window.attachEvent("onload", sfTarget);

这个 'sfTarget' 函数比其他的 Suckerfish 函数要复杂一些。这是因为,为了复制其行为,该函数必须执行 3 个操作:

  1. 页面加载时,如果 URL 包含一个锚点(例如,'#something'),则必须应用 'sftarget' 类。
  2. 如果目标已激活,并且点击了另一个锚点,则必须通过从先前目标中移除 'sftarget' 类来将其恢复正常。
  3. 如果选择了一个包含锚点的链接,则必须将 'sftarget' 类添加到锚点的目标上。

那么,让我们来一步步了解 'sfTarget' 函数,看看它是如何工作的。

  1. 首先,我们使用标准的 Suckerfish 方法,收集需要函数处理的元素。在这种情况下,我们将收集文档中的所有 <h2> 元素(var sfEls=document.getElementsByTagName("H2");)。
  2. 然后,我们需要收集所有的 <a> 元素,因为之后我们还需要处理它们(var aEls = document.getElementsByTagName("A");)。
  3. 接着,我们创建一个附加到 document 元素的空变量(document.lastTarget = null;),它将保存最后一个被激活的目标元素的引用。稍后,我们将使用它来在激活新目标元素之前将其禁用,从而一次只保持一个目标元素处于活动状态。现在,我们将开始遍历上面收集到的所有 <h2> 元素,以应用其行为。
  4. 首先,我们将找出页面 URL 是否包含指向当前元素的锚点。我们可以通过检查 location.hash 属性来做到这一点。如果它包含指向当前元素 id 的引用,那么我们就需要为它添加 'sftarget' 类。
  5. 现在我们进入关键部分——与其他的 Suckerfish 函数类似,我们为相关的元素分配事件处理器,但这次我们必须将 onclick 事件处理器分配给指向目标的锚点,而不是目标本身。其次,锚点必须知道它的目标是谁,以便它可以将其 classname 设置为 'sftarget'。我们通过遍历每个锚点元素,并检查其 hash 属性(它链接到的目标)是否与当前目标的 id 相同来实现这一点。如果相同,我们就给它一个指向目标元素 ('targetEl') 的引用,并应用 onclick 事件处理器。请注意,我们不需要使用 onkeypress 事件处理器来照顾没有指向设备的用户的需求——onclick 同样可以处理按键操作。
  6. onclick 事件处理器内部,我们首先通过移除 'sftarget' 类来关闭上一个目标(如果存在),然后通过将 'sftarget' 类添加到 'targetEl' 来开启新目标。最后,我们返回 true,以便链接正常工作。

与所有其他 Suckerfish 方法一样,一旦实现了 JavaScript,您所要做的就是复制 :target 伪类选择器。


h2:target, h2.sftarget {
	color: white;
	background: #f60;
}

示例

也许这种方法最简单有益的应用场景是当页面中有很多被链接到的标题时,一点额外的提示会很有帮助。

如果锚点是代码块而不是标题,那么整个区域都可以被重新样式化(而不仅仅是标题)。例如,HTML Dog Blog 的评论 现在就采用了这种方法