用 Javascript 编写一个包装对象
首先,如果我的问题措辞不正确,请允许我道歉 - 我不是专业的程序员,所以我的术语可能很奇怪。我希望我的代码不会太尴尬:(
我有一个 fade()
方法,可以通过鼠标悬停来淡入淡出图像。我想使用一个包装对象(我认为这是正确的术语),以保存图像元素和一些必需的属性,但我不知道如何从 HTML 中调用 fade()
,并设计为将其放入其中。一个没有太多额外设置的页面(这样我就可以轻松地将新的淡入淡出图像添加到任何 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 + ")";
}
}
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你是对的,在 HTML 中添加处理程序并不好。您还失去了将多个事件处理程序附加到一个对象的可能性。
不幸的是,微软在附加事件处理程序方面采取了自己的方式。但是您应该能够编写一个小的包装函数来处理这个问题。
有关详细信息,我建议您阅读quirksmode.org - 高级事件注册模型 。
W3C 兼容浏览器的示例(IE 不是):不要在 HTML 中添加事件处理程序,而是获取对元素的引用并调用
addEventListener
:如您所见,我直接传递对该对象的引用,因此在您的
fade
方法中您已经拥有对该对象的引用。您可以将其包装在接受 ID(或引用)的函数中,并且每次想要将事件处理程序附加到某个元素时,只需将 ID(或引用)传递给该函数即可。
如果您想让代码可重用,我建议将所有内容放入对象中,如下所示:
使用对象来保存函数可以减少对全局名称空间的污染。
然后你可以这样调用它:
上述代码的解释:
我们有一个立即函数
(function(){...}())
,这意味着该函数得到一次性定义并执行 (()
)。此函数返回一个对象(return {...};
,{..}
是对象文字表示法),该对象具有属性init
和淡出
。这两个属性都包含可以访问立即函数内定义的所有变量的函数(它们是闭包)。这意味着他们可以访问从外部无法访问的newOpacity
和setStyle
。返回的对象被分配给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
: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:
Using an object to hold your functions reduces pollution of the global namespace.
Then you could call it with:
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 propertiesinit
andfade
. Both properties hold functions that have access to all the variables defined inside the immediate function (they are closures). That means they can accessnewOpacity
andsetStyle
which are not accessible from the outside. The returned object is assigned to theFader
variable.这并不能直接回答你的问题,但你可以使用 jQuery 库。很简单,您所要做的就是在顶部添加一个 script 标签:
然后您的 div 将如下所示:
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:
Then your div would look like:
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...
如果您想保持 HTML 干净,您应该考虑使用 JQuery 来设置事件。
您的 HTML 将如下所示:-
您的 JavaScript 将“类似于”:-
我在 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:-
Your JavaScript will look "something" like this:-
I introduced some scoping concept in your Javascript to ensure you are not going to have function overriding problems.