Search code examples
ckeditorckeditor4.x

Scrolling to elements in CKEditor via JavaScript


My CKEditor fields often contain lots of content with h1, h2, h3, etc headings, and I've written a script that presents all the headings in a sidebar for quick reference. I'd also like to use this sidebar as a navigation menu for the editor content, so clicking a heading in the sidebar scrolls the editor to the related heading, but I can't figure out how to wire it all up.

This post at https://davidwalsh.name/scroll-element-ckeditor leads me to believe that it should be possible, but I can't figure out how to get to the "editor" element described in the post.

My sidebar is built with jQuery from a CKEditor textarea with id="content" like this...

var content = $('<div/>').append($('#content').val());
var sidebar = "";
$(content).find('h1,h2,h3,h4,h5,h6').addClass('heading');
$(content).find('.heading').each(function () {
  sidebar += this.outerHTML;
});
$('#sidebar').html(sidebar);

I imagine using jQuery :contains() to identify heading elements in the editor based on the text they contain, but I can't figure out how to hook back into the CKEditor instance in a way that enables this kind of DOM activity.

I am using CKEditor 4 but am happy to upgrade to version 5 if it offers a better solution to my problem.

Thanks!


Solution

  • This is what wound up working for me:

      var content = $('<div/>').append($('#content').val());
      var sidebar = "";
      $(content).find('h1,h2,h3,h4,h5,h6').addClass('heading');
      $(content).find('.heading').each(function () {
        sidebar += this.outerHTML;
      });
      $('#sidebar').html(sidebar);
      $('#sidebar .heading').click(function() {
          var element = $('#cke_content iframe').contents().find(':contains(' + $(this).text() + ')')[2];
          if (element) {
              element.scrollIntoView();
          }
      });