代码之家  ›  专栏  ›  技术社区  ›  Dan

如何在Vue.js中嵌入HTML代码笔

  •  1
  • Dan  · 技术社区  · 7 年前

    我不知道如何使用推荐的HTML方法i a vue应用程序嵌入代码笔。 AS <script> 标记不能是Vue组件模板的一部分,我尝试将其添加到index.html,在该模板中注入我的Vue应用程序时没有运气。但是,当我试图将HTML代码粘贴到Vue所在的DIV之外时,代码就变成了一个iframe。

    以下是HTML嵌入:

    <p data-height="265" data-theme-id="0" data-slug-hash="JyxKMg" data-default-tab="js,result" data-user="sindael" data-embed-version="2" data-pen-title="Fullscreen image gallery using Wallop, Greensock and Flexbox" class="codepen">See the Pen <a href="https://codepen.io/sindael/pen/JyxKMg/">Fullscreen image gallery using Wallop, Greensock and Flexbox</a> by Dan (<a href="https://codepen.io/sindael">@sindael</a>) on <a href="https://codepen.io">CodePen</a>.</p>
    

    剧本:

    <script async src="https://static.codepen.io/assets/embed/ei.js"></script>
    

    直接嵌入iframe很好,但我想知道。有没有办法让HTML正常工作?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Sphinx    7 年前

    查看 https://static.codepen.io/assets/embed/ei.js ,然后您将看到它执行 两步 :

    1. 检查 document.getElementsByClassName 如果存在,则创建它。

    2. IIFE 执行嵌入。

    所以一个简单的演示如下的黑客方法:

    1. 复制源代码 https://static.codepen.io/assets/embed/ei.js网站

    2. 复制第一步的代码,然后将其作为一个函数包装= _codepen_selector_contructor

    3. 复制第二步代码并删除 () 从结尾开始,然后将其作为一个函数包装= _codepen_embed_method

    4. 创建一个 vue-directive (我更喜欢使用该指令来支持直接处理DOM元素的功能,您可以使用其他解决方案),然后执行 _代码笔选择器 _代码笔嵌入方法

    5. 可能你想换一个 document 里面 _代码笔嵌入方法 具有 el 相反,然后执行 _codepen_embed_method(el) . 这样它就不会影响其他元素。

    下面的演示使用了hook='inserted',如果 inserted 不能满足你的要求。

    let vCodePen = {}
    
    vCodePen.install = function install (Vue) {//copy from https://static.codepen.io/assets/embed/ei.js
      let _codepen_selector_contructor = function () {
        document.getElementsByClassName||(document.getElementsByClassName=function(e){var n,t,r,a=document,o=[];if(a.querySelectorAll)return a.querySelectorAll("."+e);if(a.evaluate)for(t=".//*[contains(concat(' ', @class, ' '), ' "+e+" ')]",n=a.evaluate(t,a,null,0,null);r=n.iterateNext();)o.push(r);else for(n=a.getElementsByTagName("*"),t=new RegExp("(^|\\s)"+e+"(\\s|$)"),r=0;r<n.length;r++)t.test(n[r].className)&&o.push(n[r]);return o})
      }
      let _codepen_embed_method = //copy from https://static.codepen.io/assets/embed/ei.js then removed `()` from the end
        function(){function e(){function e(){for(var e=document.getElementsByClassName("codepen"),t=e.length-1;t>-1;t--){var u=a(e[t]);if(0!==Object.keys(u).length&&(u=o(u),u.user=n(u,e[t]),r(u))){var c=i(u),l=s(u,c);f(e[t],l)}}m()}function n(e,n){if("string"==typeof e.user)return e.user;for(var t=0,r=n.children.length;t<r;t++){var a=n.children[t],o=a.href||"",i=o.match(/codepen\.(io|dev)\/(\w+)\/pen\//i);if(i)return i[2]}return"anon"}function r(e){return e["slug-hash"]}function a(e){for(var n={},t=e.attributes,r=0,a=t.length;r<a;r++){var o=t[r].name;0===o.indexOf("data-")&&(n[o.replace("data-","")]=t[r].value)}return n}function o(e){return e.href&&(e["slug-hash"]=e.href),e.type&&(e["default-tab"]=e.type),e.safe&&("true"===e.safe?e.animations="run":e.animations="stop-after-5"),e}function i(e){var n=u(e),t=e.user?e.user:"anon",r="?"+l(e),a=e.preview&&"true"===e.preview?"embed/preview":"embed",o=[n,t,a,e["slug-hash"]+r].join("/");return o.replace(/\/\//g,"//")}function u(e){return e.host?c(e.host):"file:"===document.location.protocol?"https://codepen.io":"//codepen.io"}function c(e){return e.match(/^\/\//)||!e.match(/https?:/)?document.location.protocol+"//"+e:e}function l(e){var n="";for(var t in e)""!==n&&(n+="&"),n+=t+"="+encodeURIComponent(e[t]);return n}function s(e,n){var r;e["pen-title"]?r=e["pen-title"]:(r="CodePen Embed "+t,t++);var a={id:"cp_embed_"+e["slug-hash"].replace("/","_"),src:n,scrolling:"no",frameborder:"0",height:d(e),allowTransparency:"true",allowfullscreen:"true",allowpaymentrequest:"true",name:"CodePen Embed",title:r,"class":"cp_embed_iframe "+(e["class"]?e["class"]:""),style:"width: "+p+"; overflow: hidden;"},o="<iframe ";for(var i in a)o+=i+'="'+a[i]+'" ';return o+="></iframe>"}function d(e){return e.height?e.height:300}function f(e,n){if(e.parentNode){var t=document.createElement("div");t.className="cp_embed_wrapper",t.innerHTML=n,e.parentNode.replaceChild(t,e)}else e.innerHTML=n}function m(){"function"==typeof __CodePenIFrameAddedToPage&&__CodePenIFrameAddedToPage()}var p="100%";e()}function n(e){/in/.test(document.readyState)?setTimeout("window.__cp_domReady("+e+")",9):e()}var t=1;window.__cp_domReady=n,window.__CPEmbed=e,n(function(){new __CPEmbed})}
    
      let defaultProps = {class: 'codepen', 'data-height':265, 'data-theme-id':0, 'data-slug-hash':'', 'data-default-tab':'js,result', 'data-user':'sindael', 'data-embed-version':'2', 'data-pen-title':''}
      Vue.directive('code-pen', {
        inserted: function (el, binding, vnode) {
          let options = Object.assign({}, defaultProps, binding.value)
          Object.entries(options).forEach((item) => {
            el.setAttribute(item[0], item[1])
          })
          setTimeout(() => {
            _codepen_selector_contructor()
            _codepen_embed_method() //_codepen_embed_method(el); you can pass el to take place of `document`
          }, 100)
        },
        componentUpdated: function (el, binding, vnode) {
        }
      })
    }
    
    Vue.use(vCodePen)
    Vue.config.productionTip = false
    app = new Vue({
      el: "#app",
      data: {
        keyword: '',
      },
      mounted: function () {
      },
      methods: {
      }
    })
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
    
    <div id="app">
    <p v-code-pen="{class: 'codepen', 'data-height':'265', 'data-theme-id':0, 'data-slug-hash':'JyxKMg', 'data-default-tab':'js,result', 'data-user':'sindael', 'data-embed-version':'2', 'data-pen-title':'Test'}">
      <a href="https://codepen.io/sindael/pen/JyxKMg/"></a>
    </p>
    </div>