I'm using a HTML anchor tag for a "back to top" link in the footer of my web page:
Back to top
At the top of the page I inserted another anchor tag in the HEAD tag:
<a id="#top"></a>
I've also implemented AngularJS by declaring my app on the HTML tag of index.html:
<html lang="en" ng-app="myApp">
... and I'm using routing as follows:
angular.module('myApp', [
'ui.router'
])
.config(['$stateProvider', '$locationProvider', function($stateProvider, $locationProvider) {
$stateProvider
.state('home', {
url: '/'
});
$locationProvider
.html5Mode({
enabled: true,
requireBase: false
});
}]);
I intend in the future to make the page a full-fledged AngularJS app, but for now all this is a minimal declaration (so controllers, etc., are not included yet).
However, when I add a minimal AngularJS declaration as such, I observe strange behavior when clicking on the "back to top" link in the footer. The first time I click on this link, the page scrolls to the top as intended.
But the second time I click on it, nothing occurs. To sum up, the link doesn't work when clicking on it twice in a row.
Might anyone have an explanation for this behavior? When I remove the Angular code, the link behaves as it should.
Yes if you're using conventional anchor tag with href hash linking, then it'll conflict with routing. In angular there's service called $anchorScroll to do that, so your html should be:
<a ng-click="goTo('top')" class="footer__top">Back to top</a>
And in controller of that view have function goTo as:
$scope.goTo = function(id) {
$location.hash(id);
$anchorScroll();
};
Make sure you've injected $location & $anchorScroll as dependencies inside controller.
Plunker
Now above solution is for having hash linking on same page/route. But i you need such in other route then you can handle that centrally on event of $routeChangeSuccess or $stateChangeSuccess or in recent ui-router version Transition.onSuccess as:
$rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
$location.hash($routeParams.scrollTo);
$anchorScroll();
});
And in some other view have anchor tags like:
route1 / Foo
route2 / Bar
Plunker
Related
I have a page with a few anchors. When a user clicks an anchor, the anchors work, and user is taken to the correct location.
If a user tries to refresh the page, it retains the anchor ID in the URL window and so naturally, when refreshing, it does not go back to the top of the page.
I think it would be more user friendly to go back to the top of the page on a refresh.
How would I achieve this?
My page currently is primarily using bootstrap, css, jquery, javascript, and php.
I think I need to set up some code so that after clicking the anchor, it removes the anchor from the url window, so that if someone refreshes, they'd be refreshing just the initial page state without an anchor, but I don't know how to begin. Or maybe I'm over thinking this and there's some way to always go to top of page on a refresh regardless of anchors or not. I'm not too code savvy.
Right now my code is like this...
An example of one of my anchors:
<a class="hoverlink" href="#firefighter"><li style="float:left; margin-right:1em; color:white; background-color:red" class="appao-btn nav-btn">Fire Fighter</li></a>
One of the elements for example that the anchor will jump to:
<div style="min-height:10px;" name="firefighter" id="firefighter" class="anchor"><p style="min-height: 10px;"> </p></div>
CSS style on my anchors:
.anchor:target { height:200px; display: block; margin-top:-2em; visibility: hidden;}
Actual Results With My Code: Page Refresh Stays At Anchor Location
Desired Results: Page Refresh Goes To Top Of Page
After some searching, I found a solution that almost works for me:
<script>
window.onbeforeunload = function () {
window.scrollTo(0, 0);
}
</script>
But it creates a flickering effect that doesn't look the best such as my example site at
https://graceindustries.com/gracetest/Grace%20Industries%20Website%20Design%202019%20Alternate%20Version/documentation.html
Anyone know how to remove the "flicker"?
You can try this (with the .some-anchor is the class for all a tag that points to some destinations within the page).
$('.some-anchor').click(function() {
var target = $(this).attr("href");
$('html, body').animate({
scrollTop: $("" + target).offset().top
}, 1000);
return false;
});
The "return false;" or preventDefault() event method will prevent the page from flickering. As I observed this does not make the # to the URL so refreshing is not a problem.
Other helpful answer: jQuery flicker when using animate-scrollTo
Navigating to page content using URL Fragments (#someLink) in anchor tags is a core part of the HTML specification. The standard implementation in most (if not all) web browsers is to add the fragment to the address bar. The fragment is part of the URL and therefore, when the page is refreshed the browser scrolls to the element with that ID. Most users will be familiar with this behaviour, even if they don't understand how or why it works like that. For this reason, I'd recommend not working around this behaviour.
However, if it is absolutely necessary, the only way to achieve the result you're looking for is to not use URL fragments for navigation and use JavaScript instead, therefore not putting the fragment in the URL in the first place. It looks like the Element.scrollIntoView() method might do what you're looking for. Rather than having
Click me
you'd use
<a onclick="document.getElementById('element1').scrollIntoView();">Click me</a>
or even better, implement this in an external JS file. If you experience issues due to the element not having the href attribute, you could always add an empty fragment href="#".
You can remove the id from the url right after the user click on the anchor tag
history.scrollRestoration = "manual" will set the scroll to the top of the page on refresh
<a onclick="removeAnchorFormURL()" href="#sec-2">here</a>
<script>
history.scrollRestoration = "manual";
const removeAnchorFormURL = () => {
setTimeout(() => {
window.history.replaceState({}, "", window.location.href.split("#")[0]);
}, 100);
};
</script>
window.location docs
location.href docs
location.replace docs
scrollRestoration docs (check it for info on scrollRestoration compatibility)
For a singlepage website, how do some of those websites strip that #section id from the url?
For example: http://www.formationstone.com/
There's no /#about-us; it's just showing the root domain on every subsesuent click from their menu.
I think it may have to do with htaccess, but I can't find the relevant code where I only want my root domain showing on all links.
They are not stripping it, they just use a javascript onclick event to prevent the actual default event of the link and scroll to the headline. If you go to http://www.formationstone.com/#about the hash stays.
Let's have a look at the source code.
This is the link in the menu:
WHO WE ARE
And this is the DOM object it scrolls to
<section id="about"> <h2>Who We Are</h2> ... </section>
And the click listener is on line 128 of http://www.formationstone.com/wp-content/themes/Ignyte/includes/main-scripts.js?ver=4.9.5 line
jQuery('#menu a[href]').on('click', function(event) {
if ($(this).parent().hasClass('telephone')) {}else{
var target = jQuery(this).attr('href');
if( target.length ) {
event.preventDefault();
jQuery('html, body').animate({
scrollTop: jQuery(target).offset().top+75
}, 1000);
}}
});
It takes the href attribute of the clicked link (which is #about) and uses it as a jQuery selector, e.g. $('#about') which is the <section>. And then it scrolls 75px below these section header with a 1 second animation. The thing you are looking for is in line 145: event.preventDefault();. This stops the browser from executing the default event, which would be calling the URL #about.
A side note: There are two ways to make a direct call to http://www.formationstone.com/#about work. With a named anchor:
<section id="about">
<a name="about"></a>
<h2>Who We Are</h2>
</section>
Or with a hash listener (that's what they are using, I just couldn't find it easily). It would be something like:
$(document).ready(function() {
if (window.location.hash) {
var target = jQuery(window.location.hash);
if( target.length ) {
// scroll immediately without animation
jQuery('html, body').animate({
scrollTop: jQuery(target).offset().top+75
});
}
}
});
Everything past the # in a URL is mainly for the browser's benefit, not the server. .htaccess doesn't have much to do with this issue.
I'm not sure what SPA technology you're using, but using Angular as I do, the way I'd avoid having an anchor tag show in the URL is by not using Angular's router -- simply show and hide sections of your SPA by changing the visibility of the various sections directly.
One disadvantage of doing this is that a user can't bookmark a particular section of your app and return there reliably based on the URL they've bookmarked.
I'm trying to create a website that meets certain accessibility standards with tab clicks. I have a navigation menu on the left side of the screen and my users are requesting a "Skip to content" link so they don't have to constantly cycle through multiple links to get to where the content is.
However, I'm using AngularJS in my web app, and if I use the standard skip to content functionality (example: http://accessibility.oit.ncsu.edu/training/accessibility-handbook/skip-to-main-content.html), it won't work. I'm already using anchors (with #s) for the Angular code.
Is there any other way to implement this? I have a particular div tag that I would like the tab selection to go to. It should go to one of the elements inside the div.
I've used angular-scroll to good effect before. It's lightweight (8.5kB), easy to use, and even takes care of scrolling animations for you. It also meets accessibility standards, as the Tab key can be used to navigate just like a normal anchor tag.
Implement like this:
JS
angular
.module('app', ['duScroll'])
.controller('MainCtrl', function ($scope, $document) {
//Controller logic here
}
HTML
Navigation Link
<!-- further down the page -->
<div id="nav-one">
Content goes here.
</div>
Working CodePen for reference: http://codepen.io/Pangolin-/pen/dPQRZa
I recently worked with $anchor$croll and have some tips for you.
In your template:
Go
...
<div id="hello-scroll">Hello Scroll!</div>
In your controller:
angular
.module('someModule', [])
.controller('scrollCtrl', function($scope, $timeout, $timeout, $anchorScroll) {
/**
* #name scrollTo
* #desc Anchor scrolling within page using $anchorScroll
* #param {String} hash - Element ID.
* #return void
*/
$scope.scrollTo = function(hash) {
$location.hash(hash);
$timeout(function() {
$anchorScroll();
}, 100);
}
});
The reason I added the $timeout call is because when I tested it without it, the $scrollTo didn't seem to work. It seems that the call to $location.hash(hash) takes some small time to process, hence the 100 ms wait.
I want to know how in this web site, when I hover the mouse over report ad of the page, it show the link as ....com/***/***#report-item, but when I click on it, it shows me a pop-up. but still the original URL is not changing to ....com/***/***#report-item?
I checked the source of the page, and it shows the link code as:
<span><i class='ico-report'></i>Report Ad</span>.
That is because they prevent the browser from doing what it is meant to do (default event).
Here is the JavaScript code for that:
event.preventDefault();
You can include that inside the element, something like
Link
And inside the function, add that code. It would prevent the default function; that is to change the URL.
Maybe they're using jQuery for that because I can't see any sort of onclick="" inside the element. So what they might be doing would be this:
Generate Report
and the jQuery code would be as:
$('a.report').click(function () {
event.preventDefault(); // prevent the default function of the hyperlink
/* show the pop up */
});
This way, the website is preventing the default function and is using that link to do some other function.
Here is a fiddle for that: http://jsfiddle.net/afzaal_ahmad_zeeshan/3zPd6/
To get the Elements Attribute
To get the element's attribute in JavaScript you use the following code
document.getElementById("hyperlinkId").href;
This would get you the href of the hyperlink. And you can reference it in your call.
I have just solved an issue I had which couldn't be solved (to my limited knowledge) with an ActionLink so I used a regular hyperlink.
When these two links are rendered on the page, they are styled very similar to each other as they pass the same css conditions, however they aren't exactly the same in two ways that I have noticed:
The text is selectable on the hyperlink where is isn't on the ActionLink
When hovering over the ActionLink, the cursor changes to a hand rather than a pointer, the hyperlink stays with the pointer.
I was under the impression that an ActionLink renders a hyperlink which would explain why they are both styled by the css, but there are obviously some differences.
Does anyone know how to fix this, or suggest another solution to replacing an ActionLink with a hyperlink to call an AJAX function (which returns a PartialView)?
UPDATE
This is the rendered HTML. The first is the hyperlink, then second is the ActionLink.
<li><a id="load-partial">Test</a></li>
<li>Contact</li>
The reason I have an id in the hyperlink is so that it will run the following script to create the view in a specific div. I can't seem to replicate this using an ActionLink as it just return the view on it's own without the Layout views and completely unformatted.
<script>
$(document).ready(function () {
$('#load-partial').click(function () {
$.ajax({
url: '/Contact/List/',
datatype: 'html',
success: function (data) {
$('#adminmain').empty().html(data);
}
});
});
});
</script>
Thanks very much.
An ActionLink is nothing more than a server-side helper method that emits an HTML A tag. There is nothing else special about it.
If you are seeing differences in behavior / rendering, view the HTML source that is rendered and look for differences there.
There are very few things you cannot accomplish with an ActionLink that would require you to hand-code the A tag. Did you post a separate question about the problem you could not solve using it?
UPDATE (based on your posted HTML)
The hyperlink is missing a href so it will not do anything when clicked.
If you need to add an ID to your ActionLink, you can do something like:
#Html.ActionLink("Contact (this is the text)", "List", "Contact",
new { someQueryStringParameter = 42 },
new { id="load-partial" })
That example shows how to generate
<a id="load-partial" href="/Contact/List?someQueryStringParameter=42">Contact (this is the text)</a>
Keep in mind the ID should be unique on a given HTML page.