Как стать автором
Обновить

Учим InternetExplorer хорошему: расширяем прототипы DOM элементов.

Чулан
Возникла у меня проблемка расширять стандартные HTMLElement объекты, только не в Firefox'e, а в IE. Можно использовать библиотеку Prototype или JSX. Но мне не понравилось это решение из-за того, что используется надстройка, а не приятный глазу механизм обращения к элементам через DOM. Например, хочу, чтобы в IE появился новый метод
someDOMElement.getLastChild()


В Firefox я бы написал:
HTMLElement.prototype.getLastChild = function ()
{
	var childndex = null;
	for ( i = this.childNodes.length; i > 0 ; i-- )
	{
		if ( this.childNodes[i-1].nodeType != 1 )
			continue;
		childIndex = i-1;
		break;
	}
	return this.childNodes[childIndex];
}


В IE такая фишка не проходит, из-за корявой поддержки в нём объектности элементов. Хотя, все объекты в нём класса Object или производного от него Element, но расширять их нельзя. Можно только каждый конкретный экземпляр (пробежаться по все DOM элементам документа). Выход нашёлся в технологии HTC (HTML Components), которая поддерживается начиная с IE5.5

Я не буду вдаваться в подробности, а сразу перейду к тому, как это делается (зачастую этого достаточно, чтобы понять подробности):
<PUBLIC:COMPONENT lightWeight="true" literalContent="true">
	<PUBLIC:METHOD NAME="getLastChild" />
	<SCRIPT LANGUAGE="javascript1.3" type="text/javascript">
	function getLastChild()
	{
		var childndex = null;
		for ( i = childNodes.length; i > 0 ; i-- )
		{
			if ( childNodes[i-1].nodeType != 1 )
				continue;
			childIndex = i-1;
			break;
		}
		return childNodes[childIndex];
	}
	</SCRIPT>
</PUBLIC:COMPONENT>


&ltPUBLIC:COMPONENT lightWeight=«true» literalContent=«true»>
означает начало определение компонента. lightWeight означает, кратко, что нет ничего другого, кроме описания. literalContent означает, что код не будет парситься XHTML парсером, а будет передан сразу парсеру Javascript.

Код, что выше, должен размещаться в отдельном файле с расширением ".htc". Подключать на страницу лучше в условном комментарии:
<!--[if IE]>
<style>
* {
behavior: URL('/uri/to/file.htc');
}
</style>
<[endif]-->


теперь код:
var el = document.getElementsByTagName("body")[0].getLastChild();

будет работать и в FF и в IE.

Работать в Opere и других браузерах такой код не будет, к большому сожалению. Но, думаю, я найду (или кто-то расскажет) как это реализовать в остальных браузерах.

Естественно, технология HTC этим не ограничивается и позволяет добавлять новые события, свойства, значения по-умолчанию, а так же, создавать свои тэги.
Теги:
Хабы:
Всего голосов 7: ↑5 и ↓2 +3
Просмотры 339
Комментарии Комментарии 3