Markodwn's detailed explanation of the idea of ​​synchronous scrolling with title alignment

Markodwn's detailed explanation of the idea of ​​synchronous scrolling with title alignment

Preface

I need to add a synchronized scrolling feature to the Markodwn editor I'm writing. I searched Baidu but couldn't find a good idea. I wrote one myself.

Github contains the completed library and a more intuitive demo.

Github

This article mainly talks about the implementation ideas.

introduce

There are many ways to implement synchronized scrolling. The simple and crude way is to make HTMLElement.scrollTop equal, and also make the scroll bars scroll proportionally and the titles align with the scrolling (this is what I saw on stackedit).

The main content of this article is how to implement title alignment and synchronous scrolling.

Personally, I prefer title alignment because it is more user-friendly than the other two.

In principle, title alignment is actually an improved version of proportional scrolling. Because their core is to determine the scrolling distance by calculating the height ratio of the editing area and the preview area.

DEMO

Below is the GIF image of DEMO

Note the # on the left.

You can see that as the scroll bar moves, the scrolling distances on the left and right sides are different.

This looks a bit like proportional scrolling, but they are different. The difference is that proportional scrolling determines the scrolling distance based on the full text height on both sides, while title alignment determines the scrolling distance based on the height of the content under the title.

Ideas

The above picture is a schematic diagram:

# heading means the title, content means the content under the title. I call title + content a fragment.

I think proportional scrolling should be relatively easy to understand. It is to calculate the height ratio of the editing area and the preview area, and then calculate the scrolling distance based on the ratio.

The title alignment is more precise. It changes the height of the editing area and the preview area to the title height + the height of the content under the title, that is, the height of the fragment, and then calculates the scroll distance based on the height corresponding to the current fragment.

The md height and html height in the diagram above are the heights of the fragments we need.

Obviously, as long as we use the ratio of these two heights, we can calculate the corresponding scrolling distance.

Specific process

First, the title information of the editing area and preview area is needed. The data structure is as follows. Use editFragmentsInfo and preFragmentsInfo instead

FragmentInfo: {
    pairId, // The id used to match the title corresponding to the edit area/preview area
    offsetTop, // Distance from the top offset height // Height of title plus content}

Then you need a method to get the title block at the top of the current page. Here we use getCurrentFragment() instead.

Next, in the scroll event of the editArea/previewArea, a message is sent to the previewArea/editArea to notify it that scrolling is about to begin.

After receiving in another area, perform the following operations. (Assume that the active scrolling area is the editing area, and the passive scrolling area is the preview area, which is another area)

  1. First, get the current title at the top using getCurrentHeading() mentioned above.
  2. Then match the corresponding title in the preview area.
  3. The value calculated based on the ratio of headingInfo.height on both sides plus the value of headingInfo.offsetTop is the scrollTop of the preview area.
  4. At this point, a synchronization is complete. This process is bound to the scroll event of the element, and this process is triggered every time you scroll.

Synchronization issues

Because the scrolling of one element will cause the scrolling of another element, this will inevitably form an infinite loop. Therefore, judgment must be made in the scrolling event to avoid an infinite loop.

This is a simple mutual exclusion method that supports mutual exclusion of more than two objects.

Summarize

The above is a detailed explanation of the idea of ​​synchronous scrolling of Markodwn title alignment introduced by the editor. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to you in time!

<<:  Detailed description of the life cycle of React components

>>:  In-depth analysis of MySQL lock blocking

Recommend

A brief analysis of controlled and uncontrolled components in React

Table of contents Uncontrolled components Control...

Implementation of vue-nuxt login authentication

Table of contents introduce Link start Continue t...

Let's talk in detail about the props attributes of components in Vue

Table of contents Question 1: How are props used ...

React Router V6 Updates

Table of contents ReactRouterV6 Changes 1. <Sw...

Build a high-availability MySQL cluster with dual VIP

Table of contents 1. Project Description: 2. Proj...

Image scrolling effect made with CSS3

Achieve resultsImplementation Code html <base ...

How to use watch listeners in Vue2 and Vue3

watch : listen for data changes (change events of...

Summary of HTML formatting standards for web-based email content

1. Page requirements 1) Use standard headers and ...

Detailed explanation of the use of this.$set in Vue

Table of contents Use of this.$set in Vue use Why...

How to install Apache service in Linux operating system

Download link: Operating Environment CentOS 7.6 i...

Css3 realizes seamless scrolling and anti-shake

question The seamless scrolling of pictures and t...