0

I'm working on a fairly extensive local website. It is not on a web server, and I am more or less restricted to HTML and JavaScript.

I have a side navigation menu on all the pages that is called with this statement:

<script type="text/javascript" src="menu/menu.js"></script>

menu.js is essentially a list of links like this:

document.write("<a href='page5.html#part1'>Part 1</a>");

In place on all the pages is a sticky header script that is making linking to anchors cumbersome. If you're currently on the page the link is linking to and ABOVE the anchor the link is linking to, it works fine. But if you're currently below the anchor on the same page, it gets glitched up. It doesn't take you to where it should.

There's probably another way to do it, but I feel like an easy-to-implement solution would be to create a link that first opened the page at the top, and THEN took you to the anchor.

I tried using @Qwerty's solution from this question ([Force page reload with html anchors (#) - HTML & JS), but it didn't work. I tried this:

document.write("<a href='page5.html#part1' onclick='location.reload()'>Part 1</a>");

I'm guessing it didn't work because of it being local and/or because of the link being read from a JS file.

Example For simplicity's sake, let's say there are 3 pages on the site and each page has 3 anchors on it. I want this external JS menu to be on and work on all pages. It has these links:

page1.html#part1
page1.html#part2
page1.html#part3

page2.html#part1
page2.html#part2
page2.html#part3

page3.html#part1
page3.html#part2
page3.html#part3
Community
  • 1
  • 1
