addMethods

addMethods([methods])
addMethods(tagName, methods)

第一个参数的类型是一个 hash 列表,用于对 Element 对象进行扩展,hash 列表的名值对将转换为 扩展后 的元素的方法或属性。
第二种用法是扩展一个指定的 HTML 元素,tagName 指定 HTML 元素标签。

Element.addMethods 使你能够混入自己的方法到 Element 对象。混入后,可以在 $() 工具函数返回的 已扩展 的元素上使用你的方法,或者直接作为 Element 的方法,如下面的例子:

$(element).myOwnMethod([args...]); 

注意,也可以写成下面的方式:

Element.myOwnMethod(element|id[, args...]); 

为增加新的方法,只需简单的为 Element.addMethods 提供一个包括函数的 hash 对象。注意,hash 对象中每个函数的第一个参数必须是 element。在每个函数内,记得传递 element$(),并且,在函数结束时,若要支持在一行代码中对元素进行连续调用,请返回已扩展的 element

参数 [methods] 的形式与下述代码类似:

var myVeryOwnElementMethods = {
	myFirstMethod: function(element[, args...]) {
		element = $(element);
		// 你的程序
		return element; 
	}, 
	mySecondMethod: function(element[, args...]) {
		element = $(element);
		// 你的程序
		return element;
	}
}; 

仅扩展指定的元素(需要 v1.5.1 及后续的版本)

如果使用两个参数调用 Element.addMethods,则第一个参数是你希望增加自定义方法的 HTML 元素的标签名。

Element.addMethods('DIV', my_div_methods); 
// 自定义的方法仅增加到 DIV 元素上。 

第一个参数也可以是一个标签名数组:

Element.addMethods(['DIV', 'SPAN'], my_div_methods); 
// DIV 和 SPAN 拥有相同的扩展方法

标签名称并不区分大小写,在样例中均使用大写是为了使标签名看起来更为醒目。

最后的警告:Element.addMethods 有一个内建的安全机制,以防止你覆盖原生的元素方法或属性(如 getAttributeinnerHTML 等),但这并不能阻止你重写 Prototype 框架的方法。Prototype 在内部使用了许多自身的方法, 因此在使用该方法时请审查每一个步骤。

样例

想要在语义上清晰地标出你的元素,这需要在元素外围增加额外的 <div>。为什么不创建一个 Element.wrap('tagName') 方法,在指定的 tagName 中封装 element,然后返回封装好的封装器呢?

Element.addMethods({
	wrap: function(element, tagName) {
		element = $(element);
		var wrapper = document.createElement('tagName');
		element.parentNode.replaceChild(wrapper, element);
		wrapper.appendChild(element);
		return Element.extend(wrapper);
	}
}); 

用类似于下面的代码使用新增加的方法:

// 调用前:
<p id="first">Some content...</p> 
$(element).wrap('div'); // -> HTMLElement (div) 
// 调用后:
<div><p id="first">Some content...</p></div>

如果你确认你的 Element.wrap 方法返回新创建的 <div>,就等着到黄金时间感谢 Element.extend 吧,因为你可以立即链接一个新的方法到返回值上:

$(element).wrap('div').setStyle({backgroundImage: 'url(images/rounded-corner-top-left.png) top left'}); 

在 Web 应用中,你经常使用 Ajax.Updater 更新 DOM 元素吗? 想知道怎样才能又快又好的完成这项工作,并大幅缩减你的代码总量吗?试试这个法子:

Element.addMethods({
	ajaxUpdate: function(element, url, options) {
		element = $(element);
		element.update('<img src="/images/spinner.gif" alt="loading..." />');
		new Ajax.Updater(element, url, options);
		return element;
	}
}); 

现在,无论什么时候你想要更新一个元素的内容,只需像下面这样做就可以了:

$(element).ajaxUpdate('/new/content'); // -> HTMLElement

该方法首先替换 element 的内容为一个漂亮的 Ajax 请求等待指示器(译注:spinner.gif 图片),然后创建一个新的 Ajax.Updater。请求完成后,将自动移除指示器,并设置 element 的内容为 Ajax 请求返回的内容。

使用没有参数的 Element.addMethods

Element.addMethods 有一个不入流的小秘密,你能够不传递任何参数而直接调用它,会发生什么情况呢?它简单地遍历所有的 Element.MethodsElement.Methods.SimulatedForm.MethodsForm.Element.Methods,然后将它们增加到相关的 DOM 元素(Form.Methods 仅增加到 form 元素,相应的 Form.Element.Methods 仅扩展 inputselecttextarea)。

在什么情形下使用不带参数的 Element.addMethods

假如你希望为按钮增加一个方法,调用该方法后将使按钮失效,并替换其文本为类似于“Please wait...”的字样。 但你不希望这个方法应用于其它任何元素,要怎么做呢?请看下面的代码:

Form.Element.Methods.processing = function(element, text) {
	element = $(element); 
	if (element.tagName.toLowerCase() == 'input' && ['button', 'submit'].include(element.type))
	{
		element.value = (text === undefined ? 'Please wait...' : text);
		element.disable()
	}
	return element;
};

Element.addMethods(); 

译注:原文中的代码和说明有些不太相符,所以做了少许修改。其实可使用 addMethods(tagName, methods) 来实现上述的假设。