Giter Club home page Giter Club logo

sticksy's Introduction

Sticksy.js 📌

npm gzip size hits snyk license

Sticksy.js is a zero-dependency JavaScript library that sticks your elements to the top until they reaching the bottom. Unlike Q2W3 WordPress Plugin, you don't need WordPress, jQuery, or other stuff. You can use it in any web project.
It's simple and ultra fast. ⚡

Just import and initialize:

var stickyElems = Sticksy.initializeAll('.container > .sticky') // and that's all!

⚠️ The library is not a position: sticky polyfill, it makes the sibling elements move down.


Fixed widgets in sidebar

When do you need Sticksy?

The basic use-case of the library is to make fixed widgets in a sidebar.

The library is especially useful for ads or other items that visitors want to interact with. Sticky blocks are perceived much better by your visitors than unfixed widgets and therefore they have a significantly higher click-through rate.

But also you can use it for some design features.

Features

  • Setup in one line
  • Super performance
  • Zero dependencies
  • Fully written in ES5
  • Can react to DOM changes
  • Small size ~1.8Kb (minified gzip)

Demo

More examples in this folder.

Installation

You can simply install the library from CDN, NPM, Yarn or just download it from this repo.

CDN

Just insert the proper version of the library into your page:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/sticksy.min.js"></script>

NPM

$ npm install sticksy --save

Yarn

$ yarn add sticksy

🧱 Import an entire module if you use Webpack, Rollup or other module bundlers:

import 'sticksy'

Usage

Watch an example.

<!-- Container -->
<aside class="sidebar">
    <!-- Non sticky element -->
    <div class="widget"></div>
    <!-- Sticky element -->
    <div class="widget js-sticky-widget"></div>
    <div class="widget"></div>
    <div class="widget"></div>
</aside>

⚠️ The container shouldn't be absolutely positioned as we use absolute position to stuck the elements to the bottom.

