Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

zenscroll

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zenscroll - npm Package Compare versions

Comparing version 2.1.0 to 3.0.0

2

package.json
{
"name": "zenscroll",
"version": "2.1.0",
"version": "3.0.0",
"description": "A module to smooth-scroll web pages and DIVs",

@@ -5,0 +5,0 @@ "main": "zenscroll.js",

@@ -11,8 +11,7 @@ <p align="center">

# One JavaScript to Smooth-Scroll Them All
# One JavaScript to Smooth-Scroll&nbsp;Them&nbsp;All
Smooth animated scrolling. No&nbsp;more abrupt jumps.
Move&nbsp;elements&nbsp;into&nbsp;view, to&nbsp;the&nbsp;center, or&nbsp;scroll&nbsp;to any vertical&nbsp;position.
Smooth animated scrolling. Move&nbsp;elements&nbsp;into&nbsp;view, or&nbsp;scroll&nbsp;to any vertical&nbsp;position.
*875 bytes of pure JavaScript. No&nbsp;dependencies.*
1&nbsp;kilobyte of pure&nbsp;JavaScript. No&nbsp;dependencies.

@@ -26,9 +25,9 @@

- Animated scrolling to anchors on the same page.
- Animated scrolling to anchors on the same page (unless the browser natively supports it and it’s enabled).
- Scroll to the top of a specific element.
- Scrolling an element into view, making sure both top & bottom are visible, if possible.
- Scroll to an element while centering it on the screen.
- Customize the duration.
- Specify the spacing between the element and the edge of the screen (required for fixed navigation bars and footers).
- Only 875 bytes minimized & gzipped.
- Scroll to an element and center it on the screen.
- Customize the duration of the individual scroll operations.
- Specify the spacing between the element and the edge of the screen (e.g., for fixed navigation bars and footers).
- Just 1 kilobyte minimized & gzipped.
- No dependencies.

@@ -56,4 +55,6 @@

## Install
## Getting Started
### Installing Zenscroll
[Download Zenscroll](https://github.com/zengabor/zenscroll/archive/latest.zip) and include it into your page. A good place is at the very bottom, just before the closing `</body>` tag. For&nbsp;example:

@@ -73,7 +74,21 @@

If you want to use Zenscroll programmatically but you don’t need the automatic smoothing on local links then set `window.noZensmooth` to a non-falsy value. In this case the event handler for automatic smoothing is not installed but you can still use everything, like `zenscroll.intoView()`, etc. For&nbsp;example:
### Enabling native smooth-scrolling in the browser
If you want to leverage the native smooth-scrolling by the browser (currently available in Firefox 36+ and Chrome 49+) then set the [`scroll-behavior` CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior) to `smooth` on the body and on the elements you want to scroll. E.g.,
````css
body, .smooth-container { scroll-behavior: smooth }
````
In this case the browser already does native smooth scrolling which is probably more efficient so Zenscroll uses that automatically.
However, note that if you enable native smooth-scrolling then you loose the finer control options that Zenscroll offers: the speed of the animation, and the edge offset. So only set this CSS property on the `body` or on the elements if you don’t need this level of control.
### Disabling automatic smoothing on local links
If you want to use Zenscroll programmatically but you don’t need the automatic smoothing on local links then set `window.noZensmooth` to a non-falsy value. In this case the event handler for automatic smoothing is not installed but you can still use everything, like `zenscroll.intoView()`, etc. It’s important to set this value before Zenscroll is executed, otherwise the handler will be installed. So make sure that setting the variable comes before the loading of the script. For&nbsp;example:
````html
...
<script>window.noZensmooth = true</script>
<script>window.noZensmooth = true</script>
<script src="zenscroll-min.js"></script>

@@ -84,2 +99,3 @@ </body>

(I consider this a rare scenario that’s why I keep the default behavior of installing the event handler.)
## How to use

@@ -90,9 +106,14 @@

If Zenscroll is included in your page it will automatically animate the scrolling to anchors on the same page. This works even with content you dynamically load via ajax, as Zenscroll uses a generic click handler.
If Zenscroll is included in your page it will automatically animate the scrolling to anchors on the same page.
Since this is implemented a progressive enhancement, all internal links still work even in very old browsers. Note that internal links are intentionally not added to the history to save the users from having to hit the Back button too many times afterwards.
However, automatic smooth scrolling is not enabled in these two cases:
If you want some links to be excluded from this, then start with the path of the page. E.g., instead of writing `<a href="#about">` write `<a href="/#about">`.
1. If you set `window.noZensmooth` to a non-falsy value (see [above](#disablingautomaticsmoothingonlocallinks)).
2. If the `scroll-behavior` CSS property is set to `smooth` on the `body` (see [above](#enablingnativesmooth-scrollinginthebrowser)).
If you want only some of the links to be excluded from the automatic smoothing then start with the path of the page. E.g., instead of writing `<a href="#about">` use `<a href="/#about">`.
Automatic smooth scrolling works with content you dynamically load via AJAX, as Zenscroll uses a generic click handler. Internal links are intentionally not added to the history to save the users from having to hit the Back button too many times afterwards. Since the automatic smooth-scrolling is implemented a progressive enhancement, all internal links still work even in old browsers.
### 2. Scroll to the top of an element

@@ -152,3 +173,3 @@

The default duration is 999 which is ~1 second. The duration is automatically reduced for elements that are very close. You can specifically set the duration for each scroll method via an optional second parameter. (Note that a value of zero for duration is ignored.)
The default duration is 999 which is ~1 second. The duration is automatically reduced for elements that are very close. You can specifically set the duration for each scroll function via an optional second parameter. (Note that a value of zero for duration is ignored.)

@@ -172,3 +193,3 @@ Examples:

Anything you can do within the document you can also do inside a scrollable element. You just need to instantiate a new scoller for that element.
Anything you can do within the document you can also do inside a scrollable element. You just need to instantiate a new scoller for that element. It also falls back by default to the native browser smooth-scrolling if available (which can be overridden via `setup()`).

@@ -189,19 +210,19 @@ Example:

<script>
var c = document.getElementById("container")
var defaultDuration = 500
var edgeOffset = 4
var cScroll = new Zenscroll(c, defaultDuration, edgeOffset)
var myDiv = document.getElementById("container")
var myScroller = zenscroll.createScroller(myDiv, defaultDuration, edgeOffset)
var target = document.getElementById("item4")
cScroll.center(target)
myScroller.center(target)
</script>
````
Obviously you can use all other scroll methods and parameters with the scrollable container. Two more examples:
Obviously you can use all other scroll functions and parameters with the scrollable container. Two more examples:
````js
cScroll.toY(35)
myScroller.toY(35)
````
````js
cScroll.intoView(target, 750)
myScroller.intoView(target, 750)
````

@@ -223,2 +244,8 @@

You can change custom scrollers similarly:
````js
myScroller.setup(500, 10)
````
If you don’t want to change a value just omit the parameter or pass `null`. For example, the line below sets the default duration, while leaving other settings unchanged:

@@ -225,0 +252,0 @@

@@ -1,1 +0,1 @@

!function(t,e){"use strict";t.Zenscroll=function n(o,i,r){i=i||999,r&&0===r||(r=9);var c,l=e.documentElement,a=function(){return o?o.scrollTop:t.scrollY||l.scrollTop},u=function(){return o?Math.min(o.offsetHeight,t.innerHeight):t.innerHeight||l.clientHeight},f=function(t){return o?t.offsetTop-o.offsetTop:t.getBoundingClientRect().top+a()-l.offsetTop},s=function M(){clearTimeout(c),c=0},h=function(e,n){s();var r=a(),f=Math.max(e,0)-r;n=n||Math.min(Math.abs(f),i);var h=(new Date).getTime();!function g(){c=setTimeout(function(){var e=Math.min(((new Date).getTime()-h)/n,1),i=Math.max(Math.floor(r+f*(.5>e?2*e*e:e*(4-2*e)-1)),0);o?o.scrollTop=i:t.scrollTo(0,i),1>e&&u()+i<(o||l).scrollHeight?g():setTimeout(s,99)},9)}()},g=function H(t,e){h(f(t)-r,e)},m=function w(t,e){var n=t.getBoundingClientRect().height+2*r,o=u(),i=f(t),c=i+n,l=a();r>i-l||n>o?g(t,e):r>l+o-c&&h(c-o,e)},p=function x(t,e,n){h(Math.max(f(t)-u()/2+(n||t.getBoundingClientRect().height/2),0),e)},v=function B(e){try{history.replaceState({},"",t.location.href.split("#")[0]+(e?"#"+e:""))}catch(n){}},d=function D(e){for(var n=e.target;n&&"A"!==n.tagName;)n=n.parentNode;if(n){var o=n.getAttribute("href")||"";if(0===o.indexOf("#"))if("#"===o)e.preventDefault(),t.zenscroll.toY(0),v("");else{var i=n.hash.substring(1),r=document.getElementById(i);r&&(e.preventDefault(),t.zenscroll.to(r),v(i))}}};!o&&"addEventListener"in t&&!t.noZensmooth&&t.addEventListener("click",d,!1);var T=function E(t,e){t&&(i=t),null!==e&&(r=e)};return{setup:T,to:g,toY:h,intoView:m,center:p,stop:s,moving:function(){return!!c}}},t.zenscroll=new t.Zenscroll}(this,document);
!function(t,e){"function"==typeof define&&define.amd?define([],e()):"object"==typeof module&&module.exports?module.exports=e():t.zenscroll=e()}(this,function(){"use strict";var t=function(t,e,n){e=e||999,n&&0===n||(n=9);var o,i=document.documentElement,r=function(){return"smooth"===(t?t:document.body).style.scrollBehavior},c=function(){return t?t.scrollTop:window.scrollY||i.scrollTop},u=function(){return t?Math.min(t.offsetHeight,window.innerHeight):window.innerHeight||i.clientHeight},f=function(e){return t?e.offsetTop-t.offsetTop:e.getBoundingClientRect().top+c()-i.offsetTop},l=function(){clearTimeout(o),o=0},a=function(n,f){if(l(),r())(t||window).scrollTo(0,n);else{var a=c(),s=Math.max(n,0)-a;f=f||Math.min(Math.abs(s),e);var d=(new Date).getTime();!function h(){o=setTimeout(function(){var e=Math.min(((new Date).getTime()-d)/f,1),n=Math.max(Math.floor(a+s*(.5>e?2*e*e:e*(4-2*e)-1)),0);t?t.scrollTop=n:window.scrollTo(0,n),1>e&&u()+n<(t||i).scrollHeight?h():setTimeout(l,99)},9)}()}},s=function(t,e){a(f(t)-n,e)},d=function(t,e){var o=t.getBoundingClientRect().height+2*n,i=u(),r=f(t),l=r+o,d=c();n>r-d||o>i?s(t,e):n>d+i-l&&a(l-i,e)},h=function(t,e,n){a(Math.max(f(t)-u()/2+(n||t.getBoundingClientRect().height/2),0),e)},m=function(t,o){t&&(e=t),(0===o||o)&&(n=o)};return{setup:m,to:s,toY:a,intoView:d,center:h,stop:l,moving:function(){return!!o}}},e=t();if("addEventListener"in window&&"smooth"!==document.body.style.scrollBehavior&&!window.noZensmooth){var n=function(t){try{history.replaceState({},"",window.location.href.split("#")[0]+t)}catch(e){}};window.addEventListener("click",function(t){for(var o=t.target;o&&"A"!==o.tagName;)o=o.parentNode;if(!(!o||1!==t.which||t.shiftKey||t.metaKey||t.ctrlKey||t.altKey)){var i=o.getAttribute("href")||"";if(0===i.indexOf("#"))if("#"===i)t.preventDefault(),e.toY(0),n("");else{var r=o.hash.substring(1),c=document.getElementById(r);c&&(t.preventDefault(),e.to(c),n("#"+r))}}},!1)}return{createScroller:t,setup:e.setup,to:e.to,toY:e.toY,intoView:e.intoView,center:e.center,stop:e.stop,moving:e.moving}});
/**
* Zenscroll 2.0.0
* Zenscroll 3.0.0
* https://github.com/zengabor/zenscroll/

@@ -36,11 +36,21 @@ *

/*global define, module */
(function (win, doc) {
(function (root, zenscroll) {
if (typeof define === "function" && define.amd) {
define([], zenscroll())
} else if (typeof module === "object" && module.exports) {
module.exports = zenscroll()
} else {
root.zenscroll = zenscroll()
}
}(this, function () {
"use strict"
var createScroller = function (scrollContainer, defaultDuration, edgeOffset) {
win.Zenscroll = function Zenscroll(scrollContainer, defaultDuration, edgeOffset) {
defaultDuration = defaultDuration || 999 //ms
if (!edgeOffset || edgeOffset !== 0) {
// When scrolling this amount of distance is kept from the edges of the scrollContainer
// When scrolling, this amount of distance is kept from the edges of the scrollContainer:
edgeOffset = 9 //px

@@ -50,6 +60,11 @@ }

var scrollTimeoutId
var docElem = doc.documentElement
var docElem = document.documentElement
// Detect if the browser already supports native smooth scrolling (e.g., Firefox 36+ and Chrome 49+) and it is enabled:
var nativeSmoothScrollEnabled = function () {
return (scrollContainer ? scrollContainer : document.body).style.scrollBehavior === "smooth"
}
var getScrollTop = function () {
return scrollContainer ? scrollContainer.scrollTop : win.scrollY || docElem.scrollTop
return scrollContainer ? scrollContainer.scrollTop : (window.scrollY || docElem.scrollTop)
}

@@ -59,4 +74,4 @@

return scrollContainer ?
Math.min(scrollContainer.offsetHeight, win.innerHeight) :
win.innerHeight || docElem.clientHeight
Math.min(scrollContainer.offsetHeight, window.innerHeight) :
window.innerHeight || docElem.clientHeight
}

@@ -75,3 +90,3 @@

*/
var stopScroll = function stopScroll() {
var stopScroll = function () {
clearTimeout(scrollTimeoutId)

@@ -91,22 +106,26 @@ scrollTimeoutId = 0

stopScroll()
var startY = getScrollTop()
var distance = Math.max(endY,0) - startY
duration = duration || Math.min(Math.abs(distance), defaultDuration)
var startTime = new Date().getTime();
(function loopScroll() {
scrollTimeoutId = setTimeout(function () {
var p = Math.min((new Date().getTime() - startTime) / duration, 1) // percentage
var y = Math.max(Math.floor(startY + distance*(p < 0.5 ? 2*p*p : p*(4 - p*2)-1)), 0)
if (scrollContainer) {
scrollContainer.scrollTop = y
} else {
win.scrollTo(0, y)
}
if (p < 1 && (getViewHeight() + y) < (scrollContainer || docElem).scrollHeight) {
loopScroll()
} else {
setTimeout(stopScroll, 99) // with cooldown time
}
}, 9)
})()
if (nativeSmoothScrollEnabled()) {
(scrollContainer || window).scrollTo(0, endY)
} else {
var startY = getScrollTop()
var distance = Math.max(endY,0) - startY
duration = duration || Math.min(Math.abs(distance), defaultDuration)
var startTime = new Date().getTime();
(function loopScroll() {
scrollTimeoutId = setTimeout(function () {
var p = Math.min((new Date().getTime() - startTime) / duration, 1) // percentage
var y = Math.max(Math.floor(startY + distance*(p < 0.5 ? 2*p*p : p*(4 - p*2)-1)), 0)
if (scrollContainer) {
scrollContainer.scrollTop = y
} else {
window.scrollTo(0, y)
}
if (p < 1 && (getViewHeight() + y) < (scrollContainer || docElem).scrollHeight) {
loopScroll()
} else {
setTimeout(stopScroll, 99) // with cooldown time
}
}, 9)
})()
}
}

@@ -121,3 +140,3 @@

*/
var scrollToElem = function scrollToElem(elem, duration) {
var scrollToElem = function (elem, duration) {
scrollToY(getRelativeTopOf(elem) - edgeOffset, duration)

@@ -133,3 +152,3 @@ }

*/
var scrollIntoView = function scrollIntoView(elem, duration) {
var scrollIntoView = function (elem, duration) {
var elemScrollHeight = elem.getBoundingClientRect().height + 2*edgeOffset

@@ -157,3 +176,3 @@ var vHeight = getViewHeight()

*/
var scrollToCenterOf = function scrollToCenterOf(elem, duration, offset) {
var scrollToCenterOf = function (elem, duration, offset) {
scrollToY(

@@ -168,39 +187,2 @@ Math.max(

var replaceUrl = function replaceUrl(hash) {
try {
history.replaceState({}, "", win.location.href.split("#")[0] + (hash ? "#" + hash : ""))
} catch (e) {
// To avoid the Security exception in Chrome when the page was opened via the file protocol, e.g., file://index.html
}
}
var internalLinkHandler = function internalLinkHandler(event) {
var anchor = event.target
while (anchor && anchor.tagName !== "A") {
anchor = anchor.parentNode
}
if (anchor) {
var href = anchor.getAttribute("href") || ""
if (href.indexOf("#") === 0) {
if (href === "#") {
event.preventDefault()
win.zenscroll.toY(0)
replaceUrl("")
} else {
var targetId = anchor.hash.substring(1)
var targetElem = document.getElementById(targetId)
if (targetElem) {
event.preventDefault()
win.zenscroll.to(targetElem)
replaceUrl(targetId)
}
}
}
}
}
// create listeners for the documentElement only & exclude IE8-
if (!scrollContainer && "addEventListener" in win && !win.noZensmooth) {
win.addEventListener("click", internalLinkHandler, false)
}
/**

@@ -213,7 +195,7 @@ * Changes default settings for this scroller.

*/
var setup = function setup(newDefaultDuration, newEdgeOffset) {
var setup = function (newDefaultDuration, newEdgeOffset) {
if (newDefaultDuration) {
defaultDuration = newDefaultDuration
}
if (newEdgeOffset !== null) {
if (newEdgeOffset === 0 || newEdgeOffset) {
edgeOffset = newEdgeOffset

@@ -235,8 +217,56 @@ }

// Create a scroller for the browser window, omitting parameters:
var defaultScroller = createScroller()
// Create listeners for the documentElement only & exclude IE8-
if ("addEventListener" in window && document.body.style.scrollBehavior !== "smooth" && !window.noZensmooth) {
var replaceUrl = function (hash) {
try {
history.replaceState({}, "", window.location.href.split("#")[0] + hash)
} catch (e) {
// To avoid the Security exception in Chrome when the page was opened via the file protocol, e.g., file://index.html
}
}
window.addEventListener("click", function (event) {
var anchor = event.target
while (anchor && anchor.tagName !== "A") {
anchor = anchor.parentNode
}
if (!anchor || event.which !== 1 || event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) {
return
}
var href = anchor.getAttribute("href") || ""
if (href.indexOf("#") === 0) {
if (href === "#") {
event.preventDefault() // Prevent the browser from handling the activation of the link
defaultScroller.toY(0)
replaceUrl("")
} else {
var targetId = anchor.hash.substring(1)
var targetElem = document.getElementById(targetId)
if (targetElem) {
event.preventDefault() // Prevent the browser from handling the activation of the link
defaultScroller.to(targetElem)
replaceUrl("#" + targetId)
}
}
}
}, false)
}
win.zenscroll = new win.Zenscroll()
return {
// Expose the "constructor" that can create a new scroller:
createScroller: createScroller,
// Surface the methods of the default scroller:
setup: defaultScroller.setup,
to: defaultScroller.to,
toY: defaultScroller.toY,
intoView: defaultScroller.intoView,
center: defaultScroller.center,
stop: defaultScroller.stop,
moving: defaultScroller.moving
}
}));
})(this, document);
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc