HTML Dog

跳至导航

吸盘鱼群

作者:Patrick Griffiths 和 Dan Webb

现在我们已经为最初的吸盘鱼开发了一系列变体,这种不起眼的小鱼开始变得有点像个怪物了。如果我们想同时使用多个吸盘鱼函数,我们需要一种方法来确保所有这些吸盘鱼都能在页面上和谐共存,而不会相互干扰,也不会不必要地重复代码。显然,有很多方法可以做到这一点,但这里有一种巧妙地称为“吸盘鱼群”的解决方案。

吸盘鱼群允许我们以模块化的方式将吸盘鱼行为应用于页面,这样您就可以只包含您需要的函数,从而最小化 HTML 或 JavaScript 文件的文件大小。此外,鱼群还提供了一个简单的框架,供您编写自己的吸盘鱼类函数,以弥补 IE 缺乏标准兼容性的问题。显然,有很多东西可以修复,所以可能性是巨大的。

此外,吸盘鱼群允许您将行为应用于的元素具有更大的灵活性。当您在页面上使用大量吸盘鱼行为时,这一点很重要,因为减少吸盘鱼操作的元素数量将最小化渲染时间。

好吧,管他呢,我们先直接跳进深水区,然后再解释如何游泳。这是代码(深吸一口气!)。


function suckerfish(type, tag, parentId) {
	if (window.attachEvent) {
		window.attachEvent("onload", function() {
			var sfEls = (parentId==null)?document.getElementsByTagName(tag):document.getElementById(parentId).getElementsByTagName(tag);
			type(sfEls);
		});
	}
}

sfHover = function(sfEls) {
	for (var i=0; i<sfEls.length; i++) {
		sfEls[i].onmouseover=function() {
			this.className+=" sfhover";
		}
		sfEls[i].onmouseout=function() {
			this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
		}
	}
}

sfFocus = function(sfEls) {
	for (var i=0; i<sfEls.length; i++) {
		sfEls[i].onfocus=function() {
			this.className+=" sffocus";
		}
		sfEls[i].onblur=function() {
			this.className=this.className.replace(new RegExp(" sffocus\\b"), "");
		}
	}
}

sfActive = function(sfEls) {
	for (var i=0; i<sfEls.length; i++) {
		sfEls[i].onmousedown=function() {
			this.className+=" sfactive";
		}
		sfEls[i].onmouseup=function() {
			this.className=this.className.replace(new RegExp(" sfactive\\b"), "");
		}
	}
}

sfTarget = function(sfEls) {
	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+=" sftarget";
				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) docu.lastTarget.className = document.lastTarget.className.replace(new RegExp(" sftarget\\b"), "");
					if (this.targetEl) this.targetEl.className+=" sftarget";
					document.lastTarget=this.targetEl;
					return true;
				}
			}
		}
	}
}

初始的 suckerfish() 函数接受一个吸盘鱼函数名,一个您想应用行为的标签,以及可选的父元素 id。例如,如果您想将吸盘鱼 :hover 应用于“nav”元素内的所有列表项(如吸盘鱼 :hover吸盘鱼下拉菜单示例中),您将这样做:


suckerfish(sfHover, "LI", "nav");

再举个例子,如果您想将吸盘鱼 :focus 添加到所有的 input 元素textarea 元素上,您将这样做:


suckerfish(sfFocus, "INPUT");
suckerfish(sfFocus, "TEXTAREA");

正如您所见,它比手动更改独立吸盘鱼函数中的 var sfEls... 行提供了更大的灵活性。

您可能已经注意到,特定吸盘鱼函数的代码与独立版本或多或少相同。因为这些“模块”是相互独立的,您可以简单地删除您不想使用的模块(而且您很可能不想使用所有模块),从而得到一个精简的解决方案。

示例

很可能,您不会想使用所有的吸盘鱼,但如果您真的想,您可以这样做