📄 dom.js
字号:
/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
Version: 0.11.3
*/
/**
* @class Provides helper methods for DOM elements.
*/
YAHOO.util.Dom = function() {
var ua = navigator.userAgent.toLowerCase();
var isOpera = (ua.indexOf('opera') > -1);
var isSafari = (ua.indexOf('safari') > -1);
var isIE = (window.ActiveXObject);
var id_counter = 0;
var util = YAHOO.util; // internal shorthand
var property_cache = {}; // to cache case conversion for set/getStyle
var toCamel = function(property) {
var convert = function(prop) {
var test = /(-[a-z])/i.exec(prop);
return prop.replace(RegExp.$1, RegExp.$1.substr(1).toUpperCase());
};
while(property.indexOf('-') > -1) {
property = convert(property);
}
return property;
//return property.replace(/-([a-z])/gi, function(m0, m1) {return m1.toUpperCase()}) // cant use function as 2nd arg yet due to safari bug
};
var toHyphen = function(property) {
if (property.indexOf('-') > -1) { // assume hyphen
return property;
}
var converted = '';
for (var i = 0, len = property.length;i < len; ++i) {
if (property.charAt(i) == property.charAt(i).toUpperCase()) {
converted = converted + '-' + property.charAt(i).toLowerCase();
} else {
converted = converted + property.charAt(i);
}
}
return converted;
//return property.replace(/([a-z])([A-Z]+)/g, function(m0, m1, m2) {return (m1 + '-' + m2.toLowerCase())});
};
// improve performance by only looking up once
var cacheConvertedProperties = function(property) {
property_cache[property] = {
camel: toCamel(property),
hyphen: toHyphen(property)
};
};
return {
/**
* Returns an HTMLElement reference
* @param {String/HTMLElement/Array} el Accepts a string to use as an ID for getting a DOM reference, an actual DOM reference, or an Array of IDs and/or HTMLElements.
* @return {HTMLElement/Array} A DOM reference to an HTML element or an array of HTMLElements.
*/
get: function(el) {
if (!el) { return null; } // nothing to work with
if (typeof el != 'string' && !(el instanceof Array) ) { // assuming HTMLElement or HTMLCollection, so pass back as is
return el;
}
if (typeof el == 'string') { // ID
return document.getElementById(el);
}
else { // array of ID's and/or elements
var collection = [];
for (var i = 0, len = el.length; i < len; ++i) {
collection[collection.length] = util.Dom.get(el[i]);
}
return collection;
}
return null; // safety, should never happen
},
/**
* Normalizes currentStyle and ComputedStyle.
* @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
* @param {String} property The style property whose value is returned.
* @return {String/Array} The current value of the style property for the element(s).
*/
getStyle: function(el, property) {
var f = function(el) {
var value = null;
var dv = document.defaultView;
if (!property_cache[property]) {
cacheConvertedProperties(property);
}
var camel = property_cache[property]['camel'];
var hyphen = property_cache[property]['hyphen'];
if (property == 'opacity' && el.filters) {// IE opacity
value = 1;
try {
value = el.filters.item('DXImageTransform.Microsoft.Alpha').opacity / 100;
} catch(e) {
try {
value = el.filters.item('alpha').opacity / 100;
} catch(e) {}
}
} else if (el.style[camel]) { // camelCase for valid styles
value = el.style[camel];
}
else if (isIE && el.currentStyle && el.currentStyle[camel]) { // camelCase for currentStyle; isIE to workaround broken Opera 9 currentStyle
value = el.currentStyle[camel];
}
else if ( dv && dv.getComputedStyle ) { // hyphen-case for computedStyle
var computed = dv.getComputedStyle(el, '');
if (computed && computed.getPropertyValue(hyphen)) {
value = computed.getPropertyValue(hyphen);
}
}
return value;
};
return util.Dom.batch(el, f, util.Dom, true);
},
/**
* Wrapper for setting style properties of HTMLElements. Normalizes "opacity" across modern browsers.
* @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
* @param {String} property The style property to be set.
* @param {String} val The value to apply to the given property.
*/
setStyle: function(el, property, val) {
if (!property_cache[property]) {
cacheConvertedProperties(property);
}
var camel = property_cache[property]['camel'];
var f = function(el) {
switch(property) {
case 'opacity' :
if (isIE && typeof el.style.filter == 'string') { // in case not appended
el.style.filter = 'alpha(opacity=' + val * 100 + ')';
if (!el.currentStyle || !el.currentStyle.hasLayout) {
el.style.zoom = 1; // when no layout or cant tell
}
} else {
el.style.opacity = val;
el.style['-moz-opacity'] = val;
el.style['-khtml-opacity'] = val;
}
break;
default :
el.style[camel] = val;
}
};
util.Dom.batch(el, f, util.Dom, true);
},
/**
* Gets the current position of an element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
* @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
@ return {Array} The XY position of the element(s)
*/
getXY: function(el) {
var f = function(el) {
// has to be part of document to have pageXY
if (el.offsetParent === null || this.getStyle(el, 'display') == 'none') {
return false;
}
var parentNode = null;
var pos = [];
var box;
if (el.getBoundingClientRect) { // IE
box = el.getBoundingClientRect();
var doc = document;
if ( !this.inDocument(el) && parent.document != document) {// might be in a frame, need to get its scroll
doc = parent.document;
if ( !this.isAncestor(doc.documentElement, el) ) {
return false;
}
}
var scrollTop = Math.max(doc.documentElement.scrollTop, doc.body.scrollTop);
var scrollLeft = Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft);
return [box.left + scrollLeft, box.top + scrollTop];
}
else { // safari, opera, & gecko
pos = [el.offsetLeft, el.offsetTop];
parentNode = el.offsetParent;
if (parentNode != el) {
while (parentNode) {
pos[0] += parentNode.offsetLeft;
pos[1] += parentNode.offsetTop;
parentNode = parentNode.offsetParent;
}
}
if (isSafari && this.getStyle(el, 'position') == 'absolute' ) { // safari doubles in some cases
pos[0] -= document.body.offsetLeft;
pos[1] -= document.body.offsetTop;
}
}
if (el.parentNode) { parentNode = el.parentNode; }
else { parentNode = null; }
while (parentNode && parentNode.tagName.toUpperCase() != 'BODY' && parentNode.tagName.toUpperCase() != 'HTML')
{ // account for any scrolled ancestors
if (util.Dom.getStyle(parentNode, 'display') != 'inline') { // work around opera inline scrollLeft/Top bug
pos[0] -= parentNode.scrollLeft;
pos[1] -= parentNode.scrollTop;
}
if (parentNode.parentNode) { parentNode = parentNode.parentNode; }
else { parentNode = null; }
}
return pos;
};
return util.Dom.batch(el, f, util.Dom, true);
},
/**
* Gets the current X position of an element based on page coordinates. The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
* @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
* @return {String/Array} The X position of the element(s)
*/
getX: function(el) {
var f = function(el) {
return util.Dom.getXY(el)[0];
};
return util.Dom.batch(el, f, util.Dom, true);
},
/**
* Gets the current Y position of an element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
* @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
* @return {String/Array} The Y position of the element(s)
*/
getY: function(el) {
var f = function(el) {
return util.Dom.getXY(el)[1];
};
return util.Dom.batch(el, f, util.Dom, true);
},
/**
* Set the position of an html element in page coordinates, regardless of how the element is positioned.
* The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
* @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
* @param {Array} pos Contains X & Y values for new position (coordinates are page-based)
* @param {Boolean} noRetry By default we try and set the position a second time if the first fails
*/
setXY: function(el, pos, noRetry) {
var f = function(el) {
var style_pos = this.getStyle(el, 'position');
if (style_pos == 'static') { // default to relative
this.setStyle(el, 'position', 'relative');
style_pos = 'relative';
}
var pageXY = this.getXY(el);
if (pageXY === false) { // has to be part of doc to have pageXY
return false;
}
var delta = [ // assuming pixels; if not we will have to retry
parseInt( this.getStyle(el, 'left'), 10 ),
parseInt( this.getStyle(el, 'top'), 10 )
];
if ( isNaN(delta[0]) ) {// in case of 'auto'
delta[0] = (style_pos == 'relative') ? 0 : el.offsetLeft;
}
if ( isNaN(delta[1]) ) { // in case of 'auto'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -