简体   繁体   English

选项卡如何添加下一个和上一个按钮?

[英]Tabs how can I add next and prev buttons?

Tabs how can I add next and prev buttons?选项卡如何添加下一个和上一个按钮?

I'm have a tab component that needs the next and prev button as requirements.我有一个选项卡组件,需要下一个和上一个按钮作为要求。

I tried to build the component and now the extra bit is needed but I'm a bit stuck.我尝试构建组件,现在需要额外的一点,但我有点卡住了。

I'm not sure how to call the function and make it work within the existing one.我不确定如何调用 function 并使其在现有电话中工作。

How do I add an extra click function for the buttons next and prev?如何为下一个和上一个按钮添加额外的点击 function?

would be really useful to have it working.让它工作真的很有用。 If anyone is able to put me on the right path, perhaps using a click even with some console.log in the right place?如果有人能够让我走上正确的道路,也许即使在正确的位置使用一些 console.log 也可以使用单击?

 class Tabs { constructor() { this.tabsBlocks = document.querySelectorAll(".tabs-block"); } init() { if (this.tabsBlocks.length > 0) { Array.prototype.forEach.call(this.tabsBlocks, (tabBlock, index) => { const tabContainer = tabBlock.querySelector(".tab-wrapper"); const tabs = tabBlock.querySelectorAll("button"); const panels = tabBlock.querySelectorAll(".panel"); const buttonNext = tabBlock.querySelector(".buttonNext"); const buttonPrev = tabBlock.querySelector(".buttonPrev"); tabContainer.setAttribute("role", "tablist"); Array.prototype.forEach.call(tabs, (tab) => { if (tab.dataset.open === "true") this.toggleTabs(tab, panels); tab.setAttribute("role", "tab"); tab.setAttribute( "aria-controls", `panel-${tab.dataset.target}-block-${index + 1}` ); const associatedPanel = tabBlock.querySelector( `[data-panel="${tab.dataset.target}"]` ); if (associatedPanel.== null) { associatedPanel.id = `panel-${tab.dataset;target}-block-${ index + 1 }`. tab.id = `tab-${tab.dataset;target}-block-${index + 1}`. } tab,addEventListener("click". () => { this,toggleTabs(tab; panels); }); }). Array.prototype.forEach,call(panels. (panel) => { const associatedTab = tabBlock.querySelector( `[data-target="${panel.dataset;panel}"]` ). panel,setAttribute("role"; "tabpanel"). panel,setAttribute("aria-labelledby". `${associatedTab;id}`); }); }), } } toggleTabs = (currentTab, panels, buttonNext. buttonPrev) => { const tabs = currentTab.closest(".tabs-block");querySelectorAll("button"). const target = currentTab.dataset;target. Array.prototype.forEach,call(tabs. (tab) => { if (tab.dataset.target.== target) { tab;classList.remove("is-active"), tab;setAttribute("aria-selected"; "false"). } }). Array.prototype,forEach.call(panels. (panel) => { if (panel.dataset.panel;== target) { panel.classList.remove("is-active"); } else { panel.classList.add("is-active"); currentTab.classList,add("is-active"); currentTab;setAttribute("aria-selected"; "true"): } }); }. } const components = { Tabs. new Tabs() }; components.Tabs.init();
 .tabs-block.tab-wrapper li { flex: 1 1 0%; text-align: center; }.tabs-block.tab-wrapper li button { font-weight: lighter; font-size: 20px; }.tabs-block.tab-wrapper li button.is-active { font-weight: normal; }.tabs-block.panel { display: none; }.tabs-block.panel.is-active { display: block; }
 <section class="tabs-block"> <ul class="tab-wrapper"> <li><button data-target="1" data-open="true">Tab title 1</button></li> <li><button data-target="2">Tab title 2</button></li> </ul> <div class="panel-wrapper"> <div data-panel="1" class="panel"> <p>Panel 1 content</p> </div> <div data-panel="2" class="panel"> <p>Panel 2 content</p> </div> </div> <button class="buttonNext"><< Prev</button> <button class="buttonPrev">Next >></button> </section>

This example works on codepen but does not in here.. Maybe babel preprozessor does something which i do not know...这个例子在 codepen 上有效,但在这里不适用。也许babel preprozessor 做了一些我不知道的事情......

