2018-08-04 16:26:50 +08:00
|
|
|
|
/*********************************************************************
|
|
|
|
|
* Anot的原型方法定义区 *
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
|
|
function hyphen(target) {
|
|
|
|
|
//转换为连字符线风格
|
|
|
|
|
return target.replace(/([a-z\d])([A-Z]+)/g, '$1-$2').toLowerCase()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function camelize(target) {
|
|
|
|
|
//转换为驼峰风格
|
|
|
|
|
if (target.indexOf('-') < 0 && target.indexOf('_') < 0) {
|
|
|
|
|
return target //提前判断,提高getStyle等的效率
|
|
|
|
|
}
|
|
|
|
|
return target.replace(/[-_][^-_]/g, function(match) {
|
|
|
|
|
return match.charAt(1).toUpperCase()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
'add,remove'.replace(rword, function(method) {
|
|
|
|
|
Anot.fn[method + 'Class'] = function(cls) {
|
|
|
|
|
var el = this[0]
|
|
|
|
|
//https://developer.mozilla.org/zh-CN/docs/Mozilla/Firefox/Releases/26
|
|
|
|
|
if (cls && typeof cls === 'string' && el && el.nodeType === 1) {
|
|
|
|
|
cls.replace(/\S+/g, function(c) {
|
|
|
|
|
el.classList[method](c)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
return this
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
Anot.fn.mix({
|
|
|
|
|
attr: function(name, value) {
|
|
|
|
|
if (arguments.length === 2) {
|
|
|
|
|
this[0].setAttribute(name, value)
|
|
|
|
|
return this
|
|
|
|
|
} else {
|
|
|
|
|
return this[0].getAttribute(name)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
data: function(name, value) {
|
2019-07-16 11:45:23 +08:00
|
|
|
|
var len = arguments.length
|
|
|
|
|
var dataset = this[0].dataset
|
|
|
|
|
name = hyphen(name || '')
|
|
|
|
|
if (!name) {
|
|
|
|
|
len = 0
|
|
|
|
|
}
|
|
|
|
|
switch (len) {
|
2018-08-04 16:26:50 +08:00
|
|
|
|
case 2:
|
2019-07-16 11:45:23 +08:00
|
|
|
|
dataset[name] = value
|
2018-08-04 16:26:50 +08:00
|
|
|
|
return this
|
|
|
|
|
case 1:
|
2019-07-16 11:45:23 +08:00
|
|
|
|
var val = dataset[name]
|
2018-08-04 16:26:50 +08:00
|
|
|
|
return parseData(val)
|
|
|
|
|
case 0:
|
2019-07-16 11:45:23 +08:00
|
|
|
|
var ret = createMap()
|
|
|
|
|
for (var i in dataset) {
|
|
|
|
|
ret[i] = parseData(dataset[i])
|
|
|
|
|
}
|
2018-08-04 16:26:50 +08:00
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
removeData: function(name) {
|
|
|
|
|
name = 'data-' + hyphen(name)
|
|
|
|
|
this[0].removeAttribute(name)
|
|
|
|
|
return this
|
|
|
|
|
},
|
|
|
|
|
css: function(name, value) {
|
|
|
|
|
if (Anot.isPlainObject(name)) {
|
|
|
|
|
for (var i in name) {
|
|
|
|
|
Anot.css(this, i, name[i])
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
var ret = Anot.css(this, name, value)
|
|
|
|
|
}
|
|
|
|
|
return ret !== void 0 ? ret : this
|
|
|
|
|
},
|
|
|
|
|
position: function() {
|
|
|
|
|
var offsetParent,
|
|
|
|
|
offset,
|
|
|
|
|
elem = this[0],
|
|
|
|
|
parentOffset = {
|
|
|
|
|
top: 0,
|
|
|
|
|
left: 0
|
|
|
|
|
}
|
|
|
|
|
if (!elem) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (this.css('position') === 'fixed') {
|
|
|
|
|
offset = elem.getBoundingClientRect()
|
|
|
|
|
} else {
|
|
|
|
|
offsetParent = this.offsetParent() //得到真正的offsetParent
|
|
|
|
|
offset = this.offset() // 得到正确的offsetParent
|
|
|
|
|
if (offsetParent[0].tagName !== 'HTML') {
|
|
|
|
|
parentOffset = offsetParent.offset()
|
|
|
|
|
}
|
|
|
|
|
parentOffset.top += Anot.css(offsetParent[0], 'borderTopWidth', true)
|
|
|
|
|
parentOffset.left += Anot.css(offsetParent[0], 'borderLeftWidth', true)
|
|
|
|
|
// Subtract offsetParent scroll positions
|
|
|
|
|
parentOffset.top -= offsetParent.scrollTop()
|
|
|
|
|
parentOffset.left -= offsetParent.scrollLeft()
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
top: offset.top - parentOffset.top - Anot.css(elem, 'marginTop', true),
|
|
|
|
|
left: offset.left - parentOffset.left - Anot.css(elem, 'marginLeft', true)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
offsetParent: function() {
|
|
|
|
|
var offsetParent = this[0].offsetParent
|
|
|
|
|
while (offsetParent && Anot.css(offsetParent, 'position') === 'static') {
|
|
|
|
|
offsetParent = offsetParent.offsetParent
|
|
|
|
|
}
|
|
|
|
|
return Anot(offsetParent || root)
|
|
|
|
|
},
|
|
|
|
|
bind: function(type, fn, phase) {
|
|
|
|
|
if (this[0]) {
|
|
|
|
|
//此方法不会链
|
|
|
|
|
return Anot.bind(this[0], type, fn, phase)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
unbind: function(type, fn, phase) {
|
|
|
|
|
if (this[0]) {
|
|
|
|
|
Anot.unbind(this[0], type, fn, phase)
|
|
|
|
|
}
|
|
|
|
|
return this
|
|
|
|
|
},
|
|
|
|
|
val: function(value) {
|
|
|
|
|
var node = this[0]
|
|
|
|
|
if (node && node.nodeType === 1) {
|
|
|
|
|
var get = arguments.length === 0
|
|
|
|
|
var access = get ? ':get' : ':set'
|
|
|
|
|
var fn = valHooks[getValType(node) + access]
|
|
|
|
|
if (fn) {
|
|
|
|
|
var val = fn(node, value)
|
|
|
|
|
} else if (get) {
|
|
|
|
|
return (node.value || '').replace(/\r/g, '')
|
|
|
|
|
} else {
|
|
|
|
|
node.value = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return get ? val : this
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
Anot.parseJSON = JSON.parse
|
|
|
|
|
|
|
|
|
|
var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/
|
|
|
|
|
function parseData(data) {
|
|
|
|
|
try {
|
|
|
|
|
if (typeof data === 'object') return data
|
|
|
|
|
data =
|
|
|
|
|
data === 'true'
|
|
|
|
|
? true
|
|
|
|
|
: data === 'false'
|
2019-07-16 11:45:23 +08:00
|
|
|
|
? false
|
|
|
|
|
: data === 'null'
|
|
|
|
|
? null
|
|
|
|
|
: +data + '' === data
|
|
|
|
|
? +data
|
|
|
|
|
: rbrace.test(data)
|
|
|
|
|
? JSON.parse(data)
|
|
|
|
|
: data
|
2018-08-04 16:26:50 +08:00
|
|
|
|
} catch (e) {}
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Anot.fireDom = function(elem, type, opts) {
|
|
|
|
|
var hackEvent = DOC.createEvent('Events')
|
|
|
|
|
hackEvent.initEvent(type, true, true)
|
|
|
|
|
Anot.mix(hackEvent, opts)
|
|
|
|
|
elem.dispatchEvent(hackEvent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Anot.each(
|
|
|
|
|
{
|
|
|
|
|
scrollLeft: 'pageXOffset',
|
|
|
|
|
scrollTop: 'pageYOffset'
|
|
|
|
|
},
|
|
|
|
|
function(method, prop) {
|
|
|
|
|
Anot.fn[method] = function(val) {
|
|
|
|
|
var node = this[0] || {},
|
|
|
|
|
win = getWindow(node),
|
|
|
|
|
top = method === 'scrollTop'
|
|
|
|
|
if (!arguments.length) {
|
|
|
|
|
return win ? win[prop] : node[method]
|
|
|
|
|
} else {
|
|
|
|
|
if (win) {
|
|
|
|
|
win.scrollTo(!top ? val : win[prop], top ? val : win[prop])
|
|
|
|
|
} else {
|
|
|
|
|
node[method] = val
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
function getWindow(node) {
|
|
|
|
|
return node.window && node.document
|
|
|
|
|
? node
|
|
|
|
|
: node.nodeType === 9
|
2019-07-16 11:45:23 +08:00
|
|
|
|
? node.defaultView
|
|
|
|
|
: false
|
2018-08-04 16:26:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//=============================css相关==================================
|
|
|
|
|
|
|
|
|
|
var cssHooks = (Anot.cssHooks = createMap())
|
|
|
|
|
var prefixes = ['', '-webkit-', '-moz-', '-ms-'] //去掉opera-15的支持
|
|
|
|
|
var cssMap = {
|
|
|
|
|
float: 'cssFloat'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Anot.cssNumber = oneObject(
|
|
|
|
|
'animationIterationCount,animationIterationCount,columnCount,order,flex,flexGrow,flexShrink,fillOpacity,fontWeight,lineHeight,opacity,orphans,widows,zIndex,zoom'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
Anot.cssName = function(name, host, camelCase) {
|
|
|
|
|
if (cssMap[name]) {
|
|
|
|
|
return cssMap[name]
|
|
|
|
|
}
|
|
|
|
|
host = host || root.style
|
|
|
|
|
for (var i = 0, n = prefixes.length; i < n; i++) {
|
|
|
|
|
camelCase = camelize(prefixes[i] + name)
|
|
|
|
|
if (camelCase in host) {
|
|
|
|
|
return (cssMap[name] = camelCase)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cssHooks['@:set'] = function(node, name, value) {
|
|
|
|
|
node.style[name] = value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cssHooks['@:get'] = function(node, name) {
|
|
|
|
|
if (!node || !node.style) {
|
|
|
|
|
throw new Error('getComputedStyle要求传入一个节点 ' + node)
|
|
|
|
|
}
|
|
|
|
|
var ret,
|
|
|
|
|
computed = getComputedStyle(node)
|
|
|
|
|
if (computed) {
|
|
|
|
|
ret = name === 'filter' ? computed.getPropertyValue(name) : computed[name]
|
|
|
|
|
if (ret === '') {
|
|
|
|
|
ret = node.style[name] //其他浏览器需要我们手动取内联样式
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
cssHooks['opacity:get'] = function(node) {
|
|
|
|
|
var ret = cssHooks['@:get'](node, 'opacity')
|
|
|
|
|
return ret === '' ? '1' : ret
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
'top,left'.replace(rword, function(name) {
|
|
|
|
|
cssHooks[name + ':get'] = function(node) {
|
|
|
|
|
var computed = cssHooks['@:get'](node, name)
|
|
|
|
|
return /px$/.test(computed) ? computed : Anot(node).position()[name] + 'px'
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
var cssShow = {
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
visibility: 'hidden',
|
|
|
|
|
display: 'block'
|
|
|
|
|
}
|
|
|
|
|
var rdisplayswap = /^(none|table(?!-c[ea]).+)/
|
|
|
|
|
function showHidden(node, array) {
|
|
|
|
|
//http://www.cnblogs.com/rubylouvre/archive/2012/10/27/2742529.html
|
|
|
|
|
if (node.offsetWidth <= 0) {
|
|
|
|
|
//opera.offsetWidth可能小于0
|
|
|
|
|
var styles = getComputedStyle(node, null)
|
|
|
|
|
if (rdisplayswap.test(styles['display'])) {
|
|
|
|
|
var obj = {
|
|
|
|
|
node: node
|
|
|
|
|
}
|
|
|
|
|
for (var name in cssShow) {
|
|
|
|
|
obj[name] = styles[name]
|
|
|
|
|
node.style[name] = cssShow[name]
|
|
|
|
|
}
|
|
|
|
|
array.push(obj)
|
|
|
|
|
}
|
|
|
|
|
var _parent = node.parentNode
|
|
|
|
|
if (_parent && _parent.nodeType === 1) {
|
|
|
|
|
showHidden(_parent, array)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
'Width,Height'.replace(rword, function(name) {
|
|
|
|
|
//fix 481
|
|
|
|
|
var method = name.toLowerCase(),
|
|
|
|
|
clientProp = 'client' + name,
|
|
|
|
|
scrollProp = 'scroll' + name,
|
|
|
|
|
offsetProp = 'offset' + name
|
|
|
|
|
cssHooks[method + ':get'] = function(node, which, override) {
|
|
|
|
|
var boxSizing = -4
|
|
|
|
|
if (typeof override === 'number') {
|
|
|
|
|
boxSizing = override
|
|
|
|
|
}
|
|
|
|
|
which = name === 'Width' ? ['Left', 'Right'] : ['Top', 'Bottom']
|
|
|
|
|
var ret = node[offsetProp] // border-box 0
|
|
|
|
|
if (boxSizing === 2) {
|
|
|
|
|
// margin-box 2
|
|
|
|
|
return (
|
|
|
|
|
ret +
|
|
|
|
|
Anot.css(node, 'margin' + which[0], true) +
|
|
|
|
|
Anot.css(node, 'margin' + which[1], true)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
if (boxSizing < 0) {
|
|
|
|
|
// padding-box -2
|
|
|
|
|
ret =
|
|
|
|
|
ret -
|
|
|
|
|
Anot.css(node, 'border' + which[0] + 'Width', true) -
|
|
|
|
|
Anot.css(node, 'border' + which[1] + 'Width', true)
|
|
|
|
|
}
|
|
|
|
|
if (boxSizing === -4) {
|
|
|
|
|
// content-box -4
|
|
|
|
|
ret =
|
|
|
|
|
ret -
|
|
|
|
|
Anot.css(node, 'padding' + which[0], true) -
|
|
|
|
|
Anot.css(node, 'padding' + which[1], true)
|
|
|
|
|
}
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
cssHooks[method + '&get'] = function(node) {
|
|
|
|
|
var hidden = []
|
|
|
|
|
showHidden(node, hidden)
|
|
|
|
|
var val = cssHooks[method + ':get'](node)
|
|
|
|
|
for (var i = 0, obj; (obj = hidden[i++]); ) {
|
|
|
|
|
node = obj.node
|
|
|
|
|
for (var n in obj) {
|
|
|
|
|
if (typeof obj[n] === 'string') {
|
|
|
|
|
node.style[n] = obj[n]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return val
|
|
|
|
|
}
|
|
|
|
|
Anot.fn[method] = function(value) {
|
|
|
|
|
//会忽视其display
|
|
|
|
|
var node = this[0]
|
|
|
|
|
if (arguments.length === 0) {
|
|
|
|
|
if (node.setTimeout) {
|
|
|
|
|
//取得窗口尺寸,IE9后可以用node.innerWidth /innerHeight代替
|
|
|
|
|
return node['inner' + name]
|
|
|
|
|
}
|
|
|
|
|
if (node.nodeType === 9) {
|
|
|
|
|
//取得页面尺寸
|
|
|
|
|
var doc = node.documentElement
|
|
|
|
|
//FF chrome html.scrollHeight< body.scrollHeight
|
|
|
|
|
//IE 标准模式 : html.scrollHeight> body.scrollHeight
|
|
|
|
|
//IE 怪异模式 : html.scrollHeight 最大等于可视窗口多一点?
|
|
|
|
|
return Math.max(
|
|
|
|
|
node.body[scrollProp],
|
|
|
|
|
doc[scrollProp],
|
|
|
|
|
node.body[offsetProp],
|
|
|
|
|
doc[offsetProp],
|
|
|
|
|
doc[clientProp]
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
return cssHooks[method + '&get'](node)
|
|
|
|
|
} else {
|
|
|
|
|
return this.css(method, value)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Anot.fn['inner' + name] = function() {
|
|
|
|
|
return cssHooks[method + ':get'](this[0], void 0, -2)
|
|
|
|
|
}
|
|
|
|
|
Anot.fn['outer' + name] = function(includeMargin) {
|
|
|
|
|
return cssHooks[method + ':get'](
|
|
|
|
|
this[0],
|
|
|
|
|
void 0,
|
|
|
|
|
includeMargin === true ? 2 : 0
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
Anot.fn.offset = function() {
|
|
|
|
|
//取得距离页面左右角的坐标
|
|
|
|
|
var node = this[0]
|
|
|
|
|
try {
|
|
|
|
|
var rect = node.getBoundingClientRect()
|
|
|
|
|
// Make sure element is not hidden (display: none) or disconnected
|
|
|
|
|
// https://github.com/jquery/jquery/pull/2043/files#r23981494
|
|
|
|
|
if (rect.width || rect.height || node.getClientRects().length) {
|
|
|
|
|
var doc = node.ownerDocument
|
|
|
|
|
var root = doc.documentElement
|
|
|
|
|
var win = doc.defaultView
|
|
|
|
|
return {
|
|
|
|
|
top: rect.top + win.pageYOffset - root.clientTop,
|
|
|
|
|
left: rect.left + win.pageXOffset - root.clientLeft
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return {
|
|
|
|
|
left: 0,
|
|
|
|
|
top: 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//=============================val相关=======================
|
|
|
|
|
|
|
|
|
|
function getValType(elem) {
|
|
|
|
|
var ret = elem.tagName.toLowerCase()
|
|
|
|
|
return ret === 'input' && /checkbox|radio/.test(elem.type) ? 'checked' : ret
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var valHooks = {
|
|
|
|
|
'select:get': function(node, value) {
|
|
|
|
|
var option,
|
|
|
|
|
options = node.options,
|
|
|
|
|
index = node.selectedIndex,
|
|
|
|
|
one = node.type === 'select-one' || index < 0,
|
|
|
|
|
values = one ? null : [],
|
|
|
|
|
max = one ? index + 1 : options.length,
|
|
|
|
|
i = index < 0 ? max : one ? index : 0
|
|
|
|
|
for (; i < max; i++) {
|
|
|
|
|
option = options[i]
|
|
|
|
|
//旧式IE在reset后不会改变selected,需要改用i === index判定
|
|
|
|
|
//我们过滤所有disabled的option元素,但在safari5下,如果设置select为disable,那么其所有孩子都disable
|
|
|
|
|
//因此当一个元素为disable,需要检测其是否显式设置了disable及其父节点的disable情况
|
|
|
|
|
if ((option.selected || i === index) && !option.disabled) {
|
|
|
|
|
value = option.value
|
|
|
|
|
if (one) {
|
|
|
|
|
return value
|
|
|
|
|
}
|
|
|
|
|
//收集所有selected值组成数组返回
|
|
|
|
|
values.push(value)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return values
|
|
|
|
|
},
|
|
|
|
|
'select:set': function(node, values, optionSet) {
|
|
|
|
|
values = [].concat(values) //强制转换为数组
|
|
|
|
|
for (var i = 0, el; (el = node.options[i++]); ) {
|
|
|
|
|
if ((el.selected = values.indexOf(el.value) > -1)) {
|
|
|
|
|
optionSet = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!optionSet) {
|
|
|
|
|
node.selectedIndex = -1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|