12% off of LTD using this coupon: TWELVEPERCENTOFF. Promo ends on 2 Dec midnight UTC.
Published on Jun 27, 2018

Smooth scrolling to hash links and Back to Top in Oxygen

Sridhar Katakam

Note: Smooth scrolling to hash links is now built into Oxygen editor at Manage > Settings > Global Styles > Scripts > Smooth Scroll to Hash Links. You may follow this tutorial for the “Back to Top” part.

A common question I see being asked in the Oxygen community is:

How do I set up smooth scrolling for same-page jump links to sections and divs on my pages?

In this tutorial, I show how smooth scrolling (courtsey, css-tricks) to target sections can be set up in Oxygen along with a smooth scroll to top functionality (courtsey, codyhouse).

Step 1

At Appearance > Menus, create/edit your menu which appears on the frontend (via the Menu element).

Add URLs in this format: #section-9-224 where section-9-224 is the ID of the section or any other element to which that link should take the user to.

This ID can be obtained by inspecting the element using your browser inspector or in Oxygen itself.

Enter your Navigation Labels.

Step 2

Edit your main sitewide Oxygen template.

Add a Code Block element (screenshot) having this HTML:

<a href="#0" class="cd-top js-cd-top">Top</a>

and this CSS:

/* Back to Top */

.cd-top {
  display: inline-block;
  height: 40px;
  width: 40px;
  position: fixed;
  bottom: 40px;
  right: 10px;
  -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);
          box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);
  /* image replacement properties */
  overflow: hidden;
  text-indent: 100%;
  white-space: nowrap;
  background: rgba(101, 190, 194, 0.8) url(/wp-content/plugins/my-custom-functionality-master/assets/images/cd-top-arrow.svg) no-repeat center 50%;
  visibility: hidden;
  opacity: 0;
  -webkit-transition: opacity .3s 0s, visibility 0s .3s, background-color .3s 0s;
  transition: opacity .3s 0s, visibility 0s .3s, background-color .3s 0s;
}

.cd-top.cd-top--show,
.cd-top.cd-top--fade-out,
.cd-top:hover {
  -webkit-transition: opacity .3s 0s, visibility 0s 0s, background-color .3s 0s;
  transition: opacity .3s 0s, visibility 0s 0s, background-color .3s 0s;
}

.cd-top.cd-top--show {
  /* the button becomes visible */
  visibility: visible;
  opacity: 1;
}

.cd-top.cd-top--fade-out {
  /* if the user keeps scrolling down, the button is out of focus and becomes less visible */
  opacity: .5;
}

.cd-top:hover {
  background-color: #65bec2;
  opacity: 1;
}

@media only screen and (min-width: 768px) {
  .cd-top {
    right: 20px;
    bottom: 20px;
  }
}

@media only screen and (min-width: 1024px) {
  .cd-top {
    height: 60px;
    width: 60px;
    right: 30px;
    bottom: 30px;
  }
}

In the above replace

https://wpdevdesign.com/wp-content/plugins/my-custom-functionality-master/assets/images/cd-top-arrow.svg

with

/wp-content/plugins/my-custom-functionality-master/assets/images/cd-top-arrow.svg

Step 3

Install my custom functionality plugin.

Connect to your server using a FTP client and create a file named say, smooth-scrolling.js inside the plugin’s assets/js directory having the following code:

