【问题标题】:Browse Image and Insert into Iframe浏览图片并插入 iframe
【发布时间】:2014-01-24 10:24:27
【问题描述】:

我想知道这是否可能。

我想创建一个函数来检索图像并插入 iframe。用户必须能够选择文件(图像/视频)并将其插入 iframe。

ma​​in.html

<input type="file" id="addImage">我已经用它来让用户选择一个文件。

<iframe class="frame" id="frame" src="insert.html"></iframe> 这适用于 iframe。 iframe src 是另一个 html 文档。

插入.html

<span id="edit"></span> 位于需要插入图像的 insert.html 中。

我不太明白如何使用 javascript 从用户选择中检索图像并插入 iframe。

这可能吗?

【问题讨论】:

    标签: javascript html iframe


    【解决方案1】:

    是的,这是一个例子。关键是要挂在 iframe 上,然后使用它的contentWindow

    EDIT

    另外,我不知道你是指浏览文件还是拖放 API,所以我实现了两者。

    来自这些来源的大量帮助:

    这是一个小提琴:

    JSFiddle

    CSS

     *{
        font-family: Arial;
     }
     .section{
        width: 400px;
        padding: 20px;
        margin: auto;
     }
     #dragDiv{
        background-color: #ffffcc;
     }
     #browseDiv{
        background-color: #ccffcc;
     }
     #iframeDiv{
        background-color: #ffcccc;
     }
     #dropTarget{
        width: 300px;
        height: 300px;
        border-style: dashed;
        border-width: 5px;
     }
     .dropEnabled{
        border-color: #999999;
     }
     .dropEnabled:hover{
        border-color: #ff9933;
     }
     .dropMe{
        border-color: #99ff99;
     }
    

    JS

     /**
      * I set up the listeners for dragging and dropping as well
      * as creating an iFrame for holding dragged in images
      * @returns {undefined}
      */
     function main() {
        // The div that receives drops and the new iFrame
        var targetDiv = document.getElementById("dropTarget"),
                iframe = document.createElement("iframe");
    
        // Set the iframe to a blank page
        iframe.src = "about:blank";
    
        // Append it to the target
        document.getElementById("iframeTarget").appendChild(iframe);
    
        // Drag over is when an object is hovering over the div
        // e.preventDefault keeps the page from changing
        targetDiv.addEventListener("dragover", function(e) {
           e.preventDefault();
           this.className = "dropMe";
        }, false);
    
        // Drag leave is when the object leaves the div but isn't dropped
        targetDiv.addEventListener("dragleave", function(e) {
           e.preventDefault();
           this.className = "dropEnabled";
        }, false);
    
        // Drop is when the click is released
        targetDiv.addEventListener("drop", function(e) {
           e.preventDefault();
           this.className = "dropEnabled";
           loadFile(e.dataTransfer.files[0], iframe);
        }, false);
    
        document.getElementById("upload").addEventListener("click", function() {
           var file = document.getElementById("browsedFile").files[0];
           loadFile(file, iframe);
        }, false);
     }
    
     /**
      * Load a file and then put it on an ifrmae
      * @param {Element} f The file that needs to get loaded
      * @param {Element} destination The iframe that the file is appended to
      * @returns {undefined}
      */
     function loadFile(f, destination) {
        // Make a file reader to interpret the file
        var reader = new FileReader();
    
        // When the reader is done reading,
        // Make a new image tag and append it to the iFrame
        reader.onload = function(event) {
           var newImage = document.createElement("img");
           newImage.src = event.target.result;
           destination.contentWindow.document.getElementsByTagName("body")[0].appendChild(newImage);
        };
    
        // Tell the reader to start reading asynchrounously
        reader.readAsDataURL(f);
     }
    
     // Run the main script
     window.onload = main;
    

    HTML

    <!DOCTYPE html>
    <html>
       <head>
          <title>I framed it</title>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width">
       </head>
       <body>
          <div id="dragDiv" class="section">
             <div>The div below receives dragged in files</div>
             <div id="dropTarget" class="dropEnabled"></div>
          </div>
          <div id="browseDiv" class="section">
             <div>I upload stuff the boring way</div>
             <input type="file" id="browsedFile"><button id="upload">Upload</button>
          </div>
          <div id="iframeDiv" class="section">
             <div>And below me, an iFrame gets created</div>
             <div id="iframeTarget"></div>
          </div>
       </body>
    </html>
    

    结果如下:

    还有 DOM:

    EDIT

    还对如何处理视频进行了评论。有几种方法可以做到这一点,但这是我使用 HTML5 &lt;vido&gt; 标签的一种方法,您可以在此处找到更多信息:HTML Videos

    我敢肯定,一个棘手的事情是如何说你应该加载什么样的文件。我在文件的type 属性上使用switch(),对于MP4 视频,该属性的计算结果通常类似于:image/pngvideo/mp4。但是,这会将您绑定到特定的文件格式。 一个更好的方法是创建一个正则表达式来判断它是只是图像还是视频并忽略格式,因为这个过程粗暴这些类型的所有文件都相同。

    我添加了自己的正则表达式实现。可能不是最好的,但它现在允许所有适当的图像类型通过。

    另外,我尝试使用一些来自 Apple 的示例视频,可以在此处找到:Sample QuickTime Movies。但是,由于某种原因,这些都不起作用。所以在那之后,我刚刚下载了 W3Schools 在他们的教程中使用的示例视频。我告诉你这个是为了万一你尝试它但它不起作用,它可能是文件本身而不是你的代码。

    编辑loadFile()函数

     /**
      * Load a file and then put it on an ifrmae
      * @param {Element} f The file that needs to get loaded
      * @param {Element} destination The iframe that the file is appended to
      * @returns {undefined}
      */
     function loadFile(f, destination) {
        // Make a file reader to interpret the file
        var reader = new FileReader(),
                loaderFunc = null,
                typeRegEx = /^(\w+)\//,
                contentType = f.type.match(typeRegEx)[1];
    
        // Figure out how to load the data
        switch (contentType) {
           case "video":
              loaderFunc = function(event) {
                 var newVideo = document.createElement("video"),
                         newVideoSource = document.createElement("source");
    
                 newVideo.width = 300;
                 newVideo.height = 300;
                 newVideo.setAttribute("controls");
    
                 newVideoSource.src = event.target.result;
                 newVideoSource.type = f.type;
    
                 destination.contentWindow.document.getElementsByTagName("body")[0].appendChild(newVideo);
                 newVideo.appendChild(newVideoSource);
              };
              break;
           case "image":
              loaderFunc = function(event) {
                 var newImage = document.createElement("img");
                 newImage.src = event.target.result;
                 destination.contentWindow.document.getElementsByTagName("body")[0].appendChild(newImage);
              };
              break;
           default:
              console.log("Unknown file type");
              return;
        }
    
        // We should have returned, but just make sure
        if (loaderFunc) {
           // When the reader is done reading,
           // Make a new image tag and append it to the iFrame
           reader.onload = loaderFunc;
    
           // Tell the reader to start reading asynchrounously
           reader.readAsDataURL(f);
        }
     }
    

    【讨论】:

    • 谢谢,但我希望用户选择自己的图像,这就是我使用 标签的原因。那么我怎样才能检索他们的图像并插入到 iframe 中呢?
    • @User 好的,然后试试这个。它同时使用&lt;input type="file"&gt; 和 HTML5 中的拖放 API。
    • 谢谢,我现在正在测试它。它似乎适用于 JSFiddle,尽管我一直在尝试在 IE 和 Chrome 上使用它。 JS中有错误不断弹出JavaScript运行时错误:Unable to get property 'addEventListener' of undefined or null reference。
    • 在 IE 或 Chrome 中?每当我收到该错误时,我就与 DOM 中元素的 idgetElementById 调用不匹配。仔细检查这些 ID 是否匹配。如果您发布代码的小提琴,我可以仔细检查它。另外,如果这仅在您运行 IE 时发生,您使用的是什么版本的 IE? Internet Explorer 直到版本 9 才支持 addEventListener
    • 我在 IE 和 Chrome 上都试过了,都没有。虽然 IE 告诉我错误在哪里。还有它的 IE 9。我在注意到错误的地方使用了你的代码。所以我会检查身份证
    【解决方案2】:

    如果它们来自同一个域,您可以直接操作来自其他 iframe 的 iframe。

    jQuery/JavaScript: accessing contents of an iframe

    如果不是这种情况,你可以做的是:

    设置两个页面之间的通信过程(参见How to communicate between iframe and the parent site?

    将您的文件上传到服务器,并刷新“insert.html”页面以显示上传的图像。

    【讨论】:

    • 如果 iframe 与主窗口在同一个域中,您可以对其进行操作。
    • @Barmar 谢谢,我的错。我从来没有尝试过做同一个域,我只是记得相反是不可能的......
    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 2010-09-19
    • 1970-01-01
    • 2012-02-02
    • 2017-07-22
    相关资源
    最近更新 更多