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

scroll-into-view-if-needed

Package Overview
Dependencies
Maintainers
1
Versions
83
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scroll-into-view-if-needed - npm Package Compare versions

Comparing version 1.4.1 to 1.5.0

9

CHANGELOG.md

@@ -11,2 +11,8 @@ # Changelog

## [1.5.0] - 2018-02-25
### Added
* `sideEffects: false` in package.json to enable optimizations introduced in webpack v4.
## [1.4.0] - 2017-11-17

@@ -161,3 +167,4 @@

[unreleased]: https://github.com/stipsan/scroll-into-view-if-needed/compare/v1.4.0...HEAD
[unreleased]: https://github.com/stipsan/scroll-into-view-if-needed/compare/v1.5.0...HEAD
[1.5.0]: https://github.com/stipsan/scroll-into-view-if-needed/compare/v1.4.0...v1.5.0
[1.4.0]: https://github.com/stipsan/scroll-into-view-if-needed/compare/v1.3.0...v1.4.0

@@ -164,0 +171,0 @@ [1.3.0]: https://github.com/stipsan/scroll-into-view-if-needed/compare/v1.2.8...v1.3.0

431

dist/bundle.js
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.scrollIntoViewIfNeeded = {})));
}(this, (function (exports) { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.scrollIntoViewIfNeeded = factory());
}(this, (function () { 'use strict';
var __assign = (undefined && undefined.__assign) || Object.assign || function(t) {
/**
* https://github.com/gre/bezier-easing
* BezierEasing - use bezier curve for transition easing function
* by Gaëtan Renaudeau 2014 - 2015 – MIT License
*/
// These values are established by empiricism with tests (tradeoff: performance VS precision)
var NEWTON_ITERATIONS = 4;
var NEWTON_MIN_SLOPE = 0.001;
var SUBDIVISION_PRECISION = 0.0000001;
var SUBDIVISION_MAX_ITERATIONS = 10;
var kSplineTableSize = 11;
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
var float32ArraySupported = typeof Float32Array === 'function';
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
function C (aA1) { return 3.0 * aA1; }
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
function binarySubdivide (aX, aA, aB, mX1, mX2) {
var currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) {
aB = currentT;
} else {
aA = currentT;
}
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
return currentT;
}
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
var currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) {
return aGuessT;
}
var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
var src = function bezier (mX1, mY1, mX2, mY2) {
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
throw new Error('bezier x values must be in [0, 1] range');
}
// Precompute samples table
var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
if (mX1 !== mY1 || mX2 !== mY2) {
for (var i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
}
function getTForX (aX) {
var intervalStart = 0.0;
var currentSample = 1;
var lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
// Interpolate to provide an initial guess for t
var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
var guessForT = intervalStart + dist * kSampleStepSize;
var initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= NEWTON_MIN_SLOPE) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
}
return function BezierEasing (x) {
if (mX1 === mY1 && mX2 === mY2) {
return x; // linear
}
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
if (x === 0) {
return 0;
}
if (x === 1) {
return 1;
}
return calcBezier(getTForX(x), mY1, mY2);
};
};
// Predefined set of animations. Similar to CSS easing functions
var animations = {
ease: src(0.25, 0.1, 0.25, 1),
easeIn: src(0.42, 0, 1, 1),
easeOut: src(0, 0, 0.58, 1),
easeInOut: src(0.42, 0, 0.58, 1),
linear: src(0, 0, 1, 1)
};
var amator = animate;
function animate(source, target, options) {
var start= Object.create(null);
var diff = Object.create(null);
options = options || {};
// We let clients specify their own easing function
var easing = (typeof options.easing === 'function') ? options.easing : animations[options.easing];
// if nothing is specified, default to ease (similar to CSS animations)
if (!easing) {
if (options.easing) {
console.warn('Unknown easing function in amator: ' + options.easing);
}
easing = animations.ease;
}
var step = typeof options.step === 'function' ? options.step : noop;
var done = typeof options.done === 'function' ? options.done : noop;
var scheduler = getScheduler(options.scheduler);
var keys = Object.keys(target);
keys.forEach(function(key) {
start[key] = source[key];
diff[key] = target[key] - source[key];
});
var durationInMs = options.duration || 400;
var durationInFrames = Math.max(1, durationInMs * 0.06); // 0.06 because 60 frames pers 1,000 ms
var previousAnimationId;
var frame = 0;
previousAnimationId = scheduler.next(loop);
return {
cancel: cancel
}
function cancel() {
scheduler.cancel(previousAnimationId);
previousAnimationId = 0;
}
function loop() {
var t = easing(frame/durationInFrames);
frame += 1;
setValues(t);
if (frame <= durationInFrames) {
previousAnimationId = scheduler.next(loop);
step(source);
} else {
previousAnimationId = 0;
setTimeout(function() { done(source); }, 0);
}
}
function setValues(t) {
keys.forEach(function(key) {
source[key] = diff[key] * t + start[key];
});
}
}
function noop() { }
function getScheduler(scheduler) {
if (!scheduler) {
var canRaf = typeof window !== 'undefined' && window.requestAnimationFrame;
return canRaf ? rafScheduler() : timeoutScheduler()
}
if (typeof scheduler.next !== 'function') throw new Error('Scheduler is supposed to have next(cb) function')
if (typeof scheduler.cancel !== 'function') throw new Error('Scheduler is supposed to have cancel(handle) function')
return scheduler
}
function rafScheduler() {
return {
next: window.requestAnimationFrame.bind(window),
cancel: window.cancelAnimationFrame.bind(window)
}
}
function timeoutScheduler() {
return {
next: function(cb) {
return setTimeout(cb, 1000/60)
},
cancel: function (id) {
return clearTimeout(id)
}
}
}
var __assign$1 = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {

@@ -15,3 +225,3 @@ s = arguments[i];

};
var handleScroll = function (parent, _a) {
var handleScroll$1 = function (parent, _a) {
var scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop;

@@ -21,10 +231,9 @@ parent.scrollLeft = scrollLeft;

};
var calculate = function (target, options) {
if (!target || !(target instanceof HTMLElement)) {
function calculate(target, options) {
if (!target || !(target instanceof HTMLElement))
throw new Error('Element is required in scrollIntoViewIfNeeded');
}
var config = __assign({ handleScroll: handleScroll }, options);
var config = __assign$1({ handleScroll: handleScroll$1 }, options);
var defaultOffset = { top: 0, right: 0, bottom: 0, left: 0 };
config.offset = config.offset
? __assign({}, defaultOffset, config.offset) : defaultOffset;
? __assign$1({}, defaultOffset, config.offset) : defaultOffset;
function withinBounds(value, min, max, extent) {

@@ -79,2 +288,3 @@ if (config.centerIfNeeded === false ||

var clientTop = parent.offsetTop + parent.clientTop;
// Make area relative to parent's client area.
area = area

@@ -85,178 +295,11 @@ .relativeFromTo(target, parent)

var scrollTop = withinBounds(parent.scrollTop, area.bottom - parent.clientHeight, area.top, parent.clientHeight);
// Pass the new coordinates to the handleScroll callback
config.handleScroll(parent, { scrollLeft: scrollLeft, scrollTop: scrollTop }, config);
// Determine actual scroll amount by reading back scroll properties.
area = area.translate(clientLeft - parent.scrollLeft, clientTop - parent.scrollTop);
target = parent;
}
};
}
var NEWTON_ITERATIONS = 4;
var NEWTON_MIN_SLOPE = 0.001;
var SUBDIVISION_PRECISION = 0.0000001;
var SUBDIVISION_MAX_ITERATIONS = 10;
var kSplineTableSize = 11;
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
var float32ArraySupported = typeof Float32Array === 'function';
var A = function (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; };
var B = function (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; };
var C = function (aA1) { return 3.0 * aA1; };
var calcBezier = function (aT, aA1, aA2) {
return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
};
var getSlope = function (aT, aA1, aA2) {
return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
};
var binarySubdivide = function (aX, aA, aB, mX1, mX2) {
var currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) {
aB = currentT;
}
else {
aA = currentT;
}
} while (Math.abs(currentX) > SUBDIVISION_PRECISION &&
++i < SUBDIVISION_MAX_ITERATIONS);
return currentT;
};
var newtonRaphsonIterate = function (aX, aGuessT, mX1, mX2) {
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
var currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) {
return aGuessT;
}
var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
};
var bezier = function (mX1, mY1, mX2, mY2) {
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
throw new Error('bezier x values must be in [0, 1] range');
}
var sampleValues = float32ArraySupported
? new Float32Array(kSplineTableSize)
: new Array(kSplineTableSize);
if (mX1 !== mY1 || mX2 !== mY2) {
for (var i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
}
var getTForX = function (aX) {
var intervalStart = 0.0;
var currentSample = 1;
var lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
var dist = (aX - sampleValues[currentSample]) /
(sampleValues[currentSample + 1] - sampleValues[currentSample]);
var guessForT = intervalStart + dist * kSampleStepSize;
var initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= NEWTON_MIN_SLOPE) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
}
else if (initialSlope === 0.0) {
return guessForT;
}
else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
};
return function (x) {
if (mX1 === mY1 && mX2 === mY2) {
return x;
}
if (x === 0) {
return 0;
}
if (x === 1) {
return 1;
}
return calcBezier(getTForX(x), mY1, mY2);
};
};
var noop = function () { };
var getScheduler = function (scheduler) {
if (!scheduler) {
var canRaf = typeof window !== 'undefined' && window.requestAnimationFrame;
return canRaf ? rafScheduler() : timeoutScheduler();
}
if (typeof scheduler.next !== 'function')
throw new Error('Scheduler is supposed to have next(cb) function');
if (typeof scheduler.cancel !== 'function')
throw new Error('Scheduler is supposed to have cancel(handle) function');
return scheduler;
};
var rafScheduler = function () { return ({
next: window.requestAnimationFrame.bind(window),
cancel: window.cancelAnimationFrame.bind(window),
}); };
var timeoutScheduler = function () { return ({
next: function (cb) { return setTimeout(cb, 1000 / 60); },
cancel: function (id) { return clearTimeout(id); },
}); };
var animate = function (source, target, options) {
var start = Object.create(null);
var diff = Object.create(null);
var animations = {
ease: bezier(0.25, 0.1, 0.25, 1),
easeIn: bezier(0.42, 0, 1, 1),
easeOut: bezier(0, 0, 0.58, 1),
easeInOut: bezier(0.42, 0, 0.58, 1),
linear: bezier(0, 0, 1, 1),
};
options = options || {};
var easing = typeof options.easing === 'function'
? options.easing
: animations[options.easing];
if (!easing) {
if (options.easing) {
console.warn('Unknown easing function in amator: ' + options.easing);
}
easing = animations.ease;
}
var step = typeof options.step === 'function' ? options.step : noop;
var done = typeof options.done === 'function' ? options.done : noop;
var scheduler = getScheduler(options.scheduler);
var keys = Object.keys(target);
keys.forEach(function (key) {
start[key] = source[key];
diff[key] = target[key] - source[key];
});
var durationInMs = options.duration || 400;
var durationInFrames = Math.max(1, durationInMs * 0.06);
var previousAnimationId;
var frame = 0;
var setValues = function (t) {
keys.forEach(function (key) {
source[key] = diff[key] * t + start[key];
});
};
var loop = function () {
var t = easing(frame / durationInFrames);
frame += 1;
setValues(t);
if (frame <= durationInFrames) {
previousAnimationId = scheduler.next(loop);
step(source);
}
else {
previousAnimationId = 0;
setTimeout(function () {
done(source);
}, 0);
}
};
previousAnimationId = scheduler.next(loop);
var cancel = function () {
scheduler.cancel(previousAnimationId);
previousAnimationId = 0;
};
return { cancel: cancel };
};
var __assign$1 = (undefined && undefined.__assign) || Object.assign || function(t) {
var __assign = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {

@@ -269,6 +312,6 @@ s = arguments[i];

};
var handleScroll$1 = function (parent, _a, config) {
var handleScroll = function (parent, _a, config) {
var scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop;
if (config.duration) {
animate(parent, {
amator(parent, {
scrollLeft: scrollLeft,

@@ -283,10 +326,10 @@ scrollTop: scrollTop,

};
var isBoolean = function (options) {
function isBoolean(options) {
return typeof options === 'boolean';
};
var scrollIntoViewIfNeeded = function (target, options, animateOptions, finalElement, offsetOptions) {
}
function scrollIntoViewIfNeeded(target, options, animateOptions, finalElement, offsetOptions) {
if (offsetOptions === void 0) { offsetOptions = {}; }
if (!target || !(target instanceof HTMLElement))
throw new Error('Element is required in scrollIntoViewIfNeeded');
var config = { centerIfNeeded: false, handleScroll: handleScroll$1 };
var config = { centerIfNeeded: false, handleScroll: handleScroll };
if (isBoolean(options)) {

@@ -296,7 +339,7 @@ config.centerIfNeeded = options;

else {
config = __assign$1({}, config, options);
config = __assign({}, config, options);
}
var defaultOffset = { top: 0, right: 0, bottom: 0, left: 0 };
config.offset = config.offset
? __assign$1({}, defaultOffset, config.offset) : defaultOffset;
? __assign({}, defaultOffset, config.offset) : defaultOffset;
if (animateOptions) {

@@ -322,10 +365,6 @@ config.duration = animateOptions.duration;

return calculate(target, config);
};
}
exports.calculate = calculate;
exports['default'] = scrollIntoViewIfNeeded;
exports.scrollIntoViewIfNeeded = scrollIntoViewIfNeeded;
return scrollIntoViewIfNeeded;
Object.defineProperty(exports, '__esModule', { value: true });
})));

@@ -11,4 +11,4 @@ export interface Offset {

}
export declare type handleScrollCallback = (parent: HTMLElement, coordinates: ScrollCoordinates, config: CalculateOptions) => void;
export interface CalculateOptions {
export declare type handleScrollCallback = (parent: HTMLElement, coordinates: ScrollCoordinates, config: Options) => void;
export interface Options {
handleScroll?: handleScrollCallback;

@@ -19,2 +19,2 @@ boundary?: Element;

}
export declare const calculate: (target: Element, options: CalculateOptions) => void;
export default function calculate(target: Element, options: Options): void;

@@ -14,6 +14,5 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {

};
export var calculate = function (target, options) {
if (!target || !(target instanceof HTMLElement)) {
export default function calculate(target, options) {
if (!target || !(target instanceof HTMLElement))
throw new Error('Element is required in scrollIntoViewIfNeeded');
}
var config = __assign({ handleScroll: handleScroll }, options);

@@ -72,2 +71,3 @@ var defaultOffset = { top: 0, right: 0, bottom: 0, left: 0 };

var clientTop = parent.offsetTop + parent.clientTop;
// Make area relative to parent's client area.
area = area

@@ -78,6 +78,8 @@ .relativeFromTo(target, parent)

var scrollTop = withinBounds(parent.scrollTop, area.bottom - parent.clientHeight, area.top, parent.clientHeight);
// Pass the new coordinates to the handleScroll callback
config.handleScroll(parent, { scrollLeft: scrollLeft, scrollTop: scrollTop }, config);
// Determine actual scroll amount by reading back scroll properties.
area = area.translate(clientLeft - parent.scrollLeft, clientTop - parent.scrollTop);
target = parent;
}
};
}

@@ -1,2 +0,22 @@

export { calculate } from './calculate';
export { default, default as scrollIntoViewIfNeeded, Options } from './transition';
import { Options as CalculateOptions } from './calculate';
export interface AnimateOptions {
duration?: number;
easing?: 'ease' | 'easeIn' | 'easeOut' | 'easeInOut' | 'linear';
}
export interface OffsetConfig {
offsetTop?: number;
offsetLeft?: number;
offsetBottom?: number;
offsetRight?: number;
}
export interface Offset {
top?: number;
right?: number;
bottom?: number;
left?: number;
}
export interface Options extends CalculateOptions {
duration?: number;
easing?: 'ease' | 'easeIn' | 'easeOut' | 'easeInOut' | 'linear';
}
export default function scrollIntoViewIfNeeded(target: Element, options: boolean | Options, animateOptions?: AnimateOptions, finalElement?: Element, offsetOptions?: OffsetConfig): void;

@@ -1,2 +0,61 @@

export { calculate } from './calculate';
export { default, default as scrollIntoViewIfNeeded, } from './transition';
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
import animate from 'amator';
import calculate from './calculate';
var handleScroll = function (parent, _a, config) {
var scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop;
if (config.duration) {
animate(parent, {
scrollLeft: scrollLeft,
scrollTop: scrollTop,
}, { duration: config.duration, easing: config.easing });
}
else {
parent.scrollLeft = scrollLeft;
parent.scrollTop = scrollTop;
}
};
function isBoolean(options) {
return typeof options === 'boolean';
}
export default function scrollIntoViewIfNeeded(target, options, animateOptions, finalElement, offsetOptions) {
if (offsetOptions === void 0) { offsetOptions = {}; }
if (!target || !(target instanceof HTMLElement))
throw new Error('Element is required in scrollIntoViewIfNeeded');
var config = { centerIfNeeded: false, handleScroll: handleScroll };
if (isBoolean(options)) {
config.centerIfNeeded = options;
}
else {
config = __assign({}, config, options);
}
var defaultOffset = { top: 0, right: 0, bottom: 0, left: 0 };
config.offset = config.offset
? __assign({}, defaultOffset, config.offset) : defaultOffset;
if (animateOptions) {
config.duration = animateOptions.duration;
config.easing = animateOptions.easing;
}
if (finalElement) {
config.boundary = finalElement;
}
if (offsetOptions.offsetTop) {
config.offset.top = offsetOptions.offsetTop;
}
if (offsetOptions.offsetRight) {
config.offset.right = offsetOptions.offsetRight;
}
if (offsetOptions.offsetBottom) {
config.offset.bottom = offsetOptions.offsetBottom;
}
if (offsetOptions.offsetLeft) {
config.offset.left = offsetOptions.offsetLeft;
}
return calculate(target, config);
}

@@ -11,3 +11,3 @@ {

},
"version": "1.4.1",
"version": "1.5.0",
"main": "dist/bundle.js",

@@ -34,2 +34,6 @@ "scripts": {

},
"sideEffects": false,
"dependencies": {
"amator": "1.0.1"
},
"devDependencies": {

@@ -75,5 +79,2 @@ "@types/next": "^2.4.5",

],
"publishConfig": {
"tag": "next"
},
"lint-staged": {

@@ -106,6 +107,5 @@ "*.js": [

"generateNotes": "semantic-release-tamia/generateNotes",
"verifyRelease": "semantic-release-tamia/verifyRelease",
"branch": "next"
"verifyRelease": "semantic-release-tamia/verifyRelease"
},
"typings": "dist/index.d.ts"
}

@@ -1,3 +0,5 @@

# scroll-into-view-if-needed &middot; [![CircleCI Status](https://img.shields.io/circleci/project/github/stipsan/scroll-into-view-if-needed.svg?style=flat-square)](https://circleci.com/gh/stipsan/scroll-into-view-if-needed) [![npm stat](https://img.shields.io/npm/dm/scroll-into-view-if-needed.svg?style=flat-square)](https://npm-stat.com/charts.html?package=scroll-into-view-if-needed) [![npm version](https://img.shields.io/npm/v/scroll-into-view-if-needed.svg?style=flat-square)](https://www.npmjs.com/package/scroll-into-view-if-needed) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)
[![CircleCI Status](https://img.shields.io/circleci/project/github/stipsan/scroll-into-view-if-needed.svg?style=flat-square)](https://circleci.com/gh/stipsan/scroll-into-view-if-needed) [![npm stat](https://img.shields.io/npm/dm/scroll-into-view-if-needed.svg?style=flat-square)](https://npm-stat.com/charts.html?package=scroll-into-view-if-needed) [![npm version](https://img.shields.io/npm/v/scroll-into-view-if-needed.svg?style=flat-square)](https://www.npmjs.com/package/scroll-into-view-if-needed) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)
![scroll-into-view-if-needed](https://user-images.githubusercontent.com/81981/36357426-2f0f3152-14fe-11e8-892a-915d06488171.png)
This is a [ponyfill](https://ponyfill.com) with the added ability of animating

@@ -22,3 +24,3 @@ the scroll itself.

```js
const { scrollIntoViewIfNeeded } = require('scroll-into-view-if-needed')
const scrollIntoViewIfNeeded = require('scroll-into-view-if-needed')
const node = document.getElementById('hero')

@@ -25,0 +27,0 @@

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