Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

dom-align

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dom-align - npm Package Compare versions

Comparing version 1.0.12 to 1.1.0

lib/adjustForViewport.js

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>

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc