Dynamically loading content on local HTML page [cl

2019-06-09 21:50发布

Context:
Basically I'm attaching a little HTML help doc to go with my program (not meant to be on a server, viewed locally). HTML just because I'm most comfortable in making docs in it but I also want it to have some interactivity/dynamic content which I can't do in a PDF or whatever.

I'm dynamically replacing the content when you click on a link instead of making every page need it's own HTML page, which is just something I'm used to doing so I can change the menu and banner and whatever else on a single 'main' html file without having to adjust every single other html file for one tiny change in the shared stuff.

Current Method:
Right now it's all done through javascript and jQuery. When a user clicks a link, I use jQuery's load() function to load the appropriate content (an html file) and replace the content div with what's in the loaded html file. Currently just using relative links. E.g. the core function is something like below:

$("#ContentBox").load("content/faq.html");

This actually worked a few weeks ago when I first wrote it. It's not like I built the whole thing and didn't test its core concept until just now. But now it seems all the browsers are blocking it. Chrome says:

XMLHttpRequest cannot load file:///C:/[....]/content/home.html. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resource. `

Question:
So I understand why it's happening as it's a potential security risk to allow that, I just want to figure a good way around it that still does what I want (if it's possible). I mean I could just preload all the content as huge string variables in the javascript file or as hidden divs that get turned on and off, but I was hoping for something a little more elegant.

And I can't expect all users of my program to setup a local web server just to view to help doc.

I've considered the File and FileReader classes but they require a user input for a lot of functions. There's also iFrames but that introduces all sorts of weirdness that needs to be accounted for and I hate iFrames.

3条回答
太酷不给撩
2楼-- · 2019-06-09 22:20

To anyone still interested this is the solution I settled on as of now. At the end of the body are all the divs with the different page content styled like so:

<div id='PageName' class='content-div'>
    <!-- content goes here -->
</div>

<div id='AnotherPage' class='content-div'>
    <!-- content goes here -->
</div>

The id is important as that becomes the name of the page and the class type, which you can name whatever, I used to hide them with visibility:hidden; as well as gave it absolute positioning at 0,0 - just in case - so that they don't interact with other elements and screw up the layout.

On the page loading, along with a bunch of other functions, I store the elements into a javascript associative object by page name.

var content = {};

function onLoadThisGetsCalledSomewhere() {
    // loop through all of those divs
    $(".div-content").each(
        function() {
            // using $(this) to grab the div in the scope of the function here
            var element = $(this).element;
            var name = $(this).attr('id');
            // remove it from the html (now it exists only in the content object)
            element.detach();
            // remove that style class that makes it invisible
            element.removeClass('content-div');
            // put it into memory
            content[name] = element;
        }
    );
}

So when a link to another page is clicked, the onclick does something like switchPage(pageName) let's say.

function switchPage(requestedPage) :
    // somewhat simplified, real version has case and null checks that take you to 404 page
    var contentElement = content[requestedPage];
    // replace content in some container div where you want content to go
    $("#TheContentContainer").empty().append( contentElement );
    // have to adjust size (width possibly too but I had a fixed width)
    $("#TheContentContainer").height( contentElement.height() );
}

I'm not at the same computer so I'm writing all this up anew, not copy/pasting so there may be some bugs/typos (Caveat emptor - I'll fix it tomorrow). The version I used is somewhat more complicated as well since I have subpages as well as dynamically handled menu bar changes. Also features so that you can open the "links" correctly in new windows/tabs if such an action is made. But that's not important here now.

It's not too different I suppose with hidden divs (the benefit here is the detach() function to remove it from the html) or just storing long strings of html code in java vars (much more readable than that though), but I think it's advantage is is much cleaner (IMHO) and so far I like it. The one downside is with lots of pages you get one huge HTML doc that can be a pain to go through to edit one specific page but any decent editor should have a bookmark feature to make it a little easier to get to the line you're looking for. Also cause of that a bad idea if not local, but then again if it's online just use the jQuery load() function.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-06-09 22:21

If this is all local content then you should not be loading it via ajax. One option you have at your disposal is to set up your help files as local Javascript templates. You can then refer to them using a template library like mustache or underscore and link to them in your application like so:

<script type="text/template" src="local/helpfile.js" />

If you don't want to use a templating library then you can set up helpfile.js as JSON data, but you'll need to escape quote characters first.

查看更多
叼着烟拽天下
4楼-- · 2019-06-09 22:25

If your help docs are to be viewed on a Windows machine only, you should look into using HTML Applications to get rid of the cross-origin issues. Or you can work around it by combining all of the source code files in hidden textareas. I've done it lol

查看更多
登录 后发表回答