jquery Scroll to class name - javascript

I have the Html code like below,
<div data-stored="storenow" data-save="save" class="saveIcon" data-unique="game">Save</div>
And I write the jquery to scroll to the gameNo 456 like below.
var container = $("html,body");
var scrollTo = $(this).find('.saveIcon').attr('data-unique', 456);
container.animate({
scrollTop: scrollTo.offset().top - container.offset().top + container.scrollTop()
});
I am using jQuery version 1.9. I am getting error in console:
Cannot read property 'top' of undefined
Is that not possible to scroll to class name instead of id?
But it is working fine in Firefox. But not in chrome or IE.
I try to find the solutions from stackoverflow. But all other solutions are different than my case.

You are not targeting a DOM object, you are targeting a string.
scrollTo = $(this).find('.saveIcon').attr('data-unique', 456); -> this is wrong
So, while you are trying to target an element, you are actually setting the 'data-unique' to the '.saveIcon' element.
Try this:
scrollTo = $('.saveIcon');
Working code:
var $container = $("html,body");
var $scrollTo = $('.saveIcon');
$container.animate({scrollTop: $scrollTo.offset().top - $container.offset().top + $container.scrollTop(), scrollLeft: 0},300);

have you looked at scroll to view function?
https://developer.mozilla.org/en-US/docs/Web/API/element.scrollIntoView
element.scrollIntoView(true);

these two codes worked for me like a charm this first will take to scroll to the top of the page but if you want to scroll to some specific div use the second one with your div id.
$('body, html, #containerDiv').scrollTop(0);
document.getElementById('yourDivID').scrollIntoView();
If you want to scroll to by a class name use the below code
var $container = $("html,body");
var $scrollTo = $('.main-content');
$container.animate({scrollTop: $scrollTo.offset().top - $container.offset().top +
$container.scrollTop(), scrollLeft: 0},300);

I am using following plain js, please try if you can use it in you codes:
$('a.smooth-scroll[href*=#]:not([href=#])').click(function () {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});

Related

jQuery: Make smooth scroll function work after loading page/navigating to the page

I've got the code below in our boilerplate that seems to work fine in the current setup. It scrolls to the section on the page when you click the navigation menu link or a link in a slick slider. What I found hard to solve is making it work when navigating from another page back to the homepage. It'll add the #discover hash to the url just fine, for example, but it won't register it for some reason.
It's been a while since I properly used jQuery 😅.
I've already added the standard on document ready code around the function hoping it would be that, but no dice. Hope anyone can clue me in about what's happening here.
$(function(){ });
/*
Only enable this when you want smooth scrolling!
Usage:
- Give the anchor you want to scroll to a certain position a href which starts with # and the class "scroll" ()
- Give the container you want to scroll to a name (<section name="container"></section)
- ???
- profit
*/
const scrollOffset = 0 // the amount of pixels the animation should scroll "extra" (When you have a sticky navigation for example)
$(function () {
$(
'.menu__item a[href*="#"]:not([href="#"]), .slider-list__link[href*="#"]:not([href="#"])'
).click(function () {
if (
location.pathname.replace(/^\//, '') ==
this.pathname.replace(/^\//, '') &&
location.hostname == this.hostname
) {
var target = $(this.hash)
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']')
$('body').removeClass('no-scroll')
$('.navbar').removeClass('navbar--is-open')
if (target.length) {
setTimeout(() => { // This is used to prevent the animation from the menu closing from interfering with the scrolling animation. It could mess up the offsets otherwise
$('html, body').animate(
{
scrollTop: target.offset().top + scrollOffset, // Scroll to the target
},
400
)
return false
}, 500)
}
}
})
})

jQuery smooth scroll anchor links with fixed header and WP admin bar

I am using some JavaScript to create a smooth scroll effect to achnor links. The site has a fixed header so the content needs to be offset by whatever the height of the header is (this varies due to #media rules). On top of this when the user is logged in to WordPress the content needs to be offset further by the height of the WP admin bar (again, the height of this vaires depending on screen size).
I have set up two variables in my script to separately get the height of both these elements:
var headerHeight = $('header').height();
var adminbarHeight = $('#wpadminbar').height();
Further on in the script I want to offset the top by the height of the header plus the height of the admin bar if it exists (i.e. if a user is logged in).
$('html, body').animate({scrollTop: target.offset().top - headerHeight - adminbarHeight }, 500,
I am trying to offset by the headerHeight and the adminbarHeight but this is not working for me. If I remove 'adminbarHeight' it works but then it does not look correct for logged in users.
Is there something wrong with my syntax? Or perhaps I need to create an if statement to check if the adminbarHeight is greater than 0?
The full script I am enqueueing in my WP child theme is below:
( function( $ ) {
'use strict';
$('a[href*="#"]')
.not('[href="#"]')
.not('[href="#0"]')
.click(function(event) {
var headerHeight = $('header').height();
var adminbarHeight = $('#wpadminbar').height();
if (
location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '')
&&
location.hostname == this.hostname
) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
event.preventDefault();
$('html, body').animate({scrollTop: target.offset().top - headerHeight - adminbarHeight }, 500,
function() {
var $target = $(target);
$target.focus();
if ($target.is(":focus")) {
return false;
} else {
$target.attr('tabindex','-1');
$target.focus();
};
});
}
}
});
}( jQuery ) );
Any help will be greatly appreciated! I am new to JavaScript so apologies if this is a really obvious error.
Thanks,
Chris

