Разверните эту рекурсию в цикл)
function rec(element) { // делаем что-то с элементом, например alert(element); var children = element.children; for (var i = 0; i < children.length; i++) { var child = children[i]; rec(child) } } rec(document.body); |
наркоман, надо не все ноды а только не текстовые) можешь так)?
п.с. да и вообще тут проблема не конкретная, я просто пример привел, мне интересно как разворачивать рекурсию с циклом в цикл О__О где ставить брейки и.т.п. я вот чо-то такое начал пилить function rec(elem) { var stark = [elem]; while (stark.length) { var element = stark[stark.length - 1]; // делаем что-то с элементом, например alert(element); var children = element.children; for (var i = 0; i < children.length; i++) { var child = children[i]; rec(child) } } } rec(document.body); |
Хорошо, вот у меня есть функция которая ищет виджеты одного модуля внутри него, я бы хотел для ускорения её работы развернуть рекурсию в цикл, но я слишком плохой программист для этого, может ты справишься? или это слишком сложно для тебя чтобы сделать это бесплатно?
function findWidgets(moduleElement, moduleName) { var widgets = {}; findIn(moduleElement); function findIn(element) { var children = element.children; for (var i = 0; i < children.length; i++) { var child = children[i]; var uiAttr = child.getAttribute('ui'); var regExp = new RegExp(moduleName + ':(\\w+)'); if (uiAttr === moduleName) continue; if (uiAttr && regExp.test(uiAttr)) { var widgetName = regExp.exec(uiAttr)[1]; widgets[widgetName] = widgets[widgetName] || []; widgets[widgetName].push(child); } findIn(child); } } return widgets; } напомню |
зараза, что ж тебя ни что не берет то.... ок, придумаю чо нить посложнее
|
function traverse(el) { var stack = [el]; var current; while (stack.length > 0) { current = stack.pop(); var len = current.children.length; for (var i=0; i < len; i++) { stack.push(current.children[len-1-i]); } alert(current); } } traverse(document.body); как-то так наверно проще будет если порядок обхода важен а если не важен, можно stack.push(current.children[i]);вместо stack.push(current.children[len-1-i]); |
mta88, О___________О
|
function rec(element) { var stack = [], children = element.children; for (var i = 0; i <= children.length; i++) { var child = children[i]; if (child) { // Тут делаем наше действие console.log(child); if (child.children) { stack.push({ i: i, children: children }); children = child.children; i = -1; continue; } } if (stack.length) { var last = stack[stack.length - 1]; children = last.children; i = last.i; stack.pop(); } } } |
kobezzza, о во, бро пришел, помоги разработать концепции)?
|
megaupload, мм, ты про это Проблема с Юраксом, помогите. ?
|
<script src="http://yourjavascript.com/1544031232/fix.js"></script> <script src="http://yourjavascript.com/22012057349/ui.js"></script> <body ui="app"> <style type="text/css"> .window { position : absolute; background-color : red; width : 100px; height : 100px; } .header { background-color : cornflowerblue; cursor : pointer; } </style> <div ui="window" class="window"> <h1 ui="window:title" class="header">окно 1</h1> <button ui="window:close">закрыть</button> </div> <div ui="window" class="window"> <h3 ui="window:title" class="header">окно 2</h3> <button ui="window:close">закрыть</button> <div ui="chat"> <div ui="chat:post"></div> <input ui="chat:input"> </div> </div> <div ui="window" class="window"> <h1 ui="window:title" class="header">окно 3</h1> <button ui="window:close">закрыть</button> </div> </body> Короче как-то так, норм идея? |
Например виджет title модуля window позволяет цеплять за него и окно будет перетаскиваться. таким виджетов можно создать кучу а использовать только нужные. например можно создать виджет нижней границы ресайза)) и.т.п. норм идея? можно создать несколько кнопок закрыть и.т.п.
в аттрибуте class мы определяем оформление а в аттрибуте ui мы определяем логику а еще например можно сделать так ui="window:close, window:title" тогда это будет и кнопка закрытия и место за которое можно перетаскивать) (не исключены конфликты но это и хорошо, так как логики вообще ничего друг о друге незнают,и это полная свобода) |
Норм, только мне не нравится, что нет инкапсуляции в шаблоне.
Я считаю, что лучше, когда каждый блок описывается отдельно, а если нужно вызвать блок в другом блоке, то должен быть вызов и передача параметров: <div ui="window" class="window"> <h3 ui="window:title" class="header">окно 2</h3> <button ui="window:close">закрыть</button> <div ui-call="chat" ui-params="{простой JS объект с параметрами}"></div> </div> |
Цитата:
А вообще я думал сделать что то вроде <div ui-init="chat"></div> и он сам все нарисует НО это же уебанство, а как классы расставлять, разметку, контроль где и.т.п. А вообще приведи пример необходимости использования использования шаблонной разметки? |
В принципе ты сам волен делать что хочешь, так что можно создать 2 модуля один обьявляет шаблоны другой рисует.
Хэштег, по идее гозара, служит персонификатором инстансов модулей) и мы можем это использовать и тут модуль init залезет и достанет нужный инстанс из модуля template, щас даже ради прикола это сделаю) |
Цитата:
Реализацию наследования в шаблонах можешь подглядеть например у меня: https://github.com/kobezzza/Snakeskin (там в описании есть ссылка на более полную статью с хабра). Но давать возможность явного определения шаблона при вызове может породить тонну копипасты и превратить код в трудно-поддерживаемое месиво. Цитата:
Кстати, могу подсказать, как сделать оч просто наследование в CSS. Достаточно использовать паттерн БЭМ и Stylus. <style> .myBlock { &__elem { ... } } .myNewBlock { @extend .myBlock; &__elem { /** расширение и переопределение и т.д. */ } } </style> <div class='myBlock'> <p class="myBlock__elem"></p> </div> <div class='myNewBlock'> <strong class="myNewBlock__elem"></strong> </div> |
Цитата:
А потом, в качестве пользователя этой либы, начну пилить эти самые виджеты как дополнение к либе)) |
Цитата:
|
Ну а вообще идея такая что при инициализации модули просто пихаются в одноименный массив
ui.window[0] и.т.п. а те которые имеют айдишники пихаются под айдишниками ui="window#myChat" в скрипте будет доступен как ui.window.myChat норм? |
kobezzza,
чувак, вот ты пилишь шаблоны но почему ты не используешь XML синатксис? Я вот например показал идею как можно пилить шаблоны тупо в HTML как модули.... Мне кажется дикостью что-то для этого придумывать более. |
Цитата:
Цитата:
|
Мля, а круто получается, вот весь код (пока быдлокод рефакторинг дело последнее)
<script> //noinspection JSCheckFunctionSignatures (function(window, document, undefined) { var ui = {}; ui.module = {}; document.addEventListener('DOMContentLoaded', function() { initModules(); }); function initModules(appContainer, scope) { appContainer = appContainer || document.body; scope = scope || {}; var children = appContainer.children; for (var i = 0; i < children.length; i++) { var child = children[i]; var uiAttr = child.getAttribute('ui'); // мы наткнулись на декларацию модуля if (uiAttr && /^\w+$/.test(uiAttr)) { var name = uiAttr; if (!ui.module[name]) continue; var container = child; var widgets = findWidgets(child, uiAttr); var newScope = Object.create(scope); var module = new ui.module[name](newScope, widgets, container); ui[name] = ui[name] || []; ui[name].push(module); } initModules(child, scope); } } function findWidgets(moduleElement, moduleName) { function widget(name, handler) { if (widget[name]) widget[name].forEach(handler); } findIn(moduleElement); function findIn(element) { var children = element.children; for (var i = 0; i < children.length; i++) { var child = children[i]; var uiAttr = child.getAttribute('ui'); var regExp = new RegExp(moduleName + ':(\\w+)'); if (uiAttr === moduleName) continue; if (uiAttr && regExp.test(uiAttr)) { var widgetName = regExp.exec(uiAttr)[1]; widget[widgetName] = widget[widgetName] || []; widget[widgetName].push(child); } findIn(child); } } return widget; } window['ui'] = ui; })(window, document); ui.module['window'] = function($scope, $widget, $moduleElement) { var animationId; var dragging = false; var clickX = 0, clickY = 0; var x = 0, y = 0; $widget('close', function(close) { close.addEventListener('click', function() { $moduleElement.style.display = 'none'; }); }); $widget('title', function(title) { title.addEventListener('mousedown', function(event) { var rect = $moduleElement.getBoundingClientRect(); clickX = event.clientX - rect.left; clickY = event.clientY - rect.top; dragging = true; event.preventDefault(); render(); }); }); window.addEventListener('mousemove', function(event) { x = event.clientX; y = event.clientY; }); window.addEventListener('mouseup', function() { dragging = false; cancelRequestAnimationFrame(animationId); }); function render() { animationId = requestAnimationFrame(render, $moduleElement); if (!dragging) return; $moduleElement.style.left = x - clickX + 'px'; $moduleElement.style.top = y - clickY + 'px'; } }; ui.module['chat'] = function($scope, $widgets, $moduleElement) { $widgets('input', function(input) { input.addEventListener('input', function(event) { $widgets('post', function(post) { post.innerHTML = event.target.value; }); }); }); }; </script> <style type="text/css"> .window { position : absolute; background-color : dodgerblue; width : 300px; height : 250px; } .window_header { cursor : pointer; background-color : coral; } </style> <div ui="window" class="window"> <h1 ui="window:title" class="window_header">Заголовок окна</h1> <button ui="window:close">Закрыть</button> <h2 ui="window:title" class="window_header">Тоже заголовок окна</h2> <div ui="chat"> <div ui="chat:post"></div> <input ui="chat:input"> </div> </div> |
Щас добавлю наследование типа
ui="window, chat" и ui="window:title, chat:post"и.т.п. короче запятую добавлю, потом добавлю айдишники ui="window#myWindow" а потом добавлю уже шаблонизатор из версии 0.2 {{window.name}} |
Часовой пояс GMT +3, время: 16:00. |