2011-02-02 3 views
3

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

У меня есть метод 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 + ")"; 
    } 
} 

ответ

0

Это не прямо ответить на ваш вопрос, но вы можете использовать библиотеку 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 и т. д.

0

Если вы хотите, чтобы ваш 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, чтобы убедиться, что вы не у меня будут функции, которые могут быть переопределены.

2

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

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

Для получения дополнительной информации я предлагаю вам прочитать quirksmode.org - Advanced event registration models.

Пример для 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); 

Как вы можете видеть, что я» m, непосредственно передавая ссылку на объект, поэтому у вас есть метод 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

Спасибо Феликс, я бы предпочел избежать JQuery, пока не узнаю веревки Javascript, это очень поможет. Хотя, я теперь полностью озадачен объемом переменных Javascript. Я не понимаю, почему 'init()' и 'fade()' можно увидеть за пределами возвращаемого блока:/ – SpaceJunk

+0

@SpaceJunk: см. Мое обновление. Надеюсь, это поможет. Вы можете увидеть эту функцию, потому что 'return {...}' на самом деле не является блоком, это объектная запись для определения объектов. Это будет одно и то же: 'var obj = {init: function() {...}}; return obj; '. Обратите внимание, что я также немного изменил код и переместил 'DELTA' в непосредственную функцию. Это должно работать лучше с вашим кодом. Если у вас есть дополнительные вопросы, просто спросите. –

Смежные вопросы