Разверните эту рекурсию в цикл)
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, время: 14:49. |