(function ($) {

    // Select all links with hashes
    $('a[href*="#"]')
        // Remove links that don't actually link to anything
        .not('[href="#"]')
        .not('[href="#0"]')
        .click(function (event) {
            // On-page links
            if (
                location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '')
                &&
                location.hostname == this.hostname
            ) {
                // Figure out element to scroll to
                var target = $(this.hash);
                target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
                // Does a scroll target exist?
                if (target.length) {
                    // Only prevent default if animation is actually gonna happen
                    event.preventDefault();
                    $('html, body').animate({
                        scrollTop: target.offset().top
                    }, 1000, function () {
                        // Callback after animation
                        // Must change focus!
                        var $target = $(target);
                        $target.focus();
                        if ($target.is(":focus")) { // Checking if the target was focused
                            return false;
                        } else {
                            $target.attr('tabindex', '-1'); // Adding tabindex for elements not focusable
                            $target.focus(); // Set focus again
                        };
                    });
                }
            }
        });

    // Back to Top - by CodyHouse.co
    var backTop = document.getElementsByClassName('js-cd-top')[0],
        // browser window scroll (in pixels) after which the "back to top" link is shown
        offset = 300,
        //browser window scroll (in pixels) after which the "back to top" link opacity is reduced
        offsetOpacity = 1200,
        scrollDuration = 700
    scrolling = false;
    if (backTop) {
        //update back to top visibility on scrolling
        window.addEventListener("scroll", function (event) {
            if (!scrolling) {
                scrolling = true;
                (!window.requestAnimationFrame) ? setTimeout(checkBackToTop, 250) : window.requestAnimationFrame(checkBackToTop);
            }
        });
        //smooth scroll to top
        backTop.addEventListener('click', function (event) {
            event.preventDefault();
            (!window.requestAnimationFrame) ? window.scrollTo(0, 0) : scrollTop(scrollDuration);
        });
    }

    function checkBackToTop() {
        var windowTop = window.scrollY || document.documentElement.scrollTop;
        (windowTop > offset) ? addClass(backTop, 'cd-top--show') : removeClass(backTop, 'cd-top--show', 'cd-top--fade-out');
        (windowTop > offsetOpacity) && addClass(backTop, 'cd-top--fade-out');
        scrolling = false;
    }

    function scrollTop(duration) {
        var start = window.scrollY || document.documentElement.scrollTop,
            currentTime = null;

        var animateScroll = function (timestamp) {
            if (!currentTime) currentTime = timestamp;
            var progress = timestamp - currentTime;
            var val = Math.max(Math.easeInOutQuad(progress, start, -start, duration), 0);
            window.scrollTo(0, val);
            if (progress < duration) {
                window.requestAnimationFrame(animateScroll);
            }
        };

        window.requestAnimationFrame(animateScroll);
    }

    Math.easeInOutQuad = function (t, b, c, d) {
        t /= d / 2;
        if (t < 1) return c / 2 * t * t + b;
        t--;
        return -c / 2 * (t * (t - 2) - 1) + b;
    };

    //class manipulations - needed if classList is not supported
    function hasClass(el, className) {
        if (el.classList) return el.classList.contains(className);
        else return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
    }
    function addClass(el, className) {
        var classList = className.split(' ');
        if (el.classList) el.classList.add(classList[0]);
        else if (!hasClass(el, classList[0])) el.className += " " + classList[0];
        if (classList.length > 1) addClass(el, classList.slice(1).join(' '));
    }
    function removeClass(el, className) {
        var classList = className.split(' ');
        if (el.classList) el.classList.remove(classList[0]);
        else if (hasClass(el, classList[0])) {
            var reg = new RegExp('(\\s|^)' + classList[0] + '(\\s|$)');
            el.className = el.className.replace(reg, ' ');
        }
        if (classList.length > 1) removeClass(el, classList.slice(1).join(' '));
    }

})(jQuery);

Edit the plugin’s php file and add

wp_enqueue_script(
    'smooth-scrolling',
    plugin_dir_url( __FILE__ ) . 'assets/js/smooth-scrolling.js',
    array( 'jquery' ),
    '1.0.0',
    true
);

inside the custom_enqueue_files() function.

Step 4

Upload cd-top-arrow.svg file (source) to the plugin’s assets/images directory.

References

https://css-tricks.com/snippets/jquery/smooth-scrolling/

https://codyhouse.co/gem/back-to-top/

tagschevron-leftchevron-rightchainangle-rightangle-upangle-downfolder-omagnifiercrossmenuchevron-downarrow-right