60994


jsファイルでファイル処理をし、htmlでプログラムの中をみれないようにしたいとかんがえていますが、jsファイルで処理をすると、タグが消える現象がおきています。

Console機能を使い、処理を確認すると、innerHTMLの値はjs上では、タグを含んで出力しておりますが、htmlのファイルになると、tagが消えてしまいます。  
insertAdjacentHTMLを使う方法も試しましたが、同様の症状がでてしまいました。  
解決方法あれば、ご指導をお願いします。

■html

[code]

    <!DOCTYPE html>
    <head>
        <meta charset="Shift_jis">
        <title>chart of results</title>
    
    </head>
    <body>
    <!--ここにグラフが挿入されます-->
    
    <br>
    <br>
    
    ////////////////////////////////////////
    <table border="1" >
        <tbody >
         <div id="output_csv"></div>
         <script src="myChart.js"> </script>
        <script>
        console.log('myChart.js started')
        getCsvData();
        console.log('myChart.js completed')
    
        </script>
     </tbody>
    </table>
    
    /////////////////////////////////////
    
    <br>
    テスト
    </body>
    </html>
    
[/code]

■JSファイル

[code]

    const outputElement = document.getElementById('output_csv');
    
    function getCsvData() {
            console.log('Start in getCsvData ')
     dataPath = 'data3utf.csv';
     const request = new XMLHttpRequest();
     request.addEventListener('load', (event) => {
      const response = event.target.responseText;
      convertArray(response);
     });
     request.open('GET', dataPath, true);
     request.send();
            console.log('getCSVdata completed')
    }
    
    function convertArray(data) {
            console.log('converArray start')
     const dataArray = [];
     const dataString = data.split("\r\n");
     for (let i = 0; i < dataString.length; i++) {
      dataArray[i] = dataString[i].split(',');
     }
        //console.log(dataArray)  // confirmed
     let insertElement = '';
     dataArray.forEach((element) => {
      insertElement += '<tr>';
    
      element.forEach((childElement) => {
       insertElement += `<td>${childElement}</td>`
      });
      insertElement += '</tr>';
     });
    
    
     outputElement.innerHTML = insertElement;
                    console.log('outputElement Start')
                 console.log( outputElement.innerHTML  )
                console.log('outputElement completed')
    
            console.log('convrtArray completed')
    }
    
[/code]


CC BY-SA 4.0
2019-12-01T15:04:28.793
60992
2019-12-04T03:35:58.303
31870
question
javascript html
innerHTMLのoutputからタグが消える


ページ全体の DOM 作成が完了する前に DOM の操作をしようとしているので ちゃんと動作しないようです。  
jQeury だとよく

[code]

    $(function() {
     /* DOM を操作する処理 */
    })
    
[/code]

という書き方をしますが、DOM 操作できる ちょうどいいくらいのタイミングで  
処理が呼ばれるように工夫されています。

今回の場合は

[code]

    <script src="myChart.js"> </script>
    <script>
        window.addEventListener('load', function() {
            console.log('myChart.js started')
            getCsvData();
            console.log('myChart.js completed')
        });       
    </script>
    
[/code]

と、処理を開始するタイミング を遅くしたら 予期した動作になりました。

DOM 構築前でも

[code]

    <script>
        document.write("<tr><td>1</td></tr>");
    </script>
    
[/code]

とすれば HTML を直接出力できるのですが、  
csv ファイルを読み込み完了まで待ち合わせる事ができないので  
今回のパターンでは使えないと思います。


CC BY-SA 4.0
2019-12-01T17:20:09.117
60993
2019-12-01T17:27:37.690
2019-12-01T17:27:37.690
18851
18851
60992
answer


もう少し方法がないかなと思って、  
本家 で 検索してみたら こういう方法が 紹介されていました。  
<https://stackoverflow.com/questions/10585029/parse-an-html-string-with-js>

[code]

    var parser = new DOMParser();
    var htmlDoc = parser.parseFromString(txt, 'text/html');
    
[/code]

これで HTMLDocument が生成されるので その中の body の中の要素を設定します。

[code]

    var parser = new DOMParser();
    var htmlDoc = parser.parseFromString("<table><tr><td>1</td></tr></table>", 'text/html');
    outputElement.appendChild(htmlDoc.body.firstChild);
    
[/code]

とすると ページ全体の DOM が構築まえでも 指定の エレメントに DOM 構築されたHTMLを設定できるようです。

[MDN によると](https://developer.mozilla.org/en-
US/docs/Web/API/DOMParser#Browser_compatibility) IE10 以降であれば 利用できそうです。

利用する環境が 限定できるなら、当初の目的に一番近い方法だと思います。

* * *

MDN に書かれていたサンプルコードのリンク先を見ましたが、  
他のブラウザの対策も必要なようで、ちゃんと動作させるためには 下記リンク先のように該当機能が存在するか判定する処理が必要となるようです。

<https://gist.github.com/1129031>

* * *

ついでなので 動作確認した コードを連携します。  
IE10 でも動作するように JavaScript は書き換えてあります。  
IE10,IE11,Chrome,Edge で 同じように動作しました。

test.html

[code]

    <!DOCTYPE html>
    <head>
        <meta charset="Shift_jis">
        <title>chart of results</title>
    
    </head>
    <body>
        <!--ここにグラフが挿入されます-->
    
        <br>
        <br>
    
        ////////////////////////////////////////
        <table border="1">
            <tbody>
                <div id="output_csv"></div>
                <script src="myChart.js"></script>
                <script>
            console.log('myChart.js started')
            getCsvData();
            console.log('myChart.js completed')
    
                </script>
            </tbody>
        </table>
    
        /////////////////////////////////////
    
        <br>
        テスト
    </body>
    </html>
    
[/code]

myChart.js

[code]

    var outputElement = document.getElementById('output_csv');
    
    function getCsvData() {
        console.log('Start in getCsvData ');
        dataPath = 'data3utf.csv';
        var request = new XMLHttpRequest();
        request.addEventListener('load', function(event) {
            var response = event.target.responseText;
            convertArray(response);
        });
        request.open('GET', dataPath, true);
        request.send();
        console.log('getCSVdata completed');
    }
    
    function convertArray(data) {
        console.log('converArray start');
        var dataArray = [];
        var dataString = data.split("\r\n");
        for (var i = 0; i < dataString.length; i++) {
            dataArray[i] = dataString[i].split(',');
        }
        //console.log(dataArray)  // confirmed
        var insertElement = '';
        dataArray.forEach(function (element) {
            insertElement += '<tr>';
    
            element.forEach(function (childElement) {
                insertElement += '<td>' + childElement + '</td>';
            });
            insertElement += '</tr>';
        });
    
    
        insertElement = "<table>" + insertElement + "</table>";
        var parser = new DOMParser();
        var htmlDoc = parser.parseFromString(insertElement, 'text/html');
        outputElement.appendChild(htmlDoc.body.firstChild);
        console.log('outputElement Start');
        console.log(outputElement.innerHTML);
        console.log('outputElement completed');
    
        console.log('convrtArray completed');
    }
    
    function onLoadFunc() {
        console.log('myChart.js started');
        getCsvData();
        console.log('myChart.js completed');
    }
    
[/code]

data3utf.csv

[code]

    1,2,3
    
[/code]


CC BY-SA 4.0
2019-12-01T17:45:06.680
60994
2019-12-04T03:35:58.303
2019-12-04T03:35:58.303
18851
18851
60992
answer