Return to Snippet

Revision: 14148
at May 20, 2009 16:10 by pdswan


Updated Code
var HoverItem = Class.create({
	timeout: null,
	effect: null,
	open: false,
	enabled: true,
	initialize: function(item, trigger){
		this.item = $(item);
		if( !this.item ){
			throw 'HoverItem: invalid item';
		}
		if( !Object.isArray(trigger) ){
			trigger = [trigger];
		}
		this.triggers = trigger.map(function(e){ return $(e);}).compact();
		if( this.triggers.length === 0 ){
			throw 'HoverItem: no valid trigger element';
		}
		this.options = Object.extend({
			timeout: 0.5,
			align_to_trigger: true,
			zIndex: 100,
			effects: null
		}, arguments[2] || {});
		this.item.hide();
		if( this.options.align_to_trigger !== false ){
			var trigger_pos = this.triggers[this.options.align_to_trigger].positionedOffset();
			var trigger_dims = this.triggers[this.options.align_to_trigger].getDimensions();
			this.item.setStyle({position: 'absolute', top: trigger_pos.top + trigger_dims.height + 'px', left: trigger_pos.left + 'px', zIndex: this.options.zIndex});
		}
		[this.item].concat(this.triggers).invoke('observe', 'mouseleave', this.closeItem.bindAsEventListener(this))
		                                 .invoke('observe', 'mouseenter', this.openItem.bindAsEventListener(this));	
	},
	/* have to be careful with these because of timing issues */
	disable: function(){
		this.enabled = false;
	},
	enable: function(){
		this.enabled = true;
	},
	openItem: function(){
		console.log('openItem! ' + this.enabled);
		if( !this.enabled ){
			return;
		}
		this.stopClose();
		if (!this.open) {
			this.open = true;
			try {
				if (this.effect) {
					this.effect.cancel();
				}
				this.effect = new this.options.effects.open.effect(this.item, this.options.effects.open.options ||
				{});
			} 
			catch (e) {
				this.item.show();
			}
		}
	},
	closeItem: function(){
		if (!this.timeout) {
			this.timeout = this._closeItem.bind(this).delay(this.options.timeout);
		}
	},
	_closeItem: function(){
		this.open = false;
		try{
			if( this.effect ){
				this.effect.cancel();
			}
			this.effect = new this.options.effects.close.effect(this.item, this.options.effects.close.options || {});
		}catch(e){
			this.effect = null;
			this.item.hide();
		}
	},
	stopClose: function(){
		if (this.timeout) {
			clearTimeout(this.timeout);
			this.timeout = null;
		}
	}
});

Revision: 14147
at May 20, 2009 11:48 by pdswan


Initial Code
var HoverItem = Class.create({
	timeout: null,
	initialize: function(item, trigger){
		this.item = $(item);
		if( !this.item ){
			throw 'HoverItem: invalid item';
		}
		this.trigger = $(trigger);
		if( !this.trigger ){
			throw 'HoverItem: invalid trigger element';
		}
		this.options = Object.extend({
			timeout: 0.5,
			align_to_trigger: true,
			zIndex: 100
		}, arguments[1] || {});
		this.item.hide();
		if( this.options.align_to_trigger ){
			var trigger_pos = this.trigger.positionedOffset();
			var trigger_dims = this.trigger.getDimensions();
			this.item.setStyle({position: 'absolute', top: trigger_pos.top + trigger_dims.height + 'px', left: trigger_pos.left + 'px', zIndex: this.options.zIndex});
		}
		[this.item, this.trigger].invoke('observe', 'custom:mouseleave', this.closeItem.bindAsEventListener(this))
		                         .invoke('observe', 'custom:mouseenter', this.openItem.bindAsEventListener(this));	
	},
	openItem: function(){
		this.stopClose();
		this.item.show();
	},
	closeItem: function(){
		if (!this.timeout) {
			this.timeout = this._closeItem.bind(this).delay(this.options.timeout);
		}
	},
	_closeItem: function(){
		this.item.hide();
	},
	stopClose: function(){
		if (this.timeout) {
			clearTimeout(this.timeout);
			this.timeout = null;
		}
	}
});

Initial URL


Initial Description
added ability to use effects and some other improvements.

Initial Title
Simple Hovering Element w/ Triggering Element

Initial Tags
class

Initial Language
JavaScript