• 一个简单的DOM选择器实现


    支持ie6+,firefox,chrome等现代浏览器。


      1 /**
      2  * aiQuery
      3  * @author ouxingzhi 
      4  */
      5 void function(window, document, undefined) {
      6     var location = window.location,
      7     Slice = [].slice,
      8     RegTrim = /(?:^\s+|\s+$)/,
      9     RegBlank = /\s+/,
     10     RegOperate = /\s*(?:\s|>|\+|~(?!\=))\s*/i,
     11     RegElement = /^([\w\-]+|\*)?(?:\#([\w\-]+))?(?:\.([\w\-]+))?(?:\[([\w-]+)(?:([~|\^|\$|\*|\|]?=)['"]?([\w-]+)['"]?)?\])?(?:\:([\w-]+(?:\([\w-]+\))?))?$/i;
     12     function AIQuery(Selector, Content) {
     13         Selector = Selector.replace(RegTrim, '');
     14         Content = Content || document;
     15         if (Content.querySelectorAll) {
     16             return Slice.call(Content.querySelectorAll(Selector));
     17         } else {
     18             return querySelectorAll(Selector, Content)
     19         }
     20     }
     21     function querySelectorAll(Selector, Content) {
     22         var Groups = Selector.split(/\s*\,\s*/img),
     23         Results = [];
     24         for (var i = 0,
     25         len = Groups.length; i < len; i++) {
     26             Results = Results.concat(Find(Groups[i], Content))
     27         }
     28         return Results
     29     }
     30     function Find(Selector, Content) {
     31         var Results = [],
     32         atoms = Selector.split(RegOperate),
     33         operates = Selector.match(RegOperate);
     34         operates = operates || [];
     35         for (var i = 0,
     36         len = operates.length; i < len; i++)(operates[i] = /^\s+$/.test(operates[i]) ? ' ': operates[i].replace(RegTrim, ''));
     37         var Results = EachTo(' ', atoms.shift(), operates, atoms, Content);
     38         return Results
     39     }
     40     function EachTo(op, at, operates, atoms, Content) {
     41         var Results = [],
     42         Median = [],
     43         operate,
     44         atom;
     45         if (Content.constructor === Array || 'length' in Content) {
     46             for (var i = 0,
     47             len = Content.length; i < len; i++) {
     48                 Results = Results.concat(EachTo(op, at, operates.slice(0), atoms.slice(0), Content[i]))
     49             }
     50         } else if (Content.constructor === String) {
     51             Content = Find(Content, document);
     52             Results.concat(EachTo(op, at, operates.slice(0), atoms.slice(0), Content[i]))
     53         } else {
     54             Median = GetElementByAny(op, at, Content);
     55             if (Median) {
     56                 if (operates && operates.length && atoms && atoms.length) {
     57                     Results = EachTo(operates.shift(), atoms.shift(), operates, atoms, Median)
     58                 } else {
     59                     Results = Median
     60                 }
     61             }
     62         }
     63         return Results
     64     }
     65     function GetElementByAny(op, at, Content) {
     66         if (typeof OperateFunction[op] !== 'undefined') {
     67             return OperateFunction[op](at, Content)
     68         }
     69     }
     70     var OperateFunction = {
     71         ' ': function(at, Content) {
     72             var einfo = buildElementInfo(at),
     73             preNodes = [];
     74             if (!einfo) return [];
     75             if (einfo.Id) {
     76                 preNodes = document.getElementById(einfo.Id);
     77                 preNodes = preNodes ? [preNodes] : []
     78             } else if (einfo.ClassName && Content.getElementsByClassName) {
     79                 preNodes = Content.getElementsByClassName(einfo.ClassName);
     80                 preNodes = preNodes || []
     81             } else if (einfo.TagName && Content.getElementsByTagName) {
     82                 preNodes = Content.getElementsByTagName(einfo.TagName);
     83                 preNodes = preNodes || []
     84             } else {
     85                 preNodes = Content.getElementsByTagName('*');
     86                 preNodes = preNodes || []
     87             };
     88             return filterNode(einfo, preNodes)
     89         },
     90         '>': function(at, Content) {
     91             var einfo = buildElementInfo(at);
     92             preNodes = Content.childNodes || [];
     93             if (!einfo) return [];
     94             return filterNode(einfo, preNodes)
     95         },
     96         '+': function(at, Content) {
     97             if (Content === document) return [];
     98             var einfo = buildElementInfo(at);
     99             if (!einfo) return [];
    100             var results = [],
    101             preNodes = (function() {
    102                 var nextNode = Content.nextSibling;
    103                 while (nextNode && nextNode.nodeType != 1) {
    104                     nextNode = nextNode.nextSibling
    105                 }
    106                 return nextNode
    107             })();
    108             preNodes = preNodes ? [preNodes] : [];
    109             if (preNodes.length) {
    110                 results = filterNode(einfo, preNodes)
    111             } else {
    112                 results = []
    113             }
    114             return results
    115         },
    116         '~': function(at, Content) {
    117             if (Content === document) return [];
    118             var einfo = buildElementInfo(at),
    119             preNodes = [];
    120             if (!einfo) return [];
    121             var sibling = Content.parentNode ? Content.parentNode.childNodes: null;
    122             if (sibling) {
    123                 for (var i = 0,
    124                 len = sibling.length; i < len; i++) if (Content !== sibling[i]) preNodes.push(sibling[i])
    125             }
    126             return filterNode(einfo, preNodes)
    127         }
    128     };
    129     function buildElementInfo(at) {
    130         var Einfo = RegElement.exec(at);
    131         if (!Einfo) return;
    132         return {
    133             TagName: Einfo[1] || undefined,
    134             Id: Einfo[2] || undefined,
    135             ClassName: Einfo[3] || undefined,
    136             AttrName: Einfo[4] || undefined,
    137             AttrOper: Einfo[5] || undefined,
    138             AttrVal: Einfo[6] || undefined,
    139             FakeClass: Einfo[7] || undefined
    140         }
    141     }
    142     function filterNode(Einfo, Nodes) {
    143         var results = [],
    144             RegClassName,
    145             isMatch;
    146         if (Einfo.ClassName) RegClassName = new RegExp('\\b' + Einfo.ClassName + '\\b', 'i');
    147         for (var i = 0,
    148         len = Nodes.length; i < len; i++) {
    149             isMatch = true;
    150             if (Einfo.TagName !== undefined && Einfo.TagName.toUpperCase() !== Nodes[i].nodeName) isMatch = false;
    151             if (Einfo.Id !== undefined && Einfo.Id !== Nodes[i].id) isMatch = false;
    152             if (Einfo.ClassName !== undefined && !Nodes[i].className.match(RegClassName)) isMatch = false;
    153             isMatch = isMatchAttribute(Einfo, Nodes[i], isMatch);
    154             isMatch = isMatchFakeClass(Einfo, Nodes[i], isMatch);
    155             if (isMatch) results.push(Nodes[i])
    156         }
    157         return results
    158     }
    159     function isMatchAttribute(Einfo, node, isMatch) {
    160         if (Einfo.AttrName === undefined && Einfo.AttrOper === undefined && Einfo.AttrVal === undefined) {} else if (Einfo.AttrName !== undefined && Einfo.AttrOper === undefined && Einfo.AttrVal === undefined && node.getAttribute && node.getAttribute(Einfo.AttrName) !== null) {
    161             isMatch = true
    162         } else if (Einfo.AttrName !== undefined && Einfo.AttrOper !== undefined && Einfo.AttrVal !== undefined && node.getAttribute) {
    163             switch (Einfo.AttrOper) {
    164             case '=':
    165                 isMatch = node.getAttribute(Einfo.AttrName) === Einfo.AttrVal;
    166                 break;
    167             case '~=':
    168                 isMatch = !!(node.getAttribute(Einfo.AttrName) && node.getAttribute(Einfo.AttrName).match(new RegExp('(?:^|\\s+)' + Einfo.AttrVal + '(?:$|\\s+)', 'i')));
    169                 break;
    170             case '^=':
    171                 isMatch = !!(node.getAttribute(Einfo.AttrName) && node.getAttribute(Einfo.AttrName).match(new RegExp('^' + Einfo.AttrVal, 'i')));
    172                 break;
    173             case '$=':
    174                 isMatch = !!(node.getAttribute(Einfo.AttrName) && node.getAttribute(Einfo.AttrName).match(new RegExp(Einfo.AttrVal + '$', 'i')));
    175                 break;
    176             case '*=':
    177                 isMatch = !!(node.getAttribute(Einfo.AttrName) && node.getAttribute(Einfo.AttrName).match(new RegExp(Einfo.AttrVal, 'i')));
    178                 break;
    179             case '|=':
    180                 isMatch = !!(node.getAttribute(Einfo.AttrName) && node.getAttribute(Einfo.AttrName).match(new RegExp('(?:^|\\-)' + Einfo.AttrVal + '(?:$|\\-)', 'i')));
    181                 break
    182             }
    183         }
    184         return isMatch
    185     }
    186     function isMatchFakeClass(Einfo, node, isMatch) {
    187         if (Einfo.FakeClass === undefined) {} else {
    188             switch (Einfo.FakeClass) {
    189             case 'empty':
    190                 isMatch = node.innerHTML.replace(RegTrim, '').length == 0;
    191                 break;
    192             case 'checked':
    193                 if (node.nodeName.match(/(?:INPUT|TEXTAREA|BUTTON|SELECT|OPTION)/i)) isMatch = !!node.checked;
    194                 break;
    195             case 'enabled':
    196                 if (node.nodeName.match(/(?:INPUT|TEXTAREA|BUTTON|SELECT|OPTION)/i)) isMatch = !!node.disabled;
    197                 break;
    198             case 'disabled':
    199                 if (node.nodeName.match(/(?:INPUT|TEXTAREA|BUTTON|SELECT|OPTION)/i)) isMatch = !!node.disabled;
    200                 break;
    201             case 'target':
    202                 var hash = location.hash.replace('#', '');
    203                 isMatch = hash === node.id || (node.name && hash === node.name);
    204                 break
    205             }
    206         }
    207         return isMatch
    208     }
    209     window['aiQuery'] = AIQuery;
    210 } (window, document);
  • 相关阅读:
    Redis集群~StackExchange.redis连接Twemproxy代理服务器
    开源的Android视频播放器
    Servlet 实现文件的上传与下载
    HDU1878 欧拉回路
    C#根据域名查询IP(CMD命令参数输入或者启动程序后再输入查询)
    Windows API获取系统配置文件的配置参数
    Lucene核心--构建Lucene搜索(下篇,理论篇)
    Lucene核心--构建Lucene搜索(上篇,理论篇)
    hdu1397(素数组和成偶数的个数 用 标记法)
    hdu1248
  • 原文地址:https://www.cnblogs.com/xingzhi/p/2791747.html
Copyright © 2020-2023  润新知