Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Требуеться совет в реализации интерфейса! (https://javascript.ru/forum/dom-window/3892-trebuetsya-sovet-v-realizacii-interfejjsa.html)

B~Vladi 03.06.2009 11:17

Требуеться совет в реализации интерфейса!
 
Всем мир. Если кто сталкивался с такой задачей - подскажите.
Пока в подробности вдаваться не буду, опишу на пальцах.

Есть некий набор узлов-объектов(тупо div), с практически одинаковым содержимым, которое представляет собой управляющие элементы. У всех объектов есть одинаковый функционал и данные определённого типа, которые можно описать как их методы, и свойства.
Т.е. по-сути они пользуются одними функциями. Собственно вопрос в том, как эти функции реализовать. Есть два варианта: первый - создать кучу глобальных функций, тем самым завалить глобальными именами window, второй - описать это в виде объектов и через prototype(свойство а не библиотека) навесить на них свойств/методов. Я прекрасно понимаю, что второй вариант более предпочтительнее, но так же появляются сложности при обращении/нахождении нужного узла/объекта и от этого намного возрастает объём кода. Первый вариант так же плох тем, что далее на странице будет появляться новый код со своим функционалом и легко можно наткнуться на проблему совпадения имён, но его плюс - в меньшем объёме кода.
Приоритеты такие:
1. Маленький вес скриптов. (в идеале не более 30кб, что для этого проэкта вполне реально). Подходит первый вариант.
2. Универсальность кода. Для дальнейшего развития. Подходит второй вариант.
3. Быстрота исполнения кода. В этих областях я не силён, т.к. мало мануалов на эту тему. Если кто подскажет какой полезный ресурс из этой области - буду благодарен. Какой вариант подходит незнаю.

И ещё вопрос немного не в тему но из одной каши. Любой узел DOM это объект, которому можно прикрутить своё свойство или метод. Можно ли добавить ему свои свойства/методы через prototype? Спасибо.

Gvozd 03.06.2009 11:50

Цитата:

Сообщение от B~Vladi
Любой узел DOM это объект, которому можно прикрутить своё свойство или метод. Можно ли добавить ему свои свойства/методы через prototype

увы-нет
делаете необходимые функции, и присваиваете динамически всем интересубщим вам элементам.
кстати, внутри обработчика события this указывает на сам DOM-Элемент.
вот от него и добираетесь до всех соседних элементов, необходимых для работы этого элемента
как итог у нас имется все необходимые функции(каждая только один раз прописанная), и несколько циклов, перебирающие эелементы, и выставляющие им обработчики событий
главное выставление обработчиков делать посде того, как уже есть все элементы(т.е. после window.onload)
можно все эти функции обернуть в замыкание, и атким образом избавится от засирания глобальной области видимости

B~Vladi 03.06.2009 12:09

Цитата:

Сообщение от Gvozd
увы-нет

А жаль...
Цитата:

Сообщение от Gvozd
внутри обработчика события this указывает на сам DOM-Элемент

Да, с этим я столкнулся в первую очередь, когда писал вариант на объектах, но мне нужен был мой пользовательский объект а не узел и я долго ломал себе голову как его получать. Это и есть те сложности о которых шла речь для 2-го варианта. При разных вызовах функции в её this может попасть как узел так и объект event.
Цитата:

Сообщение от Gvozd
вот от него и добираетесь до всех соседних элементов, необходимых для работы этого элемента

Цитата:

Сообщение от Gvozd
несколько циклов, перебирающие эелементы

Да, такой вариант получения управляющих элементов возможен, но есть и другой. Каждый узел-объект и его внутренние управляющие элементы создаются динамически безо всяких innerHTML и тут же вешаются все нужные обработчики. Тут же я сохраняю полученные ссылки на эти этементы как свойства их узла-объекта. Затем при вызове какой-либо функции нахожу объект из которого был вызван обработчик и у меня получаются все ссылки на нужных его детей есть. Это очень удобно.
Цитата:

Сообщение от Gvozd
обернуть в замыкание

Ок, почитаю, посмотрю.

Я думаю о таком варианте. Не создавать пользовательских объектов, а пользоваться уже существующими. Речь идёт о моём наборе узлов. И уже в них хранить нужные ссылки на его детей, его свойства и методы. Но добавлять методы не через прототип не есть гуд для памяти(на сколько мне извесно).

Так же хотел заметить, что третий приоритет самый важный. В любом случае выберу вариант, который работает быстрее.

B~Vladi 03.06.2009 12:27

Посмотрел, про замыкания и понял, что это я знаю и уже рассматривал, как вариант. Но мне такой подход не нравится из-за "некрасивости" кода. Я считаю. что так писать нельзя ну или в самых крайних случаях.

Вот небольшой пример.У меня есть функция, которая создаёт мои узлы-объекты.

function create(){
   var o=document.createElement('div');
   o.show=function(){
      this.style.display='block';
   }
   o.hide=function(){
      this.style.display='none';
   }
   return o;
}


Я правильно понимаю, что на самом деле при создании нового о у меня будет создаваться так же ещё +2 функции ко всем?! т.е. у каждого о свои функции-методы и это не есть гуд?!

Octane 03.06.2009 12:50

А что мешает использовать addEventListener и attachEvent, чтобы не создавать каждый раз новую копию show/hide?

Да и функцию, как объект, можно использовать по ссылке:
<html>
<head>
<script type="text/javascript">
window.onload = function() {
	function F() {}
	var a = document.getElementById("test1");
	var b = document.getElementById("test2");
	a.onclick = F;
	a.onclick.key = true;
	b.onclick = F;
	alert(b.onclick.key);
	alert(F.key); // Функция используется по ссылке (не копируется), поэтому везде доступно её свойство key.
};
</script>
</head>
<body>
	<div id="test1">text1</div>
	<div id="test2">text2</div>
</body>
</html>

B~Vladi 03.06.2009 12:58

Цитата:

Сообщение от Octane
А что мешает использовать addEventListener и attachEvent

Ничто не мешает, т.к. эти методы вешают обработчик событий, а не добавляют методы к объекту. Вопрос в том, как делать?!

либо так:
function create(){
   var o=document.createElement('div');
   o.show=function(){
      this.style.display='block';
   }
   o.hide=function(){
      this.style.display='none';
   }
   addEventListener(o,'click',o.hide,false);
   return o;
}

либо так:
function create(){
   var o=document.createElement('div');
   return o;
}
function hide(){
   var o=получаем_объект;
   o.style.display='none';
}
addEventListener(create(),'click',hide,false);

B~Vladi 03.06.2009 13:06

Хотелось бы понять, как избавиться от засирания window и тем временем не плодить лишних объектов/функций, засирая этим память.

Octane 03.06.2009 13:13

Не внимательно прочитал, да назначение обработчиков здесь не причем.

Так как в IE6,7 нельзя добавить свой метод в прототип HTMLElement, то используют обёртки.
function F(node) {
     this.node = node;
}

F.prototype = {
     show: function() {
        this.node.style.display = 'block';
     },
     hide: function() {
        this.node.style.display = 'none';
     }
};

Используют так:
var obj = new F(document.getElementById('…'));

obj.show();
obj.hide();

obj.node // – ссылка на узел


Чтобы не писать каждый раз new, можно добавить что-то вроде такого:
function $(arg) {
      return new F(typeof arg == 'string' ? document.getElementById(arg) : arg);
}


Используем:
var obj = $('…');

obj.hide()

…

B~Vladi 03.06.2009 13:21

Octane, спасибо, отличный вариант. По-вашему это лучше, чем без объектов?! Просто хотелось бы понять, как это всё влияет на производительность скрипта.
Цитата:

Сообщение от Octane
Так как в IE6,7 нельзя добавить свой метод в прототип HTMLElement

Если чесно, не знал... Плохо конечно...

Octane 03.06.2009 13:27

Цитата:

Сообщение от B~Vladi
По-вашему это лучше, чем без объектов?!

Не понял о чем это.
Цитата:

Сообщение от B~Vladi
как это всё влияет на производительность скрипта.

Конструирование нового объекта немного замедляет работу, но другого варианта кросс-браузерно добавить полученному DOM-объекту набор методов, не копируя ссылки на них, нет.

B~Vladi 03.06.2009 13:34

Цитата:

Сообщение от Octane
Не понял о чем это.

О двух последних функциях. которые я приводил. Возможно это не лучший пример но суть там такая: для добавления функционала можно использовать либо методы(как в вашем примере), срабатываемые в обработчике, либо обычные функции, срабатывающие в том же обработчике. Сначала меня клонило в сторону использования ООП, но потом понял, что можно обойтись и без создания каких-либо объектов и прототипов, т.е. они просто лишне. Правильна ли такая позиция?!

B~Vladi 03.06.2009 13:36

Цитата:

Сообщение от Octane
другого варианта кросс-браузерно добавить полученному DOM-объекту набор методов, не копируя ссылки на них, нет.

Если чесно, я не вижу, чтобы методы принадлежали именно DOM-узлу. Получается он просто завёрнут в объект.

Octane 03.06.2009 13:46

Цитата:

Сообщение от B~Vladi (Сообщение 20782)
Сначала меня клонило в сторону использования ООП, но потом понял, что можно обойтись и без создания каких-либо объектов и прототипов, т.е. они просто лишне. Правильна ли такая позиция?!

Ну можно и просто набор функций создать, в которые, при вызове, будет передаваться ссылка на DOM-узел вместе с отальными параметрами:
var DOM = {
  show: function(node) {
     node.style.diplay = 'block';
  },
  hasClass: function(node, className) {
      return (' ' + node.className + ' ').indexOf(' ' + className + ' ') != -1;
  }
};

var element = document.getElementById('…');

if (DOM.hasClass(element, 'my-class')) {
   …
}

раз не нравятся конструкторы с прототипами.

Цитата:

Сообщение от B~Vladi (Сообщение 20784)
Если чесно, я не вижу, чтобы методы принадлежали именно DOM-узлу. Получается он просто завёрнут в объект.

Да, именно так. Он завернут в объект, в прототипе которого есть методы для работы с DOM-узлом.

B~Vladi 03.06.2009 13:53

Цитата:

Сообщение от Octane
раз не нравятся конструкторы с прототипами.

Мне всё нравится. И объекты и их прототипы/конструкторы. Я хочу понять какой вариант использовать и почему.

x-yuri 03.06.2009 15:37

Цитата:

Посмотрел, про замыкания и понял, что это я знаю и уже рассматривал, как вариант. Но мне такой подход не нравится из-за "некрасивости" кода. Я считаю. что так писать нельзя ну или в самых крайних случаях.
ты про такое читал?
(function() {
var a = 1;
})();
alert( a );

B~Vladi 03.06.2009 15:52

да, читал, и что?!

B~Vladi 03.06.2009 15:57

Цитата:

Сообщение от Octane
Так как в IE6,7 нельзя добавить свой метод в прототип HTMLElement, то используют обёртки.

DOM-объекту можно назначить метод. Мне и не надо было добавлять метод всем узлам, а только определённым.

Например вот такой код:

var div=document.getElementById('div');
div.method=function(){
   alert('It`s DIV');
}
div.method();


работает в ie, ff, opera.


Часовой пояс GMT +3, время: 04:20.