📄 selector-beta.js
字号:
/*Copyright (c) 2008, Yahoo! Inc. All rights reserved.Code licensed under the BSD License:http://developer.yahoo.net/yui/license.txtversion: 2.6.0*//** * The selector module provides helper methods allowing CSS3 Selectors to be used with DOM elements. * @module selector * @title Selector Utility * @namespace YAHOO.util * @requires yahoo, dom */(function() {/** * Provides helper methods for collecting and filtering DOM elements. * @namespace YAHOO.util * @class Selector * @static */var Selector = function() {};var Y = YAHOO.util;var reNth = /^(?:([-]?\d*)(n){1}|(odd|even)$)*([-+]?\d*)$/;Selector.prototype = { /** * Default document for use queries * @property document * @type object * @default window.document */ document: window.document, /** * Mapping of attributes to aliases, normally to work around HTMLAttributes * that conflict with JS reserved words. * @property attrAliases * @type object */ attrAliases: { }, /** * Mapping of shorthand tokens to corresponding attribute selector * @property shorthand * @type object */ shorthand: { //'(?:(?:[^\\)\\]\\s*>+~,]+)(?:-?[_a-z]+[-\\w]))+#(-?[_a-z]+[-\\w]*)': '[id=$1]', '\\#(-?[_a-z]+[-\\w]*)': '[id=$1]', '\\.(-?[_a-z]+[-\\w]*)': '[class~=$1]' }, /** * List of operators and corresponding boolean functions. * These functions are passed the attribute and the current node's value of the attribute. * @property operators * @type object */ operators: { '=': function(attr, val) { return attr === val; }, // Equality '!=': function(attr, val) { return attr !== val; }, // Inequality '~=': function(attr, val) { // Match one of space seperated words var s = ' '; return (s + attr + s).indexOf((s + val + s)) > -1; }, '|=': function(attr, val) { return getRegExp('^' + val + '[-]?').test(attr); }, // Match start with value followed by optional hyphen '^=': function(attr, val) { return attr.indexOf(val) === 0; }, // Match starts with value '$=': function(attr, val) { return attr.lastIndexOf(val) === attr.length - val.length; }, // Match ends with value '*=': function(attr, val) { return attr.indexOf(val) > -1; }, // Match contains value as substring '': function(attr, val) { return attr; } // Just test for existence of attribute }, /** * List of pseudo-classes and corresponding boolean functions. * These functions are called with the current node, and any value that was parsed with the pseudo regex. * @property pseudos * @type object */ pseudos: { 'root': function(node) { return node === node.ownerDocument.documentElement; }, 'nth-child': function(node, val) { return getNth(node, val); }, 'nth-last-child': function(node, val) { return getNth(node, val, null, true); }, 'nth-of-type': function(node, val) { return getNth(node, val, node.tagName); }, 'nth-last-of-type': function(node, val) { return getNth(node, val, node.tagName, true); }, 'first-child': function(node) { return getChildren(node.parentNode)[0] === node; }, 'last-child': function(node) { var children = getChildren(node.parentNode); return children[children.length - 1] === node; }, 'first-of-type': function(node, val) { return getChildren(node.parentNode, node.tagName.toLowerCase())[0]; }, 'last-of-type': function(node, val) { var children = getChildren(node.parentNode, node.tagName.toLowerCase()); return children[children.length - 1]; }, 'only-child': function(node) { var children = getChildren(node.parentNode); return children.length === 1 && children[0] === node; }, 'only-of-type': function(node) { return getChildren(node.parentNode, node.tagName.toLowerCase()).length === 1; }, 'empty': function(node) { return node.childNodes.length === 0; }, 'not': function(node, simple) { return !Selector.test(node, simple); }, 'contains': function(node, str) { var text = node.innerText || node.textContent || ''; return text.indexOf(str) > -1; }, 'checked': function(node) { return node.checked === true; } }, /** * Test if the supplied node matches the supplied selector. * @method test * * @param {HTMLElement | String} node An id or node reference to the HTMLElement being tested. * @param {string} selector The CSS Selector to test the node against. * @return{boolean} Whether or not the node matches the selector. * @static */ test: function(node, selector) { node = Selector.document.getElementById(node) || node; if (!node) { return false; } var groups = selector ? selector.split(',') : []; if (groups.length) { for (var i = 0, len = groups.length; i < len; ++i) { if ( rTestNode(node, groups[i]) ) { // passes if ANY group matches return true; } } return false; } return rTestNode(node, selector); }, /** * Filters a set of nodes based on a given CSS selector. * @method filter * * @param {array} nodes A set of nodes/ids to filter. * @param {string} selector The selector used to test each node. * @return{array} An array of nodes from the supplied array that match the given selector. * @static */ filter: function(nodes, selector) { nodes = nodes || []; var node, result = [], tokens = tokenize(selector); if (!nodes.item) { // if not HTMLCollection, handle arrays of ids and/or nodes for (var i = 0, len = nodes.length; i < len; ++i) { if (!nodes[i].tagName) { // tagName limits to HTMLElements node = Selector.document.getElementById(nodes[i]); if (node) { // skip IDs that return null nodes[i] = node; } else { } } } } result = rFilter(nodes, tokenize(selector)[0]); clearParentCache(); return result; }, /** * Retrieves a set of nodes based on a given CSS selector. * @method query * * @param {string} selector The CSS Selector to test the node against. * @param {HTMLElement | String} root optional An id or HTMLElement to start the query from. Defaults to Selector.document. * @param {Boolean} firstOnly optional Whether or not to return only the first match. * @return {Array} An array of nodes that match the given selector. * @static */ query: function(selector, root, firstOnly) { var result = query(selector, root, firstOnly); return result; }};var query = function(selector, root, firstOnly, deDupe) { var result = (firstOnly) ? null : []; if (!selector) { return result; } var groups = selector.split(','); // TODO: handle comma in attribute/pseudo if (groups.length > 1) { var found; for (var i = 0, len = groups.length; i < len; ++i) { found = arguments.callee(groups[i], root, firstOnly, true); result = firstOnly ? found : result.concat(found); } clearFoundCache(); return result; } if (root && !root.nodeName) { // assume ID root = Selector.document.getElementById(root); if (!root) { return result; } } root = root || Selector.document; var tokens = tokenize(selector); var idToken = tokens[getIdTokenIndex(tokens)], nodes = [], node, id, token = tokens.pop() || {}; if (idToken) { id = getId(idToken.attributes); } // use id shortcut when possible if (id) { node = Selector.document.getElementById(id); if (node && (root.nodeName == '#document' || contains(node, root))) { if ( rTestNode(node, null, idToken) ) { if (idToken === token) { nodes = [node]; // simple selector } else { root = node; // start from here } } } else { return result; } } if (root && !nodes.length) { nodes = root.getElementsByTagName(token.tag); } if (nodes.length) { result = rFilter(nodes, token, firstOnly, deDupe); } clearParentCache(); return result;};var contains = function() { if (document.documentElement.contains && !YAHOO.env.ua.webkit < 422) { // IE & Opera, Safari < 3 contains is broken return function(needle, haystack) { return haystack.contains(needle); }; } else if ( document.documentElement.compareDocumentPosition ) { // gecko return function(needle, haystack) { return !!(haystack.compareDocumentPosition(needle) & 16); }; } else { // Safari < 3 return function(needle, haystack) { var parent = needle.parentNode; while (parent) { if (needle === parent) { return true; } parent = parent.parentNode; } return false; }; }}();var rFilter = function(nodes, token, firstOnly, deDupe) { var result = firstOnly ? null : []; for (var i = 0, len = nodes.length; i < len; i++) { if (! rTestNode(nodes[i], '', token, deDupe)) { continue; } if (firstOnly) { return nodes[i]; } if (deDupe) { if (nodes[i]._found) { continue; } nodes[i]._found = true; foundCache[foundCache.length] = nodes[i]; } result[result.length] = nodes[i]; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -