So I want to be able to have a different styling for a link after you go to the page it's clicked on. I have been using the following code:
$(document).ready(function(){
var url = document.URL;
function contains(search, find) {
return search.indexOf(find) !== -1;
};
$('#topbar a').each(function(){
var link = $(this).attr('href');
var answer = contains(link,url);
if(answer === true){
$(this).addClass('check');
}
else{
$(this).addClass('nocheck');
};
});
});
This goes through the links in my navigation bar and checks if it's on the same page as the link, and it works, but I can't use it in one specific case: Random.
I have a link that generates a random page from the pages I have, so it does not have a specified link as it links to a function to randomly generate the page (note: I cannot change the function or access information from it).
So how can I detect that the random link was clicked previously so i can give it the .check class
If i understand your question correctly, your function does not work for the randomlink because this has a href like http://mysite.com/random, but the server will actualy redirect you to a different page, like http://mysite.com/about-me, and therefore the url of the active page does not match the href of the random button, and it will not get the active state.
One could argue if you would want it to get the active state, cause clicking it again would not (likely) bring you to the same page, but that is besides the question.
I can see to ways to solve this.
server side:
In stead of redirecting to ie. http://mysite.com/about-me in the random function, you could also redirect to http://mysite.com/about-me?random. By adding this get variable, you should not change the behaviour of the link (unless you have some very strict controller, or that variable is actually used, but that is unlikely). You could then detect with javascript if that variable is present in the url, and then activate the random button.
Something like this:
$(document).ready(function(){
var url = document.URL;
// check for random
if (url.indexOf('?random') >= 0) {
$('#topbar a.random').addClass('check');
}
// check all other
$('#topbar a:not(.random)').each(function(){
if($(this).attr('href').indexOf(url) >= 0){
$(this).addClass('check');
}
else{
$(this).addClass('nocheck');
};
});
});
cookie:
If you do not have acces to the server side random controller, you could do it entirely with javascript, by the use of a cookie (the only way I know to make a variable persist trough page requests).
On click of the random button, you would first set a random cookie to true with javascript, before letting the actual link do it's thing. On entering the page, you could then do a similar check as in my previous option, but in stead of the url you check if the cookie is tre. If so, you change it to false (so on the next page request the random button will not be active again) and set the randombutton to active.
As I believe the first solution is to be preferred (cookies should only be used as a last resort, they are sent on every page request, which means extra data, and your user might have cookies disabled, or there might be laws against using cookies, so the function could not always work), I will not write the javascript yet. Feel free to ask if you prefer this solution and need further help however.
Related
We want to have a back button in our site
but history.back in javascript does not help us.
We need this function only run on the site and if the user comes from other site, clicking the return button on the previous site should not return.
In fact, we want a return button to run on our site only.
my code is
<i class="fas fa-arrow-left"></i><span class="btn-text">Back</span>
This only works for your own made back button and won't work with the browser back button
There is two ways to achieve that: a simple but not always reliable method and a complex one but always good.
1- The simple method
You use document.referrer and ensure the domain is yours before calling history.back().
2- The complex method
You could register a JavaScript function on page load to get the first URL the internaut land which you could store using history.pushState. Before calling the back function, you could ensure this is not that page. Though, this idea is not complete as the user could probably have landed on this page twice. i.e. Home->Product->Home. I'll let you search for further code that would let you counter this problem.
This code checks the history of back button of the browser on its click event:
$('#backbtn').click(function () {
if (document.referrer.includes(window.location.hostname)) {
window.history.back();
} else {
window.location.href = "/your/path";
}
});
I would like to add a button that will take a user back a page OR if a user used direct url to get to that page (so, .back() would take them back to google for example) - a user will be redirected to my homepage.
Looks like javascript:history:back() or history.go accept step attributes only (how many pages we can go back) and that is it. Will I have to tap into session or is there a way to do it with history object?
You can check the referrer url with document.referrer, to see what was the previous page where the user come from. It can be empty that means user come from direct link, or clicked the link from other app links skype etc...
In the example I used https://stackoverflow.com as an example, but you can make it more universal if you use with location.origin more info
As #Jonas W. Mentioned in the comments, be sure you check the full domain in the right position in the referrer, because of security reasons.
function go() {
if (document.referrer.indexOf("https://stackoverflow.com/") === 0) {
history.back();
} else {
window.location.href = "https://stackoverflow.com";
}
}
document.querySelector('button').addEventListener('click', go);
<button>back</button>
SCENARIO
The web app workflow is the following:
Someone clicks on a a href element into a page. http://example.org/
The link is followed and then another page within the site is reached. http://example.org/page-2/
The link URL also contains a hash var.
(This hash var is what I intended to use in order to achieve the next point)
There is a content grid that must show the wanted part, this object was built with an out of the box CMS, so I preferably don't want to modify it. This also, only works when the user clicks on the very button filter.
(This filter is based entirely on events and not on "GUI visible" locations, thus I'm not able to call for an specific filter from the very url, the previous object -there was a previous object, yes- worked really good with hashes from URL, but the new doesn't.)
The content grid filter elements don't have any ids, they just have a data custom attribute to be identified.
And that's it.
The workaround is intended to be like this:
$( window ).load(function() {
var filter = window.location.hash.substr(1);
if(filter == "keywordA") {
$('a[data-filter=".cat-1"]').trigger('click');
}
if(filter == "keywordB"){
$('a[data-filter=".cat-2"]').trigger('click');
}
if(filter == "keywordC"){
$('a[data-filter=".cat-3"]').trigger('click');
}
if(filter == "keywordD"){
$('a[data-filter=".cat-4"]').trigger('click');
}
if(filter == "keywordE"){
$('a[data-filter=".cat-5"]').trigger('click');
}
});
Then, dark and unknown forces comes into place, because when I enter this in the address bar: http://example.org/page-2/#keywordD the DOM works well, as expected. The content grid displays exactly what I want.
But when I try to reach the same link but from an a href element within http://example.org/ it just doesn't do anything at all.
FURTHER EXPLANATION
I used window.load because that way the function is forced to be executed once everything is settled in the DOM, and after every single code instance of $(document).ready() functions, because the website already works with many of these.
Here's the problem:
When navigating from the a link http://example.org/page-2/# to a different link that is the same page, but has a different hash var, like http://example.org/page-2/#keywordD, the site doesn't actually reload. This is default behaviour, because it's meant to jump to the element on the page with the id of the hash.
Luckily, there is an event for hash changes on the site.
'onhashchange'
Now depending on how your filtering works, you might want to call a function that does all the filtering (the one that does it on loading the page), or, if this is a server-side CMS thing, you might want to reload the page.
$(window).bind('hashchange', function(e) {
// Enter your filter function here
doFiltering();
});
or if reloading the page is more appropritate.
$(window).bind('hashchange', function(e) {
document.location.reload();
});
I don't quite understand what you mean by "This filter is based entirely on events and not on 'GUI visible' locations", so you might want to elaborate a little more in a comment, if I misunderstood you, but I hope either one of these soloutions work for you.
THE ANSWER
Somehow I was triggering the event before the handler was attached, despite the window.load event is supposedly intended to trigger functions when all the DOM is entirely loaded.
https://stackoverflow.com/a/2060275/1126953
Kudos to Noah.
Based on the previous answer I could manage to set the desired behavior as it follows:
$( window ).load(function() {
setTimeout(function() {
var filter = window.location.hash.substr(1);
if(filter == "keywordA") {
$('a[data-filter=".cat-1"]').trigger('click');
}
if(filter == "keywordB"){
$('a[data-filter=".cat-2"]').trigger('click');
}
if(filter == "keywordC"){
$('a[data-filter=".cat-3"]').trigger('click');
}
if(filter == "keywordD"){
$('a[data-filter=".cat-4"]').trigger('click');
}
if(filter == "keywordE"){
$('a[data-filter=".cat-5"]').trigger('click');
}
},10);
});
Just a simple delay.
Many thanks for your time Stefan.
Is there any way to use JavaScript's OnUnload() function to find out which URL the user is navigating away to?
For example, if my code is in page1.html, and the user clicks a link to http://example.com, is there any way for JavaScript code present in page1.html, to retrieve the URL "http://example.com" and display/store it before the page unloads?
I am able to do this if I invoke a function through my link by using its OnClick, but I cannot find a way to do this otherwise. (I can post my code for that if needed, but it does meet my business requirement)
EDIT : This looks to be impossible, since my business requirement demands that I do not make any change to the content of the page, excepting the adding in of a javascript file where this code is present.
Ignore onBeforeUnload/onUnload, you don't need that. You can do it with a simple click handler like this:
$('a').on('click', function(e)
{
e.preventDefault();
var destinationLink = $(this).attr('href');
$.post('/your/analytics/url', {link:destinationLink}, function()
{
// Success
window.location.href = destinationLink;
});
});
This will stop any link from working until it's been submitted to your analytics so it's not ideal - you need to make sure what ever is receiving the data does so as quickly as possible.
You could replace the current url of the clicked link.
That will allow you to call your server to do the check of the clicked url, and then redirect it.
The code bellow change the url of the clicked link only for a couple of microseconds
$("a").on("click",function(e){
// Save the current link
var h = this.href;
//Change the link of the current a
this.href = "http://www.example1.com/redirect.php?url="+encodeURI(h);
// replace the href with the original value on the next stack
setTimeout((function(my_link){
return function(){
my_link.href = h;
};
})(this),0);
});
my link
Say I'm on a page called /example#myanchor1 where myanchor is an anchor in the page.
I'd like to link to /example#myanchor2, but force the page to reload while doing so.
The reason is that I run js to detect the anchor from the url at the page load.
The problem (normally expected behavior) here though, is that the browser just sends me to that specific anchor on the page without reloading the page.
How would I go about doing so? JS is OK.
I would suggest monitoring the anchor in the URL to avoid a reload, that's pretty much the point of using anchors for control-flow. But still here goes. I'd say the easiest way to force a reload using a simple anchor-link would be to use
where in place of $random insert a random number (assuming "dummy" is not interpreted server side). I'm sure there's a way to reload the page after setting the anchor, but it's probably more difficult then simply reacting to the anchor being set and do the stuff you need at that point.
Then again, if you reload the page this way, you can just put myanchor2 as a query parameter instead, and render your stuff server side.
Edit
Note that the link above will reload in all circumstances, if you only need to reload if you're not already on the page, you need to have the dummy variable be more predictable, like so
I would still recommend just monitoring the hash though.
Simple like that
#hardcore
an example
Another way to do that is to set the url, and use window.location.reload() to force the reload.
<a href="/example#myanchor2"
onclick="setTimeout(location.reload.bind(location), 1)">
</a>
Basically, the setTimeout delays the reload. As there is no return false in the onclick, the href is performed. The url is then changed by the href and only after that is the page reloaded.
No need for jQuery, and it is trivial.
My favorite solution, inspired by another answer is:
myanchor2
href link will not be followed so you can use your own preference, for example: "" or "#".
Even though I like the accepted answer I find this more elegant as it doesn't introduce a foreign parameter. And both #Qwerty's and #Stilltorik's answers were causing the hash to disappear after reload for me.
What's the point of using client-side JS if you're going to keep reloading the page all the time anyways? It might be a better idea to monitor the hash for changes even when the page is not reloading.
This page has a hash monitor library and a jQuery plugin to go with it.
If you really want to reload the page, why not use a query string (?foo) instead of a hash?
Another option that hasn't been mentioned yet is to bind event listeners (using jQuery for example) to the links that you care about (might be all of them, might not be) and get the listener to call whatever function you use.
Edit after comment
For example, you might have this code in your HTML:
example1
example2
example3
Then, you could add the following code to bind and respond to the links:
<script type="text/javascript">
$('a.myHash').click(function(e) {
e.preventDefault(); // Prevent the browser from handling the link normally, this stops the page from jumping around. Remove this line if you do want it to jump to the anchor as normal.
var linkHref = $(this).attr('href'); // Grab the URL from the link
if (linkHref.indexOf("#") != -1) { // Check that there's a # character
var hash = linkHref.substr(linkHref.indexOf("#") + 1); // Assign the hash to a variable (it will contain "myanchor1" etc
myFunctionThatDoesStuffWithTheHash(hash); // Call whatever javascript you use when the page loads and pass the hash to it
alert(hash); // Just for fun.
}
});
</script>
Note that I'm using the jQuery class selector to select the links I want to 'monitor', but you can use whatever selector you want.
Depending on how your existing code works, you may need to either modify how/what you pass to it (perhaps you will need to build a full URL including the new hash and pass that across - eg. http://www.example.com/example#myanchor1), or modify the existing code to accept what you pass to it from you new code.
Here's something like what I did (where "anc" isn't used for anything else):
And onload:
window.onload = function() {
var hash = document.location.hash.substring(1);
if (hash.length == 0) {
var anc = getURLParameter("anc");
if (anc != null) {
hash = document.location.hash = anc;
}
}
}
The getURLParameter function is from here
If you need to reload the page using the same anchor and expect the browser to return to that anchor, it won't. It will return to the user's previous scroll position.
Setting a random anchor, overwriting it and then reloading seems to fix it. Not entirely sure why.
var hash = window.location.hash;
window.location.hash = Math.random();
window.location.hash = hash;
window.location.reload();
Try this its help for me
<a onclick="location.href='link.html'">click me</a>
In your anchor tag instead of
click me
As suggested in another answer, monitoring the hash is also an option. I ended up solving it like this so it required minimal code changes. If I had asked the original question, I believe I would have loved to see this option fully explained.
The added benefit is that it allows for additional code for either of the situations (hash changed or page loaded). It also allows you to call the hash change code manually with a custom hash. I used jQuery because it makes the hash change detection a piece of cake.
Here goes!
Move all the code that fires when a hash is detected into a separate independent function:
function openHash(hash) {
// hashy code goes here
return false; // optional: prevents triggering href for onclick calls
}
Then detect your hash for both scenarios like so:
// page load
$(function () {
if(typeof location.hash != typeof undefined) {
// here you can add additional code to trigger only on page load
openHash(location.hash);
}
});
// hash change
$(window).on('hashchange', function() {
// here you can add additional code to trigger only on hash change
openHash(location.hash);
});
And you can also call the code manually now like
Magic
Hope this helps anyone!
Try this by adding simple question mark:
Going to Anchor2 with Refresh