上下div高度動態自適應--另類處理方案,div自適應

來源:互聯網
上載者:User

上下div高度動態自適應--另類處理方案,div自適應

     這段時間在工作中遇到一個看似較為棘手的問題。問題描述:查詢報表頁面分為上下兩部分,上部分為條件輸入地區,下部分為報表展示地區。客戶要求做到預設滿屏(但要動態適應不同的表單大小,也就是瀏覽器表單使用者會手動改變其大小),但上部分條件輸入地區有動態變化高度的現象。

     在遇到上述問題,您是否第一反應就是利用window的onresize事件,做尺寸的動態調整。但是條件輸入地區某個按鈕動態改變了上部分的高度時,我們又應該如何呢。是否有統一的處理方案呢。今兒本人就把我自己的想法和測試提供出來,供大家參考,有疑問或建議歡迎交流和溝通。

一、上代碼

閑話少說,上代碼。首先本人為了處理與IE的相容性,對現代瀏覽器,IE瀏覽器做了區別對待。然後提供了一個工廠類以供使用。

1.1、 現代瀏覽器的實現
/**        * 現代瀏覽器處理方案        */        function RptAutoHeightForModernBrower(context){            this.context = context;            this.$object = null;        }        var mPt = RptAutoHeightForModernBrower.prototype;        mPt.init = function(){            var object = document.createElement('iframe'), self = this; //object在ie11上onload方法不能執行            //區元素,絕對位置(父級必須是相對定位,否則參考到body了),四個為0,width、height為100%讓其寬、高與父級相同,pointer-events:none(不接受滑鼠事件)z-index:層級最低。            object.onload = function(){                 var context = this;                this.contentDocument.defaultView.addEventListener('resize', function(){                     self.context.onResize(context.clientHeight);                });            }            object.setAttribute('style', 'display:block; position:absolute; border:0px; visibility: hidden; left:0px; right: 0px; top: 0px; bottom: 0px; pointer-events: none; z-index: -1; overflow:hidden; width: 100%; height: 100%; opacity:0;');            //object.type = "text/html";            object.src = "about:blank";            this.context.$header.appendChild(object);            this.$object = object;            //先觸發一次             this.context.onResize(this.context.$header.clientHeight);            //window.resize事件            window.onresize = function(){                self.context.onResize(self.context.$header.clientHeight);            }        }        mPt.dispose = function(){            this.$object.contentDocument.defaultView.removeEventListener('resize');            this.context.$header.removeChild(this.$object);        }

     在此處,為了做到相容IE11(因為Ie11不支援attacheEvent方法,所以也會被判斷為現代瀏覽器),本人建立的DOM,不是使用的object而是使用的iframe,因為在IE下object的onload事件不能觸發,而iframe的可能有;並且iframe的邊框一定要去掉,否則影響判斷。

 1.2、ie瀏覽器的實現
/**        * ie的處理方案        */        function RptAutoHeightForIE(context){            this.context = context;        }        var iePt = RptAutoHeightForIE.prototype;        iePt.init = function(){            var self = this;            this.context.$header.attachEvent('onresize', function(){                self.context.onResize(window.event.srcElement.clientHeight);            });            this.context.onResize(this.context.$header.clientHeight);            //window.resize事件            window.onresize = function(){                self.context.onResize(self.context.$header.clientHeight);            }        }        iePt.dispose = function(){            this.context.$header.detachEvent('onresize');        }

     IE瀏覽器的實現相對簡單,因為IE環境下的div天身支援onresize事件。

1.3、工廠類
//處理高度自適應的Factory        function RptAutoHeightFactory(opts){            this.opts = opts || {};            this.$wrap = this.opts.wrap || document.getElementsByClassName('rpt-wrap')[0];            this.$header = this.opts.header || this.$wrap.getElementsByClassName('rpt-header')[0];            this.$cont = this.opts.cont || this.$wrap.getElementsByClassName('rpt-cont')[0];            var cxt = {                $header: this.$header,                onResize: this.resize()            };            this.diffVal = 0;            this.realize = document.attachEvent                 ? new RptAutoHeightForIE(cxt)                 : new RptAutoHeightForModernBrower(cxt);        }        var pt = RptAutoHeightFactory.prototype;        pt.init = function(){            var bTop = this.getStyle(this.$header, "border-top-width");            var bBottom = this.getStyle(this.$header, "border-bottom-width");            bTop = parseInt(bTop.replace('px', ''), 10);            bBottom = parseInt(bBottom.replace('px', ''), 10);            this.diffVal += bTop + bBottom;                        var bTop = this.getStyle(this.$cont, "border-top-width");            var bBottom = this.getStyle(this.$cont, "border-bottom-width");            bTop = parseInt(bTop.replace('px', ''), 10);            bBottom = parseInt(bBottom.replace('px', ''), 10);            this.diffVal += bTop + bBottom;                        this.realize.init();         }        pt.resize = function(){            var $cont = this.$cont, self = this;            return function(headerHeight){                var dist = self.getMaxHeight() - headerHeight - self.diffVal;                if(dist > 1 ){                    $cont.style.height = dist +'px'; //加單位,是為了相容ie                }            }        }        pt.getHeight = function(dom){            var height = dom.clientHeight;                        return height;        }        pt.getStyle = function(dom, key){            if(dom.currentStyle){                return dom.currentStyle[key];            }else if(window.getComputedStyle){                return window.getComputedStyle(dom, null)[key];            }        }        pt.getMaxHeight = function(){            return document.documentElement.clientHeight || document.body.clientHeight;        }

      此處本人在擷取style的屬性值,使用了getComputedStyle和currentStyle實現的,這民是標準的方法。

 

1.4、這樣使用

js代碼:

var irow = 2;        function addRow(){            var parent = document.getElementsByClassName('rpt-header')[0];            var p = document.createElement('p');            p.innerHTML = "<p>添加第" + irow++ + "行記錄</p>";            parent.appendChild(p);        }        var autoHeightFactory = new RptAutoHeightFactory();        autoHeightFactory.init();

html代碼:

<div class="rpt-wrap">        <div class="rpt-header">            <button type="button" onclick="addRow()">添加</button>            <p>第一行內容</p>        </div>        <div class="rpt-cont">        </div>    </div>

css代碼:

html, body{            margin: 0px;            padding: 0px;            height: 100%;        }        .rpt-wrap{            height: inherit;            overflow: hidden;        }        .rpt-header{            border: 1px solid gray;            position: relative;                    }        .rpt-cont{            border: 1px solid red;        }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.