0

I have a JS menu builder that only works when included in the main html file and will not work from a external file. I have tried several authors variation of a JS auto menu and they all exhibit the same behavior.

I have tried all the suggestions found in the previous applicable answers such as putting the script file request in other locations such as just before the "div id=submenu" or at the end of the html file. The external file is in the same directory and is the proper name. I have meticulously checked for dumb mistakes. No luck!

Update

I got the script working after trying an unknown combination of things, but I do not know what caused the problem or exactly what I did to fix the problem. It appears to have been more than one problem.

For awhile, the script had additional problems without including .., then I notice it had changed and when I removed the .. I got full functionality.

I wish I could pass on for others what is was, I almost suspect a hidden character from the Internet cut and paste I did. However I had the same problem with similar functions by other authors, and I have never had cut & paste problems before. (I did not think to turn on the hidden char feature of Notepad++.) Thanks for the help!

There have been several questions about js not working from external files...
JS clock doesn't work
Why does this script not work in external js file?
javascript won't work in external file
none of these seem to address the problem I am having.

This seems to be an important part of JS for me to understand, I am not very familiar with JS so please dumb down the answer :)

Main HTML file

<!DOCTYPE HTML>
<head>
  <title>Title</title>
</head>
<body style="margin: 50px auto; width:1000px;"> 
  <div id="submenu">building menu...</div>
  <h1>This is H1</h1>
  <h2>This is H2 one</h2>
  <h2>This is H2 two</h2>
  <h3>This is H3</h3>
  <h4>This is H4</h4>
  <!-- script include moved as suggested -->
  <script type="text/javascript" src="main.js"></script> 
</body>
</html>

External "main.js script file"

// script tags removed <script type="text/javascript">

  // Original JavaScript code by Chirp Internet: www.chirp.com.au
  // Please acknowledge use of this code by including this header.

  var buildMenu = function(targetId, headingTag) {
    var target = document.getElementById(targetId);
    var headings = document.getElementsByTagName(headingTag || "h2");

    if(headings.length > 1) {
      // construct an ordered list of links
      var menuList = document.createElement("OL");
      for(var i=0; i < headings.length; i++) {
        var anchorName = "";
        if(headings[i].id) {
          anchorName = headings[i].id;
        } else {
          anchorName = "section_" + i;
          headings[i].setAttribute("id", anchorName);
        }

        var headingText = headings[i].firstChild.nodeValue

        headings[i].firstChild.nodeValue = (i+1) + ". " + headingText;

        var menuLink = document.createElement("A");
        menuLink.setAttribute("href", "#" + anchorName);
        menuLink.appendChild(document.createTextNode(headingText));

        var listItem = document.createElement("LI");
        listItem.appendChild(menuLink);

        menuList.appendChild(listItem);
      }

      // remove all nodes from inside target element
      while(target.hasChildNodes()) target.removeChild(target.firstChild);

      // insert our generated menu into the target element
      target.appendChild(menuList);
    } else {
      // remove the target element from the DOM
      target.parentNode.removeChild(target);
    }
  };

  if(document.addEventListener) {
    document.addEventListener("DOMContentLoaded", function() {
      buildMenu("submenu", "h2");
    }, false);
  } else {
    window.attachEvent("onload", function() {
      buildMenu("submenu", "h2");
    });
  }

