Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Помогите с рекурсивной функцией (https://javascript.ru/forum/jquery/54674-pomogite-s-rekursivnojj-funkciejj.html)

WebBizMedia 27.03.2015 12:38

Помогите с рекурсивной функцией
 
Второй день голову ломаю, нужно визуализировать для пользователя иерархию DOM, вот что получилось на текущий момент:
function createTreeDoom(objRoot,treeRoot){	 
	var child = objRoot.children();			 
	if(child.length > 0){					
		if(!treeRoot){						
			var wrapTree = $('#layerTree');
			treeRoot = $('<ul/>',{text: objRoot.get(0).tagName+'_'+objRoot.attr('title')}).appendTo(wrapTree);
		}
		$.each(child, function(){
			var newlayer = $('<ul/>',{text: $(this).get(0).tagName+'_'+$(this).attr('title')}).appendTo(treeRoot);
				newlayer.data('obj_id',$(this).attr('id'));
				newlayer.css('margin-left','20px');
				if(child.children().length > 0){
						return createTreeDoom(child,newlayer);
				};
			});	
		};
				
};


Функция должна проходить по DOM-дереву и визуализировать его структуру.
Допустим есть такая структура:
<div class="pages" title="root">
			<div title="div1"></div>
			<div title="div2">
				<div title="div4">
					<div title="div6"></div>
					<div title="div7"></div>
				</div>
				<div title="div5"></div>
			</div>
			<div title="div3"></div>
		</div>


Но на выходе получаю не совсем что нужно:

DIV_root
DIV_div1
DIV_div4
DIV_div6
DIV_div7
DIV_div5
DIV_div6
DIV_div7
DIV_div2
DIV_div4
DIV_div6
DIV_div7
DIV_div5
DIV_div6
DIV_div7
DIV_div3
DIV_div4
DIV_div6
DIV_div7
DIV_div5
DIV_div6
DIV_div7

рони 27.03.2015 12:52

WebBizMedia,
сюда бы рекурсивный итератор прикрутить --- мысли вслух :)

laimas 27.03.2015 13:23

Цитата:

Сообщение от рони (Сообщение 363540)
WebBizMedia,
сюда бы рекурсивный итератор прикрутить --- мысли вслух :)

На одном из форумов была задача проверки сервером html, которую клиент мог использовать в сообщении. Нужно было проверять и вложенность и целостность.

Рекурсия при этом не обязательна, главное это правила, а проход циклом с использованием массива в качестве стека - первым вошел, последним вышел.

Там я писал на РНР, получая элементы с помощью рег. выражений, а на клиенте они уже есть как коллекция.

WebBizMedia 27.03.2015 14:01

Цитата:

Сообщение от laimas (Сообщение 363547)
На одном из форумов была задача проверки сервером html, которую клиент мог использовать в сообщении. Нужно было проверять и вложенность и целостность.

Рекурсия при этом не обязательна, главное это правила, а проход циклом с использованием массива в качестве стека - первым вошел, последним вышел.

Там я писал на РНР, получая элементы с помощью рег. выражений, а на клиенте они уже есть как коллекция.

laimas, а можно пример хотябы и на РНР

laimas 27.03.2015 14:43

Не зачем, хотя если не будет понятно, тогда приведу его. Единственная оговорка, это будем считать в данном случае html-код валидный на 100%.

Как работает - будем помещать в массив (push) открывающий тег каждой ветви дерева, и извлекая его из стека (pop), если следующий тег закрывающий и его имя равно тегу в вершине стека (ради производительности работаем с последним элементом массива). То есть получается имитация стека LIFO - последним пришел, первым вышел.

Ну и немного на примере вашего кода, как итерации цикла и действия, которые будут осуществляться в них:

1) Первый тег открывающий - заносим в стек
2) опять открывающий тег - заносим в стек
3) тег закрывающий, его имя равно тегу в вершине стека - извлекаем из стека, в стеке остался первый открывающий тег
4) открывающий тег - заносим в стек
5) открывающий тег - заносим в стек
6) открывающий тег - заносим в стек
7) тег закрывающий, его имя равно тегу в вершине стека - извлекаем из стека, в стеке остались открывающие теги (root, div1, div2, div4)

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

laimas 27.03.2015 15:01

У меня клава беспроводная, батарейки уже не тянут, глючит, дважды пропало писанное, поэтому сохранил, а это продолжение.

То что описал ранее, так работает на сервере, так как нужно проверять структуру кода и вложений. На клиенте разница будет в том, что нужно проверять не закрывающий тег, а наличие вложения, то есть в каждой ветви дерева - если нет вложения у элемента, значит в стек не заносим, если есть, то тег родителя помещаем в стек.

WebBizMedia 27.03.2015 15:53

laimas, за уделённое внимание спасибо, но у меня похоже уже мозг перегрелся и я нечего не понял ((

laimas 27.03.2015 16:11

Ну если не понятна сама суть, то и php-код показывать нет смысла.
Идея в том, что для контроля уровня вложения используется стек, его вершина - она растет при погружении в глубину вложения, и убывает при возврате назад. Для вашей задачи вершина стека и указывает на текущего родителя. Такое решение позволяет обойтись без рекурсии.

А не понятно, значит делайте рекурсивным обходом.

nerv_ 27.03.2015 16:17

Цитата:

Сообщение от рони
сюда бы рекурсивный итератор прикрутить --- мысли вслух

:) примерно так http://jsfiddle.net/929906h3/6/

Vlasenko Fedor 27.03.2015 19:02

Цитата:

Сообщение от WebBizMedia
нужно визуализировать для пользователя иерархию DOM

http://jsfiddle.net/vlasenkofedor/d6nyD/ :)


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