在Javascript中编写包装器对象

时间:2011-02-02 19:25:52

标签: javascript methods correctness

首先,如果我的问题措辞不正确,请允许我道歉 - 我不是专业编码员,所以我的术语可能很奇怪。我希望我的代码不会太尴尬:(

我有一个fade()方法,可以通过鼠标翻转淡入淡出图像。我想使用包装器对象(我认为这是正确的术语),保存图像元素和一些必需的属性,但我不知道如何实现这一点。 fade()是从HTML中调用的,设计用于放入页面而无需额外的设置(这样我就可以轻松地将新的淡入淡出图像添加到任何HTML中),如下所示:

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

fade(obj, flag)方法启动一个淡入图像的SetInterval,当指针移开时,间隔被清除,并创建一个新的SetInterval以淡出图像。为了保存不透明度状态,我在对象中添加了一些属性:obj.opacityobj.upTimerobj.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 个答案:

答案 0 :(得分:2)

你是对的,在HTML中添加处理程序并不好。您还可以为附加到一个对象的事件放置几个处理程序。

不幸的是,微软在附加事件处理程序方面走自己的路。但是你应该能够编写一个小的包装函数来处理它。

有关详细信息,建议您阅读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);

正如您所看到的,我直接传递了对象的引用,因此在您fade方法中,您已经有了对该对象的引用。

您可以将此包装在接受ID(或引用)的函数中,并且每次要将事件处理程序附加到某个元素时,您只需将ID(或引用)传递给此函数。

如果您想让代码重复使用,我建议将所有内容放入对象中,如下所示:

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 {...};{..}是对象文字符号),其中包含属性initfade。这两个属性都包含可以访问立即函数内定义的所有变量的函数(它们是闭包)。这意味着他们可以访问无法从外部访问的newOpacitysetStyle。返回的对象将分配给Fader变量。

答案 1 :(得分: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等之间的差异......

答案 2 :(得分: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中引入了一些范围概念,以确保您不会出现功能覆盖问题。