17 августа 2009, 20:42

javascript: «Bug» with previousSibling

У нас есть вот такой список HTML тэгов
<label for="text">Enter text</label>
<input name="text" type="text">
Если вызвать функцию, от имени инпута, и потом попытаться повлиять на его previousSibling, которым по идее есть label, мы упрёмся в текстовую ноду (.style is undefined — у которой нету понятия стиль и т. д., а обидно ;) ). Быстрый способ это вылечить, это написать весь HTML в одну строку, то есть убрать перенос, но это блин не выход ;)

Для этого можно написать «свой», «правильный» previousSibling, или, по желанию, модифицировать существующий, что, на моё мнение, будет излишним ;) Как всегда, залезем в прототип и дадим стране угля Обжектам, типа Нод Element (crossbrowser fix, thx Сергей Морозов), новую функцию
Element.prototype.pSib = function() { 
	var node = this; 
	while (node = node.previousSibling) { 
		// нам не нужен текст, йо ;)
		if (node.nodeType != 3) continue; 
	} 
	return node; 
}
// использовать вот так
var sometop = someid.pSib().style.top;

1 комментарий РСС

Сергей Морозов
Да, но это не кроссбраузерное решение. IE не поддерживает Node, HTMLElement и т. д. Вот если бы без лишних наворотов поместить этот код в отдельную функцию, а не в прототип узла, тогда везде будет работать.
Vitaliy Bogdanets
Да, что-то совсем забыл о ИЕ, и всё реже о нём вспоминаю.
Ну функция будет простой выход из положения ;)))
function pSib(obj) { 
	while (obj = obj.previousSibling)
		if (obj.nodeType != 3) return obj; 
	return null; 
}

Но я думаю, что стоит просто Node заменить на Element и в 7 и в 8 ИЕ начинает работать как часы, жаль на 6том уже негде потестить ;) Придётся ставить виртуалку.

Ваш комментарий

адрес не будет опубликован

ХТМЛ не работает


Ctrl + Enter