如何封装我的代码,以便我可以从一个函数传递参数到另一个函数?

huangapple go评论59阅读模式
英文:

How can I encapsulate my code, so I can pass arguments from one function to another?

问题

I wrote this simple carousel but without encapsulation. So previously I placed items from buttonControl() in global scope and added eventListeners on global scope, which are now emraced in prev() and next() functions. However, my encapsulation breaks the code. Because arguments from buttonControl() aren't global but prev() and next() needs them to work. I thought that maybe I can pass all arguments from buttonsControl() inside addEventListener('click', prev) but I cannot, because when I write this addEventListener('click', prev(slides, totalItems, allItems...)) it is launching this event without a click. And I even don't know if it's the correct way.

I thought of putting arguments from buttonsControl() inside prev() and next() but it won't work.

function buttonsControl() {
  const slides = document.querySelector('.slides');
  const totalItems = document.querySelectorAll('.slides>*').length - 1;
  const allItems = document.querySelectorAll('.slides>*').length;
  console.log(totalItems)
  let activeItem = 0;

  let controlCarouselFooter = document.querySelector('.carousel_footer');
  controlCarouselFooter.innerHTML = `1 / ${allItems}`;
  console.log(controlCarouselFooter)
  const prevButton = document.querySelector('.prev_button').addEventListener('click', prev)
  const nextButton = document.querySelector('.next_button').addEventListener('click', next)
  // no idea how to pass those arguments
}

// Buttons controls

function prev() {
  // const prevButton = document.querySelector('.prev_button').addEventListener('click', () => {

  if (activeItem === 0) {
    activeItem = totalItems;
    slides.style.transform = `translateX(-${totalItems * 100}%)`;
    console.log(`if ${activeItem}`);
    controlCarouselFooter.innerHTML = `${activeItem + 1} / ${allItems}`;
  } else {
    activeItem--;
    slides.style.transform = `translateX(-${activeItem * 100}%)`;
    console.log(`else ${activeItem}`);
    controlCarouselFooter.innerHTML = `${activeItem + 1} / ${allItems} `;
  }
}

function next() {
  // const nextButton = document.querySelector('.next_button').addEventListener('click', () => {

  if (activeItem < totalItems) {
    activeItem++;
    slides.style.transform = `translateX(-${activeItem * 100}%)`;
    console.log(`if ${activeItem}`);
    controlCarouselFooter.innerHTML = `${activeItem + 1} / ${allItems}`;
  } else {
    activeItem = 0;
    slides.style.transform = 'none';
    console.log(`else ${activeItem + 1}`);
    console.log(`totalItems ${totalItems}`);
    controlCarouselFooter.innerHTML = `${activeItem + 1} / ${allItems}`;
  }
}

buttonsControl();
英文:

I wrote this simple carousel but without encapsulation. So previously I placed items from buttonControl() in global scope and added eventListeners on global scope, which are now emraced in prev() and next() functions. However, my encapsulation breaks the code. Because arguments from buttonControl() aren't global but prev() and next() needs them to work. I thought that maybe I can pass all arguments from buttonsControl() inside addEventListener('click', prev) but I cannot, because when I write thisaddEventListener('click', prev(slides,totalItems,allItems....)) it is launching this event without a click.And I even don't know if its correct way.

I thought of puting arguments from buttonsControl() inside prev() and next() but it won't work.


