Git Product home page Git Product logo

moveto's Introduction

MoveTo Version CDNJS version CI Status

A lightweight (only 1kb gzipped) scroll animation javascript library without any dependency.

Demo

Installation

Using npm

$ npm install moveto --save

Using Yarn

$ yarn add moveto

Usage

const moveTo = new MoveTo();

const target = document.getElementById('target');

moveTo.move(target);

// Or register a trigger

const trigger = document.getElementsByClassName('js-trigger')[0];

moveTo.registerTrigger(trigger);

Trigger HTML markup

You can pass all options as data attributes with the mt prefix. Option name should be written in kebab case format, for example:

<a href="#target" class="js-trigger" data-mt-duration="300">Trigger</a>

<!-- Or -->

<button type="button" class="js-trigger" data-target="#target" data-mt-duration="300">Trigger</button>

Options

The following options are available:

new MoveTo({
  tolerance: 0,
  duration: 800,
  easing: 'easeOutQuart',
  container: window
})
Option Default Description
tolerance 0 The tolerance of the target to be scrolled, can be negative or positive
duration 800 Duration of scrolling, in milliseconds
easing easeOutQuart Ease function name
container window The container been computed and scrolled
callback noop The function to be run after scrolling complete. Target passes as the first argument

API

move(target, options)

Start scroll animation from current position to the anchor point.

target

Type: HTMLElement|Number

Target element/position to be scrolled. Target position is the scrolling distance. It must be negative if the upward movement is desired.

options

Type: Object

Pass custom options.

registerTrigger(trigger, callback)

trigger

Type: HTMLElement

This is the trigger element for starting to scroll when on click.

callback

This is the callback function to be ran after the scroll completes. This will overwrite the callback option.

addEaseFunction(name, fn)

Adds custom ease function.

name

Type: String

Ease function name.

fn

Type: Function

Ease function. See Easing Equations for more ease functions.

Examples

Pass ease function(s) when creating an instance
document.addEventListener('DOMContentLoaded', function () {
  const easeFunctions = {
    easeInQuad: function (t, b, c, d) {
      t /= d;
      return c * t * t + b;
    },
    easeOutQuad: function (t, b, c, d) {
      t /= d;
      return -c * t* (t - 2) + b;
    }
  }

  const moveTo = new MoveTo({
    duration: 1000,
    easing: 'easeInQuad'
  }, easeFunctions);

  const trigger = document.getElementsByClassName('js-trigger')[0];

  moveTo.registerTrigger(trigger);
});
Working with callback function
document.addEventListener('DOMContentLoaded', function () {
  const moveTo = new MoveTo({
    duration: 1000,
    callback: function (target) {
      // This will run if there is no overwrite
    }
  });

  const trigger = document.getElementsByClassName('js-trigger')[0];

  moveTo.registerTrigger(trigger, function (target) {
    // Overwrites global callback
  });

  // Or

  moveTo.move(1200, {
    duration: 500,
    callback: function () {
      // Overwrites global callback
    }
  });
});
Unregister a trigger
document.addEventListener('DOMContentLoaded', function () {
  const moveTo = new MoveTo();

  const trigger = document.getElementsByClassName('js-trigger')[0];

  // Register a trigger
  const unregister = moveTo.registerTrigger(trigger, { duration: 500 });

  // Unregister a trigger
  unregister();
});
Back to top
document.addEventListener('DOMContentLoaded', function () {
  const moveTo = new MoveTo();
  const triggers = document.getElementsByClassName('js-back-to-top');

  for (var i = 0; triggers.length < i; i++) {
    moveTo.registerTrigger(triggers[i]);
  }
});
<a href="#" class="js-back-to-top" data-mt-duration="300">Back to top!</a>

Development setup

# To install dev dependencies run:

$ yarn

# Or so if using npm:

$ npm install

# To start the development server run:

$ yarn start

# Or so if using npm:

$ npm run start

# To lint your code run:

$ yarn lint

# Or so if using npm:

$ npm run lint

# To make a full new build run:

$ yarn build

# Or so if using npm:

$ npm run build

# To run tests:

$ yarn test

# Or so if using npm:

$ npm test

Browser support

It should work in the current stable releases of Chrome, Firefox, Safari and Edge. To add support for older browsers, consider including polyfills/shims for the requestAnimationFrame and Element.scroll.

License

Copyright (c) 2017 Hasan Aydoğdu. See the LICENSE file for license rights and limitations (MIT).

moveto's People

Contributors

374632897 avatar danbovey avatar dependabot[bot] avatar extend1994 avatar hsnaydd avatar johnbacon avatar lex111 avatar pataar avatar pea3nut avatar yildirayunlu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

moveto's Issues

Links don’t update URL with #hash

Though it’s nice to have a slow scroll to the ID on a page, the whole point of such anchors is to keep URL updated with current page fragment ID you’ve just been scrolled to. By removing built-in functionaity you make such links less accessible by users. Buttons and links are two different things even if you could make them look similar with JS.

