Activate style with if statements for anchor position - javascript

I am a beginner and have searched thoroughly, finding not a solution for this problem.
I've written a code where a css style changes when you click on a link, such as the one below:
function spHome(){
document.getElementById("btnHome2").style.background = "url(../images/btn_navHoverArrow.png) no-repeat center bottom";
document.getElementById("btnAccount").style.background = "0";
}
function spAccount(){
document.getElementById("btnHome2").style.background = "0";
document.getElementById("btnAccount").style.background = "url(../images/btn_navHoverArrow.png) no-repeat center bottom";
}
This code works perfectly fine. The problem for me is that when I refresh the page, the click state is no longer active. Is there a code that can allow the function to stay active only when the user is at a certain anchor point of the page. For example, if we have an anchor location called index.html#home, the home button will be active and when index.html#account is clicked, the account button will stay on clicked even after page refresh.
The example below doesn't seem to be working on jsfiddle but it is fine on all browsers:
http://jsfiddle.net/JoshuaWaheed/HZLVt/3/
Is there a way to make this happen?

Add href hashes and return false onclick to avoid page reloading
You need to execute js at page load, check the url's hash, and put the button's state accordingly to the hash.
Using jQuery, it would be something like (not tested):
$(function() {
if (document.location.hash == "#home")
spHome()
else
if (document.location.hash == "#account")
spAccount()
})
If you don't want to use jQuery, you can put that code on docuent event "load"

Related

Single Page Site and Back Button Confusion

