最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - IE 11 is ignoring appendChild() for dynamically generated html pages - Stack Overflow

programmeradmin2浏览0评论

I am trying to create a pseudo report that shows me errors from importing data. to do this I have two functions:

                let createHtmlErrorReport = (err) => {

                    let currentDate = new Date().toLocaleString();
                    let contents = '<!DOCTYPE html> ' +
                        '<html>' +
                        '<head>' +
                        '<title>Import Inventory Import</title>' +
                        '<meta charset="utf-8" />' +
                        '<meta http-equiv="Content-Language" content="en">' +
                        '<style type="text/css">' +
                        ' html { margin:0;  }' +
                        ' body { background-color:#d6d6d6; font: 10pt sans-serif;}' +
                         'ul li{ padding: 3px; font:12pt;}'+
                        ' #header {padding:10px; background-color:#007fcc; color:#ffffff; } ' +
                        '</style>' +
                        '</head>' +
                        '<body>' +
                        '<div id="header">'+
                        '<strong>Import Inventory Import</strong>' +
                        '</div>' +
                        '<p><strong>Imported ' + currentDate + ' by ' + err.username + ' | ' + err.unprocessedItemsCount + ' items not imported | ' + err.processedItemsCount + ' items imported | '+ err.errorMessages.length + ' errors.</strong></p>'+
                        '<p>The following errors occured during import: </p>'+
                        '<div id="errorList" style="padding:5px;"></div>'+
                        '</body>' +
                        '</html>';
                    return contents;

                }

In the above I create a new document, add some basic styling and then create div container where I want a list of errors to be inserted.

<div id="errorList" style="padding:5px;"></div> 

The next function calls this method and builds the error list

            let generateImportErrorReport = (errors) => {
                        let doc = createHtmlErrorReport(errors);
                        let errorReportWindow = window.open('', '_blank');
                        errorReportWindow.document.write(doc);
                        let list = document.createElement('ul');
                        //builds a list of errors 
                        for (let i = 0; i < errors.errorMessages.length; i++) {
                            let item = document.createElement('li');
                            let message = errorReportWindow.document.createTextNode(errors.errorMessages[i]);           
                            item.appendChild(message);
                            list.appendChild(item);;
                        }  
}

The list is nothing more than an array of strings:

errors.errorMessages = [
{'Message 1'},
{'Message 2'}
]

This code works fine in Chrome and Firefox however in IE the new document is generated but the list is never appended to the selected Element. I can see the element generated but it will not add to the newly created document.

Internally the IE dev tools captures a generic message of Error: No such interface supported

I've seen other SO postings of similar problems but no solution that fits my scenario as I'm generating the html, and document at the same time vs working with an existing document.

Edit**: This code while standard js is written in typescript as part of an angular application. The TS is generated as ECMA3 and using either arrow functions or standard notation generates the same result.

I'd appreciate any suggestions or pointers on what I am missing.

I am trying to create a pseudo report that shows me errors from importing data. to do this I have two functions:

                let createHtmlErrorReport = (err) => {

                    let currentDate = new Date().toLocaleString();
                    let contents = '<!DOCTYPE html> ' +
                        '<html>' +
                        '<head>' +
                        '<title>Import Inventory Import</title>' +
                        '<meta charset="utf-8" />' +
                        '<meta http-equiv="Content-Language" content="en">' +
                        '<style type="text/css">' +
                        ' html { margin:0;  }' +
                        ' body { background-color:#d6d6d6; font: 10pt sans-serif;}' +
                         'ul li{ padding: 3px; font:12pt;}'+
                        ' #header {padding:10px; background-color:#007fcc; color:#ffffff; } ' +
                        '</style>' +
                        '</head>' +
                        '<body>' +
                        '<div id="header">'+
                        '<strong>Import Inventory Import</strong>' +
                        '</div>' +
                        '<p><strong>Imported ' + currentDate + ' by ' + err.username + ' | ' + err.unprocessedItemsCount + ' items not imported | ' + err.processedItemsCount + ' items imported | '+ err.errorMessages.length + ' errors.</strong></p>'+
                        '<p>The following errors occured during import: </p>'+
                        '<div id="errorList" style="padding:5px;"></div>'+
                        '</body>' +
                        '</html>';
                    return contents;

                }

In the above I create a new document, add some basic styling and then create div container where I want a list of errors to be inserted.

<div id="errorList" style="padding:5px;"></div> 

The next function calls this method and builds the error list

            let generateImportErrorReport = (errors) => {
                        let doc = createHtmlErrorReport(errors);
                        let errorReportWindow = window.open('', '_blank');
                        errorReportWindow.document.write(doc);
                        let list = document.createElement('ul');
                        //builds a list of errors 
                        for (let i = 0; i < errors.errorMessages.length; i++) {
                            let item = document.createElement('li');
                            let message = errorReportWindow.document.createTextNode(errors.errorMessages[i]);           
                            item.appendChild(message);
                            list.appendChild(item);;
                        }  
}

The list is nothing more than an array of strings:

errors.errorMessages = [
{'Message 1'},
{'Message 2'}
]

This code works fine in Chrome and Firefox however in IE the new document is generated but the list is never appended to the selected Element. I can see the element generated but it will not add to the newly created document.

Internally the IE dev tools captures a generic message of Error: No such interface supported

I've seen other SO postings of similar problems but no solution that fits my scenario as I'm generating the html, and document at the same time vs working with an existing document.

Edit**: This code while standard js is written in typescript as part of an angular application. The TS is generated as ECMA3 and using either arrow functions or standard notation generates the same result.

I'd appreciate any suggestions or pointers on what I am missing.

Share Improve this question edited Jun 30, 2017 at 19:00 rlcrews asked Jun 30, 2017 at 18:15 rlcrewsrlcrews 3,57221 gold badges72 silver badges121 bronze badges 1
  • This is a really interesting question but there's no way at all to peek into Edge's layout engine since it's proprietary. I would say it's a bug because MS announced themselves that EdgeHTML (the layout engine) would render any page fine that Webkit or Blink could, which do (Safari and Chrome). – Andrew Li Commented Jul 4, 2017 at 14:13
Add a ment  | 

1 Answer 1

Reset to default 5 +150

To make it work in IE 11, you can follow Mirko Cianfarani's suggestion: create the dynamic elements with the document object to which these elements will be appended. In your case, that is the document of the new report window, errorReportWindow.document. The report document should also be closed at the end.

var generateImportErrorReport = function(errors) {
  let doc = createHtmlErrorReport(errors);
  let errorReportWindow = window.open('', '_blank');
  let errorDoc = errorReportWindow.document; // Get the error report document object
  errorDoc.write(doc);
  let list = errorDoc.createElement('ul'); // Create with errorDoc
  // Builds a list of errors
  for (let i = 0; i < errors.errorMessages.length; i++) {
    let item = errorDoc.createElement('li'); // Create with errorDoc
    let message = errorDoc.createTextNode(errors.errorMessages[i]); // Create with errorDoc
    item.appendChild(message);
    list.appendChild(item);;
  }
  var errorList = errorDoc.getElementById('errorList');
  errorList.appendChild(list);
  errorDoc.close(); // Close the document
}

You can test the code in these two plunkers:

  • This plunker uses your original code
  • This plunker uses the code shown above
发布评论

评论列表(0)

  1. 暂无评论