这是我的Dropdown菜单类。并且在hide方法中回调函数afterFinsih 放弃了班级的范围。我不想宣布全球变通。有没有更好的解决方案?
var DropMenu = Class.create({
// Class properties.
speed: 0.4,
delay: 0,
active_submenu: null,
initialize: function() {
$$("li.drop_down_element").invoke('observe', 'mouseenter', this.mouseOver.bind(this));
$$("li.drop_down_element").invoke('observe', 'mouseleave', this.mouseOut.bind(this));
},
show: function(elem, speed) {
new Effect.BlindDown(elem, {duration: speed, queue: {position: 'end', scope: elem.identify(), limit:13}});
},
hide: function(elem, speed) {
if(elem.visible())
{
new Effect.BlindUp(elem, {duration: speed, queue: {position: 'end', scope: elem.identify(), limit: 13}, afterFinish: function(scope) { console.info(scope)}(this)});
}
},
mouseOver: function(event) {
var element = event.element(),
submenu = element.getElementsByClassName('submenu_element')[0],
width = element.getWidth();
if(submenu)
{
submenu.setStyle({minWidth: width + 'px'})
this.active_submenu = submenu;
this.show(submenu, this.speed);
}
if(!this.iefix && Prototype.Browser.IE)
{
new Insertion.After(submenu,
'<iframe id="dropdown_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
this.iefix = $(submenu.id+'_iefix');
}
//if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
},
mouseOut: function(event) {
var submenu = this.active_submenu;
if (submenu)
{
this.hide.delay(this.delay, submenu, this.speed);
}
},
fixIEOverlapping: function() {
Position.clone(this.active_submenu, this.iefix, {setTop:(!this.active_submenu.style.height)});
this.iefix.style.zIndex = 700;
this.iefix.style.border = '2px solid #000';
this.active_submenu.style.zIndex = 999;
Element.show(this.iefix);
}
});
document.observe('dom:loaded', function() { new DropMenu(); });
答案 0 :(得分:1)
你可以这样做:
if(elem.visible())
{
var that = this;
new Effect.BlindUp(elem, {
duration: speed,
queue: {position: 'end', scope: elem.identify(), limit: 13},
afterFinish: function() { console.info(that); }
});
}
......但你可能不喜欢这样。有些浏览器支持Function.prototype.bind
,它允许您创建一个绑定到所需范围的函数,例如:
if(elem.visible())
{
var that = this;
new Effect.BlindUp(elem, {
duration: speed,
queue: {position: 'end', scope: elem.identify(), limit: 13},
afterFinish: (function() { console.info(this); }).bind(this);
});
}
如果您没有Function.prototype.bind
,则可以使用此代码段(stolen from MDN)来定义它(您声明您正在使用Prototype,它应该已经拥有它):
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") // closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be fBound is not callable");
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP ? this : oThis || window, aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}