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

一个封装iframe的vue插件,可修改样式,隐藏滚动条最近有空,就抽空把以前做过的公司业务组件慢慢抽离出来做成插件,也算是对近年来的技术方面做一个总结吧。 今天要写的是一个用vue-jsx封装的iframe插件,可修改iframe中的样式,隐藏滚动条,默认设置保证页面安全等功能。不想看想直接使用的话请前往项目处pikaz-ifra…

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

今天要写的是一个用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")
        }
      })
    }
},

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

项目地址

Talk is cheap. Show you the code.

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

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

最后

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

今天的文章一个封装iframe的vue插件,可修改样式,隐藏滚动条分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19832.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注