Sticky Plugin

Makes the toolbar "stick" to the top of the viewport when scrolling, keeping it visible and accessible at all times. This plugin is especially useful for editors with large content where users need constant access to formatting tools.

Features

  • Toolbar remains fixed at top during scroll
  • Automatic activation when scrolling past editor
  • Configurable top offset for fixed headers
  • Mobile device detection and disable option
  • Dummy box to prevent content jump (IE)
  • Smooth sticky/unsticky transitions
  • Width auto-adjustment on resize
  • WYSIWYG mode only (no sticky in source mode)
  • Toggle event for external listeners
  • Sticky state query support

toolbarSticky

Type: boolean

Default: true

Enables or disables sticky toolbar behavior. When enabled, toolbar becomes fixed to viewport top when scrolling.

Example:

// Enable sticky toolbar (default)
const editor = Jodit.make('#editor', {
    toolbarSticky: true
});

// Disable sticky toolbar
const editor2 = Jodit.make('#editor2', {
    toolbarSticky: false
});

toolbarDisableStickyForMobile

Type: boolean

Default: true

When enabled, disables sticky toolbar on mobile devices. Mobile detection based on sizeSM config option compared to container width.

Example:

// Disable sticky on mobile (default)
const editor = Jodit.make('#editor', {
    toolbarDisableStickyForMobile: true
});

// Enable sticky on mobile too
const editor2 = Jodit.make('#editor2', {
    toolbarDisableStickyForMobile: false
});

toolbarStickyOffset

Type: number

Default: 0 (pixels)

Top offset for sticky toolbar position. Useful when site has fixed header that would otherwise cover the toolbar.

Example:

// No offset (default)
const editor1 = Jodit.make('#editor1', {
    toolbarStickyOffset: 0
});

// 100px offset for fixed site header
const editor2 = Jodit.make('#editor2', {
    toolbarStickyOffset: 100
});

// Joomla example with admin bar
const editor3 = Jodit.make('#editor3', {
    toolbarSticky: true,
    toolbarStickyOffset: 50  // Height of Joomla admin bar
});

Basic Sticky Toolbar

const editor = Jodit.make('#editor', {
    toolbarSticky: true
});

// Toolbar sticks to top when scrolling past editor
// User always has access to formatting buttons

Disable Sticky

const editor = Jodit.make('#editor', {
    toolbarSticky: false
});

// Toolbar scrolls away with content
// Normal inline toolbar behavior

With Fixed Site Header

// Site has 60px fixed header at top
const editor = Jodit.make('#editor', {
    toolbarSticky: true,
    toolbarStickyOffset: 60
});

// Toolbar sticks 60px from top
// Doesn't hide behind site header

Enable Sticky on Mobile

const editor = Jodit.make('#editor', {
    toolbarSticky: true,
    toolbarDisableStickyForMobile: false
});

// Sticky works on all devices including mobile

Disable Sticky on Mobile Only

const editor = Jodit.make('#editor', {
    toolbarSticky: true,
    toolbarDisableStickyForMobile: true  // Default
});

// Sticky on desktop, normal on mobile

Listen to Sticky State Changes

const editor = Jodit.make('#editor', {
    toolbarSticky: true
});

editor.e.on('toggleSticky', (isSticky) => {
    if (isSticky) {
        console.log('Toolbar is now sticky');
    } else {
        console.log('Toolbar is normal');
    }
});

Query Current Sticky State

const editor = Jodit.make('#editor');

// Check if toolbar is currently stuck
const isStuck = editor.e.fire('getStickyState');
console.log('Is toolbar stuck?', isStuck);

Large Content Example

const editor = Jodit.make('#editor', {
    toolbarSticky: true,
    toolbarStickyOffset: 0,
    height: 800
});

// User types long document
// Scrolls down to edit bottom sections
// Toolbar remains visible at top for formatting

Initialization

On plugin afterInit:

  1. Registers scroll/resize event listeners on owner window:
    • scroll.sticky - Window scroll
    • wheel.sticky - Mouse wheel
    • mousewheel.sticky - Legacy mouse wheel
    • resize.sticky - Window resize
  2. Registers getStickyState event handler (returns __isToolbarStuck)
  3. All scroll handlers throttled for performance

Scroll Detection

The __onScroll() method (throttled):

  1. Check Conditions:

    • toolbarSticky must be enabled
    • toolbar must exist
    • Editor must be in WYSIWYG mode (not source)
  2. Calculate Positions:

    • scrollWindowTop: Current scroll position (window.pageYOffset or documentElement.scrollTop)
    • offsetEditor: Editor container position relative to document
  3. Determine Sticky State:

    • Should be sticky if ALL true:
      • Editor is in WYSIWYG mode
      • Scroll position + offset > editor top (scrolled past editor start)
      • Scroll position + offset < editor top + height (not scrolled past editor end)
      • NOT (mobile disable enabled AND is mobile device)
  4. Apply or Remove Sticky:

    • If state changed: call addSticky() or removeSticky()
    • Fire toggleSticky event with new state

Add Sticky

The addSticky() method:

  1. If not already stuck:
    • Creates dummy box (IE only) if needed
    • Adds .jodit_sticky class to container
    • Sets __isToolbarStuck = true
  2. Always (even if already stuck):
    • Sets toolbar top CSS to toolbarStickyOffset (or null if 0)
    • Sets toolbar width to container width - 2px (for borders)
    • Sets dummy box height to toolbar height (prevents content jump)

Remove Sticky

The removeSticky() method:

  1. Returns if not stuck (no-op)
  2. Clears toolbar CSS:
    • Sets width to empty string (auto)
    • Sets top to empty string (auto)
  3. Removes .jodit_sticky class from container
  4. Sets __isToolbarStuck = false

Mobile Detection

The __isMobile() method:

  • Returns true if: editor.options.sizeSM >= editor.container.offsetWidth
  • sizeSM default is 768px (typical mobile breakpoint)
  • Detects narrow viewports as mobile

Dummy Box (IE)

For old Internet Explorer (non-ES-next):

  • Creates invisible dummy div: .jodit_sticky-dummy_toolbar
  • Inserted before toolbar in container
  • Height set to match toolbar height
  • Prevents content jump when toolbar becomes fixed
  • Not needed in modern browsers (handled by CSS)

CSS Classes

When sticky active:

  • Container gets .jodit_sticky class
  • CSS sets toolbar position: fixed and z-index
  • Width and top applied inline for precise control

Width Management

Toolbar width recalculated:

  • On every sticky state change
  • On window resize (via scroll handler)
  • Set to container.offsetWidth - 2 (accounts for 2px borders)
  • Ensures toolbar doesn't overflow container

Throttling

The __onScroll method decorated with @throttle():

  • Uses default throttle delay
  • Prevents excessive calculations during scroll
  • Improves performance, especially on mobile

Cleanup

On beforeDestruct:

  • Removes dummy box from DOM
  • Unregisters all .sticky namespaced events
  • Removes all event listeners from owner window

toggleSticky

Fired when sticky state changes (activated or deactivated).

Parameters:

  • doSticky (boolean): true if toolbar became sticky, false if unstuck

Example:

editor.e.on('toggleSticky', (isSticky) => {
    console.log('Sticky state changed:', isSticky);
    if (isSticky) {
        // Toolbar is now fixed to top
    } else {
        // Toolbar returned to normal position
    }
});

getStickyState

Query event to check current sticky state.

Returns: boolean - Current sticky state

Example:

const isStuck = editor.e.fire('getStickyState');
if (isStuck) {
    console.log('Toolbar is currently sticky');
}

Edge Cases

  1. Source Mode: Sticky disabled when editor in source mode (only WYSIWYG)
  2. No Toolbar: Plugin does nothing if toolbar: false in config
  3. Mobile: Automatically disabled on mobile if toolbarDisableStickyForMobile: true
  4. Editor Top: Sticky only activates when scrolled past editor start
  5. Editor Bottom: Sticky deactivates when scrolled past editor end
  6. Resize: Toolbar width recalculated on window resize
  7. Multiple Editors: Each editor has independent sticky state
  8. Fixed Headers: Use toolbarStickyOffset to avoid overlap
  9. IE Dummy Box: Only created in old IE to prevent content jump
  10. Scroll Events: Throttled to prevent performance issues

Notes

  • Plugin is class-based, extends Plugin base class
  • Uses @throttle decorator for scroll handler
  • Event namespacing: .sticky for clean removal
  • CSS class: .jodit_sticky on container when active
  • Dummy box class: .jodit_sticky-dummy_toolbar (IE only)
  • Mobile detection via sizeSM config (default 768px)
  • Width calculation: container.offsetWidth - 2 (for borders)
  • Top position: toolbarStickyOffset or null
  • Sticky only in WYSIWYG mode, not in source/split modes
  • The NEED_DUMMY_BOX constant checks for IE (!IS_ES_NEXT && IS_IE)
  • Scroll position calculated with fallback chain
  • Uses offset() helper to get editor position
  • The addSticky and removeSticky methods are public
  • Scroll events: scroll, wheel, mousewheel, resize
  • All attached to owner window (jodit.ow)
  • The plugin properly cleans up dummy box on destruction
  • Toolbar container accessed via jodit.toolbarContainer
  • The __isToolbarStuck flag tracks current state
  • State change only triggers if different from current
  • Width set on every sticky application (handles resize)
  • Top offset can be 0 for no offset (null in CSS)
  • The css() helper used for inline style manipulation
  • The Dom.safeRemove() safely removes dummy box
  • Sticky state fires event for external integrations
  • Query event allows checking state without direct access

Typical Use Case

Users working with long documents need constant access to formatting tools. The sticky plugin provides this by:

  1. Keeping toolbar visible at top when scrolling
  2. Preventing need to scroll back up for formatting
  3. Supporting site layouts with fixed headers via offset
  4. Automatically disabling on mobile to save screen space
  5. Smooth activation/deactivation as user scrolls

This improves user experience by:

  • Maintaining access to all editor functions while scrolling
  • Reducing vertical scrolling to reach toolbar
  • Adapting to site layout with offset option
  • Respecting mobile viewport constraints
  • Providing consistent formatting access in long documents

Classes