Написать объект-обертку в Javascript - PullRequest
3 голосов
/ 02 февраля 2011

Прежде всего, позвольте мне извиниться, если мой вопрос не сформулирован правильно - я не профессиональный кодер, поэтому моя терминология может быть странной. Я надеюсь, что мой код не слишком смущает: (

У меня есть метод fade(), который затухает и снимает изображение при наведении курсора мыши. Я хотел бы использовать объект-обертку (я думаю, что это правильный термин), чтобы содержать элемент изображения и несколько обязательных свойств, но я не знаю, как этого добиться. fade() вызывается из HTML и предназначен для перетаскивания на страницу без особых дополнительных настроек (чтобы я мог легко добавлять новые изображения с выцветанием в любой HTML), например:

<div id="obj" onmouseover="fade('obj', 1);" onmouseout="fade('obj', 0);">

Метод fade(obj, flag) запускает SetInterval, который приводит к исчезновению изображения, а когда указатель перемещается, интервал очищается и создается новый SetInterval для исчезновения изображения. Чтобы сохранить состояние непрозрачности, я добавил несколько свойств к объекту: obj.opacity, obj.upTimer и obj.dnTimer.

Все работает хорошо, но мне не нравится идея добавления свойств к элементам HTML, потому что это может привести к будущей ситуации, когда какой-либо другой метод перезапишет эти свойства. В идеале я думаю, что должен быть задействован объект-обертка, но я не знаю, как выполнить это без добавления кода для создания объекта при загрузке страницы. Если у кого-то есть какие-либо предложения, я был бы очень признателен!

Вот мой метод фейдера:

var DELTA = 0.05;

function fade(id, flag) {

  var element = document.getElementById(id);
  var setCmd = "newOpacity('" + id + "', " + flag + ")";

  if (!element.upTimer) {
    element.upTimer = "";
    element.dnTimer = "";
  }
  if (flag) {
    clearInterval(element.dnTimer);
    element.upTimer = window.setInterval(setCmd, 10);
  } else {
    clearInterval(element.upTimer);
    element.dnTimer = window.setInterval(setCmd, 10);
  }
}

function newOpacity(id, flag) {

  var element = document.getElementById(id);

  if (!element.opacity) {
    element.opacity = 0;
    element.modifier = DELTA;
  }

  if (flag) {
    clearInterval(element.dnTimer)
    element.opacity += element.modifier;
    element.modifier += DELTA;  // element.modifier increases to speed up fade
    if (element.opacity > 100) {
      element.opacity = 100;
      element.modifier = DELTA;
      return;
    }
    element.opacity = Math.ceil(element.opacity);
  } else {
    clearInterval(element.upTimer)
    element.opacity -= element.modifier;
    element.modifier += DELTA;  // element.modifier increases to speed up fade
    if (element.opacity < 0) {
      element.opacity = 0;
      element.modifier = DELTA;
      return;
    }
    element.opacity =
      Math.floor(element.opacity);
  }
  setStyle(id);
}

function setStyle(id) {

  var opacity = document.getElementById(id).opacity;

  with (document.getElementById(id)) {
    style.opacity = (opacity / 100);
    style.MozOpacity = (opacity / 100);
    style.KhtmlOpacity = (opacity / 100);
    style.filter = "alpha(opacity=" + opacity + ")";
  }
}

Ответы [ 3 ]

2 голосов
/ 02 февраля 2011

Вы правы, добавление обработчиков в ваш HTML не очень хорошо. Вы также теряете возможность иметь несколько обработчиков для события, прикрепленного к одному объекту.

К сожалению, Microsoft идет своим путем, подключая обработчики событий. Но вы должны быть в состоянии написать небольшую функцию-обертку, чтобы позаботиться об этом.

Для получения подробной информации, я предлагаю вам прочитать quirksmode.org - Расширенные модели регистрации событий .

Пример для W3C-совместимых браузеров (в отличие от IE): вместо добавления вашего обработчика событий в HTML, получите ссылку на элемент и вызовите addEventListener:

var obj = document.getElementById('obj');

obj.addEventListener('mouseover', function(event) {
    fade(event.currentTarget, 1);
}, false);

obj.addEventListener('mouseout', function(event) {
    fade(event.currentTarget, 0);
}, false);

Как видите, я передаю непосредственно ссылку на объект, поэтому в вашем методе fade у вас уже есть ссылка на объект.

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

Если вы хотите сделать свой код многоразовым, я предлагаю поместить все в объект, например так:

var Fader = (function() {
   var DELTA = 0.05;
   function newOpacity() {}

   function setStyle() {}

   return {
       fade: function(...) {...},

       init: function(element) {
           var that = this;
           element.addEventListener('mouseover', function(event) {
               that.fade(event.currentTarget, 1);
           }, false);

           element.addEventListener('mouseout', function(event) {
               that.fade(event.currentTarget, 0);
           }, false);
       }
   };
}())

Использование объекта для хранения ваших функций уменьшает загрязнение глобального пространства имен.

Тогда вы можете позвонить с помощью:

Fader.init(document.getElementById('obj'));

Объяснение вышеуказанного кода:

У нас есть непосредственная функция (function(){...}()), которая означает, что функция определяется и выполняется (()) за один раз. Эта функция возвращает объект (return {...};, {..} является литеральной нотацией объекта), который имеет свойства init и fade. Оба свойства содержат функции, которые имеют доступ ко всем переменным, определенным внутри непосредственной функции (они являются замыканиями). Это означает, что они могут получить доступ к newOpacity и setStyle, которые недоступны извне. Возвращенный объект присваивается переменной Fader.

0 голосов
/ 02 февраля 2011

Если вы хотите сохранить свой HTML в чистоте, вам следует подумать об использовании JQuery для настройки событий.

Ваш HTML будет выглядеть следующим образом: -

<div id="obj">

Ваш JavaScript будет выглядеть«что-то» вроде этого: -

$(document).ready(function() {
    $("#obj").mouseover(function() {
        Page.fade(this, 1);
      }).mouseout(function(){
        Page.fade(this, 0);
      });
});

var Page = new function () {
    // private-scoped variable
    var DELTA = 0.05;

    // public-scoped function
    this.fade = function(divObj, flag) {
       ...
    };

    // private-scoped function
    var newOpacity = function (divObj, flag) {
       ...
    };

    // private-scoped function
    var setStyle = function (divObj) {
        ...
    };
};

Я ввел некоторую концепцию области видимости в ваш Javascript, чтобы убедиться, что у вас не будет проблем с переопределением функций.

0 голосов
/ 02 февраля 2011

Это не дает прямого ответа на ваш вопрос, но вы можете использовать библиотеку jQuery. Это просто, все, что вам нужно сделать, это добавить тег сценария вверху:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js">

Тогда ваш div будет выглядеть так:

<div id="obj" onmouseover="$('#obj').fadeIn()" onmouseout="$('#obj').fadeOut()">

jQuery будет обрабатывать все зависимости браузера, чтобы вам не приходилось беспокоиться о таких вещах, как различия между firefox и mozilla и т. Д. *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...