JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html>
  <div id="content">
   ...

CSS

#content {
  width: 400px;
  height: 274px;
  font-size: 20px;
  overflow-y: scroll;
  line-height: 1.5;
  cursor: default; /* 统一光标样式 */
  text-align: center;
  margin: 0 auto;
  background-color: #ddd;
}
p {
  margin: 0 auto;
}

JavaScript

const content = document.getElementById('content');
let isDragging = false;
let isMiddleButtonDown = false;
let initialY = 0;

// 获取行高函数(保持原有逻辑)
function getLineHeight() {
  const computed = window.getComputedStyle(content);
  let lineHeight = parseFloat(computed.lineHeight);
  if (isNaN(lineHeight)) {
    const fontSize = parseFloat(computed.fontSize);
    lineHeight = fontSize * 1.2;
  }
  return lineHeight;
}

// 滚轮控制(保持原有逻辑)
content.addEventListener('wheel', (e) => {
  e.preventDefault();
  const lineHeight = getLineHeight();
  content.scrollBy(0, Math.sign(e.deltaY) * lineHeight);
});

// 滚动条拖动对齐(修改原有逻辑排除中键)
content.addEventListener('mousedown', (e) => {
  if (e.button !== 1) isDragging = true;
});

content.addEventListener('mouseup', (e) => {
  if (e.button !== 1) isDragging = false;
});

content.addEventListener('scroll', () => {
  if (!isDragging) return;
  
  const lineHeight = getLineHeight();
  const alignedPosition = Math.round(content.scrollTop / lineHeight) * lineHeight;
  content.scrollTo(0, alignedPosition);
});

// 新增鼠标中键控制
content.addEventListener('mousedown', (e) => {
  if (e.button === 1) { // 中键
    e.preventDefault();
    isMiddleButtonDown = true;
    initialY = e.clientY;
    content.style.cursor = 'grabbing'; // 改变光标样式

    const onMouseMove = (e) => {
      if (!isMiddleButtonDown) return;
      
      const currentY = e.clientY;
      const deltaY = currentY - initialY;
      const lineHeight = getLineHeight();
      const threshold = lineHeight / 2;

      if (Math.abs(deltaY) >= threshold) {
        const direction = Math.sign(deltaY);
        const lines = Math.floor(Math.abs(deltaY) / threshold);
        
        content.scrollBy(0, direction * lines * lineHeight);
        initialY = currentY - (deltaY % threshold) * direction;
      }
    };

    const onMouseUp = (e) => {
      if (e.button === 1) {
        isMiddleButtonDown = false;
        content.style.cursor = 'default';
        
        // 移除事件监听
       ...