Модераторы: Sardar, Aliance

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> DOM (HTML) Element в IE - от кого наследуется? 
:(
    Опции темы
dsCode
Дата 31.12.2007, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



Сабджект... Понятно, что от Object. Однако, FF и Opera после создания DOM-элемента (например, div) позволяют получить в этом элементе доступ к свойству constructor и constructor.prototype (сам элемент свойства prototype не имеет). Таким образом, можно расширить стандартные DOM-объекты. Рабочий пример:

Код

<html>
  <head>
    <title>ds [.code]</title>
    <script type="text/javascript">
      (function() {

        var div = document.createElement('div');

        // div - инстанс window.HTMLElement, который в свою очередь - инстанс Object
        alert([div instanceof window.HTMLElement, window.HTMLElement instanceof Object]);

        // конструктор div'a - function, прототип - объект
        alert([typeof div.constructor, typeof div.constructor.prototype]);

        // конструктор - window.HTMLDivElement (который является инстансом window.HTMLElement)
        alert([div.constructor === window.HTMLDivElement]);

        // расширяем прототип window.HTMLDivElement'a
        div.constructor.prototype.setContent = function(content) {
          this.innerHTML = 'Content of div, id #' + this.id + ' is: <b>' + content + '</b>';
          return true;
        };

        delete div;

        // расширяем прототип Object
        Object.prototype.setContentFromObject = function() {
          this.innerHTML += '<br />Content of ' + this.tagName + ', id #' + this.id + ' from Object';
          return true;

        }
      })();
    </script>
  </head>
  <body>

    <div id="test"></div>

    <script type="text/javascript">

      // теперь все div'ы имеют метод setContent,
      // унаследованный от window.HTMLDivElement'a
      var d = document.getElementById('test');
      d.setContent('ds [.code]');

      // а также метод setContentFromObject - от Object
      d.setContentFromObject();

    </script>
  </body>
</html>


Вопрос: если div наследуется от Object:

IE:

Код

var d = document.createElement('div');
alert([typeof d, d instanceof Object]);


то почему, d не видит метода setContentFromObject? И вообще, можно ли получить доступ к конструктору (и его прототипу) DOM-элемента в IE?

P.S.: всех с наступающим Новым годом, коллеги! Здоровья, счастья, успехов, побед!


--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
AKS
Дата 1.1.2008, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Цитата(dsCode @  31.12.2007,  21:49 Найти цитируемый пост)
Вопрос: если div наследуется от Object...

В IE <div> не наследует от Object. Проверьте:
Код

var d = document.createElement('div');
alert([d instanceof Object, d instanceof ActiveXObject]);


Цитата(dsCode @  31.12.2007,  21:49 Найти цитируемый пост)
...можно ли получить доступ к конструктору (и его прототипу) DOM-элемента в IE?

Нет, нельзя. Используемая концепция COM как-раз подразумевает обратное - объекты находятся в физически разных модулях, взаимодействующих между собой лишь посредством определенных интерфейсов. Эта концепция реализована во множестве майкрософтовсих платформ, одной из которых является IE.

PM MAIL   Вверх
dsCode
Дата 1.1.2008, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



Цитата(AKS @  1.1.2008,  10:58 Найти цитируемый пост)
В IE <div> не наследует от Object. Проверьте:

уй-ё.. Вот я лажанулся-то =) Мне реально показалось, что d instanceof Object == true, а не false (и я стал создавать тему =)))

Цитата(AKS @  1.1.2008,  10:58 Найти цитируемый пост)
Используемая концепция COM как-раз подразумевает обратное - объекты находятся в физически разных модулях, взаимодействующих между собой лишь посредством определенных интерфейсов.


объекты в разных модулях - это имеется в виду див и его конструктор? А что это за модули? И доступа к "определенным интерфейсам" тоже не получить, чтобы связаться...

Спасибо, AKS =)


--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
AKS
Дата 1.1.2008, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Цитата(dsCode @  1.1.2008,  14:46 Найти цитируемый пост)
...объекты в разных модулях - это имеется в виду див и его конструктор?

