使用插入HTML的方式在JavaScript中打开窗口。

93

如何在JavaScript中打开一个新窗口并插入HTML数据,而不是仅链接到HTML文件?

8个回答

163

我不建议你像其他人建议的那样使用document.write,因为如果你打开这样的窗口两次,你的HTML将被重复2次(或更多)。

改用innerHTML代替

var win = window.open("", "Title", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=200,top="+(screen.height-400)+",left="+(screen.width-840));
win.document.body.innerHTML = "HTML";

4
使用 innerHTML 是个好主意! - NilsB
新创建的窗口上是否会存在 body 对象? - user3245268
1
是的,它始终存在于任何页面上,即使您不放置它,浏览器也会自动添加它。 - artnikpro
2
请注意,如果您在HTML中有<script>标签,它们将不会被执行。 - Дамян Станчев
使用 width=780,height=200 会使得适应不同屏幕尺寸变得更加困难。如果你考虑的是 1920x1080 的占用空间,那么类似于 width=50%, height=20% 的设置会更好。只是不确定如何在 window.open 函数/方法中编写这样的代码。同样地,top="+(screen.height-400)+",left="+(screen.width-840) 也会存在问题。 - WinEunuuchs2Unix
显示剩余3条评论

49
你可以使用JavaScript中的window.open来打开一个新窗口/选项卡(根据浏览器设置)。
通过使用document.write,您可以将HTML内容写入已打开的窗口。

1
在您嵌入JS事件处理程序的情况下,请在write()之后调用document.close(),因为这将触发DOMContentLoad事件。 - zirkelc

34

以下是使用HTML Blob的方法,使您完全控制整个HTML文档:

https://codepen.io/trusktr/pen/mdeQbKG?editors=0010

这是代码,但StackOverflow阻止窗口被打开(请参见CodePen示例):

const winHtml = `<!DOCTYPE html>
    <html>
        <head>
            <title>Window with Blob</title>
        </head>
        <body>
            <h1>Hello from the new window!</h1>
        </body>
    </html>`;

const winUrl = URL.createObjectURL(
    new Blob([winHtml], { type: "text/html" })
);

const win = window.open(
    winUrl,
    "win",
    `width=800,height=400,screenX=200,screenY=200`
);


2
很棒的解决方案,这真的帮助我完成了一个项目,在该项目中添加额外的HTML文件以用于新窗口内容将会有问题。只需补充说明一下,在HTML的<head>标签中包含<meta charset="utf-8">是值得的,以确保它可以呈现任何非拉丁字符。 - moloko
2
这正是我一直在寻找的。这使我能够使用window.open的“noopener”选项,以防止新窗口访问我的主窗口。谢谢! - jake

32
当您使用 open 创建一个新窗口时,它会返回一个指向新窗口的引用,您可以使用该引用通过其 document 对象将内容写入到新打开的窗口中。
以下是一个示例:
var newWin = open('url','windowName','height=300,width=300');
newWin.document.write('html to write...');

11

您可以通过以下代码打开一个新的弹窗窗口:

var myWindow = window.open("", "newWindow", "width=500,height=700");
//window.open('url','name','specs');

之后,您可以使用 myWindow.document.write();myWindow.document.body.innerHTML = "HTML"; 两种方法添加HTML代码。

我建议的是先创建一个新的html文件,可以用任何名称来命名。在这个例子中,我使用了

newFile.html

并确保将所有内容都添加到该文件中,例如bootstrap cdn或jquery,即所有链接和脚本。然后创建一个带有一些id的

标签或使用body,并给它一个id。在这个例子中,我将<body>标签的id设置为“mainBody”,并将其包含在newFile.html中。

<body id="mainBody">

然后使用以下方式打开此文件

<script>    
var myWindow = window.open("newFile.html", "newWindow", "width=500,height=700");
</script>

使用以下代码在您的body标签中添加任何想要添加的内容

<script>    
 var myWindow = window.open("newFile.html","newWindow","width=500,height=700");  

   myWindow.onload = function(){
     let content = "<button class='btn btn-primary' onclick='window.print();'>Confirm</button>";
   myWindow.document.getElementById('mainBody').innerHTML = content;
    } 

myWindow.window.close();
 </script>

就是这么简单。


2
您可以创建一个名为“example.html”的页面,其中包含您想要的HTML内容,并将该页面的URL作为参数传递给window.open。
var url = '/example.html';
var myWindow = window.open(url, "", "width=800,height=600");

0

使用这个。它对我非常完美地起作用。

对于新窗口:

new_window = window.open(URL.createObjectURL(new Blob([HTML_CONTENT], { type: "text/html" })))

弹出式窗口

new_window = window.open(URL.createObjectURL(new Blob([HTML_CONTENT], { type: "text/html" })),"width=800,height=600")

将HTML_CONTENT替换为您自己的HTML代码 例如:

new_window = window.open(URL.createObjectURL(new Blob(["<h1>Hello</h1>"], { type: "text/html" })))

0

如果你的 window.open()innerHTML 正常工作,请忽略此答案

以下答案仅关注 跨域访问异常


@key-in_short,workaround:: [针对 跨域访问异常]

当您在 main.html 中执行代码 -- 尝试通过使用 window.open()innerHTML 访问文件 window_ImageGallery.html

对于任何遇到跨域访问异常的人

并且您不想禁用/修改 Chrome 安全策略

-> 您可以使用查询字符串来传输 HTML 代码数据,作为解决方法。

@details::

@problem-given_situation,@problem-arise_problem::

  • 假设您像其他答案建议的那样执行以下简单的window.open命令。

    let window_Test = window.open('window_ImageGallery.html', 'Image Enlarged Window' + $(this).attr('src'), 'width=1000,height=800,top=50,left=50');
    
    window_Test.document.body.innerHTML = 'aaaaaa';
    
  • 您可能会遇到以下跨域访问异常

    window_Test.document.body.innerHTML = 'aaaaaa'; // < Exception here
    
    Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.
    

=> @问题-解决方案-解决方法::

  • 您可以使用查询字符串来传输HTML代码数据,作为解决方法。<- 从一个HTML文件传输数据到另一个文件

  • 例如:

    • 在您的main.html文件中:

      // #>> 在新的HTML窗口中打开ViewerJs
      eleJq_Img.click(function() {
          // #>>> 发送一些查询字符串数据 -- 一个<img>标签列表, 到新的HTML窗口
          // @repeat: 必须使用查询字符串来传递HTML代码数据,否则会出现“Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.”(跨域访问问题)
          let id_ThisImg = this.id;
          let ind_ThisImg = this.getAttribute('data-index-img');
      
          let url_file_html_window_ImageGallery = 'window_ImageGallery.html'
            + '?queryStr_html_ListOfImages=' + encodeURIComponent(html_ListOfImages) 
            + '&queryStr_id_ThisImg=' + encodeURIComponent(id_ThisImg)
            + '&queryStr_ind_ThisImg=' + encodeURIComponent(ind_ThisImg);
      
          // #>>> 在新的HTML窗口中打开ViewerJs
          let window_ImageGallery = window.open(url_file_html_window_ImageGallery, undefined, 'width=1000,height=800,top=50,left=50');
        });
      
      
    • 在您的window_ImageGallery.html文件中:

      window.onload = function () {
        // #>> 从URL获取参数
        // @repeat: 必须使用查询字符串来传递HTML代码数据,否则会出现“Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.”(跨域访问问题)
        // https://dev59.com/c2Mm5IYBdhLWcg3wlvwK
        let data = getParamFromUrl();
      
        let html_ListOfImages = decodeURIComponent(data.queryStr_html_ListOfImages);
        let id_ThisImgThatOpenedTheHtmlWindow = decodeURIComponent(data.queryStr_id_ThisImg);
        let ind_ThisImgThatOpenedTheHtmlWindow = decodeURIComponent(data.queryStr_ind_ThisImg);
      
        // #>> 将图像添加到列表中
        document.getElementById('windowImageGallery_ContainerOfInsertedImages').innerHTML = html_ListOfImages;
      
        // -------- 处理HTML代码数据
      
      };
      
      function getParamFromUrl() {
        let url = document.location.href;
        let params = url.split('?')[1].split('&');
        let data = {};
        let tmp;
        for (let i = 0, l = params.length; i < l; i++) {
          tmp = params[i].split('=');
          data[tmp[0]] = tmp[1];
        }
        return data
      }
      

@小注释::

  • 有时候你可能不会收到 跨域访问异常

    • 这是因为,如果你在 main.html 中的 'window_ImageGallery.html' 的 html 加载之前 修改了它的 html,就会出现上述情况

      • 以上陈述基于我的测试

        & 另一个答案 -- window.open: is it possible open a new window with modify its DOM

      • 如果你想确保看到这个异常,

        你可以尝试等待直到打开的 html 窗口完成加载,然后继续执行你的代码

        @eg::

        • 使用 defer() <- Waiting for child window loading to complete

          let window_ImageGallery = window.open('window_ImageGallery.html', undefined, 'width=1000,height=800,top=50,left=50');
          
          window_ImageGallery.addEventListener("unload", function () {
            defer(function (){
              console.log(window_ImageGallery.document.body); // < Exception here
            });
          });
          
          function defer (callback) {
              var channel = new MessageChannel();
              channel.port1.onmessage = function (e) {
                  callback();
              };
              channel.port2.postMessage(null);
          }
          
          
        • 或者使用 sleep()async What is the JavaScript version of sleep()?

          eleJq_Img.click(async function() {
            ...
            let window_Test = window.open( ...
            ...
            await new Promise(r => setTimeout(r, 2000));
            console.log(window_Test.document.body.innerHTML); // < Exception here
          });
          
          
    • 或者你会得到 null 指针异常

      如果你尝试访问 window_ImageGallery.html 中的元素


@minor-comment::
有太多关于“跨域”问题的类似帖子。还有一些关于window.open()的帖子。我不知道哪篇文章是放置答案的最佳位置。我选择在这里回答。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接