1

I have one HTA file, one JS file is enqueued to the HTA file and HTML files with contents are loaded into the HTA file.

For example this is my_hta_file.hta

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="x-ua-compatible" content="ie=9.0" />
</head>
<body></body>
</html>
<script type="text/javascript" src="my_js_file.js"></script>

and this is my_js_file.js

function getFileContent(filePath) {
    var fileStream = new ActiveXObject('ADODB.Stream');
    fileStream.Type = 2;
    fileStream.Charset = 'utf-8';
    fileStream.Open();
    fileStream.loadFromFile(filePath);
    var fileContent = fileStream.ReadText();
    fileStream.Close();
    return fileContent;
}

// initial loading of home page
document.body.innerHTML = getFileContent('index.html');

var pageLinks = document.querySelectorAll('a');
for(i = 0; i < pageLinks.length; i++) {
    var linkHref = pageLinks[i].getAttribute('href');

    pageLinks[i].setAttribute('href','#!'+linkHref);
    // I add this leading prefix to prevent following by the link when click by it

    pageLinks[i].onclick = function() {
        var page = this.getAttribute('href').substring(3);
        if(page == '') {
            var page = 'index';
        }

        // load HTML of the page by link path when click by the link
        document.body.innerHTML = getFileContent(page+'.html');
    }
}

and my HTML files with contents are:

index.html

<a href="/">Home</a>
<a href="/second">Second</a>
<a href="/third">Third</a>
<div>Home page content</div>

second.html

<a href="/">Home</a>
<a href="/second">Second</a>
<a href="/third">Third</a>
<div>Second page content</div>

third.html

<a href="/">Home</a>
<a href="/second">Second</a>
<a href="/third">Third</a>
<div>Third page content</div>

When I click by a link, I need to load all the HTML content from the HTML file by the link path including the very links I click by.

If I open my HTA file and click the link "Second", I get the second page links and content successfully.

But after that if I click the link "Third", I get the error

Cannot find file 'file:///D:/third' ...

How to resolve the problem?


UPDATE 1

If I move my script to the bottom of the HTA body and add a div for loading HTML for example

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="x-ua-compatible" content="ie=9.0" />
</head>
<body>
  <div id="body"></div>
  <script type="text/javascript" src="my_js_file.js"></script>
</body>
</html>

and in my JS file load HTML into div i.e.

document.getElementById('body').innerHTML = ...

instead of

document.body.innerHTML = ...

the problem still remains

stckvrw
  • 1,689
  • 18
  • 42
  • 1
    A script outside of head or body element is invalid HTML, which IE might try to fix by moving the script to `body` element. Then you're overwriting the body, and the script will be gone, and the hrefs are never edited, and onclick events are never attached to the links. Move the script to the head section, or add a content wrapper element which content to change instead of the entire body. – Teemu May 30 '18 at 04:39
  • @Teemu thank you! Please see my update 1. – stckvrw May 30 '18 at 08:22
  • 1
    But the links are added dynamically, they are not the same elements anymore, and the references are lost. You've to run the script to edit the hrefs and attach the listeners again. – Teemu May 30 '18 at 09:35
  • I don't know how to run the script again. Could you write a simple example? – stckvrw May 30 '18 at 10:52

1 Answers1

1

As said in the comments, all the links with attached event listeners are replaced by new elements when innerHTML is changed. These new links don't have the listeners which the old elements had.

The snippet below shows how you can use a function to reinit the listeners. The snippet assumes a content wrapper element is used (as you already seem to use it). I've also simplified the code a bit, and used more modern JS (since IE9 mode is used in the OP).

function getFileContent (filePath) {
    // As it currently is
}

// Handles clicks on the links
function newContent (e) { // e contains information of the current event
    var path = e.target.href || 'index',
        body = document.getElementById('body');
    e.preventDefault(); // Prevents the default action of the clicked link
    body.innerHTML = getFileContent(path + '.html');
    init(); // Initialize the new content
    return;    
}

// Initializes the page
function init() {
    var links = document.querySelectorAll('a'),
        i, ei;
    for (i = 0, ei = links.length; i < ei; i++) {
        links[i].addEventListener('click', newContent);
    }
    return;
}

// Initialize the first page
init();
Teemu
  • 22,918
  • 7
  • 53
  • 106
  • Actually, I didn't check it when you wrote, but now I've opened HTA and I see blank page only... – stckvrw Jun 04 '18 at 19:26
  • Have you enabled the error messages? It would be helpful if you'd see the errors. – Teemu Jun 04 '18 at 19:29
  • As for your code, you try to initialize the first page calling the `init()` function. While not `init()` but the `newContent()` function sets `body.innerHTML`. So when I just open HTA file, nothing is displayed. – stckvrw Jun 05 '18 at 09:11
  • OK, I assumed there was initial content on the first page, but in the case there isn't, just call `newContent` instead of `init` when loading the first page. – Teemu Jun 05 '18 at 09:27
  • Ok, thank you again! Could you see my another question by [the link](https://stackoverflow.com/questions/49865865/cant-upload-a-file-to-ftp-with-wscript-shell-cmd#comment88384246_49865865) and especially my last comment yesterday – stckvrw Jun 06 '18 at 12:21
  • I'm sorry, took a look at the question, but it is beyond my knowledge. – Teemu Jun 06 '18 at 12:25