Add one page scroll to already existing template

I'm working on my first bootstrap website and yes, I'm a noob. After a long journey, I found this template to work with.
At the end of the day, it will contain over 20 fullpage sections like the header with texts, images, videos and audios.
This template has a scrolling script:
// Scrolls to the selected menu item on the page
$(function() {
$('a[href*=#]:not([href=#])').click(function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
Now, here is the special price question. There is this 'one page scroll' by Pete Design. This contains a template-css and js-file.
Is it possible to mix these two templates?
I like to add the Pete Design JS-Template to add:
scrolling section by section with the mousewheel/keyboard arrows and the swipe-function but I want/like to use the design (espacially navbar!) from Startbootstrap.

Removing a function for Safari ONLY in JQUERY

Basically I've created a single page website and I've used JQuery to create a ScrollTo effect when clicking on different links. Because I have a fixed div at the top of the page, I've offset the target to the height of the fixed div at the top of the page, so that when it scrolls, the contents isn't hidden by the fixed div at the top of the page:
if ($target) {
var targetOffset = $target.offset().top - $("#div_at_top_of_page").outerHeight();
This works fine, scrolling the target div below my fixed navigation at the top of my page. However in Safari, the scroll to already scrolls below the div by default, so adding:
$("#div_at_top_of_page").outerHeight();
this causes Safari to scroll to the target, but also adding the height of the div at the top of the page, creating a margin.
I'm just looking for a solution to cancel this:
$("#div_at_top_of_page").outerHeight()
for Safari only. Any help would be appreciated, thanks!
EDIT: I'm open to any other solutions rather than browser detection.
Here's the complete thing:
$(document).ready(function() {
function filterPath(string) {
return string
.replace(/^\//,'')
.replace(/(index|default).[a-zA-Z]{3,4}$/,'')
.replace(/\/$/,'');
}
$('a[href*=#]').each(function() {
if ( filterPath(location.pathname) == filterPath(this.pathname)
&& location.hostname == this.hostname
&& this.hash.replace(/#/,'') ) {
var $targetId = $(this.hash), $targetAnchor = $('[name=' + this.hash.slice(1) +']');
var $target = $targetId.length ? $targetId : $targetAnchor.length ? $targetAnchor : false;
if ($target) {
var targetOffset = $target.offset().top - $("#fixed_div_at_top").outerHeight();
$(this).click(function(e) {
$('html, body').animate({scrollTop: targetOffset}, 800);
e.preventDefault();
var d = document.createElement();
d.style.height = "101%";
d.style.overflow = "hidden";
document.body.appendChild(d);
window.scrollTo(0,scrollToM);
setTimeout(function() {
d.parentNode.removeChild(d);
}, 10);
return false;
});
}
}
The direct answer to your question is to use $.browser (http://api.jquery.com/jQuery.browser/ -- deprecated long ago and removed in jQuery 1.9), but I can't recommend it. Better to use feature detection. Even better not to rely on either method. Have provided this as an answer only because you initially asked specifically about targeting Safari.

How to scroll an HTML page to a given anchor

I’d like to make the browser to scroll the page to a given anchor, just by using JavaScript.
I have specified a name or id attribute in my HTML code:
<a name="anchorName">..</a>
or
<h1 id="anchorName2">..</h1>
I’d like to get the same effect as you’d get by navigating to http://server.com/path#anchorName. The page should be scrolled so that the anchor is near the top of the visible part of the page.
function scrollTo(hash) {
location.hash = "#" + hash;
}
No jQuery required at all!
Way simpler:
var element_to_scroll_to = document.getElementById('anchorName2');
// Or:
var element_to_scroll_to = document.querySelectorAll('.my-element-class')[0];
// Or:
var element_to_scroll_to = $('.my-element-class')[0];
// Basically `element_to_scroll_to` just have to be a reference
// to any DOM element present on the page
// Then:
element_to_scroll_to.scrollIntoView();
You can use jQuery's .animate(), .offset() and scrollTop. Like
$(document.body).animate({
'scrollTop': $('#anchorName2').offset().top
}, 2000);
Example link: http://jsbin.com/unasi3/edit
If you don't want to animate, use .scrollTop() like:
$(document.body).scrollTop($('#anchorName2').offset().top);
Or JavaScript's native location.hash like:
location.hash = '#' + anchorid;
2018-2020 Pure JavaScript:
There is a very convenient way to scroll to the element:
el.scrollIntoView({
behavior: 'smooth', // smooth scroll
block: 'start' // the upper border of the element will be aligned at the top of the visible part of the window of the scrollable area.
})
But as far as I understand, it does not have such good support as the options below.
Learn more about the method.
If it is necessary that the element is in the top:
const element = document.querySelector('#element')
const topPos = element.getBoundingClientRect().top + window.pageYOffset
window.scrollTo({
top: topPos, // scroll so that the element is at the top of the view
behavior: 'smooth' // smooth scroll
})
Demonstration example on CodePen
If you want the element to be in the center:
const element = document.querySelector('#element')
const rect = element.getBoundingClientRect() // get rects(width, height, top, etc)
const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
window.scroll({
top: rect.top + rect.height / 2 - viewHeight / 2,
behavior: 'smooth' // smooth scroll
});
Demonstration example on CodePen
Support:
They write that scroll is the same method as scrollTo, but support shows better in scrollTo.
More about the method.
Great solution by jAndy, but the smooth scroll seems to be having issues working in Firefox.
Writing it this way works in Firefox as well.
(function($) {
$(document).ready(function() {
$('html, body').animate({
'scrollTop': $('#anchorName2').offset().top
}, 2000);
});
})(jQuery);
In 2018, you don't need jQuery for something simple like this. The built in scrollIntoView() method supports a "behavior" property to smoothly scroll to any element on the page. You can even update the browser URL with a hash to make it bookmarkable.
From this tutorial on scrolling HTML Bookmarks, here is a native way to add smooth scrolling to all anchor links on your page automatically:
let anchorlinks = document.querySelectorAll('a[href^="#"]')
 
for (let item of anchorlinks) { // relitere
    item.addEventListener('click', (e)=> {
        let hashval = item.getAttribute('href')
        let target = document.querySelector(hashval)
        target.scrollIntoView({
            behavior: 'smooth',
            block: 'start'
        })
        history.pushState(null, null, hashval)
        e.preventDefault()
    })
}
Here is a pure JavaScript solution without jQuery. It was tested on Chrome and Internet Explorer, but not tested on iOS.
function ScrollTo(name) {
ScrollToResolver(document.getElementById(name));
}
function ScrollToResolver(elem) {
var jump = parseInt(elem.getBoundingClientRect().top * .2);
document.body.scrollTop += jump;
document.documentElement.scrollTop += jump;
if (!elem.lastjump || elem.lastjump > Math.abs(jump)) {
elem.lastjump = Math.abs(jump);
setTimeout(function() { ScrollToResolver(elem);}, "100");
} else {
elem.lastjump = null;
}
}
Demo: https://jsfiddle.net/jd7q25hg/12/
The easiest way to to make the browser to scroll the page to a given anchor is to add *{scroll-behavior: smooth;} in your style.css file and in your HTML navigation use #NameOfTheSection.
*{scroll-behavior: smooth;}
<a href="#scroll-to">Click to Scroll<a/>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<section id="scroll-to">
<p>it will scroll down to this section</p>
</section>
Smoothly scroll to the proper position
Get correct y coordinate and use window.scrollTo({top: y, behavior: 'smooth'})
const id = 'anchorName2';
const yourElement = document.getElementById(id);
const y = yourElement.getBoundingClientRect().top + window.pageYOffset;
window.scrollTo({top: y, behavior: 'smooth'});
$(document).ready ->
$("a[href^='#']").click ->
$(document.body).animate
scrollTop: $($(this).attr("href")).offset().top, 1000
The solution from CSS-Tricks no longer works in jQuery 2.2.0. It will throw a selector error:
JavaScript runtime error: Syntax error, unrecognized expression: a[href*=#]:not([href=#])
I fixed it by changing the selector. The full snippet is this:
$(function() {
$("a[href*='#']:not([href='#'])").click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
This works:
$('.scroll').on("click", function(e) {
e.preventDefault();
var dest = $(this).attr("href");
$("html, body").animate({
'scrollTop': $(dest).offset().top
}, 2000);
});
https://jsfiddle.net/68pnkfgd/
Just add the class 'scroll' to any links you wish to animate
Most answers are unnecessarily complicated.
If you just want to jump to the target element, you don't need JavaScript:
# the link:
Click here to jump.
# target element:
<div id="target">Any kind of element.</div>
If you want to scroll to the target animatedly, please refer to 5hahiL's answer.
jQuery("a[href^='#']").click(function(){
jQuery('html, body').animate({
scrollTop: jQuery( jQuery(this).attr('href') ).offset().top
}, 1000);
return false;
});
This is a working script that will scroll the page to the anchor.
To set it up, just give the anchor link an id that matches the name attribute of the anchor that you want to scroll to.
<script>
jQuery(document).ready(function ($){
$('a').click(function (){
var id = $(this).attr('id');
console.log(id);
if ( id == 'cet' || id == 'protein' ) {
$('html, body').animate({ scrollTop: $('[name="' + id + '"]').offset().top}, 'slow');
}
});
});
</script>
I found an easy and simple jQuery solution on CSS-Tricks. That's the one I'm using now.
$(function() {
$('a[href*=#]:not([href=#])').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
A Vue.js 2 solution ... add a simple data property to simply force the update:
const app = new Vue({
...
, updated: function() {
this.$nextTick(function() {
var uri = window.location.href
var anchor = ( uri.indexOf('#') === -1 ) ? '' : uri.split('#')[1]
if ( String(anchor).length > 0 && this.updater === 'page_load' ) {
this.updater = "" // only on page-load !
location.href = "#"+String(anchor)
}
})
}
});
app.updater = "page_load"
/* Smooth scrolling in CSS - it works in HTML5 only */
html, body {
scroll-behavior: smooth;
}

Categories

Resources