Then you should initialize an instance with a new keyword (it's important):

var stickyEl = new Sticksy('.js-sticky-widget')
// just for demonstration of state handling
stickyEl.onStateChanged = function (state) {
    if (state === 'fixed') stickyEl.nodeRef.classList.add('widget--fixed')
    else stickyEl.nodeRef.classList.remove('widget--fixed')
}

That's all 😎

Also, you can directly pass the target node:

var stickyEl = new Sticksy(document.getElementById('sticky-widget'))

Via JQuery/Zepto:

var stickyEl = $('.widget.js-sticky-widget').sticksy({ topSpacing: 60, listen: true })

Initialize all sticky elements

You can add the one class to all the target elements and initialize them all in one line:

<aside class="sidebar">
    <div class="widget"></div>
    <!-- Sticky element -->
    <div class="widget js-sticky-widget"></div>
</aside>
<main>
    <!-- Some content here -->
</main>
<aside class="sidebar">
    <!-- Sticky element -->
    <div class="widget js-sticky-widget"></div>
    <div class="widget"></div>
</aside>
var stickyElements = Sticksy.initializeAll('.js-sticky-widget')

Enable reaction to DOM changes

The library can detect changes of the container and its children by using MutationObserver. To enable this behavior, you have to specify listen option.

var stickyEl = new Sticksy('.js-sticky-widget', {
    listen: true, // Listen for the DOM changes in the container
})

Beware! Since the library uses style attribute to change elements position, it ignores changes of width and height properties of style attribute. Use CSS classes instead.


More examples in example folder and this section.

API

The API is as simple as possible.

Constructor options

var instance = new Sticksy(target[, options]);
  • target (String | Element) target element or query string
  • options (ContructorOptions) all options below are optional
    • topSpacing: (Number) additional top spacing for the top sticky element when it becomes fixed (sticky). Use this option when you have a fixed top panel. Optional | Default: 0
    • listen: (Boolean) should we recalculate all cached dimensions of the viewport, container and sticky elements on any DOM changes in the container element. Optional | Default: false
  • Returns: Instance

Example:

var stickyEl = new Sticksy('.block.js-sticky-widget', {
    topSpacing: 60, // Specify this when you have a fixed top panel
    listen: true, // Listen for the DOM changes in the container
})

Instance object

Properties

  • nodeRef (Element) a direct reference to the DOM element
stickyEl.onStateChanged = function (state) {
    if (state === 'fixed') stickyEl.nodeRef.classList.add('widget--fixed')
    else stickyEl.nodeRef.classList.remove('widget--fixed')
}

Methods

refresh(): void

Recalculate and update the element according to the new state.

stickyEl.refresh()

hardRefresh(): void

Recalculate all cached dimensions of the viewport, container and sticky elements and update the element according to the new state. Use it for manual refreshing, for example, if you haven't specified listen option, but you have to deal with some DOM manipulations.

stickyEl.hardRefresh()

enable(): void

Enable 'sticky' effect.

stickyEl.enable()

disable(): void

Make the element static.

stickyEl.disable()

Events

onStateChanged

Triggered when the state of the element has changed. The state can be: static, fixed and stuck.

stickyEl.onStateChanged = function (state) {
    // your handler here
    if (state === 'fixed') alert('it is fixed!')
}

Static methods

refreshAll(): void

Call refresh() method for the initialized instances.

Sticksy.refreshAll()

hardRefreshAll(): void

Call hardRefresh() method for the initialized instances.

Sticksy.hardRefreshAll()

enableAll(): void

Call enable() method for all the initialized instances.

Sticksy.enableAll()

disableAll(): void

Call disable() method for all the initialized instances.

Sticksy.disableAll()

Helper methods

initializeAll(target[, options][, ignorenothingfound])

Find and initialize all the elements with the same options. By default, it doesn't throw an error if nothing found.

  • target (String | Element | Element[] | jQuery) target element(s) or query string. Required

  • options (ContructorOptions) options for the target elements. Optional

  • ignoreNothingFound (Boolean) should we throw an error if no match is found. Default: true

  • Returns: Instance

Example:

var stickyElems = Sticksy.initializeAll('.js-sticky-widget', { listen: true }, true)

Performance

Performance is ultra high. ⚡

The library uses the simplest function to calculate the elements state:

Sticksy.prototype._calcState = function (windowOffset) {
    if (windowOffset < this._limits.top) {
        return States.STATIC
    } else if (windowOffset >= this._limits.bottom) {
        return States.STUCK
    }
    return States.FIXED
}

The function doesn't have any complicated calculations. It just compares two variables. Not more.
If the calculated state is the same as previous the library does nothing.

Cool, right? 😃

Browser Compatibility

Sticksy.js works in all modern browsers including Internet Explorer 11.
If you want the library to react to DOM changes and need to support IE10 or below, you should install Mutation Observer Polyfill.

Please, open an issue if you have any browser compatibility problems.

License (MIT)

WWWWWW||WWWWWW
 W W W||W W W
      ||
    ( OO )__________
     /  |           \
    /o o|    MIT     \
    \___/||_||__||_|| *
         || ||  || ||
        _||_|| _||_||
       (__|__|(__|__|

Sticksy.js is released under the MIT license.
Copyright (c) 2019-present Artem Kovalchuk

sticksy's People

Contributors

kovart avatar steelkovalchuk 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

sticksy's Issues

Window resize listener?

Tried

$(window).on('load resize orientationchange', function () {
	if (window.matchMedia("(min-width: 768px)").matches) {
		var stickyEl = new Sticksy('.s-cont > .sticky');
		stickyEl.hardRefresh()
	}else{
		Sticksy.disableAll(); ///seems do not clean the markup
	}
});

But after that i see a LOT of sticksy hidden nodes and element mispositioned till the page reload.

How to refresh state after window resize and clear the markup when sticky functionality is not needed?

Снимок экрана 2021-05-21 в 15 39 33

Dynamic topSpacing ?

Hi

Is it possible to change the topSpacing value "on-the-fly"? We have a responsive sticky header that changes height during scroll or resize (and at some point disappears completely) and a sidebar that has always the same distance to the header (or the top document border if the header is not visible). If we scroll, the sidebar pans with a spacing (like 50px) from the header that is 100px in height. So the sidebar should be positioned 150px from the top document border. If the header shrinks to 50px, the sidebar should be 100px from the top document. And if the header dissapears completely, the sidebar distance between document top and sidebar should be 50px. Is this possible with your sticky plugin? Can I overwrite the topSpacing value while the script is already running? Or does topSpacing support a dynamic function?

Enable/disable with jQuery

Hi, thanks for the plugin, it's really great.

I was wondering if you can tell me how to enable and disable with jquery? I want to disable on smaller screen size (mobile).

$('.sticky-element').sticksy({
    topSpacing: 20,
    listen: true
});

Thanks

Collapse (bootstrap) inside sticky element

We have a similar problem as #10 with a collapse (bootstrap) inside a sticky element.
Since the height is a fixed style property on the sticky element which only updates after the collapse is finished we get this jump in height all of a sudden. Is there a way to fix this?

You can find a recording of whats happening in the attachment.

Screen.Recording.2023-10-25.at.13.29.54.mov

Problem partially solved with an accordion

Hi, i'm using your plugin on a woocommerce site to sticky the add to cart bar, it works quite good, but i've a problem.

This bar has an accordion inside it, when i open an accordio it goes on overflow and sticky container doesn't move, it update only if i scroll the page back up of about 200px, so i made this script to hardrefresh whene i click on an item in the widget.
it quite works, but obviously it refreshes after some time, so you can see an overflow then after half second it jumps up, obviously i can't hide this overflow cause the sticky element is in absolute position....

can you suggest something? or some bugfix directly to the plugin?
thanks a lot

var stickyEl = new Sticksy('.js-sticky-widget', {
topSpacing: 85,
listen: true
})
stickyEl.onStateChanged = function (state) {
if(state === 'fixed') stickyEl.nodeRef.classList.add('widget--sticky')
else stickyEl.nodeRef.classList.remove('widget--sticky')
}

let timeOut;
jQuery('.js-sticky-widget *').click(function () {
console.log('click');
clearTimeout(timeOut);
timeOut = setTimeout(function () {
console.log('refresh');
stickyEl.hardRefresh();
}, 700)
});

image

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.