SOURCE

console 命令行工具 X clear

                    
>
console
 class DualScroll {
  constructor(container) {
    this.container = document.querySelector(container);
    this.rows = Array.from(this.container.querySelectorAll('.section-row'));
    console.log("@@@@", this.rows)
    this.currentIndex = { row: 0, col: 0 };
    
    this.initScrollSnap();
    this.setupObservers();
    this.bindEvents();
  }

  initScrollSnap() {
    this.container.style.scrollBehavior = 'smooth';
  }

  setupObservers() {
    this.observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const row = this.rows.indexOf(entry.target.parentElement);
          const col = Array.from(entry.target.parentElement.children)
                         .indexOf(entry.target);
          this.currentIndex = { row, col };
        }
      });
    }, { threshold: 0.7 });

    this.rows.forEach(row => {
      Array.from(row.children).forEach(section => {
        this.observer.observe(section);
      });
    });
  }

  bindEvents() {
    let startX, startY;
    this.container.addEventListener('wheel', (e) => {
      e.preventDefault();
      const { deltaX, deltaY } = e;
      
      if (Math.abs(deltaX) > Math.abs(deltaY)) {
        this.scrollTo(0, deltaX > 0 ? 1 : -1);
      } else {
        this.scrollTo(deltaY > 0 ? 1 : -1, 0);
      }
    }, { passive: false });

    // 触摸事件处理
    this.container.addEventListener('touchstart', (e) => {
      startX = e.touches[0].clientX;
      startY = e.touches[0].clientY;
    });

    this.container.addEventListener('touchend', (e) => {
      const endX = e.changedTouches[0].clientX;
      const endY = e.changedTouches[0].clientY;
      const diffX = startX - endX;
      const diffY = startY - endY;
      
      if (Math.abs(diffX) > Math.abs(diffY)) {
        this.scrollTo(0, diffX > 0 ? 1 : -1);
      } else {
        this.scrollTo(diffY > 0 ? 1 : -1, 0);
      }
    });
  }

  scrollTo(rowDelta, colDelta) {
    const newRow = Math.max(0, 
      Math.min(this.rows.length - 1, this.currentIndex.row + rowDelta));
    const newCol = Math.max(0, 
      Math.min(this.rows[newRow].children.length - 1, 
              this.currentIndex.col + colDelta));
    
    this.rows[newRow].children[newCol].scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center'
    });
  }
}

new DualScroll('#scroller');
  <div class="scroll-container" id="scroller">
    <div class="section-row">
      <div class="section">1-1</div>
      <div class="section">1-2</div>
      <div class="section">1-3</div>
    </div>
    <div class="section-row">
      <div class="section">2-1</div>
      <div class="section">2-2</div>
      <div class="section">2-3</div>
    </div>
  </div>
  <script src="script.js"></script>
 body { margin: 0; overflow: hidden; }
    .scroll-container {
      width: 100vw;
      height: 100vh;
      overflow: auto;
      scroll-snap-type: both mandatory;
    }
    .section-row {
      display: flex;
      width: 300vw; /* 3列水平滚动 */
      height: 100vh;
    }
    .section {
      flex: 0 0 100vw;
      height: 100vh;
      scroll-snap-align: start;
    }
    /* 奇数行背景色区分 */
    .section-row:nth-child(odd) .section { background: #f5f5f5; }
    .section-row:nth-child(even) .section { background: #e5e5e5; }