首页 > 解决方案 > 在 Vue.js 中为响应式 iframe 插入 javascript 代码

问题描述

我需要在我的 Vue.js 应用程序中集成在图表平台上创建的一些 iframe。响应式 iframe 的代码由我放入模板中的一些 html 代码和一对脚本标签之间的一些 javascript 组成。

这是html部分:

<iframe
  id="datawrapper-chart-8dfPN"
  src="//datawrapper.dwcdn.net/8dfPN/4/"
  scrolling="no"
  frameborder="0"
  allowtransparency="true"
  style="width: 0; min-width: 100% !important;" height="400"
>
</iframe>

和javascript部分:

<script type="text/javascript">
  if("undefined"==typeof window.datawrapper)window.datawrapper={};
  window.datawrapper["8dfPN"]={},
  window.datawrapper["8dfPN"].embedDeltas={"100":481,"200":427,"300":400,"400":400,"500":400,"700":400,"800":400,"900":400,"1000":400},
  window.datawrapper["8dfPN"].iframe=document.getElementById("datawrapper-chart-8dfPN"),
  window.datawrapper["8dfPN"].iframe.style.height=window.datawrapper["8dfPN"].embedDeltas[Math.min(1e3,Math.max(100*Math.floor(window.datawrapper["8dfPN"].iframe.offsetWidth/100),100))]+"px",
  window.addEventListener("message",function(a){if("undefined"!=typeof a.data["datawrapper-height"])for(var b in a.data["datawrapper-height"])if("8dfPN"==b)window.datawrapper["8dfPN"].iframe.style.height=a.data["datawrapper-height"][b]+"px"});
</script> 

我不明白我必须如何管理这段代码。如果我把它放在模板中(因为它有 html 元素)视图告诉我我不能在模板中使用脚本。但是将代码嵌入到我的 Vue 文件部分也不起作用。我试图摆脱这些元素。但它不起作用。

有没有办法重构这段代码,以便我可以在 Vue.js 中充分使用它?

标签: javascriptvue.js

解决方案


如果您查看提供的 JavaScript,实际上并没有太多内容。它设置一个初始高度,然后设置一个事件侦听器来管理 iframe 的高度。

首先,我们将绑定height到数据属性iframeHeight

<iframe
  ref="chartiframe"
  id="datawrapper-chart-8dfPN" 
  src="//datawrapper.dwcdn.net/8dfPN/4/"
  scrolling="no"
  frameborder="0"
  allowtransparency="true"
  style="width: 0; min-width: 100% !important;"
  :height="iframeHeight"></iframe>

然后

  1. const为变量创建embeddedDeltas
  2. mounted设置钩子的初始高度。
  3. 在钩子中设置message事件监听器mounted
  4. 创建一个方法来处理调整大小
  5. 移除beforeDestroy钩子中的事件监听器

ddd

const DELTAS = {
        "100":481,
        "200":427,
        "300":400,
        "400":400,
        "500":400,
        "700":400,
        "800":400,
        "900":400,
        "1000":400,
};

export default {
  data() {
    return {
      iframeHeight: '0px', // initial height
    };
  },
  computed: {
    // Necessary for initial iframe height
    iframeOffsetWidth() {      
      return this.$refs['chartiframe'].offsetWidth;
    },
  },
  mounted() {
    // set initial iframe height
    this.iframeHeight = `{DELTAS[Math.min(1e3,Math.max(100*Math.floor(this.iframeOffsetWidth/100),100))]}px`;
    // setup event listener
    window.addEventListener('message', this.handleIframeResize);
  },
  beforeDestroy() {
    // destroy event listener
    window.removeEventListener('message', this.handleIframeResize);
  },
  methods: {
    handleIframeResize(e) {
      for(var b in e.data['datawrapper-height']) {
        if ('8dfPN' === b) {
          this.iframeHeight = `${e.data['datawrapper-height'][b]}px`;
        }
      }
    },
  },
};

推荐阅读