The task here is to show an element only for the "first" time when you open the webpage and if you are refreshing the webpage.
Links in navigation redirect you to another *.html page and the "global" div element that is included in every *.html page should only be shown, if you:
opened the webpage for the first time (closing the webpage / tab, and opening it again counts as opening the website as first time as well)
refreshed the page being on the website.
The file structure and approximate code is as illustrated here:
https://stackblitz.com/edit/js-ocytv4?file=index.html
I am so used to do SPA, so I am not even sure that's possible to do in plain JS, because the webpage is always unloaded and loaded again.
I tried adding session storage item to check against, but in this case it is not possible to remove .introduction on refresh.
I tried checking the document.referrer and the actual window.location.href to no avail as well, there are inconsistencies.
For example, I could do:
const ref = document.referrer
const href = window.location.href
const showIntro = () => {
introductionNode.classList.remove('hidden')
}
if (!ref || ref === href) {
removeIntro()
} else {
removeIntro()
}
But, apparently when I arrive to the Page1 from Page2, my referrer will be Page1 and will not be set to Page2, so when refreshing the page, introduction block is not hidden. And can only work if I click on the link in the navigation for the second time, being on the same page.
Related
I have a web page in which my anchor tags refer to one of the elements within the same page using #id. But this changes my URL as it adds the #id into the suffix. So now when I want to go back to the page from where I came by clicking the back button of the browser, it doesn't go back to the previous page instead it goes back to the hash selections I have made by clicking the anchor tags. Please help me by giving a solution to this.
When you use a hash route it creates a new record in the browser history the same as if you navigated to a new page. So if you navigate on your site from a page to a hash route on that page, then navigate to a new page, you will have to click on the back button twice to get back to your original location.
So if you navigate https://example.com -> https://example.com#myHash -> https:/example.com/another-page then the first back button click will navigate to https://example.com#myHash and the second back button click will navigate to https://example.com
Hope that helps
You can use history.replaceState() function from History API to achieve such behavior. When user will click on anchor you will just replace current history item instead of adding a new one.
Edit: window.location.replace()
Another approach is to use window.location.replace() which is does not adds a new entry to browser's History:
The Location.replace() method replaces the current resource with the one at the provided URL. The difference from the assign() method is that after using replace() the current page will not be saved in session History, meaning the user won't be able to use the back button to navigate to it.
So what can be done to achieve the desired result is to add an onclick handler on the body element with a logic inside which will replace current location if current location is not a homepage (or any other page). This handler will look similar to the code below:
function handler (event) {
if (!isAnchor(event.target) return; // return if clicked element is not an anchor (isAnchor function should be also implemented by you. For example, you can add some class on every anchor and check if clicked element is <a> tag with this class)
if (window.location.href !== window.location.origin) { // check if you are currently on the homepage
event.preventDefault(); // if not on homepage then prevent default <a> tag redirect
window.location.replace(event.target.href); // and replace current history item URL with the new URL
}
}
I have a test website www.lemonbrush.com is has the two menu items "Home" and "About".
When we click on the "About" menu, the About page is loaded dynamical, which is great, but when I type the About page's url directly http://www.lemonbrush.com/about.html into the address bar, my whole plan goes for six.
I need some guidance in how shall I structure and load the pages so that the whole header and navigation are included even when we use the direct URL in the address bar.
My skills are HTML and Javascript.
Please see the following screen shots.
When you're clicking the menu item you are updating the page with the data, but when you are going to the link directly you are just getting the data. one way around this is to have common elements for the page, ie. navigation menus, In a javascript file and then use a script tag with a link where you want it on the page.
so, since i thought it would be nice for my project, to have a usable browser history and bookmarkable subpages, i yesterday tried the approach from my comments of the OP.
step 1: change the anchors in your navigation bar to something like that:
home
about
needles to say, that they don't need to be inside the same parent element. those links could be anywhere.
step 2: remove the on click handler from your script, that reacts on the navigation bar clicks!
step 3: create a function, to listen to the onhashchange event. (this has to be done once, on the main html page)
//create a function for the onhashchange event
window.onhashchange = function()
{
//check if a location hash is used
if(window.location.hash != null)
{
//store current location hash in a variable
requestedPage = location.hash;
//remove the '#' from the location hash value
requestedPage = requestedPage.replace('#','');
//load content from subpage into your content frame
$('#contentFrame').load('./' + requestedPage + '.html', function( response, status, xhr )
{
//catch 'file not found' errors and load start page
if ( status == "error" ) {
$('#mainPanel').load('./start.html');
}
});
};
for your page, you have of course to adapt, use the correct selectors and the correct file names.
you then would call your page via www.mydomain.com, and every subdomain via www.mydomain.com/#subPage
i got a problem with a connection between two html files with a *.js
i got index.html i got a formular.php and i got a backbutton.js
what i want to do is: if i send my fomular via button im calling the formular.php to write the text into my MySQL database. If someone forgets to put in an e-mail adress i got a error page which got a button "back". with that button i want to get back to the formular page.
My Problem is that my index.html is a page with 3 differt divs with the ids page1, page2, page3. when the user finishes a quiz the page changes itself from page1 to page2 with a
function checkplayer() {
if (player1 == true && player2 == true && player3 == true && player4 == true) {
setTimeout(function() {
$(document).ready(function() {
$("#page1").fadeOut(1000);
setTimeout(function() {
$("#page2").fadeIn(1000);
}, 1500);
});
}, 1000);
}
so my whole page is 1 page at all with 3 differnt divs that are faded in and out.
If i use my back button from the formular.html with history.back(); i land at the page1 div. But i need to get to the page3 div with the formular. Same happens if i reload my page. i always land on page1 since my index.html starts with page1 and page2 and page3 are set to display: none. Thats why i guess the history back is not working in this case since i step back always means a new loaded index.html
What i tried is to make a backbutton.js
function backButton() {
jQuery("#errorpage").fadeOut(0);
jQuery("#page3").fadeIn(0);
}
The errorpage is faded out but the page3 is not faded in because the backbutton.js doesnt know the index.html in which the page3 div is.
Is there any possiblity to get the errorpage to fadeout and the index.html page3 to fade in? is it possible to "import" the index.html page3 div into the backbutton.js?
Anyone got an Idea on how to get a connection between these 3 files or if there is any other way to get the errorpage to fadeout and my page3 div to fadein?
Any help is appreciated. Thank you
You can pass the hash to a URL:
function backButton() {
jQuery("#errorpage").fadeOut(0);
window.location = "index.html#page3";
}
and then check for the same hash on original page like this:
function checkHash() {
$(document).ready(function() {
if (window.location.hash === "#page3") {
$("#page3").fadeIn(1000);
}
});
}
Also, consider not allowing user to go forward at first place, if e-mail address is not entered.
Consider using the hash (#) to identify the 3 different pages; i.e. when switching from page 1 to page 2 signal it by changing your URl to 'YOUR_PHP_PAGE.php#page2' etc. This way, the browsers history (as well as re-load) should be able to correctly handle it. In the page-JS listen to the hash-changed-event and show the appropriate div. (Note that changing the hash by location.href = ...#page2 does NOT re-load the page, but triggers the event.)
Regarding the error page (fade in/out) you could place it on the same page. Then use ajax to post the data back to the server instead of loading a new page..
You can use hash term as id in div and wee can call by adding hash like this (index.html#page2) to land on the specific div. This directly lands to the id instead of reload the whole page. Same time we can use fade in fade out using jquery and ajax script to post the data
It has been common to direct the user using anchors. With HTML5 you can make use of the history / state APIs through History.js.
I rewrote your code using the history.js plugin. Read the comments within the sample code to see what is happening. Replace the page2finished() and throw_error() functions with your currently existing ways of telling when the user has finished page 2 and when an error should be shown. Those were included to show you the flow this code should take.
HTML
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/history.js"></script>
JavaScript
$(document).ready( function() {
var player1,
player2,
player3,
player4,
errorpage = $("#errorpage");
//Initialize the history.js script by binding it to the window object.
History.Adapter.bind(window,'statechange',function(){
var State = History.getState();
});
//Add page 1 to the browser history and load the first anchor.
History.pushState({state:1}, "Page 1", "?page=1");
//Make sure that the other elements are hidden when the user first loads the page.
$("#page2, #page3, #errorpage").hide();
function checkplayer() {
if (player1 && player2 && player3 && player4) {
$("#page1").fadeOut(1000, function() {
$("#page2").fadeIn(1000, function() {
//Add page 2 to the browser history and load the second anchor.
History.pushState({state:2}, "Page 2", "?page=2");
});
});
}
}
//After the user is done with page 2 throw them to page 3 by adding it to the browser history then loading the third anchor.
function page2finished() {
$("#page2").fadeOut(1000, function() {
//Add page 3 to the browser history and load the third anchor.
$("#page3").fadeIn(1000, function() {
History.pushState({state:3}, "Page 3", "?page=3");
});
});
}
//Something went wrong! Show the #errorpage element.
function throw_error(text) {
//Put the error text into the element and show it to the user.
errorpage.text(text);
//Hide the main pages.
$("#page1, #page2, #page3").hide();
//Add the error to the browser history and show that anchor.
errorpage.show();
History.pushState({state:3}, "Error", "?page=errorpage");
}
//The user clicked the back button
function backButton() {
errorpage.hide();
//We saved '3' linking to page 3 so tell history.js to go there.
History.back(3);
}
});
Is it possible to capture what link on the web page the user clicked on?
Not talking about if they manually entered an url in the address bar or if they clicked on the back button - but an existing link or menu item on the current page.
This is for a commercial web page that has a standard header & footer containing links to other pages on the company's web site.
They have a complicated order form where it's not practical to try saving & restoring the state of the form.
If in the process of filling out an order the customer needs to visit another page on the web site - to review product, etc.. Ideally I would be able offer the option of opening the link in another browser window or tab instead of leaving the page so that the user doesn't loose the work they've put into the order.
I know that I could have a different set of headers & footers that are written to open their links in another window/tab but to simplify maintenance & updating I'm trying to minimize the number of variations used. Also it is possible that the user wants to abandon the order form and may get confused if in trying to do so that another window opens instead.
I am using JQuery & Javascript.
Instead of having a completely different set of headers/footers you could replace all links in certain areas with links that open in a new window like so:
$('#header a, #footer a').each(function() {
$(this).attr('target', '_blank');
});
This is what I came up with to handle this and it is working for me.
Detects when user clicks on a page link then evaluates link to determine how to handle appropriately. It does not work for links typed in the browser address bar.
I use jquery magnific-popup (http://dimsemenov.com/plugins/magnific-popup/) to create a popup window (.popupForm-handleExitRequest in my code) that offers the user the option of opening link in same window (and losing their order data), in new window or returning to order form.
$('body a').click(function(e) {
//if link is reference to page element
if ($(this).attr('href').charAt(0)=="#") {
return;
}
//check if link is to same window
var pathname = window.location.pathname;
var pathname2 = $(this).attr('href');
pathname2 = pathname2.replace(/^.+\.\//, '');
if (pathname.indexOf(pathname2) >= 0) {
//link clicked is contained on same page
//prevent page from getting reloaded & losing data
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
return;
}
//link clicked on is another page
if (hasMerchandise) { //var to indicate user has items on order form
//give user options: leave page, open link in other page, stay, etc.
// $('.popupForm-handleExitRequest').click(); //roll your own code
//prevent page from getting reloaded & losing data
//in case user wants to cancel page change or open link in another window
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
} else {
//load new page
$(this).removeAttr('target');
}
});
My application has pages with several tabs that simply switch the visible content. However, the page also has links that will add tabs to the page. In addition, the application remembers (with cookies) which tab you last viewed in case the page is refreshed (strict cache settings cause refreshes even when using the back and forward buttons).
My problem is that the first time you visit this set of pages, it should show the first tab (Tab A). Then, you click a link, and it adds a tab, and it remembers that new tab (Tab B). However, if you hit back, now it looks like it did nothing because it remembers and displays the tab you last clicked (Tab B).
Remembering Tab B is desirable behavior if you click forward to a new page and then use our in-application history to return to the previous page. However, it is undesirable if you click the Back Button, because you want it to again show Tab A, the way it did when you first arrived.
My question is whether the JavaScript onunload event can detect the difference between leaving the page with the Back Button, or some other means. At this point, I want it to forget any tabs that it had remembered for that page.
If the difference you are trying to detect is between a user clicking a link and navigating away from the page some other way, you can detect a link click using JavaScript by attaching onclick event handlers to each link you want to observe clicks on.
So if onunload fires without an onclick first having fired, the user is leaving the page some other way than by clicking one of your tracked links.
<script type="text/javascript">
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].onclick = setGlobal;
}
function setGlobal() {
window.linkClicked = true;
}
window.onunload = function() {
if (typeof window.linkClicked === 'undefined' || !window.linkClicked) {
// they are leaving some other way than by clicking a link
}
}
</script>
It gets a bit trickier if you already have onclick events on your <a> tags, if that's the case I can provide a way to do that too.
Of course you can also attach to all the onclick events using jQuery or another JavaScript library.
Browsers remember the state of the timers (setTimeout calls) that were made on that page.
The first time the page loads the onLoad will be called, set a timer that forwards to the next page based on the history. If you are already on the last page, no problem :D, if not then it will be forwarded.
For IE the onLoad is always called, no matter if is with the back button, therefore you can put the same portion of code there.