用 Javascript 编写一个包装对象

发布于 2024-10-16 00:15:56 字数 2361 浏览 3 评论 0原文

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

我有一个 fade() 方法,可以通过鼠标悬停来淡入淡出图像。我想使用一个包装对象(我认为这是正确的术语),以保存图像元素和一些必需的属性,但我不知道如何从 HTML 中调用 fade() ,并设计为将其放入其中。一个没有太多额外设置的页面(这样我就可以轻松地将新的淡入淡出图像添加到任何 HTML 中),就像这样:

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

fade(obj, flag) 方法启动一个淡入图像的 SetInterval,并且当指针移开时,间隔将被清除,并创建一个新的 SetInterval 来淡出图像。为了保存不透明度状态,我向对象添加了一些属性:obj.opacity、obj.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 + ")";
  }
}

First off, let me apologize if my question isn't worded correctly - I'm not a professional coder so my terminology might be weird. I hope my code isn't too embarrassing :(

I have a fade() method that fades an image in and out with a mouse rollover. I would like to use a wrapper object (I think this is the correct term), to hold the image element and a few required properties, but I don't know how to accomplish this. fade() is called from the HTML, and is designed to be dropped into a page without much additional setup (so that I can easily add new fading images to any HTML), just like this:

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

The fade(obj, flag) method starts a SetInterval that fades the image in, and when the pointer is moved away, the interval is cleared and a new SetInterval is created to fade the image out. In order to save the opacity state, I've added a few properties to the object: obj.opacity, obj.upTimer, and obj.dnTimer.

Everything works okay, but I don't like the idea of adding properties to HTML elements, because it might lead to a future situation where some other method overwrites those properties. Ideally, I think there should be a wrapper object involved, but I don't know how to accomplish this cleanly without adding code to create the object when the page loads. If anyone has any suggestions, I would greatly appreciate it!

Here's my fader method:

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 + ")";
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

丑丑阿 2024-10-23 00:15:56

你是对的,在 HTML 中添加处理程序并不好。您还失去了将多个事件处理程序附加到一个对象的可能性。

不幸的是,微软在附加事件处理程序方面采取了自己的方式。但是您应该能够编写一个小的包装函数来处理这个问题。

有关详细信息,我建议您阅读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 方法中您已经拥有对该对象的引用。

您可以将其包装在接受 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 {...};{..} 是对象文字表示法),该对象具有属性 init淡出。这两个属性都包含可以访问立即函数内定义的所有变量的函数(它们是闭包)。这意味着他们可以访问从外部无法访问的 newOpacitysetStyle。返回的对象被分配给 Fader 变量。

You are right, adding the handlers in your HTML is not good. You also loose the possible to have several handlers for event attached to one object.

Unfortunately Microsoft goes its own way regarding attaching event handlers. But you should be able to write a small wrapper function to take care of that.

For the details, I suggest you read quirksmode.org - Advanced event registration models.

An example for W3C compatible browsers (which IE is not): Instead of adding your event handler in the HTML, get a reference to the element and call 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);

As you can see I'm passing directly a reference to the object, so in you fade method you already have a reference to the object.

You could wrap this in a function that accepts an ID (or reference) and every time you want to attach an event handler to a certain element, you can just pass the ID (or reference) to this function.

If you want to make your code reusable, I suggest to put everything into an object, like this:

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);
       }
   };
}())

Using an object to hold your functions reduces pollution of the global namespace.

Then you could call it with:

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

Explanation of the above code:

We have an immediate function (function(){...}()) which means, the function gets defined and executed (()) in one go. This function returns an object (return {...};, {..} is the object literal notation) which has the properties init and fade. Both properties hold functions that have access to all the variables defined inside the immediate function (they are closures). That means they can access newOpacity and setStyle which are not accessible from the outside. The returned object is assigned to the Fader variable.

往日 2024-10-23 00:15:56

这并不能直接回答你的问题,但你可以使用 jQuery 库。很简单,您所要做的就是在顶部添加一个 script 标签:

<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 之间的差异等问题...

This doesn't directly answer your question but you could use the jQuery library. It's simple, all you have to do is add a script tag at the top:

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

Then your div would look like:

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

jQuery will handle all the browser dependencies for you so you don't have to worry about things like differences between firefox and mozilla etc...

清旖 2024-10-23 00:15:56

如果您想保持 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 中引入了一些范围概念,以确保您不会出现函数覆盖问题。

If you want to keep your HTML clean, you should consider using JQuery to set up the events.

Your HTML will look like this:-

<div id="obj">

Your JavaScript will look "something" like this:-

$(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) {
        ...
    };
};

I introduced some scoping concept in your Javascript to ensure you are not going to have function overriding problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文