DevGang
Авторизоваться

Рекурсия в JavaScript 

В JavaScript рекурсия - это когда вы вызываете функцию изнутри себя до тех пор, пока условие не будет выполнено. Сегодня давайте посмотрим, как это работает.

Пример

Допустим, у вас есть коллекция вложенных элементов, например:

...

Вы хотите написать функцию JavaScript, которая позволит вам получить расстояние в дереве DOM между элементом и его родителем. Например, .bg-5 на два уровня выше .bg-7.

Создание вспомогательной функции

Сначала давайте создадим функцию levelsUp().

Мы передадим в elem и selector в качестве аргументов. Мы также добавим третий аргумент, который будем использовать для отслеживания distance между нашим elem и selector.

var levelsUp = function (elem, selector, distance) {
	// Do stuff...
};

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

Мы проверим, существует ли значение distance, и если нет, мы установим ему значение 0. Затем мы будем использовать ++ для увеличения нашего значения distance на 1.

var levelsUp = function (elem, selector, distance) {

	// If distance isn't defined yet, set it to 0
	if (!distance) {
		distance = 0;
	}

	// Increase the distance by 1
	distance++;

};

Далее мы получим parent от текущего elem с помощью свойства elem.parentNode.

var levelsUp = function (elem, selector, distance) {

	// If distance isn't defined yet, set it to 0
	if (!distance) {
		distance = 0;
	}

	// Increase the distance by 1
	distance++;

	// Get the parent of the current element
	var parent = elem.parentNode;

};

Теперь мы можем использовать метод matches(), чтобы проверить, совпадает ли parent c selector.

Если parent совпадение, мы можем вернуть наш distance.

var levelsUp = function (elem, selector, distance) {

	// If distance isn't defined yet, set it to 0
	if (!distance) {
		distance = 0;
	}

	// Increase the distance by 1
	distance++;

	// Get the parent of the current element
	var parent = elem.parentNode;

	// If we've reached the parent, return the distance
	if (parent.matches(selector)) return distance;

};

Добавление рекурсии

Вот здесь и начинается рекурсия.

Если parent не совпадает, мы хотим запустить снова levelsUp(), используя parent в качестве нашего начального элемента. Мы также передадим selector, и наш distance.

И поскольку функция в конечном итоге должна возвращать значение, мы с помощью return получим любой результат нашей рекурсивной функции levelsUp().

var levelsUp = function (elem, selector, distance) {

	// If distance isn't defined yet, set it to 0
	if (!distance) {
		distance = 0;
	}

	// Increase the distance by 1
	distance++;

	// Get the parent of the current element
	var parent = elem.parentNode;

	// If we've reached the parent, return the distance
	if (parent.matches(selector)) return distance;

	// Otherwise, recursively run levelsUp() again
	return levelsUp(parent, selector, distance);

};

Метод levelsUp() будет выполняться несколько раз до тех пор, пока не найдет совпадение или попадет в элемент window, и будет возвращать конечное значение distance если совпадение найдено (или , -1 если не найдено).

И теперь у нас есть рекурсивная функция.

Одна последняя деталь

Если соответствия selector нет, вы можете оказаться достаточно далеко в дереве DOM, чтобы попасть в элемент, который не поддерживает метод matches() (например, в window).

Прежде чем пытаться использовать matches(), давайте сначала проверим, поддерживает ли parent этот метод. Если нет, мы вернемся -1 и предположим, что совпадения нет.

var levelsUp = function (elem, selector, distance) {

	// If distance isn't defined yet, set it to 0
	if (!distance) {
		distance = 0;
	}

	// Increase the distance by 1
	distance++;

	// Get the parent of the current element
	var parent = elem.parentNode;

	// If you we reach an element with no matches() method, bail
	if (!parent.matches) return -1;

	// If we've reached the parent, return the distance
	if (parent.matches(selector)) return distance;

	// Otherwise, recursively run levelsUp() again
	return levelsUp(parent, selector, distance);

};

Поиграться на CodePen:

Источник:

#JavaScript
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

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

Попробовать

Оплатив хостинг 25$ в подарок вы получите 100$ на счет

Получить