Нет, я имел ввиду jscript-объекты и элементы документа. Т.е. jscript'вский Object - это одна "песня",  и к узлам документа (к элементам, в частности) эта "песня" не имеет никакого отношения.

Цитата(dsCode @  1.1.2008,  14:46 Найти цитируемый пост)
И доступа к "определенным интерфейсам" тоже не получить, чтобы связаться...

Доступ к интерфейсам Вы как-раз имеете. Т.е. Вы имеете в своем распоряжении некий API (интерфейс программирования приложений), позовляющий Вам получить доступ средствами одного языка программирования (в данном случае речь о jscript) к объектам, написанным на другом языке программирования. 
А вот какую функциональность предоставили Вам "гениальные" майкрософтовские кодеры - это уже другой вопрос. Получилось так, что они решили не давать Вам доступ к конструктору элемента, о котором Вы писали. Можно даже резюмировать следующим образом - все, что касается "происхождения" элементов документа, просто-напросто "скрыли в черном ящике". 
Однако винить в чем-либо разработчиков IE было бы совершенно нелепо. Они используют "привычный" для своих продуктов технологический стандарт COM, и им незачем от него отказываться (программисты, как известно, о-о-очень редко отказываются от того, что, как они любят выражаться, "итак работает" ;) ).
PM MAIL   Вверх
dsCode
Дата 1.1.2008, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



ну да, в общем получается для расширения DOM-объектов в IE надо пихать эту функцию (расширения) в метод получения объекта (т.е. хранить расширенные методы для каждого объекта индивидуально; ну и помечать, что объект уже расширен, чтобы не делать холостых операций каждый раз), в то время как в FF и Opera все это можно хранить в прототипе конструктора, что намного "легче" (по весу объектов, т.к. в последнем случае они ссылаются на нужный прототип):

Код

<html>
  <head>
    <title>ds [.code]</title>
    <script type="text/javascript">

      Object.extend = function(destination, source) {
        for (property in source) {
          destination[property] = source[property];
        }
        return destination;
      }

      var $ = function(id) {
        var obj = document.getElementById(id);
        // для FF и Opera - расширили в самом window.HTMLElement
        if (window.HTMLElement) {
          return obj;
        }
        // для IE - индивидуально для каждого объекта
        if (!obj.__extended) {
          Object.extend(obj, {
            show: function() {
              obj.style.display = '';
              return obj;
            },
            hide: function() {
              obj.style.display = 'none';
              return obj;
            },
            isHidden: function() {
              return (obj.style.display == 'none');
            }
          });
          obj.__extended = true;
        }
        return obj;
      }

    </script>
  </head>
  <body>
    <div id="test">test</div>
    <input type="button" value="Show / Hide"
      onclick="
        var div = $('test');
        //div.hide().show();
        if (div.isHidden()) {
          div.show();
        } else {
          div.hide();
        }
        return true;
      "
    />
  </body>
</html>



--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
AKS
Дата 1.1.2008, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



dsCode, можно сделать несколько проще. Используя специфичные для IE HTML компоненты, можно добиться почти того же самого, что и в случае с FF/Opera (даже определить геттеры/сеттеры для элементов):
html (с кодом для FF, в котором специально написал геттер isHidden):
Код

<html>
<head>
<title>ds [.code]</title>
<style type='text/css'>
* {
    behavior:url(b.htc); /* !!! ie css extention */
}    
</style>    
<script type='text/javascript'>

if (typeof window.HTMLElement == 'function') {
    window.p = window.HTMLElement.prototype;
    p.changeDisplayValue = function () {
        this.style.display = this.isHidden
                             ? '' : 'none';
    };
    p.__defineGetter__('isHidden',
                       function () {
                           return (this.style.display == 'none');
                       });
    delete p;
};

</script>
</head>
<body>
    <div id='test'>test</div>
    <input type='button'
           value='Show / Hide'
           onclick='document.getElementById("test").changeDisplayValue();'>
</body>
</html>

htc (для IE):
Код

<public:component lightweight='true'>
<public:property name='isHidden' get='getDisplayValue' />
<script type='text/jscript'>
/*<![CDATA[*/

