[转帖]Mootools源码分析-23 -- Selectors-2

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

原作者:我佛山人

 

//根据四种操作符查找
Selectors.Getters = {
    
//空格,表示根据标签名和id的常规查找
    ' 'function(found, self, tag, id, uniques)    {
        
var items = Selectors.Utils.getByTagAndID(self, tag, id);
        
for (var i = 0, l = items.length; i < l; i++)    {
            
var item = items[i];
            
if (Selectors.Utils.chk(item, uniques)) found.push(item);
        }
        
return found;
    },

    
//大于号>表示子节点的查找
    '>'function(found, self, tag, id, uniques)    {
        
var children = Selectors.Utils.getByTagAndID(self, tag, id);
        
for (var i = 0, l = children.length; i < l; i++)    {
            
var child = children[i];
            
if (child.parentNode == self && Selectors.Utils.chk(child, uniques))    found.push(child);
        }
        
return found;
    },

    
//加号+表示后兄弟节点的查找
    '+'function(found, self, tag, id, uniques)    {
        
while ((self = self.nextSibling))    {
            
if (self.nodeType == 1)    {
                
if (Selectors.Utils.chk(self, uniques) && Selectors.Filters.byTag(self, tag) && Selectors.Filters.byID(self, id))
                    found.push(self);
                
break;
            }
        }
        
return found;
    },

    
//波浪号~表示后兄弟节点的查找
    '~'function(found, self, tag, id, uniques)    {
        
while ((self = self.nextSibling))    {
            
if (self.nodeType == 1)    {
                
if (!Selectors.Utils.chk(self, uniques))    break;
                
if (Selectors.Filters.byTag(self, tag) && Selectors.Filters.byID(self, id))    found.push(self);
            } 
        }
        
return found;
    }
};

//过滤器
Selectors.Filters = {
    
//根据标签过滤
    byTag: function(self, tag)    {
        
return (tag == '*' || (self.tagName && self.tagName.toLowerCase() == tag));
    },

    
//根据id过滤
    byID: function(self, id)    {
        
return (!id || (self.id && self.id == id));
    },

    
//根据CSS类名过滤
    byClass: function(self, klass)    {
        
return (self.className && self.className.contains(klass, ' '));
    },

    
//根据伪类过滤
    byPseudo: function(self, parser, argument, local)    {
        
return parser.call(self, argument, local);
    },

    
//根据属性过滤
    byAttribute: function(self, name, operator, value)    {
        
//获取属性值
        var result = Element.prototype.getProperty.call(self, name);
        
if (!result)    return false;
        
if (!operator || value == undefined)    return true;
        
//属性值运算
        switch (operator)    {
        
//相等
        case '='return (result == value);
        
//包含
        case '*='return (result.contains(value));
        
//打头
        case '^='return (result.substr(0, value.length) == value);
        
//结尾
        case '$='return (result.substr(result.length - value.length) == value);
        
//不等
        case '!='return (result != value);
        
//空格分隔包含
        case '~='return result.contains(value, ' ');
        
//连接符分隔包含
        case '|='return result.contains(value, '-');
        }
        
return false;
    }
};

//伪类查找
Selectors.Pseudo = new Hash({
    
// w3c pseudo selectors
    //:empty,匹配不包含文本的节点
    empty: function()    {
        
return !(this.innerText || this.textContent || '').length;
    },

    
//:not,匹配非指定标签
    not: function(selector)    {
        
return !Element.match(this, selector);
    },

    
//:contains,匹配节点内容中包含指定字符的节点
    contains: function(text)    {
        
return (this.innerText || this.textContent || '').contains(text);
    },

    
//:first-child,匹配第一个节点
    'first-child'function()    {
        
return Selectors.Pseudo.index.call(this0);
    },

    
//:last-child,匹配最后一个节点
    'last-child'function()    {
        
var element = this;
        
while ((element = element.nextSibling))    {
            
if (element.nodeType == 1return false;
        }
        
return true;
    },

    
//:only-child,匹配一个子节点类型全为Element的节点
    'only-child'function()    {
        
var prev = this;
        
while ((prev = prev.previousSibling))    {
            
if (prev.nodeType == 1)    return false;
        }
        
var next = this;
        
while ((next = next.nextSibling))    {
            
if (next.nodeType == 1)    return false;
        }
        
return true;
    },

    
//:nth-child,匹配第n个节点
    'nth-child'function(argument, local)    {
        argument 
= (argument == undefined) ? 'n' : argument;
        
var parsed = Selectors.Utils.parseNthArgument(argument);
        
//非nth伪类的处理转移
        if (parsed.special != 'n')    return Selectors.Pseudo[parsed.special].call(this, parsed.a, local);
        
var count = 0;
        local.positions 
= local.positions || {};
        
var uid = $uid(this);
        
//如果没有位置标记的记录
        if (!local.positions[uid])    {
            
var self = this;
            
//查找前面的兄弟节点
            while ((self = self.previousSibling))    {
                
//忽略非Element节点
                if (self.nodeType != 1)    continue;
                count 
++;
                
var position = local.positions[$uid(self)];
                
//如果有标记了位置的兄弟节点,加上位置后即可跳出循环
                if (position != undefined)    {
                    count 
= position + count;
                    
break;
                }
            }
            local.positions[uid] 
= count;
        }
        
//a*n + b的判断,可由count = a*n + b推出
        return (local.positions[uid] % parsed.a == parsed.b);
    },

    
// custom pseudo selectors
    //:index,匹配指定索引的节点
    index: function(index)    {
        
var element = this, count = 0;
        
//向前步进计算当前索引
        while ((element = element.previousSibling))    {
            
if (element.nodeType == 1 && ++count > index)    return false;
        }
        
return (count == index);
    },

    
//:even,匹配索引为偶数的节点
    even: function(argument, local)    {
        
return Selectors.Pseudo['nth-child'].call(this'2n+1', local);
    },

    
//:odd,匹配索引为奇数的节点
    odd: function(argument, local)    {
        
return Selectors.Pseudo['nth-child'].call(this'2n', local);
    }
})

 

posted @ 2009-11-06 22:09  webgis松鼠  阅读(168)  评论(0编辑  收藏  举报