📄 domutils.js
字号:
// First, make sure all browsers have necessary ECMAScript v3
// and DOM Level 1 properties
/** @type undefined */
var undefined;
/** @type Object */
var Node = Node ? Node : {};
/** @type number */
Node.ELEMENT_NODE = 1;
/** @type number */
Node.ATTRIBUTE_NODE = 2;
/** @type number */
Node.TEXT_NODE = 3;
/** @type number */
Node.CDATA_SECTION_NODE = 4;
/** @type number */
Node.ENTITY_REFERENCE_NODE = 5;
/** @type number */
Node.ENTITY_NODE = 6;
/** @type number */
Node.PROCESSING_INSTRUCTION_NODE = 7;
/** @type number */
Node.COMMENT_NODE = 8;
/** @type number */
Node.DOCUMENT_NODE = 9;
/** @type number */
Node.DOCUMENT_TYPE_NODE = 10;
/** @type number */
Node.DOCUMENT_FRAGMENT_NODE = 11;
/** @type number */
Node.NOTATION_NODE = 12;
/**
* String convenience method to trim leading and trailing whitespace.
*
* @returns string
*/
String.prototype.trim = function () {
return this.replace(/^\s*(.+)/gi,"$1").replace(/\s*$/gi,"");
};
/**
* String convenience method for checking if the end of this string equals
* a given string.
*
* @returns boolean
*/
String.prototype.endsWith = function (s) {
if ("string" != typeof s) {
throw("IllegalArgumentException: Must pass a string to " +
"String.endsWith()");
}
var start = this.length - s.length;
return this.substring(start) == s;
};
/**
* Array convenience method to check for membership.
*
* @param object element
* @returns boolean
*/
Array.prototype.contains = function (element) {
for (var i = 0; i < this.length; i++) {
if (this[i] == element) {
return true;
}
}
return false;
};
/**
* Array convenience method to remove element.
*
* @param object element
* @returns boolean
*/
Array.prototype.remove = function (element) {
var result = false;
var array = [];
for (var i = 0; i < this.length; i++) {
if (this[i] == element) {
result = true;
} else {
array.push(this[i]);
}
}
this.clear();
for (var i = 0; i < array.length; i++) {
this.push(array[i]);
}
array = null;
return result;
};
/**
* Array convenience method to clear membership.
*
* @param object element
* @returns void
*/
Array.prototype.clear = function () {
this.length = 0;
};
/**
* Array convenience method to add stack functionality to <code>Array</code>s
* in browsers that do not support ECMAScript v3.
*
* @param object element
* @returns number
*/
Array.prototype.push = function (element) {
this[this.length] = element;
return this.length;
};
/**
* Array convenience method to add set functionality to <code>Array</code>s
* ... if the element is already a member of this array, return false.
* Otherwise, add it and return true.
*
* @param object element
* @returns boolean
*/
Array.prototype.add = function (element) {
if (this.contains(element)) {
return false;
}
this.push(element);
return false;
};
/**
* Array convenience method to add set functionality to <code>Array</code>s
* ... Uniquely adds all elements in the array parameter to this array.
* Returns true if any new elements were added to this array. False otherwise.
*
* @param Array that
* @returns boolean
*/
Array.prototype.addAll = function (that) {
var result = false;
for (var i = 0; i < that.length; i++) {
if (this.add(that[i])) {
result = true;
}
}
return true;
};
/**
* A utility class that exists to combine common DOM algorithms and utilities
* into a single class as static methods and constants. This class is not
* meant to be subclassed.
*
* @constructor
*/
function DomUtils() {}
/**
* @param Element target
* @returns void
*/
DomUtils.show = function (target) {
target.style.display = "";
};
/**
* @param Element target
* @returns void
*/
DomUtils.hide = function (target) {
target.style.display = "none";
};
/**
* @param Element target
* @returns boolean
*/
DomUtils.isShowing = function (target) {
return target.style.display.toLowerCase() != "none";
};
/**
* Toggles <code>target</code>'s visibility.
* @param Element target
* @returns void
*/
DomUtils.toggle = function (target) {
if (DomUtils.isShowing(target)) {
DomUtils.hide(target);
} else {
DomUtils.show(target);
}
};
/**
* @param Node target
* @param string k
* @returns void
*/
DomUtils.addClassName = function (target,k) {
if(!DomUtils.isElementNode(target)) {
throw "Attempting to add a className to a non-Element Node";
}
var classNames = target.className.split(/\s+/g);
if (classNames.contains(k)) {
return;
} else {
classNames.push(k);
}
target.className = classNames.join(" ");
target.className = target.className.trim();
};
/**
* @param Node target
* @param string k
* @returns void
*/
DomUtils.removeClassName = function (target,k) {
if (!DomUtils.isElementNode(target)) {
throw "Attempting to remove a className to a non-Element Node";
}
var classNames = target.className.split(/\s+/g);
if (!classNames.contains(k)) {
return;
} else {
classNames.remove(k);
}
target.className = classNames.join(" ");
target.className = target.className.trim();
};
/**
* @param Node target
* @param string k
* @returns void
*/
DomUtils.toggleClassName = function (target,k) {
if (DomUtils.hasClassName(target,k)) {
DomUtils.removeClassName(target,k);
} else {
DomUtils.addClassName(target,k);
}
};
/**
* Tests to see if <code>target</code>'s <code>getNodeType()</code>
* method returns <code>Node.ELEMENT_NODE</code>.
* @param Element target
* @returns boolean
*/
DomUtils.isElementNode = function (target) {
return Node.ELEMENT_NODE == target.nodeType;
};
/**
* Tests to see if <code>target</code>'s <code>getTagName()</code>
* method returns <code>Node.ELEMENT_NODE</code>.
* @param Element target
* @returns boolean
*/
DomUtils.hasTagName = function (target,tagName) {
return target.tagName.toLowerCase() == tagName.toLowerCase();
};
/**
* @param Element target
* @param string id
* @returns boolean
*/
DomUtils.hasId = function (target,id) {
return target.id == id;
};
/**
* @param Element target
* @param string className
* @returns boolean
*/
DomUtils.hasClassName = function (target,className) {
function _isLastOfMultpleClassNames(all,className) {
var spaceBefore = all.lastIndexOf(className)-1;
return all.endsWith(className) &&
all.substring(spaceBefore,spaceBefore+1) == " ";
}
className = className.trim();
var cn = target.className;
if (!cn) {
return false;
}
cn = cn.trim();
if (cn == className) {
return true;
}
if (cn.indexOf(className + " ") > -1) {
return true;
}
if (_isLastOfMultpleClassNames(cn,className)) {
return true;
}
return false;
};
/**
* @param Node target
* @param string className
* @returns Element
*/
DomUtils.getFirstAncestorOrSelfByClassName = function (target,
className) {
var parent = target;
do {
if (DomUtils.isElementNode(parent) &&
DomUtils.hasClassName(parent,className)) {
return parent;
}
} while (parent = parent.parentNode);
return null;
};
/**
* @param Node target
* @param string className
* @returns Element
*/
DomUtils.getFirstAncestorByClassName = function (target,className) {
var parent = target;
while (parent = parent.parentNode) {
if (DomUtils.isElementNode(parent) &&
DomUtils.hasClassName(parent,className)) {
return parent;
}
}
return null;
};
/**
* @param Node target
* @param string className
* @returns Element
*/
DomUtils.getFirstChildByClassName = function (target,className) {
var kids = target.childNodes;
for (var i = 0; i < kids.length; i++) {
var kid = kids[i];
if (DomUtils.isElementNode(kid) &&
DomUtils.hasClassName(kid,className)) {
return kid;
}
}
return null;
};
/**
* @param Node target
* @param string className
* @returns Element
*/
DomUtils.getFirstChildByTagName = function (target,tagName) {
var kids = target.childNodes;
for (var i = 0; i < kids.length; i++) {
var kid = kids[i];
if (DomUtils.isElementNode(kid) &&
DomUtils.hasTagName(kid,tagName)) {
return kid;
}
}
return null;
};
/**
* @param Node target
* @param string className
* @returns Array
*/
DomUtils.getChildrenByClassName = function (target,className) {
var result = [];
var kids = target.childNodes;
for (var i = 0; i < kids.length; i++) {
var kid = kids[i];
if (DomUtils.isElementNode(kid) &&
DomUtils.hasClassName(kid,className)) {
result.push(kid);
}
}
return result;
};
/**
* Retreives <code>target</code>'s first descendant element with an
* HTML <code>class</code> attribute value that includes <code>
* className</code> using a breadth-first algorithm.
*
* @param Element target
* @param string className
* @returns Element
*/
DomUtils.getFirstDescendantByClassNameBreadthFirst = function (target,
className) {
var result;
if (result = DomUtils.getFirstChildByClassName(target,className)) {
return result;
}
for (var i = 0; i < target.childNodes.length; i++) {
result = DomUtils.getFirstDescendantByClassNameBreadthFirst(
target.childNodes.item(i),
className );
if (result) {
return result;
}
}
return null;
};
/**
* Retreives <code>target</code>'s first descendant element with an
* HTML <code>class</code> attribute value that includes <code>
* className</code> using a depth-first algorithm.
*
* @param Element target
* @param string className
* @returns Element
*/
DomUtils.getFirstDescendantByClassNameDepthFirst = function (target,
className) {
var child;
var result;
for (var i = 0; i < target.childNodes.length; i++) {
child = target.childNodes.item(i);
if (DomUtils.isElementNode(child) &&
DomUtils.hasClassName(child,className)) {
return child;
}
result = DomUtils.getFirstDescendantByClassNameDepthFirst(
target.childNodes.item(i),
className );
if (result) {
return result;
}
}
return null;
};
/**
* Returns all descendant elements of <code>target</code> with HTML <code>
* class</code> attribute values that contain <code>className</code>
* as an Array. NOTE that unlike the
* algorithms specified in the DOM spec, a <code>NodeList</code> is NOT
* returned. This method searched for all descendants of <code>target
* </code> meeting the criteria using a breadth-first algorithm.
*
* @param Element target
* @param string className
* @returns Element
*/
DomUtils.getDescendantsByClassName = function (target,className) {
var result = [];
result.addAll(DomUtils.getChildrenByClassName(target,className));
for (var i = 0; i < target.childNodes.length; i++) {
result.addAll(DomUtils.getDescendantsByClassName(
target.childNodes.item(i),
className));
}
return result;
};
/**
* @constructor
* @param MouseEvent evt
*/
function Evt(evt) {
this._evt = evt ? evt : window.event;
this._source = this._evt.currentTarget ?
this._evt.currentTarget : this._evt.srcElement;
}
/**
* @returns Element
*/
Evt.prototype.getSource = function () {
return this._source;
};
/**
* @returns void
*/
Evt.prototype.consume = function () {
if (this._evt.stopPropagation) {
this._evt.stopPropagation();
this._evt.preventDefault();
} else if (this._evt.cancelBubble) {
this._evt.cancelBubble = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -