Reputation: 159
I'm trying to run an ajax function when links are clicked, but I need to exclude links to anchors on the same page so I don't try to re-load in the page content when I'm simply scrolling down to a different part of the same page.
I know I can test if the href include a hash but that's not good enough:
if (href.indexOf("#") === -1)
Because I will have links that go to another page AND scroll to a local anchor. So I need to test if the href points to the current page AND includes a hash. And in that case I would exclude it from the function. But if it points to a different page and includes a hash it should still be included.
How can I achieve this with jQuery?
Upvotes: 10
Views: 19642
Reputation: 893
Here you go,
// extract hash from URL
const hash = new URL(`https://example.com/#your-anchor`).hash; // return => #your-anchor
// if hash exists in the URL, and the anchor is also exists
if(hash.length && document.querySelectorAll(hash).length){
// do something
}
Upvotes: 0
Reputation: 15491
You do not need jQuery for this. Just use regex in Javascript.
if(/^#/.test(href)) { // .test() returns a boolean
/* do not run AJAX function */
} else {
/* run the AJAX function */
}
Explanation:
^#
is the regex. //
is where you wrap your regex in. ^
means at the beginning of the string and #
is what you are looking for. .test()
is a javascript function that executes the regex on a given string and return a boolean value.
Read up: RegExp.prototype.test()
- JavaScript | MDN
Update 1:
In case if the href
is not starting with a #
but it still points to the same webpage, your problem is reduced to checking if a string is a substring of another string. You can make use of window.location.href
and .indexOf()
to achieve this:
if(href.indexOf(window.location.href) > -1) {
/* do not run AJAX function */
} else {
/* run the AJAX function */
}
window.location.href
returns the URL of the webpage that you are on and href.indexOf(window.location.href)
checks if window.location.href
is substring of href
;
Example: https://www.example.com/page1
is a substring of https://www.example.com/page1#myDiv
Read up:
Update 2:
Good find by @Tib. My code in update above was not checking if the hostnames are the same. I have fixed it below:
if(<hostnames are the same>) { // make use of window.location.hostname here to get hostname of current webpage
if(href.indexOf(window.location.href) > -1) {
/* do not run AJAX function */
} else {
/* run the AJAX function */
}
} else {
/* do not run AJAX function */
}
Upvotes: 15
Reputation: 3128
/**
* Checks if the href belongs to the same page and returns the anchor if so.
*
* @param {String} href
* @returns {Boolean|String}
*/
function getSamePageAnchor (href) {
var link = document.createElement('a');
link.href = href;
/**
* For IE compatibility
* @see https://stackoverflow.com/a/24437713/1776901
*/
var linkCanonical = link.cloneNode(false);
if (
linkCanonical.protocol !== window.location.protocol ||
linkCanonical.host !== window.location.host ||
linkCanonical.pathname !== window.location.pathname ||
linkCanonical.search !== window.location.search
) {
return false;
}
return link.hash;
}
Upvotes: 2
Reputation: 418
This is my take, much slimmer :-
$('a[href*=\\#]').on('click', function (event) {
if(this.pathname === window.location.pathname){
// Do something
}
});
Upvotes: 17
Reputation: 1253
Supported in all browsers:
"use strict"; // Start of use strict
$('a').bind('click', function(event) {
if (this.pathname == window.location.pathname &&
this.protocol == window.location.protocol &&
this.host == window.location.host) {
alert('links to same page');
event.preventDefault();
} else {
alert('links to a different page');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#same-page">Same Page</a>
<br>
<a href="/users/913950#page">Other Page</a>
Upvotes: 8
Reputation: 1509
Far from perfect, but works for me. Don't forget to use jQuery.
Have fun with it:
jQuery('a').on('click',function (e) {
var current = window.location.href.split('#')[0];
var goto = jQuery(this).attr('href').split('#')[0];
if (current == goto && this.hash) {
e.preventDefault();
var target = this.hash;
var $target = jQuery(target);
if($target.length){
jQuery('html,body').stop().animate({
'scrollTop': $target.offset().top
}, 900, 'swing');
}
}
});
jQuery('a[href^=#]:not([href=#])').on('click',function (e) {
e.preventDefault();
var target = this.hash;
var $target = jQuery(target);
if($target.length){
history.pushState( null, jQuery('#title').html() , target);
jQuery('html,body').stop().animate({
'scrollTop': $target.offset().top }, 900, 'swing');
}
});
jQuery('a[href=#]').on('click',function (e) {
e.preventDefault();
history.pushState( null, jQuery('#title').html() , location.href.replace(location.hash,""));
jQuery('html,body').stop().animate({
'scrollTop': 0
}, 900, 'swing');
});
Upvotes: 2