UNPKG

avalon2

Version:

an elegant efficient express mvvm framework

137 lines (131 loc) 5.24 kB
import { avalon, msie } from '../../seed/core' import { cssMap, cssHooks, getWindow } from './share' /* istanbul ignore if */ if (msie < 9) { cssMap['float'] = 'styleFloat' var rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i var rposition = /^(top|right|bottom|left)$/ var ralpha = /alpha\([^)]+\)/i var ropactiy = /(opacity|\d(\d|\.)*)/g var ie8 = msie === 8 var salpha = 'DXImageTransform.Microsoft.Alpha' var border = { thin: ie8 ? '1px' : '2px', medium: ie8 ? '3px' : '4px', thick: ie8 ? '5px' : '6px' } cssHooks['@:get'] = function (node, name) { //取得精确值,不过它有可能是带em,pc,mm,pt,%等单位 var currentStyle = node.currentStyle var ret = currentStyle[name] if ((rnumnonpx.test(ret) && !rposition.test(ret))) { //①,保存原有的style.left, runtimeStyle.left, var style = node.style, left = style.left, rsLeft = node.runtimeStyle.left //②由于③处的style.left = xxx会影响到currentStyle.left, //因此把它currentStyle.left放到runtimeStyle.left, //runtimeStyle.left拥有最高优先级,不会style.left影响 node.runtimeStyle.left = currentStyle.left //③将精确值赋给到style.left,然后通过IE的另一个私有属性 style.pixelLeft //得到单位为px的结果;fontSize的分支见http://bugs.jquery.com/ticket/760 style.left = name === 'fontSize' ? '1em' : (ret || 0) ret = style.pixelLeft + 'px' //④还原 style.left,runtimeStyle.left style.left = left node.runtimeStyle.left = rsLeft } if (ret === 'medium') { name = name.replace('Width', 'Style') //border width 默认值为medium,即使其为0' if (currentStyle[name] === 'none') { ret = '0px' } } return ret === '' ? 'auto' : border[ret] || ret } cssHooks['opacity:set'] = function (node, name, value) { var style = node.style var opacity = Number(value) <= 1 ? 'alpha(opacity=' + value * 100 + ')' : '' var filter = style.filter || '' style.zoom = 1 //不能使用以下方式设置透明度 //node.filters.alpha.opacity = value * 100 style.filter = (ralpha.test(filter) ? filter.replace(ralpha, opacity) : filter + ' ' + opacity).trim() if (!style.filter) { style.removeAttribute('filter') } } cssHooks['opacity:get'] = function (node) { var match = node.style.filter.match(ropactiy) || [] var ret = false for (var i = 0, el; el = match[i++];) { if (el === 'opacity') { ret = true } else if (ret) { return (el / 100) + '' } } return '1' //确保返回的是字符串 } } /* istanbul ignore next */ avalon.fn.offset = function () { //取得距离页面左右角的坐标 var node = this[0], box = { left: 0, top: 0 } if (!node || !node.tagName || !node.ownerDocument) { return box } var doc = node.ownerDocument var body = doc.body var root = doc.documentElement var win = doc.defaultView || doc.parentWindow if (!avalon.contains(root, node)) { return box } //http://hkom.blog1.fc2.com/?mode=m&no=750 body的偏移量是不包含margin的 //我们可以通过getBoundingClientRect来获得元素相对于client的rect. //http://msdn.microsoft.com/en-us/library/ms536433.aspx if (node.getBoundingClientRect) { box = node.getBoundingClientRect() // BlackBerry 5, iOS 3 (original iPhone) } //chrome/IE6: body.scrollTop, firefox/other: root.scrollTop var clientTop = root.clientTop || body.clientTop, clientLeft = root.clientLeft || body.clientLeft, scrollTop = Math.max(win.pageYOffset || 0, root.scrollTop, body.scrollTop), scrollLeft = Math.max(win.pageXOffset || 0, root.scrollLeft, body.scrollLeft) // 把滚动距离加到left,top中去。 // IE一些版本中会自动为HTML元素加上2px的border,我们需要去掉它 // http://msdn.microsoft.com/en-us/library/ms533564(VS.85).aspx return { top: box.top + scrollTop - clientTop, left: box.left + scrollLeft - clientLeft } } //生成avalon.fn.scrollLeft, avalon.fn.scrollTop方法 /* istanbul ignore next */ avalon.each({ scrollLeft: 'pageXOffset', scrollTop: 'pageYOffset' }, function (method, prop) { avalon.fn[method] = function (val) { var node = this[0] || {} var win = getWindow(node) var root = avalon.root var top = method === 'scrollTop' if (!arguments.length) { return win ? (prop in win) ? win[prop] : root[method] : node[method] } else { if (win) { win.scrollTo(!top ? val : avalon(win).scrollLeft(), top ? val : avalon(win).scrollTop()) } else { node[method] = val } } } })