19.01.2015, 16:01
|
Интересующийся
|
|
Регистрация: 28.12.2014
Сообщений: 20
|
|
Функция 'забывает', из какого места она вызвана
Из одной функции вызываю вторую, которая, при наличии вложений, должна вызывать саму себя с новыми аргументами.
function parseDrawnTreeElems(ContainerParId) {
// бла бла
for (var i=0; i<window.document.getElementById(ContainerParId).children.length; i++) {
parseDrawnTreeElems(window.document.getElementById(ContainerParId).children[i].id);
}
Всё работает нормально, пока цикл спускается 'лесенкой' без пропусков по вложениям первой ноды, однако, как только встречается нода без детей и цикл не запускается, она прекращает своё выполнение полностью.
Я предполагал, что она должна вернуться туда, откуда была запущена и продолжить со следуюущей ноды на том уровне, где была вызвана.
Интересно, что аналогичная конструкция с циклом for.. in (по свойствам объектов) у меня работает корректно, а тут я упускаю что-то важное. Киньте хоть ссылку, пожалуйста, а то моего словарного запаса не хватает, чтобы гугл ответил что-нибудь внятное. Такое ощущение, что уже где-то читал об этом, но все мои поисковые запросы ведут в никуда.
|
|
19.01.2015, 16:59
|
|
Профессор
|
|
Регистрация: 11.09.2010
Сообщений: 8,804
|
|
Пошагово выполняй. Ошибок точно в консоль не выпадает?
DOM не изменяешь в процессе работы функции?
Про TreeWalker и NodeIterator слышал?
Зачем в цикле вызываешь функцию getElementById с одним и тем же аргументом?
__________________
В личку только с интересными предложениями
|
|
20.01.2015, 05:54
|
Интересующийся
|
|
Регистрация: 28.12.2014
Сообщений: 20
|
|
danik.js,
DOM не меняется.
За TreeWalker и NodeIterator - спасибо огромное, добавил в избранное.
Сообщение от danik.js
|
Зачем в цикле вызываешь функцию getElementById с одним и тем же аргументом?
|
Не понял вопрос. Возможно, именно здесь я что-то упускаю?
Сообщение от danik.js
|
Пошагово выполняй. Ошибок точно в консоль не выпадает?
|
Ошибок нет, выполняю пошагово, всё увешал консоле.логами и алёртами.
4. По завершении подвызова предыдущий контекст достаётся из стека, выполнение в нём возобновляется.
Собственно, именно такого поведения и ожидаю, но что-то сильно не так с контекстом или чем-то около него.
Вопрос остаётся открытым.
|
|
20.01.2015, 06:24
|
|
Профессор
|
|
Регистрация: 30.04.2012
Сообщений: 3,018
|
|
Так ты получается запускаешь ф-цию, которая пробегается по всем детям элемента и для каждого из них запускает эту же ф-цию, которая опять запускает себя в цикле для каждого ребёнка, и т.д., где логика? Или обьясни, что ты хочешь сделать?
Последний раз редактировалось ruslan_mart, 20.01.2015 в 06:26.
|
|
20.01.2015, 08:45
|
Интересующийся
|
|
Регистрация: 28.12.2014
Сообщений: 20
|
|
Ruslan_xDD,
Изначальная задумка - да, перебор всех детей у каждого элемента, для поиска последнего ребёнка с заданным параметрами (они хранятся в атрибутах 'data-XXXX'), поэтому lastChild не катит.
Потом я меняю у найденного элемента стили, и эта проверка должна пройти по всем элементам дерева.
Вот я накатал примерчик с массивами, который прекрасно работает, к отличие от моего кода.
function try2RecurseIt() {
var MyArr = [[1,[2,3],4],[5,6],[7,8,[9,0]]];
letsDance(MyArr);
}
function letsDance(arr) {
for (var i=0; i<arr.length; i++) {
console.log("arr["+i+"] "+ arr[i]);
if (arr[i].constructor.toString().indexOf("Array") > -1) { // isArray check
letsDance(arr[i]);
}
}
}
Собственно, проблема не связана с изменениями в DOM, она более общая и где-то в другом месте. В основном коде уже убрал все действия, кроме консоле.логов, уже поменял переменную i на gsagdfsa, чтобы она была наверняка уникальной, но всё равно не могу понять, где и почему (и - что) теряет контекст выполнения. Блин.
|
|
20.01.2015, 09:10
|
Интересующийся
|
|
Регистрация: 28.12.2014
Сообщений: 20
|
|
Всё, вопрос снят. Код был не такой:
function parseDrawnTreeElems(ContainerParId) {
// бла бла
for (var i=0; i<window.document.getElementById(ContainerParId).children.length; i++) {
parseDrawnTreeElems(window.document.getElementById(ContainerParId).children[i].id);
}
Собственно, '// бла бла' мне всё и перекосило.
Я, когда готовил вопрос, выкидывал из кода лишнее, вот и выплеснул ребёнка вместе с водой.
Реальный код вместо 'бла-бла' был примерно такой:
function parseDrawnTreeElems(ContainerParId) {
ParId = ContainerParId.slice(9); // (****)
А в вызове внутри функции стояла не переменная ContainerParId, а полученная из неё ParId:
parseDrawnTreeElems(window.document.getElementById(ParId).children[i].id);
}
И вся фигня происходила от того, что я в строке **** не использовал слово 'var'.
Блин.
Блин.
Блин.
|
|
20.01.2015, 10:54
|
|
Профессор
|
|
Регистрация: 11.09.2010
Сообщений: 8,804
|
|
И все-таки замени все это на TreeWalker, хотя сам не помню как с ним работать.
А вообще - ты неправильный подход выбрал. Наверняка ведь можно сделать так, чтобы не пришлось лазить по всему DOM'у чтобы найти то, что нужно.
__________________
В личку только с интересными предложениями
|
|
20.01.2015, 11:32
|
Интересующийся
|
|
Регистрация: 28.12.2014
Сообщений: 20
|
|
danik.js,
да, я глянул TreeWalker на МДН, очень интересная штука, буду иметь ввиду.
Насчёт неправильного подхода - наверняка так и есть, я юзаю то, что знаю, а знаю я пока немного. ))
|
|
|
|