2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 基于vue简单封装的iframe插件 可修改样式 隐藏滚动条

基于vue简单封装的iframe插件 可修改样式 隐藏滚动条

时间:2021-12-23 06:17:59

相关推荐

基于vue简单封装的iframe插件 可修改样式 隐藏滚动条

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

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

背景

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

iframe常用属性

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]// 插入styleconst 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 = thisiframe.onload = function () {that.$emit("onload")}})}},

ps:评论区有小伙伴提醒iframe的onload在404的情况下也会触发,回去之后尝试着解决一下这个问题,结果发现传入url时iframe跨域没法获取iframe的dom,自然也没法判断是否是404页面了,如果有更好的方法欢迎在评论区留言。

项目地址

Talk is cheap. Show you the code.

想查看完整代码,可前往pikaz-iframe

已上传至npm,如有需要,可直接使用。

最后

如果对您有帮助,请点个赞吧。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。