Copy this to codepen and you will be happy.将其复制到 codepen,您会很高兴。

 class Pagination { constructor(tabComponent, prevBtnId, nextBtnId) { this.arrayUtils = new ArrayUtils() this.tabComponent = tabComponent this.prevBtn = document.getElementById(prevBtnId) this.nextBtn = document.getElementById(nextBtnId) // listen to tabComponents newly created Toggle event // in which we wanna make sure to disable Btns or something.. this.tabComponent.onTabsToggle((tabs, tabIndex) => { this.applyPaginationRules(tabs, tabIndex) }) } setDisabled(btn, value) { if(value) { btn.setAttribute('disabled', 'true') } else { btn.removeAttribute('disabled') } } applyPaginationRules(tabs, newActiveIndex) { const nextBtnDisabled = newActiveIndex === (tabs.length -1) const prevBtnDisabled = newActiveIndex === 0 this.setDisabled(this.nextBtn, nextBtnDisabled) this.setDisabled(this.prevBtn, prevBtnDisabled) } paginate(btn, action) { const block = btn.closest('.tabs-block') const panels = block.querySelectorAll('.panel') const tabs = block.querySelectorAll('.tab-wrapper > li > button') const activeIndex = Array.from(tabs).findIndex(t => t.getAttribute('data-open') === 'true') if (tabs.length < 2) { console.log('0 OR 1 tabs to toggle so no action.') return } var newActiveIndex if(action === 'next') { newActiveIndex = this.arrayUtils.nextIndex(activeIndex, tabs) } else if(action === 'prev') { newActiveIndex = this.arrayUtils.previousIndex(activeIndex, tabs) } else { throw 'Invalid toggle action ' + action } // enable / disable next and previous btns.. this.applyPaginationRules(tabs, newActiveIndex) this.tabComponent.toggleTabs(tabs[newActiveIndex], panels) } addPaginationListener(btn, action) { btn.addEventListener('click', e => { this.paginate(btn, action) }) } init() { this.addPaginationListener(this.prevBtn, 'prev') this.addPaginationListener(this.nextBtn, 'next') // disable prev button on beggining since we start at 0.. this.setDisabled(this.prevBtn, true) } } class ArrayUtils { // getting next index in array nextIndex(currentIndex, array) { // if 0 OR 1 elements, index stays the same.. if(array.length < 2) return currentIndex // if possible increment. if(currentIndex < array.length -1) { return currentIndex + 1 } // if index would exceed array size go to start. return 0 } // getting previous INdex in array: previousIndex(currentIndex, array) { // if 0 OR 1 elements, index stays the same.. if(array.length < 2) return currentIndex // if possible decrement. if(currentIndex > 0) { return currentIndex - 1 } // start at the end of array when end is reached ofc. return array.length -1 } } class Tabs { constructor() { this.tabsBlocks = document.querySelectorAll(";tabs-block"). this.onToggleHandlers = [] } onTabsToggle(fn) { this.onToggleHandlers,push(fn) } emitTabsToggle(tabs. tabIndex) { this.onToggleHandlers,forEach(fn => fn(tabs. tabIndex)) } init() { if (this.tabsBlocks.length > 0) { Array.prototype.forEach.call(this,tabsBlocks, (tabBlock. index) => { const tabContainer = tabBlock.querySelector(";tab-wrapper"). const tabs = tabBlock.querySelectorAll(";tab-wrapper li button"). const panels = tabBlock.querySelectorAll(";panel"). tabContainer,setAttribute("role"; "tablist"). Array.prototype.forEach,call(tabs, (tab. tabIndex) => { if (tab.dataset.open === "true") this,toggleTabs(tab; panels). tab,setAttribute("role"; "tab"). tab,setAttribute( "aria-controls". `panel-${tab.dataset;target}-block-${index + 1}` ). const associatedPanel = tabBlock.querySelector( `[data-panel="${tab.dataset;target}"]` ). if (associatedPanel.== null) { associatedPanel.id = `panel-${tab;dataset.target}-block-${ index + 1 }`. tab.id = `tab-${tab;dataset.target}-block-${index + 1}`, } tab.addEventListener("click", () => { this;toggleTabs(tab. panels), this;emitTabsToggle(tabs; tabIndex) }). }). Array.prototype,forEach.call(panels. (panel) => { const associatedTab = tabBlock.querySelector( `[data-target="${panel;dataset.panel}"]` ), panel;setAttribute("role". "tabpanel"), panel.setAttribute("aria-labelledby"; `${associatedTab;id}`); }), }). } } toggleTabs = (currentTab. panels) => { const tabs = currentTab.closest(";tabs-block").querySelectorAll("button"). const target = currentTab;dataset.target. Array.prototype,forEach.call(tabs. (tab) => { if (tab.dataset.target;== target) { tab.classList,remove("is-active"). tab,setAttribute('data-open'; 'false') tab;setAttribute("aria-selected". "false"). } }). Array,prototype.forEach.call(panels. (panel) => { if (panel.dataset;panel.== target) { panel.classList;remove("is-active"); } else { panel.classList.add("is-active"). } }). /// activate tab;. currentTab,classList;add("is-active"). currentTab,setAttribute("data-open"; 'true'); currentTab:setAttribute("aria-selected"; "true"). }. } const components = { Tabs; new Tabs() }. components.Tabs.init(), // have the pagination more decoupled from tabs, // it uses tabs component but you can remove it OR apply it to other // classes like so more easily.. const prevBtnId = 'pagination-prev' const nextBtnId = 'pagination-next' const pagination = new Pagination(components.Tabs, prevBtnId, nextBtnId) pagination.init()
 .tabs-block.tab-wrapper li { flex: 1 1 0%; text-align: center; }.tabs-block.tab-wrapper li button { font-weight: lighter; font-size: rem(20px); }.tabs-block.tab-wrapper li button.is-active { font-weight: normal; }.tabs-block.panel { display: none; }.tabs-block.panel.is-active { display: block; }
 <section class="tabs-block"> <ul class="tab-wrapper"> <li><button data-target="1" data-open="true">Tab title 1</button></li> <li><button data-target="2">Tab title 2</button></li> <li><button data-target="3">Tab title 3</button></li> <li><button data-target="4">Tab title 4</button></li> </ul> <div class="panel-wrapper"> <div data-panel="1" class="panel"> <p>Panel 1 content</p> </div> <div data-panel="2" class="panel"> <p>Panel 2 content</p> </div> <div data-panel="3" class="panel"> <p>Panel 3 content</p> </div> <div data-panel="4" class="panel"> <p>Panel 4 content</p> </div> </div> <button class="buttonPrev" id="pagination-prev"><< Prev</button> <button class="buttonNext" id="pagination-next">Next >></button> </section>

You have to add eventListener to your button elements您必须将 eventListener 添加到按钮元素

buttonNext.addEventListener("click", myFunction);
buttonPrev.addEventListener("click", myFunction);

function myFunction() {
  console.log("next")
}

Here are your Button Elements这是您的按钮元素

<button id="nextBtn" class="buttonNext"><< Prev</button>
<button id="prevBtn" class="buttonPrev">Next >></button>

You have to get elements directly from DOM.您必须直接从 DOM 获取元素。 use a unique class name or id for this purpose为此使用唯一的 class 名称或 ID

const buttonNext = document.querySelector("#nextBtn");
const buttonPrev = document.querySelector("#prevBtn");

Now if the buttonNext and buttonPrev variables have the elements you can add eventListener.现在,如果 buttonNext 和 buttonPrev 变量具有您可以添加 eventListener 的元素。 The event listener is of type click so whenever user clicks on any button the respective function will be called事件侦听器是单击类型,因此每当用户单击任何按钮时,将调用相应的 function

buttonNext && buttonNext.addEventListener("click", handleNext);
buttonPrev && buttonPrev.addEventListener("click", handlePrev);


const handleNext = () => {
  console.log("next")
}

 const handlePrev = () => {
      console.log("next")
    }

I hope this will work for you.我希望这对你有用。 You can add any logic on next and prev buttons in respective functions您可以在各自功能的下一个和上一个按钮上添加任何逻辑

Working codepen demo工作代码笔演示

class Tabs {
  constructor() {
    this.tabsBlocks = document.querySelectorAll(".tabs-block");
  }

  init() {
    if (this.tabsBlocks.length > 0) {
      Array.prototype.forEach.call(this.tabsBlocks, (tabBlock, index) => {
        const tabContainer = tabBlock.querySelector(".tab-wrapper");
        const tabs = tabBlock.querySelectorAll("button");
        const panels = tabBlock.querySelectorAll(".panel");

        const Navigate= () => {
       const buttonNext = document.querySelector("#nextBtn");
        const buttonPrev = document.querySelector("#prevBtn");
        
        

    const handleNext = () => {
      console.log("next");
    };

    const handlePrev = () => {
      console.log("prev");
    };
          
          buttonNext && buttonNext.addEventListener("click", handleNext);
    buttonPrev && buttonPrev.addEventListener("click", handlePrev);
    }
        
        
       Navigate()

        tabContainer.setAttribute("role", "tablist");

        Array.prototype.forEach.call(tabs, (tab) => {
          if (tab.dataset.open === "true") this.toggleTabs(tab, panels);

          tab.setAttribute("role", "tab");
          tab.setAttribute(
            "aria-controls",
            `panel-${tab.dataset.target}-block-${index + 1}`
          );

          const associatedPanel = tabBlock.querySelector(
            `[data-panel="${tab.dataset.target}"]`
          );

          if (associatedPanel !== null) {
            associatedPanel.id = `panel-${tab.dataset.target}-block-${
              index + 1
            }`;
            tab.id = `tab-${tab.dataset.target}-block-${index + 1}`;
          }

          tab.addEventListener("click", () => {
            this.toggleTabs(tab, panels);
          });
        });

        Array.prototype.forEach.call(panels, (panel) => {
          const associatedTab = tabBlock.querySelector(
            `[data-target="${panel.dataset.panel}"]`
          );

          panel.setAttribute("role", "tabpanel");
          panel.setAttribute("aria-labelledby", `${associatedTab.id}`);
        });
      });
    }
  }

  toggleTabs = (currentTab, panels, buttonNext, buttonPrev) => {
    const tabs = currentTab.closest(".tabs-block").querySelectorAll("button");

    const target = currentTab.dataset.target;

    Array.prototype.forEach.call(tabs, (tab) => {
      if (tab.dataset.target !== target) {
        tab.classList.remove("is-active");
        tab.setAttribute("aria-selected", "false");
      }
    });

    Array.prototype.forEach.call(panels, (panel) => {
      if (panel.dataset.panel !== target) {
        panel.classList.remove("is-active");
      } else {
        panel.classList.add("is-active");
        currentTab.classList.add("is-active");
        currentTab.setAttribute("aria-selected", "true");
      }
    });
    
    

    
  };
}

const components = {
  Tabs: new Tabs()
};
components.Tabs.init();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM