解决在vue引入iframe 高度不自适应的问题

class Iframe {
    constructor(options) {
        this.$el = document.createElement('IFRAME');
        this.$options = options;
        this.$target = options.target ? document.getElementById(options.target) : null;
        this.$content = options.content;
        this.browser = this.findBrowser();
        this.lastMaxHight = 0;
        this.timer = null;
    }

    //创建iframe
    createIframe() {
        if (typeof this.$options.margin === "string") {
            warn("margin只能是个number类型");
        }
        //初始化iframe参数
        let style = {
            width: "100%",
            border: "0",
            frameSpacing: "0",
            marginHeight: "0",
            frameBorder: "no",
            scrolling: "no",
            vspale: "0",
            webkitOverflowScrolling: 'touch',
            height: document.body.clientHeight - (this.$options.margin ? this.$options.margin : 0)
        };

        for (let key in style) {
            this.$el[key] = style[key];
        }

        //给iframe添加内容
        if (this.browser.versions.ios) {
            //console.log('IOS 设备特殊处理');
            //IFRAME.srcdoc = '';
        } else {
            this.$el.srcdoc = this.$content;
        }

        //给当前实例扩展一些属性
        this._options = {
            "phoneWidth": document.body.clientWidth,
            "lastMaxHight": 0,
            "resized": 0,
            "isIos": this.browser.versions.ios
        };

        this.$el.onload = () => {
            this.updateIframe();
        };

        if (!this.$target) return warn("目标元素为htm dom元素");
        this.$target.appendChild(this.$el);

        this._iframeWin = this.$el.contentWindow || this.$el.contentDocument.parentWindow;
        if (this._options.isIos) {
            this._iframeWin.document.body.innerHTML = this.$content;
            //console.log('IOS 设备特殊处理iframeWin.document.body.innerHTML')
        }

        //定时更新iframe
        this.timer = setInterval(() => {
            this.updateIframe();
        }, 500)
    }

    //更新iframe
    updateIframe() {
        if (!this._iframeWin) {
            this._iframeWin = this.$el.contentWindow || this.$el.contentDocument.parentWindow;
        }
        if (this._iframeWin.document.body) {
            let $document = this._iframeWin.document;
            let newHeight = $document.documentElement.scrollHeight || $document.body.scrollHeight;
            let clientHeight = $document.documentElement.clientHeight || $document.body.clientHeight;

            if (clientHeight > newHeight) {
                newHeight = clientHeight;
            }

            if (newHeight > 0 && newHeight !== this.lastMaxHight) {
                if (this.isMobile() && this._options.resized < 2) {
                    this._options.resized++;
                    let imgs = $document.body.querySelectorAll('img');
                    let fonts = $document.body.querySelectorAll('font');
                    newHeight = newHeight / 2;
                    //img
                    let w = this._options.phoneWidth - 30 - 16;
                    //console.log('适应手机的图片尺寸为:' + w)
                    let half = w / 2;

                    for (let item of imgs) {
                        if (item.width >= w) {
                            let ratio = w / item.width;
                            if (item.height > 0) {
                                item.height = item.height * ratio;
                            }
                            item.width = w;
                        } else if (item.width > half) {
                            let ratio = half / item.width;
                            if (item.height > 0) {
                                item.height = item.height * ratio;
                            }
                            item.width = half;
                        }
                    }
                    //font
                    for (let item of fonts) {
                        if (item.size > 3) {
                            item.size = `${item.size - 2}`
                        } else if (item.size === 3) {
                            item.size = `${item.size - 1}`
                        }
                    }
                }
                this.lastMaxHight = newHeight;
                this.$el.height = this.lastMaxHight;
                console.log('IFRAME高度更新为:' + this.$el.height);
            }
        }
    }

    //清除定时器
    clearTimer() {
        if (this.timer) {
            clearInterval(this.timer);
        }
    }

    //判断浏览器版本
    findBrowser() {
        return {
            versions: function () {
                let u = navigator.userAgent, app = navigator.appVersion;
                return {//移动终端浏览器版本信息
                    trident: u.indexOf('Trident') > -1, //IE内核
                    presto: u.indexOf('Presto') > -1, //opera内核
                    webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
                    gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
                    mobile: !!u.match(/AppleWebKit.*Mobile.*/) || !!u.match(/AppleWebKit/), //是否为移动终端
                    ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
                    android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或者uc浏览器
                    iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1, //是否为iPhone或者QQ HD浏览器
                    iPad: u.indexOf('iPad') > -1, //是否iPad
                    webApp: u.indexOf('Safari') == -1 //是否web应该程序,没有头部与底部
                };
            }(),
            language: (navigator.browserLanguage || navigator.language).toLowerCase()
        };
    }

    //判断是不是手机
    isMobile() {
        let versions = this.browser.versions;
        if (versions.ios || versions.android || versions.android || versions.iPad) {
            /*console.log(" ios终端: " + versions.ios);
            console.log(" android终端: " + versions.android);
            console.log(" 是否为iPhone: " + versions.iPhone);
            console.log(" 是否iPad: " + versions.iPad);
            console.log(navigator.userAgent);*/
            return true
        } else {
            return false
        }
    }
}

/**
 * 每次调用会产生一个实例, 这个方法是为了定时期更新iframe的高度,解决iframe渲染时高度不准确的情况,兼容pc和mobile
 * @param options {
 *   target:dom,
 *   content:html,
 *   margin:number
 * }
 * @returns {Iframe}
 */
export default (options) => {
    let iframe = new Iframe(options);
    iframe.createIframe();
    return iframe;
};
发布了80 篇原创文章 · 获赞 5 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_28473733/article/details/102650161