Jump to content

Smooth Scrolling bugs


Nic727

Recommended Posts

Hi,

 

I'm using a smooth scrolling for my website (currently WIP) and that's the current code used.

$(document).ready(function(){
	$('a[href^="#"]').on('click',function (e) {
	    e.preventDefault();

	    var target = this.hash;
	    var $target = $(target);
        var i = $(this).attr("href");
        var k = $(i).offset().top;
	    $('html, body').stop().animate({
	        scrollTop: k - 150
	    }, 1800, 'swing' ,function () {
	        window.location.hash = target;
	    });
	});
});

A small summary of the script :

1. Check if Href with # is clicked

2. Target = Go to this ID

3. scrollTop: k-150 is about stopping 150 (px?) before top of the section.

4. 1800 = time

5. 'swing' = ease

6. function for window.location.hash to show # in URL.

 

 

I have three problems with this script.

 

1. Can't change easing. I downloaded JQuery UI, but doesn't work. I would like EaseInOutBack, but doesn't work. Even tried normal EaseInOut...

 

2. In Internet Explorer and MS Edge, the last function to show hash in URL is an issue. The animation stop 150 before section (like normally), but right after, it jump (without animation) to selected hash (section ID). Any fixes?

 

3. Sometimes the scrolling animation seem to stuck in the page. You should try.

 

 

Thank you

Link to comment
Share on other sites

Can't change easing. I downloaded JQuery UI, but doesn't work.

What do you mean? I'm pretty sure that jQuery UI works. Are you checking for error messages? How did you include it on the page? Are you sure you're using the right value for the easing function?

 

For the issue about setting the hash, there's a discussion here:

 

http://stackoverflow.com/questions/3870057/how-can-i-update-window-location-hash-without-jumping-the-document

Link to comment
Share on other sites

Hi,

 

That's the error I get when changing easing options :

 

Uncaught TypeError: jQuery.easing[this.easing] is not a function

Tween.run @ jquery.js:9216

Animation.tick @ jquery.js:8914

jQuery.fx.timer @ jquery.js:9511

Animation @ jquery.js:8981

doAnimation @ jquery.js:9305

jQuery.extend.dequeue @ jquery.js:3948

(anonymous function) @ jquery.js:3991

jQuery.extend.each @ jquery.js:657

jQuery.fn.jQuery.each @ jquery.js:266

jQuery.fn.extend.queue @ jquery.js:3984

jQuery.fn.extend.animate @ jquery.js:9316

(anonymous function) @ index.html:26

jQuery.event.dispatch @ jquery.js:5095

elemData.handle @ jquery.js:4766

 

 

 

And that's how I organize it :

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.2.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="js/jquery.js"></script>
Link to comment
Share on other sites

You include jQuery once, then you include jQuery UI, then you include jQuery again and overwrite what you included the first time, including UI. Only include jQuery once, before you include any other plugins.

Link to comment
Share on other sites

  • 2 weeks later...

Hi,

 

I tried with this instead

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.2.min.js"></script>
<script src="js/jquery-ui.min.js"></script>

and my smooth scrolling script :

$(function() {
        $('a[href*=#]:not([href=#])').click(function() {
          if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
            var target = $(this.hash);
            var i = $(this).attr("href");
        var k = $(i).offset().top;
            target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
            if (target.length) {
              $('html,body').animate({
                scrollTop: k - 0
              }, 1000, 'swing');
              return false;
            }
          }
        });
      });    

But now it's not working anymore. The 'swing' thing is just the animation and it worked before, but now I'm just lost. Should I add JQuery UI first?

 

Maybe this solution could be better?

http://www.gsgd.co.uk/sandbox/jquery/easing/

 

 

I'm trying to get "EaseInOut" (or Ease-in-out?) or "EaseInOutBack".

 

Thank you

 

 

EDIT :

 

 

Just saw that only

<script src="js/jquery.js"></script>

works. Why? Is it because when testing locally I can't add external JS? Why does JQuery UI doesn't work?

Edited by Nic727
Link to comment
Share on other sites

Should I add JQuery UI first?

No. All jQuery plugins require that jQuery is already loaded.

 

