You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
5.8 KiB
229 lines
5.8 KiB
|
|
function _contains(nodeA, nodeB) {
|
|
// Bypass comparison on document node since
|
|
// we don't deal with cross frame,
|
|
// e.g. document.body.parentNode.parentNode == document (false for IE).
|
|
if (nodeA.nodeType == 9 && nodeB.nodeType != 9) {
|
|
return true;
|
|
}
|
|
while ((nodeB = nodeB.parentNode)) {
|
|
if (nodeB == nodeA) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
var _getSetAttrDiv = document.createElement('div');
|
|
_getSetAttrDiv.setAttribute('className', 't');
|
|
var _GET_SET_ATTRIBUTE = _getSetAttrDiv.className !== 't';
|
|
|
|
function _getAttr(el, key) {
|
|
key = key.toLowerCase();
|
|
var val = null;
|
|
// IE6,IE7,IE=EmulateIE7
|
|
if (!_GET_SET_ATTRIBUTE && el.nodeName.toLowerCase() != 'script') {
|
|
var div = el.ownerDocument.createElement('div');
|
|
div.appendChild(el.cloneNode(false));
|
|
var list = _getAttrList(_unescape(div.innerHTML));
|
|
if (key in list) {
|
|
val = list[key];
|
|
}
|
|
} else {
|
|
// IE8设置<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />,抛出异常
|
|
try {
|
|
val = el.getAttribute(key, 2);
|
|
} catch(e) {
|
|
val = el.getAttribute(key, 1);
|
|
}
|
|
}
|
|
if (key === 'style' && val !== null) {
|
|
val = _formatCss(val);
|
|
}
|
|
return val;
|
|
}
|
|
|
|
function _queryAll(expr, root) {
|
|
var exprList = expr.split(',');
|
|
if (exprList.length > 1) {
|
|
var mergedResults = [];
|
|
_each(exprList, function() {
|
|
_each(_queryAll(this, root), function() {
|
|
if (_inArray(this, mergedResults) < 0) {
|
|
mergedResults.push(this);
|
|
}
|
|
});
|
|
});
|
|
return mergedResults;
|
|
}
|
|
root = root || document;
|
|
function escape(str) {
|
|
if (typeof str != 'string') {
|
|
return str;
|
|
}
|
|
return str.replace(/([^\w\-])/g, '\\$1');
|
|
}
|
|
function stripslashes(str) {
|
|
return str.replace(/\\/g, '');
|
|
}
|
|
function cmpTag(tagA, tagB) {
|
|
return tagA === '*' || tagA.toLowerCase() === escape(tagB.toLowerCase());
|
|
}
|
|
function byId(id, tag, root) {
|
|
var arr = [],
|
|
doc = root.ownerDocument || root,
|
|
el = doc.getElementById(stripslashes(id));
|
|
if (el) {
|
|
if (cmpTag(tag, el.nodeName) && _contains(root, el)) {
|
|
arr.push(el);
|
|
}
|
|
}
|
|
return arr;
|
|
}
|
|
function byClass(className, tag, root) {
|
|
var doc = root.ownerDocument || root, arr = [], els, i, len, el;
|
|
if (root.getElementsByClassName) {
|
|
els = root.getElementsByClassName(stripslashes(className));
|
|
for (i = 0, len = els.length; i < len; i++) {
|
|
el = els[i];
|
|
if (cmpTag(tag, el.nodeName)) {
|
|
arr.push(el);
|
|
}
|
|
}
|
|
} else if (doc.querySelectorAll) {
|
|
els = doc.querySelectorAll((root.nodeName !== '#document' ? root.nodeName + ' ' : '') + tag + '.' + className);
|
|
for (i = 0, len = els.length; i < len; i++) {
|
|
el = els[i];
|
|
if (_contains(root, el)) {
|
|
arr.push(el);
|
|
}
|
|
}
|
|
} else {
|
|
els = root.getElementsByTagName(tag);
|
|
className = ' ' + className + ' ';
|
|
for (i = 0, len = els.length; i < len; i++) {
|
|
el = els[i];
|
|
if (el.nodeType == 1) {
|
|
var cls = el.className;
|
|
if (cls && (' ' + cls + ' ').indexOf(className) > -1) {
|
|
arr.push(el);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return arr;
|
|
}
|
|
function byName(name, tag, root) {
|
|
var arr = [], doc = root.ownerDocument || root,
|
|
els = doc.getElementsByName(stripslashes(name)), el;
|
|
for (var i = 0, len = els.length; i < len; i++) {
|
|
el = els[i];
|
|
if (cmpTag(tag, el.nodeName) && _contains(root, el)) {
|
|
if (el.getAttribute('name') !== null) {
|
|
arr.push(el);
|
|
}
|
|
}
|
|
}
|
|
return arr;
|
|
}
|
|
function byAttr(key, val, tag, root) {
|
|
var arr = [], els = root.getElementsByTagName(tag), el;
|
|
for (var i = 0, len = els.length; i < len; i++) {
|
|
el = els[i];
|
|
if (el.nodeType == 1) {
|
|
if (val === null) {
|
|
if (_getAttr(el, key) !== null) {
|
|
arr.push(el);
|
|
}
|
|
} else {
|
|
if (val === escape(_getAttr(el, key))) {
|
|
arr.push(el);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return arr;
|
|
}
|
|
function select(expr, root) {
|
|
var arr = [], matches;
|
|
matches = /^((?:\\.|[^.#\s\[<>])+)/.exec(expr);
|
|
var tag = matches ? matches[1] : '*';
|
|
if ((matches = /#((?:[\w\-]|\\.)+)$/.exec(expr))) {
|
|
arr = byId(matches[1], tag, root);
|
|
} else if ((matches = /\.((?:[\w\-]|\\.)+)$/.exec(expr))) {
|
|
arr = byClass(matches[1], tag, root);
|
|
} else if ((matches = /\[((?:[\w\-]|\\.)+)\]/.exec(expr))) {
|
|
arr = byAttr(matches[1].toLowerCase(), null, tag, root);
|
|
} else if ((matches = /\[((?:[\w\-]|\\.)+)\s*=\s*['"]?((?:\\.|[^'"]+)+)['"]?\]/.exec(expr))) {
|
|
var key = matches[1].toLowerCase(), val = matches[2];
|
|
if (key === 'id') {
|
|
arr = byId(val, tag, root);
|
|
} else if (key === 'class') {
|
|
arr = byClass(val, tag, root);
|
|
} else if (key === 'name') {
|
|
arr = byName(val, tag, root);
|
|
} else {
|
|
arr = byAttr(key, val, tag, root);
|
|
}
|
|
} else {
|
|
var els = root.getElementsByTagName(tag), el;
|
|
for (var i = 0, len = els.length; i < len; i++) {
|
|
el = els[i];
|
|
if (el.nodeType == 1) {
|
|
arr.push(el);
|
|
}
|
|
}
|
|
}
|
|
return arr;
|
|
}
|
|
var parts = [], arr, re = /((?:\\.|[^\s>])+|[\s>])/g;
|
|
while ((arr = re.exec(expr))) {
|
|
if (arr[1] !== ' ') {
|
|
parts.push(arr[1]);
|
|
}
|
|
}
|
|
var results = [];
|
|
if (parts.length == 1) {
|
|
return select(parts[0], root);
|
|
}
|
|
var isChild = false, part, els, subResults, val, v, i, j, k, length, len, l;
|
|
for (i = 0, lenth = parts.length; i < lenth; i++) {
|
|
part = parts[i];
|
|
if (part === '>') {
|
|
isChild = true;
|
|
continue;
|
|
}
|
|
if (i > 0) {
|
|
els = [];
|
|
for (j = 0, len = results.length; j < len; j++) {
|
|
val = results[j];
|
|
subResults = select(part, val);
|
|
for (k = 0, l = subResults.length; k < l; k++) {
|
|
v = subResults[k];
|
|
if (isChild) {
|
|
if (val === v.parentNode) {
|
|
els.push(v);
|
|
}
|
|
} else {
|
|
els.push(v);
|
|
}
|
|
}
|
|
}
|
|
results = els;
|
|
} else {
|
|
results = select(part, root);
|
|
}
|
|
if (results.length === 0) {
|
|
return [];
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
function _query(expr, root) {
|
|
var arr = _queryAll(expr, root);
|
|
return arr.length > 0 ? arr[0] : null;
|
|
}
|
|
|
|
K.query = _query;
|
|
K.queryAll = _queryAll;
|
|
|