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;
};
解决在vue引入iframe 高度不自适应的问题
猜你喜欢
转载自blog.csdn.net/qq_28473733/article/details/102650161
今日推荐
周排行