Is it because when testing locally I can't add external JS?

That might be the case, depending on your browser's security settings.
Link to comment
Share on other sites

And you're still only including jQuery once, right? If you include it a second time, after you include UI, then it will overwrite and effectively remove UI. That's what you were doing in post 3.

Link to comment
Share on other sites

That's my full code for smooth scrolling.

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.2.min.js"></script>
<script src="js/jquery.js"></script> <!-- Because first one doesn't work locally? -->
<script src="js/jquery-ui.min.js"></script>

<script>

$(function() {
        $('a[href*=#]:not([href=#])').click(function() {
          if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) { // I don't understand this part of the code.
            var target = $(this.hash);
            var i = $(this).attr("href");
        var k = $(i).offset().top;
            target = target.length ? target : $('[name=' + this.hash.slice(1) +']'); //Something easier for that?
            if (target.length) {
              $('html,body').animate({
                scrollTop: k - 0 //Distance from top of section.
              }, 1000, 'swing'); //I'm trying to change 'swing' to something else, but doesn't work.
             return false; //Doesn't show hash in URL. The problem here is that if I want to show change in URL, I remove that, but it reload the page each time? No way to just show hash without reloading the page?
            }
          }
        });
      });    

</script>
Edited by Nic727
Link to comment
Share on other sites

k is just the value of offset.

 

I have other scripts solutions :

 

Other smooth scroll #1

 $(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-70	// Height of fixed nav
                    }, 1000);
                    return false;
                }
            }
        });
    });

Other smooth scroll #2

$(document).ready(function(){
	$('a[href^="#"]').on('click',function (e) {
	    e.preventDefault();

	    var target = this.hash;
	    var $target = $(target);
        var i = $(this).attr("href");
        var k = $(i).offset().top;
	    $('html, body').stop().animate({
	        scrollTop: k - 150
	    }, 1000, 'swing');
	});
});
When changing swing I have this error in console log

 

SCRIPT438: Object doesn't support property or method 'EaseInOut'

jquery.js (9216,4)

 

 

​In JQuery UI code, I can find this :

(function() {

// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)

var baseEasings = {};

$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
	baseEasings[ name ] = function( p ) {
		return Math.pow( p, i + 2 );
	};
});

$.extend( baseEasings, {
	Sine: function( p ) {
		return 1 - Math.cos( p * Math.PI / 2 );
	},
	Circ: function( p ) {
		return 1 - Math.sqrt( 1 - p * p );
	},
	Elastic: function( p ) {
		return p === 0 || p === 1 ? p :
			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
	},
	Back: function( p ) {
		return p * p * ( 3 * p - 2 );
	},
	Bounce: function( p ) {
		var pow2,
			bounce = 4;

		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
	}
});

$.each( baseEasings, function( name, easeIn ) {
	$.easing[ "easeIn" + name ] = easeIn;
	$.easing[ "easeOut" + name ] = function( p ) {
		return 1 - easeIn( 1 - p );
	};
	$.easing[ "easeInOut" + name ] = function( p ) {
		return p < 0.5 ?
			easeIn( p * 2 ) / 2 :
			1 - easeIn( p * -2 + 2 ) / 2;
	};
});

})();
It seem that it doesn't want to go outside normal jQuery... Doesn't want to check in jQuery ui. Edited by Nic727
Link to comment
Share on other sites

I don't think "EaseInOut" is a valid value. It's not on the documentation page you linked to earlier. And, isn't that what swing does? The swing function is an ease in/out function. You're also capitalizing it, which is wrong. Try "easeInOutQuad" or something else listed in the documentation. Make sure to capitalize it correctly.

Link to comment
Share on other sites

It works!

 

All this for a bad capitalization :( *stupid*

 

Thank you very much.

 

But can I ask one other question?

 

How to show #section in URL when clicking on the nav options?

If I delete "return false" to the code, it show in URL, but it refresh the page each time the URL change. Anyway to just change URL without refreshing the page?

Link to comment
Share on other sites

You can add history entries if you want to make sure the back button still works, but if you change the URL then the browser will respond to that. You can't change the URL without the browser responding.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...