
Security News
Browserslist-rs Gets Major Refactor, Cutting Binary Size by Over 1MB
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
ember-concurrency-scroll
Advanced tools
A service to manage window and element scrolling using ember-concurrency.
This addon provides a scroller
service that leverages ember-concurrency tasks to manage window and element scrolling. By using ember-concurrency
, you can perform a scroll task, then chain a follow up task or action afterwards. This can be very useful in situations where you need to scroll to an element that needs the user's attention, by scrolling first, then calling the user's attention with some sort of behavior like a modal or popover.
The other benefit to using ember-concurrency
is that the scrolling task can be cancelled at any point, either by calling another scroll task, or explicitly cancelling it with cancelAll.
ember install ember-concurrency-scroll
ember-concurrency-scroll
offers three scrolling tasks via the scroller service
, two of which have functions that return a task, with accompanying task versions:
scroller.scrollToElementId(id, options)
(function)Primary use, allows you to scroll to a specific element by its id
attribute. Returns an Ember Concurrency task.
scroller.scrollToElementIdTask(id, options)
(async function)Ember Concurrency task that version of scrollToElementId
. Primary use, allows you to scroll to a specific element by its id
attribute.
scroller.scrollToElement(element, options)
(function)Allows you to scroll to an element by passing the element itself. Useful for components to scroll to themselves if they're out of the viewport. Returns an Ember Concurrency task.
scroller.scrollToElementTask(element, options)
(async function)Ember Concurrency task version of scrollToElement
. Allows you to scroll to an element by passing the element itself. Useful for components to scroll to themselves if they're out of the viewport.
scroller.scrollTo(start, end, options)
(function)Core function, handles actual scrolling via easing, calling window.scrollTo
or setting the value via element.scrollTop
and element.scrollLeft
. Start and end values can be either numeric (when we only want to scroll in one axis), OR they can be coordinate objects containing an x and y value ({x:0, y:0}). Returns an Ember Concurrency task.
scroller.scrollToTask(start, end, options)
(async function)Core task, handles actual scrolling via easing, calling window.scrollTo
or setting the value via element.scrollTop
and element.scrollLeft
. Start and end values can be either numeric (when we only want to scroll in one axis), OR they can be coordinate objects containing an x and y value ({x:0, y:0}).
Scroll duration in milliseconds. Default is 1000
.
Adds an offset to the number of pixels above and to the left of the target element when scrolling. Can either be a number (used for both x
and y
values), or an object containing x
and y
values. Useful if you want to scroll using scrollToElement
, but don't want to scroll to the exact position of the element. Can also be a negative value, to scroll past the target element position. Default is 20
.
Easing type used in scroll. Default is sinusoidal
.
Easing options are available (via the node-easing
library), but the default is a sinusoidal ease. The available easing types are:
cubic
circular
exponential
linear
quartic
quadratic
quintic
sinusoidal
(default)The number of ease steps are calculated using the scroll duration value (default is 1000ms), which results in an array of predefined easing steps used for the scrolling.
Determines the axis to scroll on, when the start
and end
values are numeric. Default is 'y'.
Determines if the scrollTo task should scroll if the target position is already in the viewport. Default is true
.
A DOM element or id to target for scrolling. Allows you to scroll the contents of fixed size elements with overflow property set to scroll. See the example below for further explanation.
Cancels all scrolling tasks. Useful to interrupt scrolling if the user scrolls during a scrolling task.
// example element-scroll component
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { task } from 'ember-concurrency';
export default Component.extend({
tagName: 'button',
scroller: service(),
scroll: task(function *() {
// It is recommended to wrap the scroller service task in component task to allow for cleanup if the component is destroyed mid task
yield this.get('scroller').scrollToElementId(...arguments);
}),
click() {
this.get('scroll').perform(this.get('target'), {
duration: 1500,
easeType: 'linear',
// padding determines the how far above or to the left of the target element to scroll to, so we don't scroll to the exact edge of the element
padding: {
x: 100,
y: 100
}
});
}
});
// implementing the component
{{#element-scroll target="title"}}scroll to title{{/element-scroll}}
Here are some ways for calling the scrollTo task directly. Do note that it is recommended that you follow ember-concurrency
's guidelines in implementing these tasks in your code, as calling them anywhere without managing the concurrency may have unintended results (like double scrolling or scrolls cancelling immediately):
// scroll on the y axis
this.get('scroller').scrollTo(0, 1000);
// scroll on the x axis
this.get('scroller').scrollTo(0, 1000, { axis: 'x' });
// scroll on both x and y
this.get('scroller').scrollTo({ x: 0, y: 0}, { x: 1000, y: 1000});
You can limit the scroll to a specific element, for instance, if you had a fixed size container that you wanted to scroll to a specific element inside that container, you'd pass either the container id or the element as the container
option. Note that if you do use the container option, it will only scroll inside the container, and the window will not scroll to the container element itself. You could solve this by first scrolling to the container, then scrolling to the element inside the container with the container option.
<div id="contents">
<div id="bibliography">
... stuff
</div>
<div id="title">
... titles
</div>
</div>
scrollToContentsTitle : task(function *() {
yield this.get('scroller').scrollToElementId('contents');
yield this.get('scroller').scrollToElementId('title', {container: 'contents'});
})
You can also use the perform
helper to call the tasks from inside a template, but it's not the recommended implementation so use at your own risk.
// note that options can be passed using the hash helper
<button onclick={{perform scroller.scrollToElementIdTask 'myDiv' (hash duration=2000)}}>My Div</button>
The scroller defaults can be set in config/environment.js
, allowing you to set the defaults for your entire app, rather than having to override every time you use the scroller.
// config/environment.js
/* eslint-env node */
'use strict';
module.exports = function(environment) {
let ENV = {
modulePrefix: 'dummy',
...
// add your defaults at the root level of the config
'ember-concurrency-scroll': {
duration: 1400,
easeType: 'linear',
padding: {
x: 0,
y: 0
},
// you can also set overrides which take preference over everything
// this is useful for testing purposes
// default is duration: 1 in testing mode
overrides: {
}
}
}
See the Contributing guide for details.
This project is licensed under the MIT License.
FAQs
A service to manage window and element scrolling using ember-concurrency.
The npm package ember-concurrency-scroll receives a total of 237 weekly downloads. As such, ember-concurrency-scroll popularity was classified as not popular.
We found that ember-concurrency-scroll demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Research
Security News
Eight new malicious Firefox extensions impersonate games, steal OAuth tokens, hijack sessions, and exploit browser permissions to spy on users.
Security News
The official Go SDK for the Model Context Protocol is in development, with a stable, production-ready release expected by August 2025.