function buttonsControl(){
const slides = document.querySelector(&#39;.slides&#39;);
const totalItems = document.querySelectorAll(&#39;.slides&gt;*&#39;).length - 1;
const allItems = document.querySelectorAll(&#39;.slides&gt;*&#39;).length;
console.log(totalItems)
let activeItem = 0;

let controlCarouselFooter = document.querySelector(&#39;.carousel_footer&#39;);
controlCarouselFooter.innerHTML = `1 / ${allItems}`
console.log(controlCarouselFooter)
const prevButton = document.querySelector(&#39;.prev_button&#39;).addEventListener(&#39;click&#39;, prev)
const nextButton = document.querySelector(&#39;.next_button&#39;).addEventListener(&#39;click&#39;, next)
// no idea how to pass those arguments
}

// Buttons controls

function prev(){
// const prevButton = document.querySelector(&#39;.prev_button&#39;).addEventListener(&#39;click&#39;, () =&gt; {
 
if (activeItem === 0) {
    activeItem = totalItems;
    slides.style.transform = `translateX(-${totalItems * 100}%)`;
    console.log(`if ${activeItem}`)
    controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems}`
  }else {
    activeItem--;
    slides.style.transform = `translateX(-${activeItem * 100}%)`;
    console.log(`else ${activeItem}`)
    controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems} `
  }
  }
//   );
// }

function next(){
  // const nextButton = document.querySelector(&#39;.next_button&#39;).addEventListener(&#39;click&#39;, () =&gt; {
 
  if(activeItem &lt; totalItems) {
    activeItem++;
      slides.style.transform = `translateX(-${activeItem * 100}%)`;
      console.log(`if ${activeItem}`)
      controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems}`
  } else {
    activeItem = 0;
    slides.style.transform = &#39;none&#39;;
    console.log(`else ${activeItem+1}`)
    console.log(`totalItems ${totalItems}`)
    controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems}`
  }
}
// );
// };
// });
buttonsControl();

答案1

得分: 1

最简单的解决方案是在buttonsControl函数内部定义prevnext函数,以便所有局部变量都在闭包中。以下是代码的翻译部分:

function buttonsControl() {
  const slides = document.querySelector('.slides');
  const totalItems = document.querySelectorAll('.slides>*').length - 1;
  const allItems = document.querySelectorAll('.slides>*').length;

  let activeItem = 0;
  let controlCarouselFooter = document.querySelector('.carousel_footer');

  controlCarouselFooter.innerHTML = `1 / ${allItems}`;

  const prevButton = document.querySelector('.prev_button').addEventListener('click', prev);
  const nextButton = document.querySelector('.next_button').addEventListener('click', next);

  // 按钮控制
  function prev() {
    if (activeItem === 0) {
      activeItem = totalItems;
    } else {
      activeItem--;
    }
    slides.style.transform = `translateX(-${totalItems * 100}%)`;
    controlCarouselFooter.innerHTML = `${activeItem + 1} / ${allItems}`;
  }
  function next() {
    if (activeItem < totalItems) {
      activeItem++;
      slides.style.transform = `translateX(-${activeItem * 100}%)`;
    } else {
      activeItem = 0;
      slides.style.transform = 'none';
    }
    controlCarouselFooter.innerHTML = `${activeItem + 1} / ${allItems}`;
  }
}
buttonsControl();

希望这对你有帮助。如果你需要进一步的翻译或有其他问题,请随时告诉我。

英文:

The easiest solution would be to define the functions prev and next inside the buttonsControl function, so that all its local variables are in scope through closure:

function buttonsControl() {
const slides = document.querySelector(&#39;.slides&#39;);
const totalItems = document.querySelectorAll(&#39;.slides&gt;*&#39;).length - 1;
const allItems = document.querySelectorAll(&#39;.slides&gt;*&#39;).length;
let activeItem = 0;
let controlCarouselFooter = document.querySelector(&#39;.carousel_footer&#39;);
controlCarouselFooter.innerHTML = `1 / ${allItems}`;
const prevButton = document.querySelector(&#39;.prev_button&#39;).addEventListener(&#39;click&#39;, prev);
const nextButton = document.querySelector(&#39;.next_button&#39;).addEventListener(&#39;click&#39;, next);
// Buttons controls
function prev() {
if (activeItem === 0) {
activeItem = totalItems;
} else {
activeItem--;
}
slides.style.transform = `translateX(-${totalItems * 100}%)`;
controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems}`
} 
function next() {
if (activeItem &lt; totalItems) {
activeItem++;
slides.style.transform = `translateX(-${activeItem * 100}%)`;
} else {
activeItem = 0;
slides.style.transform = &#39;none&#39;;
}
controlCarouselFooter.innerHTML = `${activeItem+1} / ${allItems}`
}
}
buttonsControl();

答案2

得分: 0

如果我正确理解你的问题,你可以将变量绑定到监听器上。

EDIT:有人指出你正在改变activeItems,这是正确的。因此,你需要首先在一个对象上定义所有你的变量,以便在函数调用之间保持变异。

function buttonsControl() {
    let obj = {};
    obj.slides = document.querySelector('.slides');
    obj.totalItems = document.querySelectorAll('.slides>*').length - 1;
    obj.allItems = document.querySelectorAll('.slides>*').length;

    console.log(obj.totalItems);

    obj.activeItem = 0;

    obj.controlCarouselFooter = document.querySelector('.carousel_footer');
    controlCarouselFooter.innerHTML = `1 / ${allItems}`;
    console.log(controlCarouselFooter);

    // 绑定你想要在你的输入上使用的变量
    const prevButton = document.querySelector('.prev_button').addEventListener('click', prev.bind(null, obj));
    const nextButton = document.querySelector('.next_button').addEventListener('click', next.bind(null, obj));
    // 不知道如何传递这些参数
}

// 按钮控制

function prev(obj) {
    // 在你的函数参数中定义参数。
    // const prevButton = document.querySelector('.prev_button').addEventListener('click', () => {
 
    if (obj.activeItem === 0) {
        obj.activeItem = totalItems;
        obj.slides.style.transform = `translateX(-${totalItems * 100}%)`;
        console.log(`if ${activeItem}`);
        obj.controlCarouselFooter.innerHTML = `${obj.activeItem+1} / ${obj.allItems}`;
    } else {
        obj.activeItem--;
        obj.slides.style.transform = `translateX(-${activeItem * 100}%)`;
        console.log(`else ${obj.activeItem}`);
        obj.controlCarouselFooter.innerHTML = `${obj.activeItem+1} / ${obj.allItems} `;
    }
  }
//   );
// }

function next(obj) {
    // ...与prev()类似的实现
}
// );
// };
// });

buttonsControl();
英文:

If I'm understanding your question correctly, You could bind the variables to the listeners.

EDIT: someone pointed out that you're mutating activeItems, which is true. So you will want to define all your variables on an object first so that mutation is persistent between function calls.

function buttonsControl() {
    let obj = {};
    obj.slides = document.querySelector(&#39;.slides&#39;);
    obj.totalItems = document.querySelectorAll(&#39;.slides&gt;*&#39;).length - 1;
    obj.allItems = document.querySelectorAll(&#39;.slides&gt;*&#39;).length;

    console.log(obj.totalItems)

    obj.activeItem = 0;

    obj.controlCarouselFooter = document.querySelector(&#39;.carousel_footer&#39;);
    controlCarouselFooter.innerHTML = `1 / ${allItems}`
    console.log(controlCarouselFooter)

    // bind the variables you want to use to your input
    const prevButton = document.querySelector(&#39;.prev_button&#39;).addEventListener(&#39;click&#39;,  prev.bind(null, obj))
    const nextButton = document.querySelector(&#39;.next_button&#39;).addEventListener(&#39;click&#39;, next.bind(null, obj))
    // no idea how to pass those arguments
}

// Buttons controls

function prev(obj) {
    //define the arguments in your fn params. 
    // const prevButton = document.querySelector(&#39;.prev_button&#39;).addEventListener(&#39;click&#39;, () =&gt; {
 
    if (obj.activeItem === 0) {
        obj.activeItem = totalItems;
        obj.slides.style.transform = `translateX(-${totalItems * 100}%)`;
        console.log(`if ${activeItem}`)
        obj.controlCarouselFooter.innerHTML = `${obj.activeItem+1} / ${obj.allItems}`
    } else {
        obj.activeItem--;
        obj.slides.style.transform = `translateX(-${activeItem * 100}%)`;
        console.log(`else ${obj.activeItem}`)
        obj.controlCarouselFooter.innerHTML = `${obj.activeItem+1} / ${obj.allItems} `
    }
  }
//   );
// }

function next(obj) {
    // ...similar implementation to prev()
}
// );
// };
// });

buttonsControl();

huangapple
  • 本文由 发表于 2023年2月6日 03:47:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75355051.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定