[转帖]Mootools源码分析-45 -- Tips

原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-409496

原作者:我佛山人

 

代码
//信息提示层
//
演示地址:http://demos.mootools.net/Tips

var Tips = new Class({
    
//继承自Events和Options,UI插件的特点
    Implements: [Events, Options],
    options: {
        
//显示事件
        onShow: function(tip)    {
            tip.setStyle(
'visibility''visible');
        },

        
//隐藏事件
        onHide: function(tip)    {
            tip.setStyle(
'visibility''hidden');
        },
        
//显示延时
        showDelay: 100,
        
//隐藏延时
        hideDelay: 100,
        
//提示层样式名
        className: null,
        
//提示层显示时相对于鼠标位置的偏移量
        offsets: {x: 16, y: 16},
        
//显示时是否不随鼠标移动
        fixed: false
    },

    
//构造函数
    initialize: function()    {
        
//利用Array.link自动选择参数
        var params = Array.link(arguments, {options: Object.type, elements: $defined});
        
//合并参数
        this.setOptions(params.options);
        
//提示层对象
        this.tip = new Element('div').inject(document.body);
        
//如果指定CSS类名,添加
        if (this.options.className) this.tip.addClass(this.options.className);
        
//提示层顶部
        var top = new Element('div', {'class''tip-top'}).inject(this.tip);
        
//提示层内容的容器
        this.container = new Element('div', {'class''tip'}).inject(this.tip);
        
//提示层底部
        var bottom = new Element('div', {'class''tip-bottom'}).inject(this.tip);
        
//绝对位置,不可见
        this.tip.setStyles({position: 'absolute', top: 0, left: 0, visibility: 'hidden'});
        
//附加使用提示层的对象
        if (params.elements)    this.attach(params.elements);
    },

    
//为使用提示层的对象附加事件监听
    attach: function(elements)    {
        
//遍历每项
        $$(elements).each(function(element)    {
            
//获取缓存标题
            var title = element.retrieve('tip:title', element.get('title'));
            
//获取缓存内容
            var text = element.retrieve('tip:text', element.get('rel'|| element.get('href'));
            
//缓存鼠标进入监听事件
            var enter = element.retrieve('tip:enter'this.elementEnter.bindWithEvent(this, element));
            
//缓存鼠标离开监听事件
            var leave = element.retrieve('tip:leave'this.elementLeave.bindWithEvent(this, element));
            
//添加鼠标进入和离开事件监听
            element.addEvents({mouseenter: enter, mouseleave: leave});
            
//如果跟随鼠标
            if (!this.options.fixed)    {
                
//缓存鼠标移动监听事件
                var move = element.retrieve('tip:move'this.elementMove.bindWithEvent(this, element));
                
//添加鼠标移动事件监听
                element.addEvent('mousemove', move);
            }
            element.store(
'tip:native', element.get('title'));
            
//去除原title属性,避免显示重复的提示
            element.erase('title');
        }, 
this);
        
return this;
    },

    
//移除事件监听
    detach: function(elements)    {
        
//遍历每项
        $$(elements).each(function(element)    {
            
//移除鼠标进入的事件监听
            element.removeEvent('mouseenter', element.retrieve('tip:enter'|| $empty);
            
//移除鼠标离开的事件监听
            element.removeEvent('mouseleave', element.retrieve('tip:leave'|| $empty);
            
//移除鼠标移动的事件监听
            element.removeEvent('mousemove', element.retrieve('tip:move'|| $empty);
            
//移除鼠标进入的事件监听
            element.eliminate('tip:enter').eliminate('tip:leave').eliminate('tip:move');
            
//读取缓存的title值
            var ōriginal = element.retrieve('tip:native');
            
//如果存在恢复其属性值
            if (original)    element.set('title', original);
        });
    
return this;
    },

    
//鼠标进入当前对象时的处理
    elementEnter: function(event, element)    {
        
//清空提示内容
        this.container.empty();
        
//读取缓存的提示标题
        var title = element.retrieve('tip:title');
        
//如果存在标题缓存
        if (title)    {
            
//创建对象并加到内容容器
            this.titleElement = new Element('div', {'class''tip-title'}).inject(this.container);
            
//以缓存标题填充
            this.fill(this.titleElement, title);
        }
        
//读取缓存的提示内容
        var text = element.retrieve('tip:text');
        
//如果存在标题缓存
        if (text)    {
            
//创建对象并加到内容容器
            this.textElement = new Element('div', {'class''tip-text'}).inject(this.container);
            
//以缓存内容填充
            this.fill(this.textElement, text);
        }
        
//为防止重复,先清除计时器
        this.timer = $clear(this.timer);
        
//延时显示
        this.timer = this.show.delay(this.options.showDelay, this);
        
//如果设置提示层随鼠标移动,传送鼠标坐标信息,否则传送当前对象的坐标信息
        this.position((!this.options.fixed) ? event : {page: element.getPosition()});
    },
    
//鼠标离开时的处理
    elementLeave: function(event)    {
        
//清除计时器
        $clear(this.timer);
        
//延时隐藏提示层
        this.timer = this.hide.delay(this.options.hideDelay, this);
    },

    
//鼠标移动时的处理
    elementMove: function(event)    {
        
//重新定位提示层
        this.position(event);
    },

    
//定位提示层
    position: function(event)    {
        
//获取文档窗口的尺寸和滚动条信息
        var size = window.getSize(), scroll = window.getScroll();
        
//提示层的尺寸
        var tip = {x: this.tip.offsetWidth, y: this.tip.offsetHeight};
        
//用于定位需要遍历的属性
        var props = {x: 'left', y: 'top'};
        
//遍历定位需要处理的属性
        for (var z in props)    {
            
//计算出当前坐标方向上的目标值
            var pos = event.page[z] + this.options.offsets[z];
            
//对于提示层超出窗口时的处理
            if ((pos + tip[z] - scroll[z]) > size[z])    pos = event.page[z] - this.options.offsets[z] - tip[z];
            
//设置当前坐标方向上的坐标值
            this.tip.setStyle(props[z], pos);
        }
    },

    
//以指定内容或对象填充对象
    fill: function(element, contents)    {
        (
typeof contents == 'string'? element.set('html', contents) : element.adopt(contents);
    },

    
//显示提示层
    show: function()    {
        
//触发onShow事件
        this.fireEvent('onShow'this.tip);
    },

    
//显示提示层
    hide: function()    {
        
//触发onShow事件
        this.fireEvent('onHide'this.tip);
    }
});

 

posted @ 2009-12-01 19:49  webgis松鼠  阅读(574)  评论(0编辑  收藏  举报