习惯了iOS的masonry约束布局,写html就想用一样的办法。没有就尝试自己写一个。目前一堆问题,以后慢慢优化。
先把今天写的一点代码记录一下
demo.html
<html>
<head>
<script src="masonry.js"></script>
</head>
<body id="body" style="background-color: blue;">
<div id="head" class="head" style="background-color: red;">
head
</div>
<div id="main" class="main" style="background-color: white;">
12
<div id="div1" class="main" style="background-color: gold;">
div1
</div>
<div id="div2" class="main" style="background-color: green;">
div2
</div>
<div id='div3' style="background-color: red;margin: 20px; left: 10;width: 100px;height: 100px;position: relative;">
<div id='div4' style="background-color: blue;position: absolute;left: 10;width: 50px;height: 50px;">
div4
</div>
</div>
</div>
<div id="footer" class="footer" style="background-color: aqua;">
foot
</div>
<script type="text/javascript">
M('head').width.equals(M('body')).offset(-200);
M('head').height.equals(100);
M('head').centerX.equals(M('body')).offset(-0)
M('head').top.equals(M('body')).offset(60);
M('main').width.equals(M('body')).multipliedBy(0.5);
M('main').centerX.equals(M('body'));
M('main').bottom.equals(M('body'));
M('main').top.equals(M('head').bottomValue);
M('div1').width.equals(30);
M('div1').height.equals(30);
M('div1').left.equals(0);
M('div1').top.equals(0);
M('div2').left.equals(M('div1').rightValue);
M('div2').top.equals(M('div1'));
M('div2').width.equals(100);
M('div2').height.equals(100);
Masonry.reloadDoms();
</script>
</body>
</html>
js部分
masonry.js
function MDom(elementID) {
var dom = document.getElementById(elementID)
if (dom) {
if (typeof (dom.mas) == 'undefined') {
dom.mas = {}
dom.mas.elementID = elementID
dom.mas.width = {}
dom.mas.height = {}
dom.mas.left = {}
dom.mas.right = {}
dom.mas.top = {}
dom.mas.bottom = {}
dom.mas.centerX = {}
dom.mas.centerY = {}
dom.mas.widthValue = function () {
return dom.clientWidth
}
dom.mas.heightValue = function () {
return dom.clientHeight
}
dom.mas.leftValue = function () {
return Masonry.getLeft(dom)
}
dom.mas.rightValue = function () {
return dom.mas.leftValue() + dom.mas.widthValue()
}
dom.mas.topValue = function () {
return Masonry.getTop(dom)
}
dom.mas.bottomValue = function () {
return dom.mas.topValue() + dom.mas.heightValue()
}
dom.mas.width.equals = function (s) {
dom.mas.width.eq = s;
return dom.mas.width;
}
dom.mas.width.offset = function (s) {
dom.mas.width.oft = s;
return dom.mas.width;
}
dom.mas.width.multipliedBy = function (s) {
dom.mas.width.mpb = s;
return dom.mas.width;
}
dom.mas.left.equals = function (s) {
dom.mas.left.eq = s;
return dom.mas.left;
}
dom.mas.left.offset = function (s) {
dom.mas.left.oft = s;
return dom.mas.left;
}
dom.mas.left.multipliedBy = function (s) {
dom.mas.left.mpb = s;
return dom.mas.left;
}
dom.mas.right.equals = function (s) {
dom.mas.right.eq = s;
return dom.mas.right;
}
dom.mas.right.offset = function (s) {
dom.mas.right.oft = s;
return dom.mas.right;
}
dom.mas.right.multipliedBy = function (s) {
dom.mas.right.mpb = s;
return dom.mas.right;
}
dom.mas.top.equals = function (s) {
dom.mas.top.eq = s;
return dom.mas.top;
}
dom.mas.top.offset = function (s) {
dom.mas.top.oft = s;
return dom.mas.top;
}
dom.mas.top.multipliedBy = function (s) {
dom.mas.top.mpb = s;
return dom.mas.top;
}
dom.mas.bottom.equals = function (s) {
dom.mas.bottom.eq = s;
return dom.mas.bottom;
}
dom.mas.bottom.offset = function (s) {
dom.mas.bottom.oft = s;
return dom.mas.bottom;
}
dom.mas.bottom.multipliedBy = function (s) {
dom.mas.bottom.mpb = s;
return dom.mas.bottom;
}
dom.mas.height.equals = function (s) {
dom.mas.height.eq = s;
return dom.mas.height;
}
dom.mas.height.offset = function (s) {
dom.mas.height.oft = s;
return dom.mas.height;
}
dom.mas.height.multipliedBy = function (s) {
dom.mas.height.mpb = s;
return dom.mas.height;
}
dom.mas.centerX.equals = function (s) {
dom.mas.centerX.eq = s;
return dom.mas.centerX;
}
dom.mas.centerX.offset = function (s) {
dom.mas.centerX.oft = s;
return dom.mas.centerX;
}
dom.mas.centerX.multipliedBy = function (s) {
dom.mas.centerX.mpb = s;
return dom.mas.centerX;
}
dom.mas.centerY.equals = function (s) {
dom.mas.centerY.eq = s;
return dom.mas.centerY;
}
dom.mas.centerY.offset = function (s) {
dom.mas.centerY.oft = s;
return dom.mas.centerY;
}
dom.mas.centerY.multipliedBy = function (s) {
dom.mas.centerY.mpb = s;
return dom.mas.centerY;
}
}
return dom.mas;
}
return null;
}
var Masonry = {}
Masonry.constraints = []; //约束
Masonry.domsMap = new Map();
Masonry.getLeft = function (e) {
var offset = e.offsetLeft;
if (e.offsetParent != null) offset += Masonry.getLeft(e.offsetParent);
return offset;
}
Masonry.getTop = function (e) {
var offset = e.offsetTop;
if (e.offsetParent != null) offset += Masonry.getTop(e.offsetParent);
return offset;
}
// 重载dom。按照
Masonry.reloadDoms = function () {
var map = Masonry.domsMap
for (var item of map) {
var key = item[0]
var mas = item[1]
var htmlDom = document.getElementById(key);
var parentDom = htmlDom.parentNode
var x = Masonry.getLeft(parentDom)
var y = Masonry.getTop(parentDom)
var w = parentDom.clientWidth
var h = parentDom.clientHeight
if (mas.width.eq) {
if (typeof (mas.width.eq) == 'object') {
w = document.getElementById(mas.width.eq.elementID).clientWidth
} else if (typeof (mas.width.eq) == 'number') {
w = mas.width.eq
} else if (typeof (mas.width.eq) == 'function') {
w = mas.width.eq()
}
if (typeof (mas.width.mpb) == 'number') {
w = w * mas.width.mpb
}
if (typeof (mas.width.oft) == 'number' && mas.width.oft != 0) {
w = w + mas.width.oft
}
}
if (mas.height.eq) {
if (typeof (mas.height.eq) == 'object') {
h = document.getElementById(mas.height.eq.elementID).clientHeight
} else if (typeof (mas.height.eq) == 'number') {
h = mas.height.eq
} else if (typeof (mas.height.eq) == 'function') {
h = mas.height.eq()
}
if (typeof (mas.height.mpb) == 'number') {
h = h * mas.height.mpb
}
if (typeof (mas.height.oft) == 'number' && mas.height.oft != 0) {
h = h + mas.height.oft
}
}
if (mas.left.eq) {
if (typeof (mas.left.eq) == 'object') {
x = Masonry.getLeft(document.getElementById(mas.left.eq.elementID))
} else if (typeof (mas.left.eq) == 'number') {
x = mas.left.eq
} else if (typeof (mas.left.eq) == 'function') {
x = mas.left.eq()
}
if (typeof (mas.left.mpb) == 'number') {
x = x * mas.left.mpb
}
if (typeof (mas.left.oft) == 'number' && mas.left.oft != 0) {
x = x + mas.left.oft
}
}
if (mas.right.eq) {
if (typeof (mas.right.eq) == 'object') {
var refDom = document.getElementById(mas.right.eq.elementID)
var x_max = Masonry.getLeft(refDom) + refDom.clientWidth
w = x_max - x
} else if (typeof (mas.right.eq) == 'number') {
w = mas.right.eq - x
} else if (typeof (mas.right.eq) == 'function') {
w = mas.right.eq() - x
}
if (typeof (mas.right.mpb) == 'number') {
w = w * mas.right.mpb
}
if (typeof (mas.right.oft) == 'number' && mas.right.oft != 0) {
w = w + mas.right.oft
}
}
if (mas.top.eq) {
if (typeof (mas.top.eq) == 'object') {
var refDom = document.getElementById(mas.top.eq.elementID)
y = Masonry.getTop(refDom)
} else if (typeof (mas.top.eq) == 'number') {
y = mas.top.eq - Masonry.getTop(parentDom)
} else if (typeof (mas.top.eq) == 'function') {
y = mas.top.eq()
}
if (typeof (mas.top.mpb) == 'number') {
y = y * mas.top.mpb
}
if (typeof (mas.top.oft) == 'number' && mas.top.oft != 0) {
y = y + mas.top.oft
}
}
if (mas.bottom.eq) {
if (mas.bottom.eq && mas.height.eq) {
if (typeof (mas.bottom.eq) == 'object') {
var refDom = document.getElementById(mas.bottom.eq.elementID)
y = Masonry.getTop(refDom) + refDom.clientHeight
} else if (typeof (mas.bottom.eq) == 'number') {
y = mas.bottom.eq - h
} else if (typeof (mas.top.eq) == 'function') {
y = mas.bottom.eq() - h
}
if (typeof (mas.bottom.mpb) == 'number') {
y = y * mas.bottom.mpb
}
if (typeof (mas.bottom.oft) == 'number' && mas.bottom.oft != 0) {
y = y + mas.bottom.oft
}
}
if (mas.bottom.eq && mas.top.eq) {
if (typeof (mas.bottom.eq) == 'object') {
var refDom = document.getElementById(mas.bottom.eq.elementID)
h = Masonry.getTop(refDom) + refDom.clientHeight - y
} else if (typeof (mas.bottom.eq) == 'number') {
h = mas.bottom.eq - y
} else if (typeof (mas.top.eq) == 'function') {
h = mas.bottom.eq() - y
}
if (typeof (mas.bottom.mpb) == 'number') {
h = h * mas.bottom.mpb
}
if (typeof (mas.bottom.oft) == 'number' && mas.bottom.oft != 0) {
h = h + mas.bottom.oft
}
}
}
if (mas.centerX.eq) {
if (typeof (mas.centerX.eq) == 'object') {
var refDom = document.getElementById(mas.centerX.eq.elementID)
var ref_w = refDom.clientWidth;
var ref_x = Masonry.getLeft(refDom);
var center_x = ref_x + ref_w / 2.0;
x = center_x - w / 2.0
} else if (typeof (mas.centerX.eq) == 'number') {
x = mas.centerX.eq - w / 2.0
} else if (typeof (mas.centerX.eq) == 'function') {
x = mas.centerX.eq() - w / 2.0
}
if (typeof (mas.centerX.mpb) == 'number') {
x = x * mas.centerX.mpb
}
if (typeof (mas.centerX.oft) == 'number' && mas.centerX.oft != 0) {
x = x + mas.centerX.oft
}
}
if (mas.centerY.eq) {
if (typeof (mas.centerY.eq) == 'object') {
var refDom = document.getElementById(mas.centerY.eq.elementID)
var ref_h = refDom.clientHeight;
var ref_y = Masonry.getTop(refDom);
var center_y = ref_y + ref_h / 2.0;
y = center_y - h / 2.0
} else if (typeof (mas.centerY.eq) == 'number') {
y = mas.centerY.eq - h / 2.0
} else if (typeof (mas.centerY.eq) == 'function') {
y = mas.centerY.eq() - h / 2.0
}
if (typeof (mas.centerY.mpb) == 'number') {
y = y * mas.centerY.mpb
}
if (typeof (mas.centerY.oft) == 'number' && mas.centerY.oft != 0) {
y = y + mas.centerY.oft
}
}
Masonry.setDom(htmlDom, x, y, w, h);
console.log('ret:' + key + 'x:' + x + ';y=' + y + ';w:' + w + ';h=' + h);
}
}
Masonry.setDom = function (htmlDom, x, y, w, h) {
var positionNode = Masonry.getParentPositionNode(htmlDom)
if (positionNode) {
htmlDom.style.setProperty('position', 'absolute', 'important');
htmlDom.style.setProperty('width', w, 'important');
htmlDom.style.setProperty('height', h, 'important');
htmlDom.style.setProperty('left', x - Masonry.getLeft(positionNode), 'important');
htmlDom.style.setProperty('top', y - Masonry.getTop(positionNode), 'important');
} else {
htmlDom.style.setProperty('position', 'absolute', 'important');
htmlDom.style.setProperty('width', w, 'important');
htmlDom.style.setProperty('height', h, 'important');
htmlDom.style.setProperty('left', x, 'important');
htmlDom.style.setProperty('top', y, 'important');
}
}
Masonry.getParentPositionNode = function (htmlDom) {
var curDom = htmlDom;
while (true) {
var parentDom = curDom.parentNode
if (parentDom) {
var position = Masonry.getCssPosition(parentDom)
if (position == 'relative' || position == 'absolute') {
return parentDom;
} else {
curDom = parentDom;
}
} else {
break;
}
}
return null;
}
Masonry.dom = function (s) {
var d = Masonry.domsMap.get(s)
if (d) {
return d
}
var mDom = new MDom(s)
Masonry.domsMap.set(s, mDom)
return mDom;
}
Masonry.getCssPosition = function (obj) {
if (typeof (obj) != 'undefined' && typeof (obj.style) != 'undefined') {
if (typeof (obj.style.position) == 'string') {
return obj.style.position;
}
}
return '';
}
function M(s) {
return Masonry.dom(s);
}