[转帖]Mootools源码分析-14 -- Element-1

原帖地址:http://space.flash8.net/space/?18713/viewspace-402754.html

原作者:我佛山人

 

/*
对HTML Element的包装
*/
var  Element  =   new  Native({

    
// 族名,为$type方法提供精准类型
    name:  ' Element ' ,

    
// 包装扩展的原型
    legacy: window.Element,

    
// 初始化,使用Document对象的newElement创建对象
    initialize:  function (tag, props)    {

        
// 先看有没有特殊的HTML Element
         var  konstructor  =  Element.Constructors.get(tag);

        
// 对特殊的HTML Element对象特别处理
         if  (konstructor)     return  konstructor(props);

        
// 如果提供标签名,根据标签名创建HTML Element对象
         if  ( typeof  tag  ==   ' string ' )     return  document.newElement(tag, props);

        
// 设置属性
         return  $(tag).set(props);
    },

    
// 执行后续处理,每为Element增加一个扩展,Elements也会同时实现
    afterImplement:  function (key, value)    {
        
if  ( ! Array[key])    Elements.implement(key, Elements.multi(key));
        Element.Prototype[key] 
=  value;
    }

});

Element.Prototype 
=  {$family: {name:  ' element ' }};

Element.Constructors 
=   new  Hash;