Robby
  • 843
  • 3
  • 19
  • 53
  • 2
    Lost on what your objective is, need more code, I don't want to write a whole webpage guessing how your page is made. – zer00ne Nov 16 '16 at 21:42
  • 1
    99% of questions posted are required to have a [MCVE (**M**inimal, **C**omplete, and **V**erifiable **E**xample)](http://stackoverflow.com/help/mcve). Please post JavaScript/jQuery, CSS, and HTML that would be relevant to your question. Create a demo using any or all of the following services: [jsFiddle.net](https://jsfiddle.net/), [CodePen.io](https://codepen.io/), [Plunker.co](http://plnkr.co/), [JS Bin](https://jsbin.com/) or a snippet (7th icon located on the text editor toolbar or CTRL+M). – zer00ne Nov 16 '16 at 21:42
  • I can't. It has to work locally, and I don't think any of those services can emulate that. Plus I'm working with an external JS file, which throws a wrench in things. – Robby Nov 16 '16 at 21:44
  • This site will emulate multiple files:http://plnkr.co/ external JS files are not a problem. The monkey wrench you are experiencing is `document.write` don't use it...ever. https://developer.mozilla.org/en-US/docs/Web/API/Document/write – zer00ne Nov 16 '16 at 21:45
  • Does it emulate being a local file though? I asked a question on here a week or two ago, and it turned into a big discussion because I didn't realize it mattered that the site wasn't on a web server. – Robby Nov 16 '16 at 21:46
  • 1
    It matters under certain circumstances, but in your case it might not, hard to tell without code or clear intentions of author of said webpage. – zer00ne Nov 16 '16 at 21:49
  • @zer00ne I added some example code for the links. It's not the code I'm actually using since it has to be JavaScript. But I gave an example of that at the top of my question. – Robby Nov 16 '16 at 21:51
  • Each page should have:`` located right before the closing body tag `

    `. The src value is for a Windows machine, I don't know for a Mac.

    – zer00ne Nov 16 '16 at 21:53
  • It does. The menu shows up, but because of the sticky headers, I need the link to basically open two locations. One to go to the page and another to go to the anchor. – Robby Nov 16 '16 at 21:55
  • I see. Use a hash `#` at end of url and then the id of element in the other page. – zer00ne Nov 16 '16 at 21:57
  • I plunked your "website" http://plnkr.co/edit/vbrkPBhhxGIE71pEmiId?p=preview , everything works fine. Can you reproduce your problem? – br3t Nov 16 '16 at 22:14
  • @Robby I created a working demo on [Plunker](http://embed.plnkr.co/Yg42DVH7XWXuzNY4WIsy/) it has 6 pages, each page having 3 parts, each link generated by JavaScript. – zer00ne Nov 16 '16 at 23:14
  • @br3t That works for me, even as a local file, but the method in which the menu is constructed is drastically different from what I have now. In my JS menu file, I'm also using a Slashdot-style menu from dynamicdrive.com in that file. There are a lot of factors in play. I was hoping for a clever way of linking to essentially 2 different locations in one click. – Robby Nov 17 '16 at 15:10
  • @Robby, you are wellcome to make any changes at my plnkr-example to show us your infrastructure – br3t Nov 17 '16 at 15:14
  • I don't know understand why the exact specifics of the site matter. I have a local-only site with an external JS menu. The menu has links to different pages and anchors on those pages. As an example, I just want to be able to be in #part5 of page1.html, click a link to page1.html#part2, and the behavior is to open page1.html and then go to page1.html#part2 instead of a standard link that takes you straight to page1.html#part2. – Robby Nov 17 '16 at 15:35
  • That's exactly what I have in my Plunker, we need to know your code when you start asking "Where's the menu?" I'm flabbergasted by your inability to realize that each member (myself included) have been trying to work around the fact that you have not provided any semblance of your work. Look at the most current good questions on the site, then look at the code provided.The reason we can give an answer at all is because the subject is trivial. Do you understand the answers provided to you? Because it seems that you don't. – zer00ne Nov 17 '16 at 16:40
  • I understand and appreciate what you have all been doing. I just thought it would make more sense to make this a sort of general question so that other people could benefit from the answer since my exact situation is probably very unique: it's a local website, the links are coming from an external JS menu, etc. But the fact that there are dozens of pages, links, and anchors involved doesn't matter. I would have the exact same problem if there were just 2 pages, links, and anchors. – Robby Nov 17 '16 at 17:40

2 Answers2

0

This may either be brutally irrelevant to your question or give you an idea, how your app could be structured better. To handle your navigation needs, you don't need Javascript. But you can add it to the mix to improve this solution with nice gimmicks.

<html>

<head>
  <title>one-page-app</title>
  <style>
    .pages {
      display: none;
    }
    .pages:target {
      display: block;
    }
  </style>
</head>

<body>

  <nav>
    <p>Main Menu:</p>
    <a href="#home">Home</a>
    <a href="#faq">FAQ</a>
    <a href="#external">External content (other file)</a>
  </nav>

  <a name="home"></a>
  <div id="home" class="pages">

    <h1>Home</h1>
    <p>Hi. Check <a href="#faq">FAQ</a> to see how it's working.</p>

  </div>

  <a name="faq"></a>
  <div id="faq" class="pages">

    <h1>FAQ</h1>
    <ul>
      <li>
        <h2>How does it work?</h2>
        <p>The magic of the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/:target">:target pseudo-class in CSS</a>.</p>
      </li>
      <li>
        <h2>What if I have more content?</h2>
        <p>
          I've worked with 2-3 MB html files without a problem. That's when smartphone browsers were really choking. ;) For local pages, loading time is no issue after all.</p>
      </li>
      <li>
        <h2>What about REALLY old browsers?</h2>
        <p>They will see all the content at once, but due to the anchors, the main menu will still work. Add "back to top" links to the pages if you want.</p>

  </div>

  <a name="external"></a>
  <iframe id="external" class="pages" src="http://google.com"></iframe>

</body>

</html>

EDIT - after question-edit:

If you want to keep your current structure, you could just do:

<a name="page1_1"></a>
<iframe id="page1_1" class="pages" src="page1.html#part1"></iframe>

<a name="page1_2"></a>
<iframe id="page1_2" class="pages" src="page1.html#part2"></iframe>

and so on.

bid
  • 86
  • 5
  • The menu code is being read from an external file on all the pages, similar to SSI. The only way I've figured out how to do this for a local website is to use JavaScript. – Robby Nov 17 '16 at 14:23
  • That's my point: This approach doesn't need that. All navigation is done my "normal" links in a single HTML file. I have that file build from a pug-template by [Gulp](http://gulpjs.com), but you can write it by hand too. The content can be in that file TOO - giving you a single-file-app! Or you can put the content into individual html files and include those with an IFrame, while still having all navigation in this single file. Usually using IFrames gives you problems like "weird" Back-Buttons, no Browser History, etc, but with this approach (using anchor-links) none of that applies. – bid Nov 17 '16 at 18:09
  • So with your structure, your menu would look like `Page one part onePage one part two` and the corresponding content would be the IFrames in the last example of my answer. Your content files (page1.html, page2.html) would just be the *pure* content without any menu. They get included by IFrames, while the menu stays in the index.html – bid Nov 17 '16 at 18:24
0

The Snippet below is for ease of reference there's more involved with this than what is in the Snippet. If you like a live demonstration go to this PLUNKER.

The first page must be index.html as a requirement of the website, but you may name your pages however you want on your PC. Keep in mind the links do not include index.html because I'm too lazy to include it, it would mean writing code that wouldn't be useful for you.

// Code goes here

var pages = 5;
var parts = 3;
var pg = [];
var pt = [];
var menu = document.getElementById('menu');
var i, j;
for (i = 0; i < pages; i++) {
  var page = 'page' + (i+1);
  pg.push(page);
  for (j = 0; j < parts; j++) {
    var part = 'part' + (j+1);
    pt.push(part);
    var url = pg[i] + '.html#' + pt[j];
    var anchor = document.createElement('a');
    anchor.href = url;
    anchor.textContent = 'Page ' +(i+1) + ' Part ' +(j+1) ;
    menu.appendChild(anchor);
  }
}
<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="style.css">

</head>

<body>
  <h1>Index</h1>
  <nav id='menu'></nav>
  <section id='part1'>
    <h2>Part1</h2>
  </section>
  <section id='part2'>
    <h2>Part2</h2>
  </section>
  <section id='part3'>
    <h2>Part3</h2>
  </section>
  <script src="menu.js"></script>
</body>

</html>
zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • I appreciate this, but a menu isn't showing on the Plunker. Is it supposed to? – Robby Nov 17 '16 at 14:19
  • All of those links were generated to specific sections on each page. The menu is the links. `` is what it looks like but after the pages load each nav will be populated with 15 links, that's 5 pages and each page having 3 parts. When you click a link, it will take you exactly on the part of the page as requested. You will not actually see a full url in menu.js because each url is built programmatically. If you want to see the HTML after it's built, you must use F12. Have you actually clicked any of the links or looked at the files? [CONT-->] – zer00ne Nov 17 '16 at 15:18
  • [-->CONT] Also, you can't expect the menu to look anything like your menu. If I tried to do that with the info provided, it'd take me days to do so since I would need to guess blindly. – zer00ne Nov 17 '16 at 15:25
  • Put styles in, most of the style.css rulesets are from a demo page I made so most of it doesn't apply. Although I ended up making a small website, I'm not going to put anymore effort in it take or leave it. You need some fundamental knowledge in HTML and more exposure to JavaScript. – zer00ne Nov 17 '16 at 16:31