Please add some History API magic or figure out a way to have ID to be added to URL but prevent page from jumping. Otherwise this script should be considered harmful to web UX.

Problem with request animation frame loop

After encountering problems where the window simply wasn't scrolled, despite a correct call to the move function I started looking around in the code and found a problem in the request animation frame loop. Basically if the duration is too long but the scroll change is too little, the loop is exited after the first iteration because the window was scrolled less than half a pixel, therefore lastPageYOffset and currentPageYOffset remain the same.

A possible solution could be, to simply change this

if (lastPageYOffset && from === to) {
  if (
    lastPageYOffset === currentPageYOffset ||
    change > 0 && lastPageYOffset > currentPageYOffset ||
    change < 0 && lastPageYOffset < currentPageYOffset)
  {
    return options.callback(target);
  }
}

to this

if (currentPageYOffset === to) {
  return options.callback(target);
}

Now this might have unintended consequences I don't realize, but some form of check to see if the window actually scrolled to where it's supposed to could make sense.

cheers

Multiple moveTo triggers doesn't work

I have 2 navs on the page. Mobile and desktop. I want MoveTo in both navs. If I do

<a href="#bazinga" class="js-trigger" data-mt-duration="300">Anchor Link</a>
<a href="#bazinga" class="js-trigger" data-mt-duration="300">Anchor Link 2</a>

Only first smooth scroll is working!

Doesn't use proper browser History

Scrolling about from #A to #Z does not effect the URL in the browser bar, nor does it modify the window.history
If a user presses "back", the URL will change completely, not "back up" to an earlier internal #link.

Lazy loading images

Hi, can you add an "step" option (like jQuery.animate) in the library to re-calculate the final position if there are lazy loading images in the page?

Eg:

step: function( now, fx ) {
   var newOffset = $target.offset().top;
   if(fx.end !== newOffset)
     fx.end = newOffset;
}

Regards

Focus remains on button

Clicking on the button in your demo does indeed bring you back to top visually, but the focus remains on the button. The focus should move to wherever the page visually scrolls to instead of staying with the button clicked.

Second click moves page on Top

I noticed that if I do second click on link (after I scroll to needed element) MoveTo jumps to Top of the page. Not sure why it's happening without my knowledge. Is this a desired behavior? Can I turn this off?

Some minifications suggestions

Great work! I really like this kind of tiny masterpieces, instead of overcomplicated stuff soo common nowadays... This is not an issue at all. Just a few suggestions to get the code even smaller after minification.

1_ cache prototype object:

var proto = MoveTo.prototype;

Before minification:

var proto = MoveTo.prototype:
proto.registerTrigger = function(){ };
proto.move = function(){ };
proto.addEaseFunction = function(){ };

After minification:

var p=MoveTo.prototype:p.registerTrigger=function(){};p.move=function(){};p.addEaseFunction=function(){};

Minification without caching:

MoveTo.prototype.registerTrigger=function(){};MoveTo.prototype.move=function(){};MoveTo.prototype.addEaseFunction=function(){};

2_ save some methods and properties in strings, and later use brackets notation. For example, the getAttribute methods:

Before minification:

var _getAttribute = 'getAttribute':
var attr1 = elem[_getAttribute]('data-attr-1');
var attr1 = elem[_getAttribute]('data-attr-2');
var attr3 = elem[_getAttribute]('data-attr-3');

After minification:

var a='getAttribute',b=e[a]('data-attr-1'),c=e[a]('data-attr-2'),d=e[a]('data-attr-3');

Minification without caching:

var b=e.getAttribute('data-attr-1'),c=e.getAttribute('data-attr-2'),d=e.getAttribute('data-attr-3');

You can "cache" some others objects/properties more... like "forEach"

Yeah... I know that the differences are insignificant, but is a good practice and even more important if you plan to extend some functionality or add more methods to the constructor...

Anyway good work!

SyntaxError: Unexpected token: punc ()) - version 1.5.2

I'm currently including moveto in a project and it appears to work great in development.

However when I attempt a production build with webpack it will throw an error from Uglify:
ERROR in vendor.js from UglifyJs
SyntaxError: Unexpected token: punc ()) [vendor.js:xx,xx]

commenting out the import will allow the build to be successful:
import MoveTo from 'moveto';

Any help appreciated.

Top margin of the first section ignored when scroll to top

In my case, the top margin of the first section is ignored when scroll back to top. I have to use padding instead of margin or wrap the sections in a container div.

NOT WORKING :

<body>
      <section></section>
      <section></section>
      <section></section>
      <button>Back to top</button>
</body>

section {
      margin: 50px 0 0 0;
}

WORKING :

<body>
      <section></section>
      <section></section>
      <section></section>
      <button>Back to top</button>
</body>

section {
      padding: 50px 0 0 0;
}

OR

<body>
      <div class="wrapper">
            <section></section>
            <section></section>
            <section></section>
            <button>Back to top</button>
      </div>
</body>

section {
      margin: 50px 0 0 0;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.