if (typeof window.ActiveXObject == 'function' &&
        typeof window.ActiveXObject.prototype == 'object') {
    var p = window.ActiveXObject.prototype;
    if (typeof p.changeDisplayValue != 'function') {
        p.changeDisplayValue = function () {
            this.style.display = this.isHidden
                                 ? '' : 'none';
        };
        p.getDisplayValue = function () {
            return (this.style.display == 'none');
        };
    };
    var getDisplayValue = p.getDisplayValue;
    element.changeDisplayValue = p.changeDisplayValue;
};

/*]]>*/
</script>
</public:component>

PM MAIL   Вверх
cruelangel
Дата 2.1.2008, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 319
Регистрация: 12.9.2007

Репутация: 4
Всего: 8



Код

document.styleSheets[0].addRule( '*', 'behavior: expression( Object.extend( this ) )' );


Это сообщение отредактировал(а) cruelangel - 2.1.2008, 19:43
PM MAIL   Вверх
dsCode
Дата 5.1.2008, 01:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



прошу прощения, что долго не отвечал, я в отъезде (до сих пор) =)

AKScruelangel, спасибо за ответы. Кстати, насчет htc и behavior в стиле я как-то и не знаю вообще (и последней конструкции в частности - ...'*', 'behavior: expression(...) ...). Расскажите, если не трудно, что это значит для IE, ну и "пару ссылок" почитать тоже было бы неплохо =)

И еще вопрос - есть ли разница, если геттер/сеттер объявлен как "обычный метод" или через __defineGetter__ (он, вроде, доступен только в Gecko)? И если нет, то зачем эти __defineGetter__ / __defineSetter__? Для красоты?


--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
AKS
Дата 5.1.2008, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Цитата(dsCode @  5.1.2008,  01:07 Найти цитируемый пост)
"пару ссылок" почитать тоже было бы неплохо...

HTC Reference
Introduction to DHTML Behaviors
behavior Attribute
setExpression Method

Цитата(dsCode @  5.1.2008,  01:07 Найти цитируемый пост)
есть ли разница, если геттер/сеттер объявлен как "обычный метод" или через __defineGetter__ (он, вроде, доступен только в Gecko)

Разница есть, конечно же. При создании такое свойство ("виртуальное" св-во, на самом деле это ведь метод), судя по всему, получает атрибут { ReadOnly }, т.к. "переписать" такое св-во не удастся. Ну и использовать их проще - var a = myObj.get; myObj.set = a * 2;
Чаще всего можно встретить писанину, в которой показывают, как геттеры/сеттеры использовать для доступа к "приватным" св-вам. Только для ECMAScript 3 "возня" с "приватом" не столь актуальна. 
Можно, естественно, "поручить" геттерам/сеттерам и более сложную логику, что-нибудь, вроде такого:
Код

var a = {
    a: 0,
    
    get b () {
        var res = this.a * 2;
        if (!isFinite(res)) {
            res = this.a;
        };
        return res;
    },
    
    set b (v) {
        if (!isFinite(v)) {
            v = this.a;
        };
        this.a = v;
    }
};

console.log(a.b);

a.b = -10;

console.log(a.b);

Но, поскольку, геттеры/сеттеры пока поддерживаются только на ограниченном кол-ве платформ:
  • Firefox
  • Opera 9.5
  • Safari 3
 особо на них рассчитывать не приходится - в других браузерах такой код станет причиной "вылета" ошибки...

PM MAIL   Вверх
dsCode
Дата 8.1.2008, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



AKS, ага, thx =) И еще парочка вопросов:

- часто ли кто использует htc в своих разработках? Теоретически для IE можно было бы расширить прототип ActiveXObject'a и использовать нужные методы. Или так не получилось бы и надо обязательно через htc - расширять прототип ActiveXObject'a, а потом копировать в функцию element'a (себе: вот лень самому написать проверить, надо здесь писать, да? =)))? Но вообще, конечно, понятно - от ActiveXObject'a много кто наследуется (и инстанцируется), а не только какой-то там div, поэтому "засорять" его (ActiveXObject) только для div'a - тоже мало смысла.

