Comparing version 1.0.12 to 1.1.0
258
lib/index.js
@@ -18,157 +18,24 @@ /** | ||
// http://yiminghe.iteye.com/blog/1124720 | ||
var _getOffsetParent = require('./getOffsetParent'); | ||
/** | ||
* 获取 node 上的 align 对齐点 相对于页面的坐标 | ||
*/ | ||
var _getOffsetParent2 = _interopRequireDefault(_getOffsetParent); | ||
function getAlignOffset(region, align) { | ||
var V = align.charAt(0); | ||
var H = align.charAt(1); | ||
var w = region.width; | ||
var h = region.height; | ||
var x = undefined; | ||
var y = undefined; | ||
var _getVisibleRectForElement = require('./getVisibleRectForElement'); | ||
x = region.left; | ||
y = region.top; | ||
var _getVisibleRectForElement2 = _interopRequireDefault(_getVisibleRectForElement); | ||
if (V === 'c') { | ||
y += h / 2; | ||
} else if (V === 'b') { | ||
y += h; | ||
} | ||
var _adjustForViewport = require('./adjustForViewport'); | ||
if (H === 'c') { | ||
x += w / 2; | ||
} else if (H === 'r') { | ||
x += w; | ||
} | ||
var _adjustForViewport2 = _interopRequireDefault(_adjustForViewport); | ||
return { | ||
left: x, | ||
top: y | ||
}; | ||
} | ||
var _getRegion = require('./getRegion'); | ||
/** | ||
* 得到会导致元素显示不全的祖先元素 | ||
*/ | ||
var _getRegion2 = _interopRequireDefault(_getRegion); | ||
function getOffsetParent(element) { | ||
// ie 这个也不是完全可行 | ||
/* | ||
<div style="width: 50px;height: 100px;overflow: hidden"> | ||
<div style="width: 50px;height: 100px;position: relative;" id="d6"> | ||
元素 6 高 100px 宽 50px<br/> | ||
</div> | ||
</div> | ||
*/ | ||
// element.offsetParent does the right thing in ie7 and below. Return parent with layout! | ||
// In other browsers it only includes elements with position absolute, relative or | ||
// fixed, not elements with overflow set to auto or scroll. | ||
// if (UA.ie && ieMode < 8) { | ||
// return element.offsetParent; | ||
// } | ||
// 统一的 offsetParent 方法 | ||
var doc = element.ownerDocument; | ||
var body = doc.body; | ||
var parent = undefined; | ||
var positionStyle = _utils2['default'].css(element, 'position'); | ||
var skipStatic = positionStyle === 'fixed' || positionStyle === 'absolute'; | ||
var _getElFuturePos = require('./getElFuturePos'); | ||
if (!skipStatic) { | ||
return element.nodeName.toLowerCase() === 'html' ? null : element.parentNode; | ||
} | ||
var _getElFuturePos2 = _interopRequireDefault(_getElFuturePos); | ||
for (parent = element.parentNode; parent && parent !== body; parent = parent.parentNode) { | ||
positionStyle = _utils2['default'].css(parent, 'position'); | ||
if (positionStyle !== 'static') { | ||
return parent; | ||
} | ||
} | ||
return null; | ||
} | ||
// http://yiminghe.iteye.com/blog/1124720 | ||
/** | ||
* 获得元素的显示部分的区域 | ||
*/ | ||
function getVisibleRectForElement(element) { | ||
var visibleRect = { | ||
left: 0, | ||
right: Infinity, | ||
top: 0, | ||
bottom: Infinity | ||
}; | ||
var el = getOffsetParent(element); | ||
var scrollX = undefined; | ||
var scrollY = undefined; | ||
var winSize = undefined; | ||
var doc = element.ownerDocument; | ||
var win = doc.defaultView || doc.parentWindow; | ||
var body = doc.body; | ||
var documentElement = doc.documentElement; | ||
// Determine the size of the visible rect by climbing the dom accounting for | ||
// all scrollable containers. | ||
while (el) { | ||
// clientWidth is zero for inline block elements in ie. | ||
if ((navigator.userAgent.indexOf('MSIE') === -1 || el.clientWidth !== 0) && ( | ||
// body may have overflow set on it, yet we still get the entire | ||
// viewport. In some browsers, el.offsetParent may be | ||
// document.documentElement, so check for that too. | ||
el !== body && el !== documentElement && _utils2['default'].css(el, 'overflow') !== 'visible')) { | ||
var pos = _utils2['default'].offset(el); | ||
// add border | ||
pos.left += el.clientLeft; | ||
pos.top += el.clientTop; | ||
visibleRect.top = Math.max(visibleRect.top, pos.top); | ||
visibleRect.right = Math.min(visibleRect.right, | ||
// consider area without scrollBar | ||
pos.left + el.clientWidth); | ||
visibleRect.bottom = Math.min(visibleRect.bottom, pos.top + el.clientHeight); | ||
visibleRect.left = Math.max(visibleRect.left, pos.left); | ||
} else if (el === body || el === documentElement) { | ||
break; | ||
} | ||
el = getOffsetParent(el); | ||
} | ||
// Clip by window's viewport. | ||
scrollX = _utils2['default'].getWindowScrollLeft(win); | ||
scrollY = _utils2['default'].getWindowScrollTop(win); | ||
visibleRect.left = Math.max(visibleRect.left, scrollX); | ||
visibleRect.top = Math.max(visibleRect.top, scrollY); | ||
winSize = { | ||
width: _utils2['default'].viewportWidth(win), | ||
height: _utils2['default'].viewportHeight(win) | ||
}; | ||
visibleRect.right = Math.min(visibleRect.right, scrollX + winSize.width); | ||
visibleRect.bottom = Math.min(visibleRect.bottom, scrollY + winSize.height); | ||
return visibleRect.top >= 0 && visibleRect.left >= 0 && visibleRect.bottom > visibleRect.top && visibleRect.right > visibleRect.left ? visibleRect : null; | ||
} | ||
function getElFuturePos(elRegion, refNodeRegion, points, offset) { | ||
var xy = undefined; | ||
var diff = undefined; | ||
var p1 = undefined; | ||
var p2 = undefined; | ||
xy = { | ||
left: elRegion.left, | ||
top: elRegion.top | ||
}; | ||
p1 = getAlignOffset(refNodeRegion, points[1]); | ||
p2 = getAlignOffset(elRegion, points[0]); | ||
diff = [p2.left - p1.left, p2.top - p1.top]; | ||
return { | ||
left: xy.left - diff[0] + +offset[0], | ||
top: xy.top - diff[1] + +offset[1] | ||
}; | ||
} | ||
function isFailX(elFuturePos, elRegion, visibleRect) { | ||
@@ -182,43 +49,2 @@ return elFuturePos.left < visibleRect.left || elFuturePos.left + elRegion.width > visibleRect.right; | ||
function adjustForViewport(elFuturePos, elRegion, visibleRect, overflow) { | ||
var pos = _utils2['default'].clone(elFuturePos); | ||
var size = { | ||
width: elRegion.width, | ||
height: elRegion.height | ||
}; | ||
if (overflow.adjustX && pos.left < visibleRect.left) { | ||
pos.left = visibleRect.left; | ||
} | ||
// Left edge inside and right edge outside viewport, try to resize it. | ||
if (overflow.resizeWidth && pos.left >= visibleRect.left && pos.left + size.width > visibleRect.right) { | ||
size.width -= pos.left + size.width - visibleRect.right; | ||
} | ||
// Right edge outside viewport, try to move it. | ||
if (overflow.adjustX && pos.left + size.width > visibleRect.right) { | ||
// 保证左边界和可视区域左边界对齐 | ||
pos.left = Math.max(visibleRect.right - size.width, visibleRect.left); | ||
} | ||
// Top edge outside viewport, try to move it. | ||
if (overflow.adjustY && pos.top < visibleRect.top) { | ||
pos.top = visibleRect.top; | ||
} | ||
// Top edge inside and bottom edge outside viewport, try to resize it. | ||
if (overflow.resizeHeight && pos.top >= visibleRect.top && pos.top + size.height > visibleRect.bottom) { | ||
size.height -= pos.top + size.height - visibleRect.bottom; | ||
} | ||
// Bottom edge outside viewport, try to move it. | ||
if (overflow.adjustY && pos.top + size.height > visibleRect.bottom) { | ||
// 保证上边界和可视区域上边界对齐 | ||
pos.top = Math.max(visibleRect.bottom - size.height, visibleRect.top); | ||
} | ||
return _utils2['default'].mix(pos, size); | ||
} | ||
function flip(points, reg, map) { | ||
@@ -239,24 +65,17 @@ var ret = []; | ||
function getRegion(node) { | ||
var offset = undefined; | ||
var w = undefined; | ||
var h = undefined; | ||
if (!_utils2['default'].isWindow(node) && node.nodeType !== 9) { | ||
offset = _utils2['default'].offset(node); | ||
w = _utils2['default'].outerWidth(node); | ||
h = _utils2['default'].outerHeight(node); | ||
function convertOffset(str, offsetLen) { | ||
var n = undefined; | ||
if (/%$/.test(str)) { | ||
n = parseInt(str.substring(0, str.length - 1), 10) / 100 * offsetLen; | ||
} else { | ||
var win = _utils2['default'].getWindow(node); | ||
offset = { | ||
left: _utils2['default'].getWindowScrollLeft(win), | ||
top: _utils2['default'].getWindowScrollTop(win) | ||
}; | ||
w = _utils2['default'].viewportWidth(win); | ||
h = _utils2['default'].viewportHeight(win); | ||
n = parseInt(str, 10); | ||
} | ||
offset.width = w; | ||
offset.height = h; | ||
return offset; | ||
return n || 0; | ||
} | ||
function normalizeOffset(offset, el) { | ||
offset[0] = convertOffset(offset[0], el.width); | ||
offset[1] = convertOffset(offset[1], el.height); | ||
} | ||
/* | ||
@@ -276,5 +95,7 @@ * align node | ||
var points = align.points; | ||
var offset = align.offset; | ||
var offset = align.offset || [0, 0]; | ||
var targetOffset = align.targetOffset || [0, 0]; | ||
var overflow = align.overflow; | ||
offset = offset && [].concat(offset) || [0, 0]; | ||
offset = [].concat(offset); | ||
targetOffset = [].concat(targetOffset); | ||
overflow = overflow || {}; | ||
@@ -285,9 +106,12 @@ var newOverflowCfg = {}; | ||
// 当前节点可以被放置的显示区域 | ||
var visibleRect = getVisibleRectForElement(el); | ||
var visibleRect = (0, _getVisibleRectForElement2['default'])(el); | ||
// 当前节点所占的区域, left/top/width/height | ||
var elRegion = getRegion(el); | ||
var elRegion = (0, _getRegion2['default'])(el); | ||
// 参照节点所占的区域, left/top/width/height | ||
var refNodeRegion = getRegion(refNode); | ||
var refNodeRegion = (0, _getRegion2['default'])(refNode); | ||
// 将 offset 转换成数值,支持百分比 | ||
normalizeOffset(offset, elRegion); | ||
normalizeOffset(targetOffset, refNodeRegion); | ||
// 当前节点将要被放置的位置 | ||
var elFuturePos = getElFuturePos(elRegion, refNodeRegion, points, offset); | ||
var elFuturePos = (0, _getElFuturePos2['default'])(elRegion, refNodeRegion, points, offset, targetOffset); | ||
// 当前节点将要所处的区域 | ||
@@ -309,2 +133,3 @@ var newElRegion = _utils2['default'].merge(elRegion, elFuturePos); | ||
offset = flipOffset(offset, 0); | ||
targetOffset = flipOffset(targetOffset, 0); | ||
} | ||
@@ -324,2 +149,3 @@ } | ||
offset = flipOffset(offset, 1); | ||
targetOffset = flipOffset(targetOffset, 1); | ||
} | ||
@@ -330,3 +156,3 @@ } | ||
if (fail) { | ||
elFuturePos = getElFuturePos(elRegion, refNodeRegion, points, offset); | ||
elFuturePos = (0, _getElFuturePos2['default'])(elRegion, refNodeRegion, points, offset, targetOffset); | ||
_utils2['default'].mix(newElRegion, elFuturePos); | ||
@@ -343,3 +169,3 @@ } | ||
if (newOverflowCfg.adjustX || newOverflowCfg.adjustY) { | ||
newElRegion = adjustForViewport(elFuturePos, elRegion, visibleRect, newOverflowCfg); | ||
newElRegion = (0, _adjustForViewport2['default'])(elFuturePos, elRegion, visibleRect, newOverflowCfg); | ||
} | ||
@@ -352,3 +178,6 @@ } | ||
// 例如 <div 'relative'><el absolute></div> | ||
_utils2['default'].offset(el, { left: newElRegion.left, top: newElRegion.top }); | ||
_utils2['default'].offset(el, { | ||
left: newElRegion.left, | ||
top: newElRegion.top | ||
}); | ||
@@ -367,2 +196,3 @@ // need judge to in case set fixed with in css on height auto element | ||
offset: offset, | ||
targetOffset: targetOffset, | ||
overflow: newOverflowCfg | ||
@@ -372,5 +202,5 @@ }; | ||
domAlign.__getOffsetParent = getOffsetParent; | ||
domAlign.__getOffsetParent = _getOffsetParent2['default']; | ||
domAlign.__getVisibleRectForElement = getVisibleRectForElement; | ||
domAlign.__getVisibleRectForElement = _getVisibleRectForElement2['default']; | ||
@@ -377,0 +207,0 @@ exports['default'] = domAlign; |
{ | ||
"name": "dom-align", | ||
"version": "1.0.12", | ||
"version": "1.1.0", | ||
"description": "Align DOM Node Flexibly ", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -5,3 +5,2 @@ # dom-align | ||
align source html element with target html element flexibly. | ||
port from [kissyteam/component align](https://github.com/kissyteam/component/blob/master/lib/component/extension/align.js) | ||
@@ -56,4 +55,5 @@ [![NPM version][npm-image]][npm-url] | ||
domAlign(sourceNode, targetNode, { | ||
points: ['tl', 'tr'] // align top left point of sourceNode with top right point of targetNode | ||
offset: [10, 20] // the offset sourceNode by 10px in x and 20px in y | ||
points: ['tl', 'tr'], // align top left point of sourceNode with top right point of targetNode | ||
offset: [10, 20], // the offset sourceNode by 10px in x and 20px in y, | ||
targetOffset: [30%,40%], // the offset targetNode by 30% of targetNode width in x and 40% of targetNode height in y, | ||
}); | ||
@@ -88,5 +88,12 @@ ``` | ||
<td>Number[2]</td> | ||
<td>offset source node by offset[0] in x and offset[1] in y</td> | ||
<td>offset source node by offset[0] in x and offset[1] in y. | ||
If offset contains percentage string value, it is relative to sourceNode region.</td> | ||
</tr> | ||
<tr> | ||
<td>targetOffset</td> | ||
<td>Number[2]</td> | ||
<td>offset target node by offset[0] in x and offset[1] in y. | ||
If targetOffset contains percentage string value, it is relative to targetNode region.</td> | ||
</tr> | ||
<tr> | ||
<td>overflow</td> | ||
@@ -93,0 +100,0 @@ <td>Object</td> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
34097
11
800
126
0