You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

电商网站分页按钮故障:代码删除致消失及重复容器疑问

分页功能实现问题排查

问题

  • 删除script.js中任意代码(如移除pageNumbers函数),页面分页按钮就会消失;
  • 不理解为何生成额外分页容器:JS仅通过document.createElement创建新的pagination-buttons元素,未关联HTML中已有容器,却出现重复分页按钮。

尝试注释代码段排查,但删除任何代码都会导致按钮消失,无法推进调试。

相关代码

原始HTML代码

<!DOCTYPE html>
<html lang="en">

    <head>
      
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Tech2etc Ecommerce Tutorial</title>
       
        <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" />

        <link rel="stylesheet" href="style.css">
        
        <link rel="stylesheet" href="pagination.css">

   
    </head>

    <body>


        <!-- Pagination Buttons -->

        <div class="pagination-buttons">
  <button type="button" class="page-btn prev-page">prev</button>
  <button type="button" class="page-btn start-page">start</button>
  <button type="button" class="page-btn active">1</button>
  <button type="button" class="page-btn">2</button>
  <button type="button" class="page-btn">3</button>
  <button type="button" class="page-btn">4</button>
  <button type="button" class="page-btn">5</button>
  <button type="button" class="page-btn">6</button>
  <button type="button" class="page-btn">7</button>
  <button type="button" class="page-btn">8</button>
  <button type="button" class="page-btn">9</button>
  <button type="button" class="page-btn next-page">next</button>
  <button type="button" class="page-btn end-page">end</button>
</div> 

<script src="script.js" defer>  </script>

        
    </body>

</html>

CSS代码

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  font-family: sans-serif;
  padding: 25px;
  background: #fff;
  color: #111;
  display: flex;
  justify-content: center;
  align-items: center;
}

*, *::after, *::before {
  box-sizing: border-box;
}

button {
  background: none;
  appearance: none;
  -webkit-appearance: none;
  -ms-appearance: none;
  -moz-appearance: none;
  border: none;
  cursor: pointer;
}

.page-btn {
  background: #ddd;
  color: #2c303a;
  height: 35px;
  border-radius: 2px;
  padding: 0 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  transition: background 0.3s ease;
  margin: 0 2px
}

.page-btn:first-of-type {
  margin-left: 0;
}

.page-btn:last-of-type {
  margin-right: 0;
}

.page-btn:not([class$="-page"]) {
  width: 35px;
}

.pagination-buttons {
  display: flex;
  align-items: center;
}

.page-btn[class*="-page"] {
  background: #ccc;
  font-size: 0.6em;
  font-weight: 700;
}

.page-btn.active {
  background: #717790;
  color: #fff;
}

.page-btn[disabled] {
  opacity: 0.3;
}

原始JavaScript代码

const pageNumbers = (total, max, current) => {
    const half = Math.floor(max / 2);
    let to = max;
    
    if(current + half >= total) {
      to = total;
    } else if(current > half) {
      to = current + half ;
    }
    
    let from = Math.max(to - max, 0);
  
    return Array.from({length: Math.min(total, max)}, (_, i) => (i + 1) + from);
  }
  
  function PaginationButton(totalPages, maxPagesVisible = 10, currentPage = 1) {
    let pages = pageNumbers(totalPages, maxPagesVisible, currentPage);
    let currentPageBtn = null;
    const buttons = new Map();
    const disabled = {
      start: () => pages[0] === 1,
      prev: () => currentPage === 1 || currentPage > totalPages,
      end: () => pages.slice(-1)[0] === totalPages,
      next: () => currentPage >= totalPages
    }
    const frag = document.createDocumentFragment();
    const paginationButtonContainer = document.createElement('div');
    paginationButtonContainer.className = 'pagination-buttons';
    
    const createAndSetupButton = (label = '', cls = '', disabled = false, handleClick) => {
      const buttonElement = document.createElement('button');
      buttonElement.textContent = label;
      buttonElement.className = `page-btn ${cls}`;
      buttonElement.disabled = disabled;
      buttonElement.addEventListener('click', e => {
        handleClick(e);
        this.update();
        paginationButtonContainer.value = currentPage;
        paginationButtonContainer.dispatchEvent(new CustomEvent('change', {detail: {currentPageBtn}}));
      });
      
      return buttonElement;
    }
    
    const onPageButtonClick = e => currentPage = Number(e.currentTarget.textContent);
    
    const onPageButtonUpdate = index => (btn) => {
      btn.textContent = pages[index];
      
      if(pages[index] === currentPage) {
        currentPageBtn.classList.remove('active');
        btn.classList.add('active');
        currentPageBtn = btn;
        currentPageBtn.focus();
      }
    };
    
    buttons.set(
      createAndSetupButton('start', 'start-page', disabled.start(), () => currentPage = 1),
      (btn) => btn.disabled = disabled.start()
    )
    
    buttons.set(
      createAndSetupButton('prev', 'prev-page', disabled.prev(), () => currentPage -= 1),
      (btn) => btn.disabled = disabled.prev()
    )
    
    pages.map((pageNumber, index) => {
      const isCurrentPage = currentPage === pageNumber;
      const button = createAndSetupButton(
        pageNumber, isCurrentPage ? 'active' : '', false, onPageButtonClick
      );
      
      if(isCurrentPage) {
        currentPageBtn = button;
      }
      
      buttons.set(button, onPageButtonUpdate(index));
    });
    
    buttons.set(
      createAndSetupButton('next', 'next-page', disabled.next(), () => currentPage += 1),
      (btn) => btn.disabled = disabled.next()
    )
    
    buttons.set(
      createAndSetupButton('end', 'end-page', disabled.end(), () => currentPage = totalPages),
      (btn) => btn.disabled = disabled.end()
    )
    
    buttons.forEach((_, btn) => frag.appendChild(btn));
    paginationButtonContainer.appendChild(frag);
    
    this.render = (container = document.body) => {
      container.appendChild(paginationButtonContainer);
    }
    
    this.update = (newPageNumber = currentPage) => {
      currentPage = newPageNumber;
      pages = pageNumbers(totalPages, maxPagesVisible, currentPage);
      buttons.forEach((updateButton, btn) => updateButton(btn));
    }
    
    this.onChange = (handler) => {
      paginationButtonContainer.addEventListener('change', handler);
    }
  }
  
  const paginationButtons = new PaginationButton(10, 5);
  
  paginationButtons.render();
  
  paginationButtons.onChange(e => {
    console.log('-- changed', e.target.value)
  });

