Background
- In our company, we install our offline documentation topics (thousands of .htm files in a folder) on our users' computers. Users view our documentation offline through their browser using the file:/// protocol.
- I have a banner that appears in the footer of each .htm file that asks users to decide whether we can track user analytics (via Application Insights). Once they make their choice, we don't show the banner.
My Goal and Overall Problem
My goal is to store their choice in the browser's local storage. I can do that just fine, but the problem is this:
These are offline .htm files. There is no website domain. So, the key and value for any local storage is stored only for the .htm file they are on at the time they make their choice. If they come back to a topic they made their choice on, then yes, my script can retrieve their choice. But if they navigate to another topic in our documentation system (another .htm file), the local storage key and value don't persist to those other topics, and my script doesn't know what they chose--so then the banner pops up again.
My Workaround Idea
I doubt this is the best approach, but not having a lot of experience and not knowing what else to try, necessity becomes the mother of invention.
Here's what I'm trying:
- Have my local storage requests go through a single .htm file called storage.htm, thereby getting around the above problem by always having a single point of contact (storage.htm) with the local storage.
- storage.htm loads via a blank iframe.
- The iframe is tacked onto each .htm topic.
- When a topic .htm loads, the iframe also loads and any functions inside it become (hopefully) available for use by my main script.
- When users click on the banner, I send the choice as query parameters through my main script to the iframe's src.
- storage.htm contains a
parseQuery()
function, and inside that function, it parses any query params and then does the actuallocalStorage.getValue(key)
andlocalStorage.setValue(key,value)
requests. - I then want to somehow force the iframe to refresh with those parameters and then call the
parseQuery()
function there from my main script.
My Code
From my main script:
Attempt 1:
I've tried the top-voted item from this thread,
How to check if iframe is loaded or it has a content?
but I get stuck inside the checkIfFrameLoaded()
function, and it continues to loop through the check to see if the iframe is loaded. It never loads. I think it's because the contentWindow
and/or contentDocument
don't work with my offline files, so I won't bore you with that code.
Attempt 2: This is what I'd like to do as it seems cleaner:
function doIframeStorage(type,key,value){
// We get a handle on the iframe's id of 'storage'.
let storage = document.querySelector('#storage');
const src = storage.getAttribute('src');
let query = src;
if (type==='get'){
query = src + `?type=${type}&key=${key}`;
} else if (type==='set'){
query = src + `?type=${type}&key=${key}&value=${value}`;
}
storage.src = query;
storage.addEventListener('load', (e) => parseQuery());
}
But I'm running into a problem where my parseQuery()
function (from storage.htm) is always undefined:
Uncaught ReferenceError: parseQuery is not defined
Is it possible to load and access my parseQuery()
function from my main script like I'm doing? If so, how? I thought the addEventListener
would ensure it was loaded and therefore the parseQuery()
function would then be available.
Or Is there a better way to do what I'm attempting?