Conflict between anchor and smooth scrolling

Asked

Viewed 169 times

1

When I click on the anchor and scroll the page there is a conflict between the smooth scrolling script and the anchor script causing the site to roll to the top, I have tried anyway to resolve this and I can not at all, if anyone can help me I will be extremely grateful

WEBSITE: https://circuito-da-saude.herokuapp.com/web

SMOOTH SCROLLBAR SCRIPT:

function smooth(){
    new WSmoothScroll(document,120,12);
}
 
// var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
 
function WSmoothScroll(target, speed, smooth) {
    if (target == document)
        target = (document.documentElement || document.body.parentNode || document.body) // cross browser support for document scrolling
    var moving = false
    var pos = target.scrollTop
    if(navigator.userAgent.indexOf("Firefox") > -1) {
        target.addEventListener('DOMMouseScroll', scrolled, {passive: false});
    } else {
        if(navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
           
        } else {
            target.addEventListener("wheel", scrolled, {passive: false} );
        }
    }
 
    function scrolled(e) {
        e.preventDefault(); // disable default scrolling
 
        var delta = normalizeWheelDelta(e)
 
        pos += -delta * speed
        pos = Math.max(0, Math.min(pos, target.scrollHeight - target.clientHeight)) // limit scrolling
 
        if (!moving) update()
    }
 
    function normalizeWheelDelta(e){
        if(e.detail){
            if(e.wheelDelta)
                return e.wheelDelta/e.detail/40 * (e.detail>0 ? 1 : -1) // Opera
            else
                return -e.detail/8 // Firefox 3
        }else
            return e.wheelDelta/360 // IE,Safari,Chrome 120
    }
 
    function update() {
        moving = true
        var delta = (pos - target.scrollTop) / smooth
        target.scrollTop += delta
        if (Math.abs(delta) > 0.5)
            requestFrame(update)
        else
            moving = false
    }
 
    var requestFrame = function() { // requestAnimationFrame cross browser
        return (
            window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function(func) {
                window.setTimeout(func, 1000 / 50); // 1000 / 50
            }
        );
    }()
}

ANCHOR SCRIPT:

var links = document.getElementsByClassName('scroll-link');
 
for (var k = 0; k < links.length; k++) {
    links[k].onclick = scroll;
}
 
function scroll(e) {
    e.preventDefault();
    var id = this.getAttribute('href').replace('#', '');
    var target = document.getElementById(id).getBoundingClientRect().top;
    animateScroll(target);
 
    // recolhe menu após smoothScroll
 
    if(document.querySelector('.sandwich-trigger').classList.contains('sandwich-open') == true) {
        document.querySelector('.menu ul').classList.remove('nav-open');
        document.querySelector('.sandwich-trigger').classList.remove('sandwich-open');
    }
 
}
 
function animateScroll(targetHeight) {
    targetHeight = document.body.scrollHeight - window.innerHeight > targetHeight + scrollY ?
        targetHeight : document.body.scrollHeight - window.innerHeight;
    var initialPosition = window.scrollY;
    var SCROLL_DURATION = 40;
    var step_x = Math.PI / SCROLL_DURATION;
    var step_count = 0;
    requestAnimationFrame(step);
    function step() {
        if (step_count < SCROLL_DURATION) {
            requestAnimationFrame(step);
            step_count++;
            window.scrollTo(0, initialPosition + (targetHeight - 70) * 0.25 * Math.pow((1 - Math.cos(step_x * step_count)), 2));
        }
    }
}

2 answers

3

I’ll give you one work Around. Today it is possible to make soft anchors with CSS only using the scroll-behavior, so you don’t necessarily need to use a Soft Anchor Script, use CSS to do this, thus eliminating one of the Scripts and preventing this conflict.

Here you can read about the scroll-behavior https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior

Browser Support: https://caniuse.com/#feat=css-scroll-behavior

Follow a practical example of smooth scrolling with CSS only, no JS here.

html {
    overflow-y: scroll;
    scroll-behavior: smooth;
}     
body {
	background-image: linear-gradient(to bottom, #00f 0%, #000 100%);
}     
html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
a {
	font-size: 40px;
	color: #fff;
}
#ancoragem {
	height: 100px;
	background-color: red;
	margin-top: 150vh;
    display:block;
    position:relative;
}
<a href="#ancoragem" id="ancora">ancora</a>

<a href="#ancora" id="ancoragem">VOLTAR PRO TOPO!</a>

  • Hello thank you so much for making your time available, the issue of anchor with css is the support that is still limited and the target audience of the site is composed of lay people who use older browsers, so I need a solution in js that is crossbrowser

  • @Renanhugo yes it is still something with little support, it is more a palliative if you do not get some more precise answer.

0

this line (line 9 of the scroll script) transforms the target variable into a Boolean value target = (Document.documentElement || Document.body.parentNode || Document.body) thus in line 11 target.scrollTop returns Undefined which causes the behavior

  • Hello William, I commented on this line but the code stopped working... What would be the suggestion to remedy this problem?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.