修改后的JavaScript代码(移除pageNumbers函数)

function PaginationButton(totalPages, maxPagesVisible = 10, currentPage = 1) {
    let pages = pageNumbers(totalPages, maxPagesVisible, currentPage);
    let currentPageBtn = null;
    const buttons = new Map();
    const disabled = {
      start: () => pages[0] === 1,
      prev: () => currentPage === 1 || currentPage > totalPages,
      end: () => pages.slice(-1)[0] === totalPages,
      next: () => currentPage >= totalPages
    }
    const frag = document.createDocumentFragment();
    const paginationButtonContainer = document.createElement('div');
    paginationButtonContainer.className = 'pagination-buttons';
    
    const createAndSetupButton = (label = '', cls = '', disabled = false, handleClick) => {
      const buttonElement = document.createElement('button');
      buttonElement.textContent = label;
      buttonElement.className = `page-btn ${cls}`;
      buttonElement.disabled = disabled;
      buttonElement.addEventListener('click', e => {
        handleClick(e);
        this.update();
        paginationButtonContainer.value = currentPage;
        paginationButtonContainer.dispatchEvent(new CustomEvent('change', {detail: {currentPageBtn}}));
      });
      
      return buttonElement;
    }
    
    const onPageButtonClick = e => currentPage = Number(e.currentTarget.textContent);
    
    const onPageButtonUpdate = index => (btn) => {
      btn.textContent = pages[index];
      
      if(pages[index] === currentPage) {
        currentPageBtn.classList.remove('active');
        btn.classList.add('active');
        currentPageBtn = btn;
        currentPageBtn.focus();
      }
    };
    
    buttons.set(
      createAndSetupButton('start', 'start-page', disabled.start(), () => currentPage = 1),
      (btn) => btn.disabled = disabled.start()
    )
    
    buttons.set(
      createAndSetupButton('prev', 'prev-page', disabled.prev(), () => currentPage -= 1),
      (btn) => btn.disabled = disabled.prev()
    )
    
    pages.map((pageNumber, index) => {
      const isCurrentPage = currentPage === pageNumber;
      const button = createAndSetupButton(
        pageNumber, isCurrentPage ? 'active' : '', false, onPageButtonClick
      );
      
      if(isCurrentPage) {
        currentPageBtn = button;
      }
      
      buttons.set(button, onPageButtonUpdate(index));
    });
    
    buttons.set(
      createAndSetupButton('next', 'next-page', disabled.next(), () => currentPage += 1),
      (btn) => btn.disabled = disabled.next()
    )
    
    buttons.set(
      createAndSetupButton('end', 'end-page', disabled.end(), () => currentPage = totalPages),
      (btn) => btn.disabled = disabled.end()
    )
    
    buttons.forEach((_, btn) => frag.appendChild(btn));
    paginationButtonContainer.appendChild(frag);
    
    this.render = (container = document.body) => {
      container.appendChild(paginationButtonContainer);
    }
    
    this.update = (newPageNumber = currentPage) => {
      currentPage = newPageNumber;
      pages = pageNumbers(totalPages, maxPagesVisible, currentPage);
      buttons.forEach((updateButton, btn) => updateButton(btn));
    }
    
    this.onChange = (handler) => {
      paginationButtonContainer.addEventListener('change', handler);
    }
  }
  
  const paginationButtons = new PaginationButton(10, 5);
  
  paginationButtons.render();
  
  paginationButtons.onChange(e => {
    console.log('-- changed', e.target.value);
  });

内容的提问来源于stack exchange,提问作者coder12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 13:34:52