// removed </script>
jwzumwalt
  • 186
  • 9
  • 2
    What is a *"main html file"* vs. an *"external file"*?? Do you mean it only works when the JavaScript is content within the ``, and not when it's in a `.js` fiel you load via ``? – T.J. Crowder Oct 16 '19 at 08:55
  • Your one code block seems to be showing two different things. Could you please identify what those two things are and separate them into separate code blocks? – T.J. Crowder Oct 16 '19 at 08:57
  • 2
    Put the external file `.js` up to the closing `

    `, because if you put at top of the file, the html elements are not in `DOM`.

    – Roy Bogado Oct 16 '19 at 08:57
  • @Roy - Actually, looking at the script it would probably be okay in teh `head`. – T.J. Crowder Oct 16 '19 at 08:58
  • 3
    Ah, are you including the `` tags in your external file?? If so, remove them, as it needs to be JUST javascript – freefaller Oct 16 '19 at 08:59
  • is there any error in browser's console ?? – Akbar Mirsiddikov Oct 16 '19 at 09:01
  • Thanks for clarifying! That helped us point you at the solution. Side note: You've said you're new to this stuff. One of the things you'll want to develop the habit of doing is opening your web console and checking for errors there. On most browsers it's F12 and/or Ctrl+Shift+I and/or Ctrl+Shift+J (on Mac OS, Cmd+Shift+I) to open the "dev tools," then choose the Console tab. Your console is likely showing the error referenced by [the linked question](https://stackoverflow.com/questions/31926326/syntaxerror-expected-expression-got-what-does-that-mean). – T.J. Crowder Oct 16 '19 at 09:02
  • if ext file was included properly paste your script teg before – Akbar Mirsiddikov Oct 16 '19 at 09:02
  • 1
    THIS IS NOT A DUPLICATE QUESTION. As I have pointed out, all the above suggestions are in the other "stack" linked answers. They do not fix the problem... – jwzumwalt Oct 16 '19 at 09:05
  • 2
    @jwzumwalt - If you fix the `` problem described by the linked question's answers and the comments above, the above **does** work. I copied and pasted it locally. Also: https://plnkr.co/edit/5T2or6KuHmnQ5xLjQqcU?p=preview – T.J. Crowder Oct 16 '19 at 09:12
  • This might be a duplicate, but the one pointed out is clearly not a solution. – Deblaton Jean-Philippe Oct 16 '19 at 09:13
  • 2
    @jwzumwalt - Please don't shout. Please take the [tour] (you get a badge!), have a look around, and read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) – T.J. Crowder Oct 16 '19 at 09:14
  • @DeblatonJean-Philippe - It clearly is. If you take what's above and fix it according to the answers there, [it works](https://plnkr.co/edit/5T2or6KuHmnQ5xLjQqcU?p=preview). – T.J. Crowder Oct 16 '19 at 09:14
  • @ T.J. Crowder removing causes the function to not work correctly, that causes numbers to show at the actual

    locations and does not build the menu at the top.

    – jwzumwalt Oct 16 '19 at 09:17
  • @jwzumwalt - Sorry, but you must have made a mistake when doing so. See [the example I linked above](https://plnkr.co/edit/5T2or6KuHmnQ5xLjQqcU?p=preview). – T.J. Crowder Oct 16 '19 at 09:19
  • Side note because again you said this is a new area for you: Putting `script` tags in the `head` that don't use `async` or `defer` is an anti-pattern. It works with this particular script, but best practice is to put such scripts at the end of the document body, just prior to the closing `

    ` tag. (Or use `defer`, or in really modern browsers, you can use modules.)

    – T.J. Crowder Oct 16 '19 at 09:20
  • I don't have a mistake. Copy the exact code I have posted into the HTML file at the script source location and it works. The same code in a external file does not work. – jwzumwalt Oct 16 '19 at 09:20
  • For the sake of argument, I have moved the script include line to

    - it still does not work.

    – jwzumwalt Oct 16 '19 at 09:22
  • @jwzumwalt - It's not necessary with this script, as I said above. Does [this](https://plnkr.co/edit/5T2or6KuHmnQ5xLjQqcU?p=preview) work? Do you have any errors in the web console? Do you have the filename right? If you go to the Network tab in the dev tools, do you see the script being loaded? Perhaps you have a server config issue. – T.J. Crowder Oct 16 '19 at 09:24
  • @T.J.Crowder I think the root of the problem is use of DOMContentLoaded in external JS. It is likely this event has already been triggered by the time the code that registers the event handler runs. Perhaps this would be a better dupe: https://stackoverflow.com/questions/39993676/code-inside-domcontentloaded-event-not-working – phuzi Oct 16 '19 at 09:49
  • @phuzi - No, it isn't likely. The `script` tag shown is not `async`, `defer`, or `type="module"`, so it runs synchronously with the HTML parsing, before `DOMContentLoaded` fires. It's **very** basic, standard usage. – T.J. Crowder Oct 16 '19 at 10:00
  • @jwzumwalt - Just saw your update. Glad you figured it out! – T.J. Crowder Oct 16 '19 at 10:00

0 Answers0