📄 element.js
字号:
/*
* Ext JS Library 2.2.1
* Copyright(c) 2006-2009, Ext JS, LLC.
* licensing@extjs.com
*
* http://extjs.com/license
*/
/**
* @class Ext.Element
* Represents an Element in the DOM.<br><br>
* Usage:<br>
<pre><code>
// by id
var el = Ext.get("my-div");
// by DOM element reference
var el = Ext.get(myDivElement);
</code></pre>
* <b>Animations</b><br />
* Many of the functions for manipulating an element have an optional "animate" parameter. The animate parameter
* should either be a boolean (true) or an object literal with animation options. Note that the supported Element animation
* options are a subset of the {@link Ext.Fx} animation options specific to Fx effects. The Element animation options are:
<pre>
Option Default Description
--------- -------- ---------------------------------------------
duration .35 The duration of the animation in seconds
easing easeOut The easing method
callback none A function to execute when the anim completes
scope this The scope (this) of the callback function
</pre>
* Also, the Anim object being used for the animation will be set on your options object as "anim", which allows you to stop or
* manipulate the animation. Here's an example:
<pre><code>
var el = Ext.get("my-div");
// no animation
el.setWidth(100);
// default animation
el.setWidth(100, true);
// animation with some options set
el.setWidth(100, {
duration: 1,
callback: this.foo,
scope: this
});
// using the "anim" property to get the Anim object
var opt = {
duration: 1,
callback: this.foo,
scope: this
};
el.setWidth(100, opt);
...
if(opt.anim.isAnimated()){
opt.anim.stop();
}
</code></pre>
* <b> Composite (Collections of) Elements</b><br />
* For working with collections of Elements, see {@link Ext.CompositeElement}
* @constructor Create a new Element directly.
* @param {String/HTMLElement} element
* @param {Boolean} forceNew (optional) By default the constructor checks to see if there is already an instance of this element in the cache and if there is it returns the same instance. This will skip that check (useful for extending this class).
*/
(function(){
var D = Ext.lib.Dom;
var E = Ext.lib.Event;
var A = Ext.lib.Anim;
// local style camelizing for speed
var propCache = {};
var camelRe = /(-[a-z])/gi;
var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
var view = document.defaultView;
Ext.Element = function(element, forceNew){
var dom = typeof element == "string" ?
document.getElementById(element) : element;
if(!dom){ // invalid id/element
return null;
}
var id = dom.id;
if(forceNew !== true && id && Ext.Element.cache[id]){ // element object already exists
return Ext.Element.cache[id];
}
/**
* The DOM element
* @type HTMLElement
*/
this.dom = dom;
/**
* The DOM element ID
* @type String
*/
this.id = id || Ext.id(dom);
};
var El = Ext.Element;
El.prototype = {
/**
* The element's default display mode (defaults to "")
* @type String
*/
originalDisplay : "",
visibilityMode : 1,
/**
* The default unit to append to CSS values where a unit isn't provided (defaults to px).
* @type String
*/
defaultUnit : "px",
/**
* Sets the element's visibility mode. When setVisible() is called it
* will use this to determine whether to set the visibility or the display property.
* @param visMode Element.VISIBILITY or Element.DISPLAY
* @return {Ext.Element} this
*/
setVisibilityMode : function(visMode){
this.visibilityMode = visMode;
return this;
},
/**
* Convenience method for setVisibilityMode(Element.DISPLAY)
* @param {String} display (optional) What to set display to when visible
* @return {Ext.Element} this
*/
enableDisplayMode : function(display){
this.setVisibilityMode(El.DISPLAY);
if(typeof display != "undefined") this.originalDisplay = display;
return this;
},
/**
* Looks at this node and then at parent nodes for a match of the passed simple selector (e.g. div.some-class or span:first-child)
* @param {String} selector The simple selector to test
* @param {Number/Mixed} maxDepth (optional) The max depth to
search as a number or element (defaults to 10 || document.body)
* @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node
* @return {HTMLElement} The matching DOM node (or null if no match was found)
*/
findParent : function(simpleSelector, maxDepth, returnEl){
var p = this.dom, b = document.body, depth = 0, dq = Ext.DomQuery, stopEl;
maxDepth = maxDepth || 50;
if(typeof maxDepth != "number"){
stopEl = Ext.getDom(maxDepth);
maxDepth = 10;
}
while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
if(dq.is(p, simpleSelector)){
return returnEl ? Ext.get(p) : p;
}
depth++;
p = p.parentNode;
}
return null;
},
/**
* Looks at parent nodes for a match of the passed simple selector (e.g. div.some-class or span:first-child)
* @param {String} selector The simple selector to test
* @param {Number/Mixed} maxDepth (optional) The max depth to
search as a number or element (defaults to 10 || document.body)
* @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node
* @return {HTMLElement} The matching DOM node (or null if no match was found)
*/
findParentNode : function(simpleSelector, maxDepth, returnEl){
var p = Ext.fly(this.dom.parentNode, '_internal');
return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
},
/**
* Walks up the dom looking for a parent node that matches the passed simple selector (e.g. div.some-class or span:first-child).
* This is a shortcut for findParentNode() that always returns an Ext.Element.
* @param {String} selector The simple selector to test
* @param {Number/Mixed} maxDepth (optional) The max depth to
search as a number or element (defaults to 10 || document.body)
* @return {Ext.Element} The matching DOM node (or null if no match was found)
*/
up : function(simpleSelector, maxDepth){
return this.findParentNode(simpleSelector, maxDepth, true);
},
/**
* Returns true if this element matches the passed simple selector (e.g. div.some-class or span:first-child)
* @param {String} selector The simple selector to test
* @return {Boolean} True if this element matches the selector, else false
*/
is : function(simpleSelector){
return Ext.DomQuery.is(this.dom, simpleSelector);
},
/**
* Perform animation on this element.
* @param {Object} args The animation control args
* @param {Float} duration (optional) How long the animation lasts in seconds (defaults to .35)
* @param {Function} onComplete (optional) Function to call when animation completes
* @param {String} easing (optional) Easing method to use (defaults to 'easeOut')
* @param {String} animType (optional) 'run' is the default. Can also be 'color', 'motion', or 'scroll'
* @return {Ext.Element} this
*/
animate : function(args, duration, onComplete, easing, animType){
this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
return this;
},
/*
* @private Internal animation call
*/
anim : function(args, opt, animType, defaultDur, defaultEase, cb){
animType = animType || 'run';
opt = opt || {};
var anim = Ext.lib.Anim[animType](
this.dom, args,
(opt.duration || defaultDur) || .35,
(opt.easing || defaultEase) || 'easeOut',
function(){
Ext.callback(cb, this);
Ext.callback(opt.callback, opt.scope || this, [this, opt]);
},
this
);
opt.anim = anim;
return anim;
},
// private legacy anim prep
preanim : function(a, i){
return !a[i] ? false : (typeof a[i] == "object" ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
},
/**
* Removes worthless text nodes
* @param {Boolean} forceReclean (optional) By default the element
* keeps track if it has been cleaned already so
* you can call this over and over. However, if you update the element and
* need to force a reclean, you can pass true.
*/
clean : function(forceReclean){
if(this.isCleaned && forceReclean !== true){
return this;
}
var ns = /\S/;
var d = this.dom, n = d.firstChild, ni = -1;
while(n){
var nx = n.nextSibling;
if(n.nodeType == 3 && !ns.test(n.nodeValue)){
d.removeChild(n);
}else{
n.nodeIndex = ++ni;
}
n = nx;
}
this.isCleaned = true;
return this;
},
/**
* Scrolls this element into view within the passed container.
* @param {Mixed} container (optional) The container element to scroll (defaults to document.body). Should be a
* string (id), dom node, or Ext.Element.
* @param {Boolean} hscroll (optional) False to disable horizontal scroll (defaults to true)
* @return {Ext.Element} this
*/
scrollIntoView : function(container, hscroll){
var c = Ext.getDom(container) || Ext.getBody().dom;
var el = this.dom;
var o = this.getOffsetsTo(c),
l = o[0] + c.scrollLeft,
t = o[1] + c.scrollTop,
b = t+el.offsetHeight,
r = l+el.offsetWidth;
var ch = c.clientHeight;
var ct = parseInt(c.scrollTop, 10);
var cl = parseInt(c.scrollLeft, 10);
var cb = ct + ch;
var cr = cl + c.clientWidth;
if(el.offsetHeight > ch || t < ct){
c.scrollTop = t;
}else if(b > cb){
c.scrollTop = b-ch;
}
c.scrollTop = c.scrollTop; // corrects IE, other browsers will ignore
if(hscroll !== false){
if(el.offsetWidth > c.clientWidth || l < cl){
c.scrollLeft = l;
}else if(r > cr){
c.scrollLeft = r-c.clientWidth;
}
c.scrollLeft = c.scrollLeft;
}
return this;
},
// private
scrollChildIntoView : function(child, hscroll){
Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
},
/**
* Measures the element's content height and updates height to match. Note: this function uses setTimeout so
* the new height may not be available immediately.
* @param {Boolean} animate (optional) Animate the transition (defaults to false)
* @param {Float} duration (optional) Length of the animation in seconds (defaults to .35)
* @param {Function} onComplete (optional) Function to call when animation completes
* @param {String} easing (optional) Easing method to use (defaults to easeOut)
* @return {Ext.Element} this
*/
autoHeight : function(animate, duration, onComplete, easing){
var oldHeight = this.getHeight();
this.clip();
this.setHeight(1); // force clipping
setTimeout(function(){
var height = parseInt(this.dom.scrollHeight, 10); // parseInt for Safari
if(!animate){
this.setHeight(height);
this.unclip();
if(typeof onComplete == "function"){
onComplete();
}
}else{
this.setHeight(oldHeight); // restore original height
this.setHeight(height, animate, duration, function(){
this.unclip();
if(typeof onComplete == "function") onComplete();
}.createDelegate(this), easing);
}
}.createDelegate(this), 0);
return this;
},
/**
* Returns true if this element is an ancestor of the passed element
* @param {HTMLElement/String} el The element to check
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -