Sticky toolbar cho Trix editor

Đăng bởi Lưu Đại vào ngày 02-02-2023

1. Vấn đề. 

Khi viết các bài viết dài mình phải kéo, rê chuột chán chê lên trên để có thể dùng thanh công cụ của trix editor

2. Dùng sticky toolbar (tương tự như sticky header)

  • Ý tưởng là mình sẽ set max height cho trix editor và đặt overflow là scroll 
  • Sau đó lấy ra vị trí div cha của trix-editor so với đầu màn hình. 
  • Lấy ra vị trí của toolbar so với đầu màn hình. 
  • Sau khi trừ 2 giá trị này cho nhau mình được sticky. Sau khi scroll được sticky pixel thì sẽ append 1 class vào cho trix editor với position là fixed và vị trí top. Trong đó vị trí top cũng k cố định do tỉ lệ các màn hình khác nhau sẽ làm thay đổi số này nên cũng gán bằng js luôn. 
<div class="form-group content-input" id="trix-content-editor">
  <%= form.label :content, 'Content', id: 'content-label' %>
  <div>
    <%= form.rich_text_area :content, class: 'min-vh-60', data: {
      emoji_picker_target: "trixEditor"
    } %>
  </div>
</div>
Element mình dùng có dạng như sau. 
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {
    const trixToolbar = document.querySelectorAll('[id^=trix-toolbar]')[0];
    const trixEditor = document.getElementById('trix-content-editor');
    const adminContainer = document.getElementsByClassName('admin-container')[0];

    trixEditor.onscroll = function() {stickyScroll()}
    adminContainer.onscroll = function() {stickyScroll()}

    function stickyScroll() {
      var distanceToolbarToTop = trixToolbar.offsetTop;
      var distanceEditorToTop = trixEditor.offsetTop;
      var sticky = distanceToolbarToTop - distanceEditorToTop;
      var scrolled = adminContainer.scrollTop === 0 ? 0 : adminContainer.scrollTop + window.scrollY;
      var contentLabelToTop = document.getElementById('content-label').offsetTop - scrolled;

      if(trixEditor.scrollTop > sticky){
        trixToolbar.classList.add('sticky');
        trixToolbar.style.top = `${contentLabelToTop}px`;
      }
      if (trixEditor.scrollTop == 0) {
        trixToolbar.classList.remove('sticky');
        trixToolbar.style = '';
      }
    }
  }
}
Dùng jquery cho quen thuộc =)))

Sản phẩm tạo ra:
stiky_toolbar_trix.gif