一个封装iframe的vue插件,可修改样式,隐藏滚动条

微信扫一扫,分享到朋友圈

一个封装iframe的vue插件,可修改样式,隐藏滚动条

最近有空,就抽空把以前做过的公司业务组件慢慢抽离出来做成插件,也算是对近年来的技术方面做一个总结吧。

今天要写的是一个用vue-jsx封装的iframe插件,可修改iframe中的样式,隐藏滚动条,默认设置保证页面安全等功能。不想看想直接使用的话请前往项目处 pikaz-iframe

背景

由于公司爬取了一些文章,需要对文章进行展示,那么第一时间想到的当然就是iframe了,虽然它有这样那样的缺点,但不得不说还是一个方便快捷的解决方案。

iframe常用属性

参数 说明
frameborder 是否显示iframe的边框
sandbox 启用iframe中内容的额外限制
src 被嵌套的页面的 URL 地址
srcdoc html内容

iframe常用的属性其实也不多,大致用到的也就上面几个:

frameborder控制iframe是否显示边框,一般是设置为0的,也就是不显示,然后再由css来书写边框样式;

sandbox控制对iframe的内容权限控制,如果只是需要展示页的话,设置为allow-same-origin allow-scripts即可,前者为同源,后者允许iframe启用脚本,这样展示页就无法做出提交表单,允许弹窗等危险操作!,另外,当被嵌入的文档与主页面同源时,强烈建议不要同时使用 allow-scripts 和 allow-same-origin。如果同时使用,嵌入的文档就可以通过代码删除 sandbox 属性。如果还有其他需求,可以前往 MDN-iframe
查看;

src大部分人就知道了,传入url,显示网页;

srcdoc可以传入html内容,显示网页,vue中其实也有一个v-html指令可以展示html内容,但是缺点是易受全局css样式污染,需要做额外封装,而且权限控制也得封装,所以权衡之下引入网页内容的话还是用iframe。

iframe插件封装

因为iframe中的属性太多了,我们不可能一个个属性去写在模板上,所以自然就得借助vue的渲染函数来书写。

ps:别问我为啥要用vue,公司是什么技术栈当然就用什么喽,一般确实很少用vue写jsx,都是切换到react才会去写,不过这次写的时候惊奇的发现vue的jsx可以使用指令了,比如v-model!amazing!

上代码!

.vue file:

export default {
props: {
setting:Object
},
render () {
return (
<iframe {...{ attrs: this.attrs }}>
</iframe>
);
},
computed:{
attrs(){
}
}
}
复制代码

处理iframe属性

先使用一个setting参数来接收所有所需参数,然后在computed里处理参数iframe标签所需,再返回。

在attr里处理sandbox,frameborder的默认值,默认无边框,使用url时设置为’allow-same-origin allow-scripts’,使用html内容时设置为’allow-scripts’,保障安全。

attrs(){
const attr = {}
Object.keys(this.setting).forEach(key => {
if (!(key === 'hideScrolling' || key === 'css')) {
attr[key] = this.setting[key]
}
// 处理css样式
if (key === 'srcdoc' && this.setting.css && this.setting.srcdoc) {
// 查找head标签
const pattern = "<head.*(?=>)(.|n)*?</head>"
const html = this.setting.srcdoc.match(pattern)[0]
// 插入style
const style = `<style>${this.setting.css}</style></head>`
const newHtml = html.replace("</head>", style)
const doc = this.setting.srcdoc.replace(html, newHtml)
attr[key] = doc
}
})
// 设置默认值
if (!attr.sandbox || attr.sandbox !== '') {
// 同源文档
if (this.setting.srcdoc) {
attr.sandbox = 'allow-scripts'
} else {
attr.sandbox = 'allow-same-origin allow-scripts'
}
}
// 无边框
if (!attr.frameborder) {
attr.frameborder = 0
}
return attr
}
复制代码

修改srcdoc内容的样式

另外因为产品有需求,就是修改文档的滚动条,所以还需要一个修改样式的功能:

在setting里传入css参数,为css样式代码,之后要做的就是将css样式插入传入的html内容中。

先查找head标签

const pattern = "<head.*(?=>)(.|n)*?</head>"
const html = this.setting.srcdoc.match(pattern)[0]
复制代码

再对head末尾处添加css样式,并赋值到srcdoc属性中

const style = `<style>${this.setting.css}</style></head>`
const newHtml = html.replace("</head>", style)
const doc = this.setting.srcdoc.replace(html, newHtml)
attr['srcdoc'] = doc
复制代码

隐藏滚动条

另外有些页面不需要滚动条,所以还需要一个隐藏滚动条的功能:

谷歌浏览器默认的滚动条是18px宽,所以只需要在外部的容器设置宽,并设置overflow-x: hidden;内部的iframe的width比外部大18px,即可隐藏滚动条,当然,还需要考虑兼容性问题,就是有些浏览器滚动条不一定是18px宽,所以还需要可接收宽度值,设置iframe比外部大于这个宽度。

render () {
return (
<div id="pikaz-iframe-container">
<iframe {...{ attrs: this.attrs }} style={this.hideScrollBar}>
</iframe>
</div>
);
},
computed:{
hideScrollBar () {
if (this.setting.hideScrolling) {
if (Object.prototype.toString.call(this.setting.hideScrolling) === "[object String]") {
return { width: `calc(100% + ${this.setting.hideScrolling})` }
} else {
return { width: `calc(100% + 18px)` }
}
}
return {}
},
}
...
<style scoped>
#pikaz-iframe-container {
width: 100%;
height: 100%;
overflow-x: hidden;
}
#pikaz-iframe-container::-webkit-scrollbar {
display: none;
}
#pikazIframe {
width: 100%;
height: 100%;
}
</style>
复制代码

iframe加载完成回调

只需要在iframe的加载完的onload中加入回调函数即可,比较简单

render () {
return (
<div id="pikaz-iframe-container">
<iframe {...{ attrs: this.attrs }} style={this.hideScrollBar} id="pikazIframe">
</iframe>
</div>
);
},
mounted () {
this.iframeOnload()
},
methods: {
iframeOnload () {
this.$nextTick(() => {
const iframe = document.getElementById("pikazIframe");
const that = this
iframe.onload = function () {
that.$emit("onload")
}
})
}
},
复制代码

微信扫一扫,分享到朋友圈

一个封装iframe的vue插件,可修改样式,隐藏滚动条

不可忽略的空格(white-space)

上一篇

实力宠粉! 6·5京东超级品牌日海量爆品尖货6.1…

下一篇

你也可能喜欢

一个封装iframe的vue插件,可修改样式,隐藏滚动条

长按储存图像,分享给朋友