Javascript.RU

Удобное дерево с AJAX-подгрузкой

Эта статья показывает, как написать простое и удобное дерево с AJAX-подгрузкой узлов.

Она основана на материалах грамотное javascript-дерево и интеграция AJAX в интерфейс.

Добавить AJAX-подгрузку, используя эти две технологии - очень просто. Вообще, это может послужить основой для того, чтобы создавать любые AJAX-виджеты и сложные системы интерфейсов.

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

id
ID узла DOM, который служит контейнером для дерева
url
Адрес, с которого подгружать узлы при помощи AJAX-запроса

Код ниже полностью описывает дерево, за исключением функции AJAX-подгрузки узлов load, которая будет разобрана ниже. Он полностью соответствует оригинальной статье, только чуть реорганизован.

Все, что он делает - это отслеживает клик на элементе element.onclick, содержащем дерево, получает узел по event.target и, если узел не содержит элементов и еще не было попыток загрузки - то получает его с сервера вызовом load. Саму функцию загрузки load разберем дальше в статье.

Функции hasClass и toggleNode - вспомогательные, для индикации скрытия-открытия ветки дерева через CSS-класс.

function tree(id, url) {
	var element = document.getElementById(id)

	/* вспомогательная функция */
	function hasClass(elem, className) {
		return new RegExp("(^|\\s)"+className+"(\\s|$)").test(elem.className)
	}

	function toggleNode(node) {
		// определить новый класс для узла
		var newClass = hasClass(node, 'ExpandOpen') ? 'ExpandClosed' : 'ExpandOpen'
		// заменить текущий класс на newClass
		// регексп находит отдельно стоящий open|close и меняет на newClass
		var re =  /(^|\s)(ExpandOpen|ExpandClosed)(\s|$)/
		node.className = node.className.replace(re, '$1'+newClass+'$3')
	}

	function load(node) {/* ... загрузить узел с сервера, код далее ... */}

	element.onclick = function(event) {
		event = event || window.event
		var clickedElem = event.target || event.srcElement

		if (!hasClass(clickedElem, 'Expand')) {
			return // клик не там
		}

		// Node, на который кликнули
		var node = clickedElem.parentNode
		if (hasClass(node, 'ExpandLeaf')) {
			return // клик на листе
		}

		if (node.isLoaded || node.getElementsByTagName('LI').length) {
			// Узел уже загружен через AJAX(возможно он пуст)
			toggleNode(node)
			return
		}


		if (node.getElementsByTagName('LI').length) {
			// Узел не был загружен при помощи AJAX, но у него почему-то есть потомки
			// Например, эти узлы были в DOM дерева до вызова tree()
			// Как правило, это "структурные" узлы
			// ничего подгружать не надо
			toggleNode(node)
			return
		}

		// загрузить узел
		load(node)
	}
}

Чтобы инициализовать дерево - достаточно запустить функцию tree на DOM-контейнере для дерева.

Вспомним, что согласно структуре дерева - для этого служит элемент UL.

Можно взять дерево с уже готовыми узлами, а можно и пустое дерево с единственным корневым узлом "Каталог", вот такого вида (просто картинка, рабочий вариант далее):

Наше дерево:
  • Каталог

HTML-код:

Наше дерево:
<ul class="Container" id="tree">
  <li class="Node IsRoot IsLast ExpandClosed">
    <div class="Expand"></div>
    <div class="Content">Каталог</div>
    <ul class="Container">
    </ul>
  </li>
</ul>

Яваскрипт-вызов для инициализации дерева:

tree('id', '/ajax/data.php')

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

Для этого нужно реализовать метод load и необходимые вспомогательные функции.

При описании дерева была предусмотрена AJAX-индикация, а в статье по интеграции AJAX в интерфейс - стандартные методы и последовательность вызовов. Остается применить их для дерева.

...