I have been searching for hours about how to do this, trying different things and not succeeding.
All I want to do is make a one-page site that shows/hides divs and does one simple animation. I have already made it do everything I want and look the way I want it to look: When you click a link in my navbar, there is a script that runs that hides one div, shows another, and also changes the size of the header image. This is all done with simple JS and CSS, but the back button doesn't work and the URL does not change even when I make the link a hash anchor. Maybe having all the divs on the index and showing/hiding them isn't even the best way to do this.
The implementation of the HTML5 History API (If I should even be using that) has got me stumpped, and I can't seem to find a simple straightforward working example of this.
Can anyone point me to a fiddle or codepen of something like this working properly?
This is the basics of what I'm doing:
Link:
Work
Function:
function work() {
document.getElementById("work").style.cssText = 'display: block; opacity: 1;'
document.getElementById("about").style.cssText = 'display: none; opacity: 0;'
document.getElementById("hero").style.cssText = 'height: 85px; transition: 200ms ease-in-out;'
document.getElementById("introcontainer").style.cssText = 'visibility: hidden; opacity: 0; transition: visibility 200ms, opacity 200ms linear;';
}
When my "Work" link is clicked, "about" is hidden, "introcontainer" is hidden, height of "hero" is changed, and "work" is displayed. I have two other "pages" and they function the same way.
History API is made just for such scenarios , instead of scanning url hashes and running complex if else you can use pushState to keep track of application state and decide what happens at each state.
The gist of this API is when you push something using pushState it gets returned to you on popState (on hitting back button).
history.pushState(objState,title,Url);
The first argument is where we pass stuff that will help identify application state you can put anything but it has to be enclosed in an object
I will ignore the 2nd one(pass any string). 3rd one is what URL bar would show relative to current path on executing PushState()
Assuming you have nav something like this
<ul id="nav">
<li>About</li>
<li>Contact</li>
<li>Team</li>
</ul>
assign click handlers for pushing state
$('a').click(function(e){
e.preventDefault();
var targetUrl = $(this).attr('href');
history.pushState({url:targetUrl}, targetUrl, targetUrl);
applyState(targetUrl); //will show div associated with this anchor
});
Now when user clicks a link you need to push something related to this say its href or title to identify it later (I've used its href but you are free to use anything) after it gets pushed you may animate and show div associated with this link eg. If I click <a href="work"> then push “work” and show the div that holds your work details(while minimizing/hiding other divs) .Your url reads xyz/work atm
Next if I click <a href="contact"> state for contact gets pushed and same way it's associated div gets highlighted.Your url reads xyz/contact atm
Now when I hit back history will pop and url will change from xyz/contact to xyz/work popping the latest inactive state (wiz. work and not contact!)
If you have assigned handler for onpopstate you can catch the popped content
window.onpopstate = function(e) {
var popie = e.state ? e.state.url : null;
applyState(popie);
}
so popie would be “work” , applyState will do its fancy animation and show work div
applyState might look like
function applyState(url) {
$('#status').text('Current active page ' + url);
switch(url){
case "work": //show work details div hide others
break;
case "about": //show aboutdetails div hide others
break;
}

Trying to get this wordpress theme to scroll to an id when a link is clicked on a different page

Easiest way to explain it is if you have a look at the site - haloespresso.com.au/working/
If you click the "menu" option in the top menu, it scrolls to the menu id #pg-9-4, which is what I want. On the other pages, the menu is slightly different and the same link is changed to link to the home page with #pg-9-4 added to the end of it. The point here is clearly to get the link from another page to open the home page but scroll to the menu part of it. I don't even need it to smooth scroll or anything, just go to that spot. It looks like it does go there for like, one frame, as it's loading, but it keeps jumping to the top. It's simply beyond me to try and figure out what is causing it to lose this basic HTML (afaik) functionality and keep forcing me to the top of the page...
Any help would be really great, as I'm a bit of a noob when it comes to anything other than html/css and simple jquery.
Just append the anchor to the end of the link.
Simply insert a link like:
Link to section on another page
Edit: Just noticed you're not getting this to work. What do your links look like, and what's the HTML with the ID on the target page?
Try this jQuery code:
$(document).ready(function() {
function hashScroll() {
// get URL Hash
var hash = window.location.hash;
// check if hash is set and not empty
if (hash != '') {
// scroll to hash ID after 10ms delay
setTimeout(function() {
$(document).scrollTop( $(hash).offset().top );
}, 10);
// debugging
console.log(hash);
console.log('offset:'+ $(hash).offset().top );
}
}
hashScroll(); // fire hash scroll function
});
Explanation:
This function will capture the URL hash (www.example.com/#hash), checks if it's not empty and then scrolls the page to the element with the ID which matches the hash after 10 ms. The delay is there to make sure browsers don't mess up the loading process.

Is it possible to make a link to a one page webpage to open and position itself at a specific article?

Is there a way to open a specific artical via an external link and focus on it when the links open on a one page wepage?
I have a webpage that shows content as you click on links by hiding and showing the divs. What i want is to make an external link to my webpage in the form of mywebpage/(div's name) and have the link open my page but showing the content of that div right away, instead of its usual opening content you would get when clicking on just the ordinary mywebpage link.
Is it possible? And how?
Short answer: yes.
Long answer: You will have to examine the URL's hash on page load and manually translate that into hidden or shown divs (or other positioning).
While you're at it, you could include browser history support when your divs are opened and closed.
Pulling apart what I did for http://www.tipmedia.com (Segment starts on line 322 of the page source)
//on page ready
$(document).ready(function() {
//examine hash
if(window.location.hash == "#thanks") {
//scroll to an anchor tag, slight delay to insure correct page height
setTimeout(function() {
$('html,body').animate({scrollTop:$("#contact").offset().top}, 0);
},500);
//hide and show necessary divs
$("#contactThanks").css({"display":"block"});
$("#contactIndex").css({"display":"none"});
$("#contactGeneral").css({"display":"none"});
$("#contactMeeting").css({"display":"none"});
$("#contactCareers").css({"display":"none"});
//clear the hash (not necessary for your use)
window.location.hash = "";
}
}
The history stuff is easy too, I used Modernizer.js for the best cross browser support, but it looks like this (non-Modernizer use is very similar)
//during the hide/show of new content...
//if history is available
if(Modernizr.history) {
//this data is whatever it is you wish to save
lastPageState = { div:divName, pos:amount, page:lastLoadedPage };
history.pushState(lastPageState, divName.substring(1,divName.length-6), "index.html");
}
//...
//then later, the popsate event handler
window.onpopstate = function(event) {
//examine event.state and do whatever you need to
//example segment starts line 989
//Whatever data you saved would be read here and you would do the appropriate action,
//hiding or showing divs, reloading AJAX content, etc.
}
Yes, you can use an anchor link.
So in your target page name the div with an id,say div id="target".
Then in the referring page use a link in this form
Referring Page:
GO to Target Info...
Target Page:
<div id="target">
...content...
</div>
FYI-"target" is just an example name, it could be anything...

Browser back button does not work for Anchor links

In the footer of my page there a few links that point to different sections on the same page using anchor tags (# appended to the URL of the page).
This works fine, just the browser back button does not work: I cannot move back to the previous page from where I had navigated to the anchored page.
The simple question here is, is it possible to move back to previous page after navigating in the anchored page a few times? If it is then please could you suggest how?
Anchored page: the page that has several sections marked by the id attribute that can be pointed to by a URL with #anchorId at the end.
I also faced the same problem see my question anchor links referring to the page sections not working on browser refresh, back and forward
But I had to do it the way normal links work so what I did was I manually go to that section by getting the element from the hash.
$(window).on('hashchange', function ()
{
var top = $(window.location.hash).offset().top;
$(window).scrollTop(top);
});
This works for forward and back buttons.
And for refresh also you need to do the same thing. Get the element from the hash and scroll to that element manually.
History and the Back Button.
In days of old, the back button did little more that go to the previous item in the browser's history. That's changed quite a bit since then, as it keeps its own history according to a somewhat simple set of rules. Good luck digging through standards docs to find it though.
UI/UX and why NOT to change expected behaviors.
Please reference w3c's 'don't brek the back-button before you go making changes to a browser's default behavior. Its like that for a reason, following mountains of debate and defining standards.
Ultimately, this is what browsers do, and so this is what the users expect. If you begin to subvert the behavior away from user's expectations, you're likely to start pissing off your users. When buttons and links repeatedly don't behave as expected, users will often just give up and leave your site.
Prevent Default.
If you really must alter the default behavior, the using javascript would be the best way to do it:
<a href="#id" onclick="return gotoAnchor(this);">
<script>
function gotoAnchor(elm) {
window.event.returnValue = false;
var url = location.href;
location.href = elm.href;
history.replaceState(null,null,url);
return false;
}
</script>
http://www.the-art-of-web.com/javascript/remove-anchor-links/
Visit that site. Scroll to the bottom and use test the anchors. It's doing what you want.
"The following code will parse your HTML page and override the function of any links that target anchor points on the same page. The link function will be replaced with a call to the scrollIntoView method of the target element:
document.addEventListener("DOMContentLoaded", function() {
var links = document.getElementsByTagName("A");
for(var i=0; i < links.length; i++) {
if(!links[i].hash) continue;
if(links[i].origin + links[i].pathname != self.location.href) continue;
(function(anchorPoint) {
links[i].addEventListener("click", function(e) {
anchorPoint.scrollIntoView(true);
e.preventDefault();
}, false);
})(document.getElementById(links[i].hash.replace(/#/, "")));
}
}, false);
if (document.referrer == "") {
window.open("index.php");
} else {
window.history.go(-1);
return false;
}

Javascript : Change the function of the browser's back button

Is there a way to make the user's back button on their browser, call a javascript function instead of going back a page?
You can't override the behaviour that if a user follows a link to your page, clicking Back will take them off it again.
But you can make JavaScript actions on your page add entries into the history as though they were clicks to new pages, and control what happens with Back and Forward in the context of those clicks.
There are JavaScript libraries to help with this, with Really Simple History being a popular example.
yes, you can. Use this js:
(function(window, location) {
history.replaceState(null, document.title, location.pathname+"#!/stealingyourhistory");
history.pushState(null, document.title, location.pathname);
window.addEventListener("popstate", function() {
if(location.hash === "#!/stealingyourhistory") {
history.replaceState(null, document.title, location.pathname);
setTimeout(function(){
location.replace("http://www.programadoresweb.net/");
},0);
}
}, false);
}(window, location));
That will redirect your back button to the location.replace you specify
I think this will do the trick.
you can write your custom code to execute on browser back button click inside onpopstate function.
This works in HTML5.
window.onpopstate = function() {
alert("clicked back button");
}; history.pushState({}, '');
I assume you wish to create a one-page application that doesn't reload the website as the user navigates, and hence you want to negate the back button's native functionality and replace it with your own. This can also be useful in mobile web-apps where using the back button inside apps is common to close an in-app window for example. To achieve this without a library, you need to:
1st. Throughout your application modify the window's location.hash instead of the location.href (which is what tags will do by default). For example, your buttons could fire on click events that modify the location.hash like this:
button.addEventListener('click', function (event) {
// Prevent default behavior on <a> tags
event.preventDefault()
// Update how the application looks like
someFunction()
// Update the page's address without causing a reload
window.location.hash = '#page2'
})
Do this with every button or tag you have that would otherwise redirect to a different page and cause a reload.
2nd. Load this code so that you can run a function every time the page history changes (both back and forward). Instead of the switch that I used in this example, you can use an if and check for other states, even states and variables not related to location.hash. You can also replace any conditional altogether and just run a function every time the history changes.
window.onpopstate = function() {
switch(location.hash) {
case '#home':
backFromHome()
break
case '#login':
backFromLogin()
break
default:
defaultBackAnimation()
}
}
This will work until the user reaches the first page they opened from your website, then it will go back to new tab, or whatever website they were in before. This can't be prevented and the teams that develop browsers are patching hacks that allow this, if a user wants to exit your website by going back, they expect the browser to do that.
If you are creating a one-page web application, where your html body has different sections and you want to nevigate through back button to the previous section you were. This answer will help you.
Where your website sections are differentiated by #. Such as:
your-web-address.com/#section-name
Just follow a few steps:
Add a class and a id in every section in you html body. Here it is ".section"
<section class="section" id="section-name">...</section>
Add two CSS class in your linked css (e.g., style.css) file to your html (e.g., index.html) file such:
.section .hide {
display: none;
}
.section .active{
dislplay: block;
}
Add this JavaScript function in you linked .js (e.g., main.js) file to your html file.
window.onpopstate = function () {
if (location.hash !== "") {
const hash = location.hash;
// Deactivating existing active 'section'
document.querySelector(".section.active").classList.add("hide");
document.querySelector(".section.active").classList.remove("active");
// Activating new 'section'
document.querySelector(hash).classList.add("active");
document.querySelector(hash).classList.remove("hide");
}
}

Categories