- насчет геттеров/сеттеров - значит единственное отличие - это ReadOnly атрибут - т.е. если не будет сеттера и написать a.b = 3 вылезет ошибка, что для этого свойства есть только геттер, а менять его нельзя, с этим понятно =) Ну и мини-вопрос - разницы между get b и __defineGetter__(...) нет, да? Я знал их и раньше, но никогда не использовал. Да собственно, и не вижу особой надобности на данном этапе. Единственное применение - какие-нибудь внутренние свойства какого-нибудь ядра (фреймворка), которое могут все использовать, но  менять свойства внутренних сущностей - нет.

Это сообщение отредактировал(а) dsCode - 8.1.2008, 15:09


--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
AKS
Дата 8.1.2008, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Цитата(dsCode @  8.1.2008,  15:04 Найти цитируемый пост)
...часто ли кто использует htc в своих разработках? 

Мне ничего не известно о подобной статистике. Можно обойтись одним только Jscript'ом, htc - это "навороты" немного из другой области.

Цитата(dsCode @  8.1.2008,  15:04 Найти цитируемый пост)
Теоретически для IE можно было бы расширить прототип ActiveXObject'a и использовать нужные методы.

Если только теоретически, поскольку расширяй-не расширяй - толку нет (элементы ничего не узнают об этих методах). Это я просто ради эксперимента его использовал, т.ч. не обращайте внимание.

Цитата(dsCode @  8.1.2008,  15:04 Найти цитируемый пост)
...разницы между get b и __defineGetter__(...) нет, да?

Разница-то всегда должна быть, а иначе зачем разный синтаксис. __defineGetter__ можно использовать когда угодно (динамически, а не в момент инициализации объекта).
PM MAIL   Вверх
dsCode
Дата 8.1.2008, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



Цитата(AKS @  8.1.2008,  15:41 Найти цитируемый пост)
Мне ничего не известно о подобной статистике

я имел в виду здешних участников форума =) ну да ладно

Цитата(AKS @  8.1.2008,  15:41 Найти цитируемый пост)
поскольку расширяй-не расширяй - толку нет (элементы ничего не узнают об этих методах)

хех, тогда, конечно, какой смысл?! я-то думал, что они будут "видны". Тогда и смысла не было в расширении ActiveXObject.prototype  в примере с htc и можно было написать element.changeDisplayValue = function()  {...};. А вообще странно... почему не будут видны? prototype - есть, расширить можно, div - инстанс ActiveXObject'a и может достучаться (не напрямую, ибо - суть темы, а как инстанс) до (уже расширенного) прототипа..

Цитата(AKS @  8.1.2008,  15:41 Найти цитируемый пост)
__defineGetter__ можно использовать когда угодно (динамически, а не в момент инициализации объекта). 

а, ну здесь - да, конечно - да.

P.S.: и в очередной раз - спасибо, еще +1 =)

Это сообщение отредактировал(а) dsCode - 8.1.2008, 18:44


--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
AKS
Дата 8.1.2008, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Цитата(dsCode @  8.1.2008,  18:35 Найти цитируемый пост)
...в примере с htc и можно было написать element.changeDisplayValue = function()  {...};. 

Неужели не уловили суть? ;)

PM MAIL   Вверх
dsCode
Дата 8.1.2008, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



Цитата(AKS @  8.1.2008,  20:38 Найти цитируемый пост)
Неужели не уловили суть? ;)

представьте себе ;) наверно потому, что htc не знаю =) так что - разъяснения будут более полезны smile


--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
AKS
Дата 9.1.2008, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Просто в таком случае: element.changeDisplayValue = function()  {...};, для каждого элемента будет создаваться своя, всякий раз новая функция. И если элементов много (* { behavior:...} - т.е. вообще все эл-ты на странице), то это будет не простой процесс.
А если же создать один раз, разместив их в каком-либо "хранилище" в глобальной области видимости (я с дуру выбрал ActiveXObject.prototype ;) ), то js-функций будет создаваться значительно меньше (меньше занимаемая память, например). 
Единственное неудобство - надо явно создать "поля" у каждого элемента и присвоить им указатель на функцию. В случае с HTMLElement.prototype этого делать не надо, однако и доступ к методу будет дольше (у элемента нет такого метода - надо искать в prototype chain)...

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1201 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.