在html中使用masonry布局

习惯了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);
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_x阅读 15,967评论 3 119
  • 用到的组件 1、通过CocoaPods安装 2、第三方类库安装 3、第三方服务 友盟社会化分享组件 友盟用户反馈 ...
    SunnyLeong阅读 14,599评论 1 180
  • 给表弟打电话问他的近况。他一所普通大学毕业,学经济,刚毕业一年,独自一人在省会城市打拼。 说老实话,...
    zhounini107阅读 116评论 0 0
  • 一、安装依赖 安装 Git 依赖的库:curl、zlib、openssl、expat,还有libiconv yum...
    蚂蚁窝大梦想阅读 619评论 0 0
  • 机械制造业之殇 对于冷冰冰,黑乎乎的机械设备我打心底不喜欢。结...
    杯中阅读 216评论 0 1