function load(node) {

	/*
	  код этих трех функций - 
      как в статье по интеграции AJAX в интерфейсы 
    */ 
	function onSuccess(data) {... }
	function onAjaxError(xhr, status) {... }
	function onLoadError(error) { ...}

    /*
	  функция showLoading использует способ 
      AJAX-индикации через CSS из этой же статьи.
    */
	function showLoading(on) {
		var expand = node.getElementsByTagName('DIV')[0]
		expand.className = on ? 'ExpandLoading' : 'Expand'
	}

	function onLoaded(data) {

		for(var i=0; i<data.length; i++) {
			var child = data[i]
			var li = document.createElement('LI')
			li.id = child.id

			li.className = "Node Expand" + (child.isFolder ? 'Closed' : 'Leaf')
			if (i == data.length-1) li.className += ' IsLast'

			li.innerHTML = '<div class="Expand"></div><div class="Content">'+child.title+'</div>'
			if (child.isFolder) {
				li.innerHTML += '<ul class="Container"></ul>'
			}
			node.getElementsByTagName('UL')[0].appendChild(li)
		}

		node.isLoaded = true
		toggleNode(node)
	}


	showLoading(true)


	$.ajax({
		url: url,
		data: node.id,
		dataType: "json",
		success: onSuccess,
		error: onAjaxError,
		cache: false
	})
}
...

Для начала заметим, что все вспомогательные функции объявлены внутри load. Это удобно, т.к. автоматически дает им доступ к узлу node.

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

Оригинальная функция здесь, пожалуй, всего одна - это onLoaded. Она принимает данные с сервера в виде массива объектов-детей:

[
  { id: 1, title: 'Node 1', isFolder: 1},
  { id: 2, title: 'Node 2', isFolder: 1},
  { id: 3, title: 'Node 3', isFolder: 0}
]

Из этих объектов создается DOM-структура дерева.

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

Жмите на +, чтобы загрузить детей с сервера.

На стороне сервера используется скрипт, который сначала полсекунды спит (чтобы продемонстрировать индикацию загрузки), а затем возвращает 3 узла с последовательными номерами и примерно 33%-ным шансом того, что узел является листовым (isFolder=0).

Наше дерево:
  • Каталог

Вы также можете:


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 11:25
#permalink

Models flux canny designed to provide structural guidance using canny edges taken from an input image along with a text prompt.


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 10:47
#permalink

Models flux canny designed to provide structural guidance using canny edges taken from an input image along with a text prompt.


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 10:47
#permalink

Models flux canny designed to provide structural guidance using canny edges taken from an input image along with a text prompt.


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 10:48
#permalink

Models flux canny designed to provide structural guidance using canny edges taken from an input image along with a text prompt.


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 10:48
#permalink

Thanks for sharing FLUX Canny


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 10:49
#permalink

Thanks for sharing FLUX Canny


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 11:10
#permalink

Models flux canny designed to provide structural guidance using canny edges taken from an input image along with a text prompt.


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 11:11
#permalink

Models flux canny designed to provide structural guidance using canny edges taken from an input image along with a text prompt.


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 11:24
#permalink

Thanks for sharing https://fluxcanny.online/


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 12:17
#permalink

Models flux canny designed to provide structural guidance using canny edges taken from an input image along with a text prompt.


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 12:18
#permalink

Models flux canny designed to provide structural guidance using canny edges taken from an input image along with a text prompt.


Автор: Гость (не зарегистрирован), дата: 26 ноября, 2024 - 12:20
#permalink

This blog should be shared, as the information I discovered here holds value that transcends monetary worth FLUX Tools .


Автор: dotyhughes117 (не зарегистрирован), дата: 26 ноября, 2024 - 23:47
#permalink

May I quote some of the information found in your web site to my local people? kitchen remodeling jacksonville


Автор: dotyhughes117 (не зарегистрирован), дата: 26 ноября, 2024 - 23:48
#permalink

May I quote some of the information found in your web site to my local people? kitchen remodeling jacksonville


Автор: fritzsara5225 (не зарегистрирован), дата: 27 ноября, 2024 - 00:17
#permalink

Hope you will not get tired on making posts as informative as this.
bathroom remodeling jacksonville


Автор: Гость (не зарегистрирован), дата: 27 ноября, 2024 - 11:03
#permalink

Models flux canny designed to provide structural guidance using canny edges taken from an input image along with a text prompt.


Автор: Гость (не зарегистрирован), дата: 27 ноября, 2024 - 11:05
#permalink

FLUX.1 AI Tools is a set of models that enhances our main text-to-image model, FLUX.1. It flux tools allows users to control and adjust images, whether they are real or generated.


Автор: rubewrenn269 (не зарегистрирован), дата: 27 ноября, 2024 - 13:05
#permalink

Great blog! I found some interesting things in here that I might use for future references. kitchen remodeling nashville


 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum