Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Доступ к элементу после модификации HTML inner и outer (https://javascript.ru/forum/misc/73991-dostup-k-ehlementu-posle-modifikacii-html-inner-i-outer.html)

xShift 03.06.2018 19:47

Доступ к элементу после модификации HTML inner и outer
 
В общем пилил запиливатель красивых элементов форм на чистом JS и нашел угарный баг браузеров.

Lets look:

let test = document.querySelectorAll('#tabs');

	test[0].parentElement.parentElement.outerHTML = '<div class="zalupa">'+ test[0].parentElement.parentElement.outerHTML +'</div>';

	console.log( document.querySelectorAll('#logotype')[0].closest('#mainHeader') ); // work

	console.log( test[0].parentElement.parentElement.parentElement ); // zalupa null

	console.log( test[0].closest('.zalupa') );	// zalupa null


<div id="shell">
		<header id="mainHeader">
			<h1 id="logotype">
				<a href="#" data-title="and add">adds</a> 
				:: <span>asdasdasdsad</span></h1>
		</header>
	</div><!--#shell-->

	<div id="testElements">
		
		<section style="text-align: center; width: 980px; margin: 0 auto">
			<aside id="tabs" class="tabs">
				<ul>
					<li data-link="tab-1">1</li>
					<li class="activetab" data-link="tab-2">2</li>
					<li data-link="tab-3">3</li>
				</ul>

				<div data-content="tab-1">Tous mes rêves se réalisent.</div>

				<div class="tabactive" data-content="tab-2">Si on vit sans but, on mourra pour rien.</div>

				<div data-content="tab-3">Jouis de chaque moment.</div>

			</aside>
		</section>
</div>



В общем долго не понимал почему нет доступа к залупе :haha: и почему у меня не работает unwrap . Оказывается залупа не добавляется в какой-то там node-list и приходится каждый раз получать через querySelector.

И тогда я решил создавать залупу не строчно, но c помощью запиленной в браузер функциональности:

let test = document.querySelectorAll('#tabs');

	let zalupa = document.createElement('div');

	zalupa.classList.add('zalupa');

	zalupa.innerHTML = test[0].parentElement.parentElement.outerHTML;

	test[0].parentElement.parentElement.outerHTML = zalupa.outerHTML

	console.log(test[0].closest('.zalupa')); // zalupa null


Таким образом выяснилось, что даже так залупа не появляется, а кроме innerHTML и outerHTML я средств манипуляции содержимым не знаю.

Может кто-то знает более изящный и простой способ манипулировать такими данными, чтобы они потом были доступны в next, previous node list и конечно closest или parentElement? Не охота мне писать createElement вообще ибо это расточительство.

Nexus 04.06.2018 10:41

Цитата:

Сообщение от xShift
и нашел угарный баг браузеров.

Если что-то работает не так, как вам хочется - это не значит, что это баг.

В первом варианте вы сохраняете в переменную test ссылку на DOM элемент, после изменяете outerHTML родителя. После внесения изменений ветка измененного родителя "перестраивается" и ваш test указывает уже на несуществующий элемент.

Во втором случае все почти тоже самое, только вы родителю "скармливаете" outerHTML виртуального DOM элемента.

xShift 04.06.2018 10:58

Nexus, так а решить то как по другому?

Nexus 04.06.2018 11:06

Цитата:

Сообщение от xShift
Nexus, так а решить то как по другому?

Я бы представление изменил или нашел решение без оборачивания элементов.

Alexandroppolus 04.06.2018 11:39

Если не менять логику с элементами, то можно вот так

var test = document.querySelectorAll('#tabs');
var parent = test[0].parentElement.parentElement;
var newParent = document.createElement('div');
newParent.className = 'zalupa';
parent.parentNode.replaceChild(newParent, parent);
newParent.appendChild(parent);


при этом все объекты-элементы сохраняются.

xShift 04.06.2018 12:25

Alexandroppolus, хм тоже выход оказывается. Но к сожалению не получается сделать без обезьяньих скачек по дереву разными методами.

ruslan_mart 04.06.2018 13:02

xShift, потому что нужно правильно оформлять HTML разметку, чтобы было удобно манипулировать DOM-элементами. Лично у меня, таких извращений не было с элементами, хотя я миллион раз писал различные модули табов, форм, модалок и т.д., на чистом JS. Просто пересмотрите свой подход. Даже не могу представить, в каком случае и при каком действии может понадобиться обернуть элемент в другой. Разметка должна быть строгой, а для манимуляции с DOM - вполне должно быть достаточно добавление/удаление новых элементов в каком-либо блоке, или изменение className. Все эти методы, типа wrap и т.д. - это чистой воды извращение, такого быть не должно и не должно возникать такой нужды при грамотном подходе к разметке и скриптингу в целом!

xShift 04.06.2018 15:41

ruslan_mart, окей, пишем стилизатор select. Как вы без замены стандартных options и их контейнера это сделаете без wrap. Вы конечно правы но бывают ситуации , когда в движек лезти и менять разметку нецелесообразно.

Nexus 04.06.2018 15:46

Цитата:

Сообщение от xShift
Как вы без замены стандартных options и их контейнера это сделаете без wrap

Скрыть нативный, добавить кастомный до/после нативного :)

xShift 04.06.2018 15:49

Nexus, и будете как обезьяна по next prev скакать чтобы selected отметить? Форма то должна работать потом а не просто для красоты.


Часовой пояс GMT +3, время: 02:56.