// 同时对Element和Document对象进行扩展
Native.implement([Element, Document], {

    
// 根据选择符选择一个子Element
    getElement:  function (selector, notrash)    {
        
return  $( this .getElements(selector,  true )[ 0 ||   null , notrash);
    },

    
// 根据选择符选择子Element
    getElements:  function (tags, nocash)    {
        tags 
=  tags.split( ' , ' );
        
var  elements  =  [];
        
var  ddup  =  (tags.length  >   1 );
        tags.each(
function (tag)    {
            
var  partial  =   this .getElementsByTagName(tag.trim());
            (ddup) 
?  elements.extend(partial) : elements  =  partial;
        }, 
this );
        
return   new  Elements(elements, {ddup: ddup, cash:  ! nocash});
    }    

});

// 用于获取保存在当前Element下的临时对象,参考Fx.Tween和Drag
Element.Storage  =  {

    get: 
function (uid)    {
        
return  ( this [uid]  ||  ( this [uid]  =  {}));
    }

};

// 相当于当前Element的四个位置的DOM插入
Element.Inserters  =   new  Hash({

    
// 在context指代的Element之前插入eleemnt
    before:  function (context, element)    {
        
if  (element.parentNode)    element.parentNode.insertBefore(context, element);
    },

    
// 在context指代的Element之后插入eleemnt
    after:  function (context, element)    {
        
if  ( ! element.parentNode)     return ;
        
var  next  =  element.nextSibling;
        (next) 
?  element.parentNode.insertBefore(context, next) : element.parentNode.appendChild(context);
    },

    
// 在context指代的Element内最后插入eleemnt
    bottom:  function (context, element)    {
        element.appendChild(context);
    },

    
// 在context指代的Element内首位插入eleemnt
    top:  function (context, element)    {
        
var  first  =  element.firstChild;
        (first) 
?  element.insertBefore(context, first) : element.appendChild(context);
    }

});

// 别名
Element.Inserters.inside  =  Element.Inserters.bottom;

// 生成injectTop/grabTop之类的快捷方式
Element.Inserters.each( function (value, key)    {

    
var  Key  =  key.capitalize();

    
// injectTop,injectBefore,injectAfter,injectBottom
    Element.implement( ' inject '   +  Key,  function (el)    {
        value(
this , $(el,  true ));
        
return   this ;
    });

    
// grabTop,grabBefore,grabAfter,grabBottom
    Element.implement( ' grab '   +  Key,  function (el)    {
        value($(el, 
true ),  this );
        
return   this ;
    });

});

Element.implement({

    
// 当前Element所属的Document
    getDocument:  function ()    {
        
return   this .ownerDocument;
    },

    
// 当前Element所属的Window
    getWindow:  function ()    {
        
return   this .ownerDocument.getWindow();
    },

    
// 根据ID查找当前Element下的对象
    getElementById:  function (id, nocash)    {
        
var  el  =   this .ownerDocument.getElementById(id);
        
if  ( ! el)     return   null ;
        
for  ( var  parent  =  el.parentNode; parent  !=   this ; parent  =  parent.parentNode)    {
            
if  ( ! parent)     return   null ;
        }
        
return  $.element(el, nocash);
    },

    
// 万能的setter
    set:  function (prop, value)    {
        
switch  ($type(prop))    {
        
case   ' object ' :
            
for  ( var  p  in  prop)     this .set(p, prop[p]);
            
break ;
        
case   ' string ' :
            
var  property  =  Element.Properties.get(prop);
            (property 
&&  property.set)  ?  property.set.apply( this , Array.slice(arguments,  1 )) :  this .setProperty(prop, value);
        }
        
return   this ;
    },

    
// 万能的getter
    get:  function (prop)    {
        
var  property  =  Element.Properties.get(prop);
        
return  (property  &&  property.get)  ?  property.get.apply( this , Array.slice(arguments,  1 )) :  this .getProperty(prop);
    },

    
// 万能的eraser
    erase:  function (prop)    {
        
var  property  =  Element.Properties.get(prop);
        (property 
&&  property.erase)  ?  property.erase.apply( this , Array.slice(arguments,  1 )) :  this .removeProperty(prop);
        
return   this ;
    },

    
// 判断当前Element是否匹配指定标签名
    match:  function (tag)    {
        
return  ( ! tag  ||  Element.get( this ' tag ' ==  tag);
    },

    
// 根据where指定的位置,将当前Element注入到el
    inject:  function (el, where)    {
        Element.Inserters.get(where 
||   ' bottom ' )( this , $(el,  true ));
        
return   this ;
    },

    
// 根据where指定的位置,使当前Element作为el的父Element
    wraps:  function (el, where)    {
        el 
=  $(el,  true );
        
return   this .replaces(el).grab(el, where);
    },

    
// 和inject相反
    grab:  function (el, where)    {
        Element.Inserters.get(where 
||   ' bottom ' )($(el,  true ),  this );
        
return   this ;
    },

    
// 追加文本
    appendText:  function (text, where)    {
        
return   this .grab( this .getDocument().newTextNode(text), where);
    },

    
// 将多个对象追加到当前Element内
    adopt:  function ()    {
        Array.flatten(arguments).each(
function (element)    {
            element 
=  $(element,  true );
            
if  (element)     this .appendChild(element);
        }, 
this );
        
return   this ;
    },

    
// 从DOM节点中删除
    dispose:  function ()    {
        
return  ( this .parentNode)  ?   this .parentNode.removeChild( this ) :  this ;
    },

    
// 从当前Element克隆出新的Element,contents指定是否包含子节点,keepid指定是否忽略id属性
    clone:  function (contents, keepid)    {
        
switch  ($type( this ))    {
        
case   ' element ' :
            
var  attributes  =  {};
            
for  ( var  j  =   0 , l  =   this .attributes.length; j  <  l; j ++ )    {
                
var  attribute  =   this .attributes[j], key  =  attribute.nodeName.toLowerCase();
                
var  value  =  (key  ==   ' style '   &&   this .style)  ?   this .style.cssText : attribute.nodeValue;
                
if  ( ! $chk(value)  ||  key  ==   ' uid '   ||  (key  ==   ' id '   &&   ! keepid))     continue ;
                
if  (value  !=   ' inherit '   &&  [ ' string ' ' number ' ].contains($type(value)))    attributes[key]  =  value;
            }        
            
var  element  =   new  Element( this .nodeName.toLowerCase(), attributes);
            
if  (contents  !==   false )    {
                
for  ( var  i  =   0 , k  =   this .childNodes.length; i  <  k; i ++ )    {
                    
var  child  =  Element.clone( this .childNodes[i],  true , keepid);
                    
if  (child)    element.grab(child);
                }
            }
            
return  element;
        
// 如果当前是文本节点
         case   ' textnode ' return     document.newTextNode( this .nodeValue);
        }
        
return   null ;
    },

    
// 替换节点
    replaces:  function (el)    {
        el 
=  $(el,  true );
        el.parentNode.replaceChild(
this , el);
        
return   this ;
    },

    
// 是否使用指定css类名
    hasClass:  function (className)    {
        
return   this .className.contains(className,  '   ' );
    },

    
// 添加指定css类名
    addClass:  function (className)    {
        
if  ( ! this .hasClass(className))  this .className  =  ( this .className  +   '   '   +  className).clean();
        
return   this ;
    },

    
// 移除指定css类名
    removeClass:  function (className)    {
        
this .className  =   this .className.replace( new  RegExp( ' (^|\\s) '   +  className  +   ' (?:\\s|$) ' ),  ' $1 ' ).clean();
        
return   this ;
    },

    
// 切换指定css类名
    toggleClass:  function (className)    {
        
return   this .hasClass(className)  ?   this .removeClass(className) :  this .addClass(className);
    },

    
// 获取运行时的样式属性
    getComputedStyle:  function (property)    {
        
// IE
         if  ( this .currentStyle)     return   this .currentStyle[property.camelCase()];
        
// 非IE
         var  computed  =   this .getWindow().getComputedStyle( this null );
        
return  (computed)  ?  computed.getPropertyValue([property.hyphenate()]) :  null ;
    },

    
// 清空当前Element,包括内部节点的删除和内存释放
    empty:  function ()    {
        $A(
this .childNodes).each( function (node)    {
            Element.empty(node);
            
this .removeChild(node);
            memfree(node);
        }, 
this );
        
return   this ;
    },

    
// 销毁当前Element,删除所有有关的一切
    destroy:  function ()    {
        memfree(
this .empty().dispose());
        
return   null ;
    },

    
// 获取选中的子项,仅当<select multi>有效
    getSelected:  function ()    {
        
return  $A( this .options).filter( function (option){
            
return  option.selected;
        });
    },

    
// 将当前Element内的表单项数据转为查询串格式,以用于Ajax或get方式的提交
    toQueryString:  function ()    {
        
var  queryString  =  [];
        
this .getElements( ' input, select, textarea ' ).each( function (el)    {
            
if  ( ! el.name  ||  el.disabled)     return ;
            
var  value  =  (el.tagName.toLowerCase()  ==   ' select ' ?  Element.getSelected(el).map( function (opt)    {
                
return  opt.value;
            }) : ((el.type 
==   ' radio '   ||  el.type  ==   ' checkbox ' &&   ! el.checked)  ?   null  : el.value;
            $splat(value).each(
function (val)    {
                
if  (val) queryString.push(el.name  +   ' = '   +  encodeURIComponent(val));
            });
        });
        
return  queryString.join( ' & ' );
    },

    
// 读取属性值,包括自定义属性
    getProperty:  function (attribute)    {
        
var  EA  =  Element.Attributes, key  =  EA.Props[attribute];
        
var  value  =  (key)  ?   this [key] :  this .getAttribute(attribute,  2 );
        
return  (EA.Bools[attribute])  ?   !! value : (key)  ?  value : value  ||   null ;
    },

    
// 根据属性列表读取相应值,以objecct方式返回结果
    getProperties:  function ()    {
        
var  args  =  $A(arguments);
        
return  args.map( function (attr)    {
            
return   this .getProperty(attr);
        }, 
this ).associate(args);
    },

    
// 属性设置
    setProperty:  function (attribute, value)    {
        
var  EA  =  Element.Attributes, key  =  EA.Props[attribute], hasValue  =  $defined(value);
        
if  (key  &&  EA.Bools[attribute]) value  =  (value  ||   ! hasValue)  ?   true  :  false ;
        
else   if  ( ! hasValue)     return   this .removeProperty(attribute);
        (key) 
?   this [key]  =  value :  this .setAttribute(attribute, value);
        
return   this ;
    },

    
// 批量属性设置
    setProperties:  function (attributes)    {
        
for  ( var  attribute  in  attributes)     this .setProperty(attribute, attributes[attribute]);
        
return   this ;
    },

    
// 移除属性
    removeProperty:  function (attribute)    {
        
var  EA  =  Element.Attributes, key  =  EA.Props[attribute], isBool  =  (key  &&  EA.Bools[attribute]);
        (key) 
?   this [key]  =  (isBool)  ?   false  :  ''  :  this .removeAttribute(attribute);
        
return   this ;
    },

    
// 批量移除属性
    removeProperties:  function ()    {
        Array.each(arguments, 
this .removeProperty,  this );
        
return   this ;
    }

});

 

转载于:https://www.cnblogs.com/maapaa/articles/mootools-s-14.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值