简体   繁体   English

在 Javascript 中,我如何编写一个 function 会影响多个按钮,每个按钮都有自己单独的 arrays?

[英]In Javascript, how do I write one function that will effect multiple buttons, each with their own separate arrays?

I am currently setting up an application with three separate buttons, each which is supposed to randomly select an element from an array specific to that button.我目前正在使用三个单独的按钮设置一个应用程序,每个按钮都应该随机 select 一个特定于该按钮的数组中的元素。 I've successfully coded it with individual functions for each button, but I was wondering if there is a way to condense it into a single function that can apply to all three buttons.我已经成功地为每个按钮编写了单独的功能,但我想知道是否有办法将它压缩成一个可以应用于所有三个按钮的 function。

This is my current Javascript:这是我目前的 Javascript:

const greyButton = document.querySelector('#grey');
greyButton.addEventListener('click', () => {
  let grey = ['Statblocks/Grey/badger.png', 'Statblocks/Grey/giantrat.png', 'Statblocks/Grey/badger.png', 'Statblocks/Grey/boar.png', 'Statblocks/Grey/panther.png', 'Statblocks/Grey/gitant badger.png', 'Statblocks/Grey/dire wolf.png', 'Statblocks/Grey/giant elk.png']
  
  for (i=0;i<grey.length;i++){
    let greyBalls = grey[Math.floor(Math.random() * grey.length)];
    document.getElementById('greyBall').src = greyBalls;
  }
});

const rustButton = document.querySelector('#rust');
rustButton.addEventListener('click', () => {
  let rust = ['Statblocks/Rust/rat.png', 'Statblocks/Rust/owl.png', 'Statblocks/Rust/mastiff.png', 'Statblocks/Rust/goat.png', 'Statblocks/Rust/giant goat.png', 'Statblocks/Rust/giant boar.png', 'Statblocks/Rust/lion.png', 'Statblocks/Rust/brown bear.png']
  
  for (i=0;i<rust.length;i++){
    let rustBalls = rust[Math.floor(Math.random() * rust.length)];
    document.getElementById('rustBall').src = rustBalls;
  }
});

const tanButton = document.querySelector('#tan');
tanButton.addEventListener('click', () => {
  let tan = ['Statblocks/Tan/jackal.png', 'Statblocks/Tan/ape.png', 'Statblocks/Tan/baboon.png', 'Statblocks/Tan/axe beak.png', 'Statblocks/Tan/black bear.png', 'Statblocks/Tan/giant weasel.png', 'Statblocks/Tan/giant hyena.png', 'Statblocks/Tan/tiger.png']
  
  for (i=0;i<tan.length;i++){
    let tanBalls = tan[Math.floor(Math.random() * tan.length)];
    document.getElementById('tanBall').src = tanBalls;
  }
});

And the connected HTML:和连接的HTML:

 <div class="row">
            <div class="column">
                <h1>Grey Bag of Tricks</h1>
                <button class="button" id='grey'>Draw from the Bag</button>
                <img src="" alt="" id="greyBall">
            </div>
            <div class="column">
                <h1>Rust Bag of Tricks</h1>
                <button class="button" id='rust'>Draw from the Bag</button>
                <img src="" alt="" id="rustBall">
            </div>
            <div class="column">
                <h1>Tan Bag of Tricks</h1>
                <button class="button" id='tan'>Draw from the Bag</button>
                <img src="" alt="" id="tanBall">
            </div>
        </div>

 var urlsByColor = { grey: ['Statblocks/Grey/badger.png', 'Statblocks/Grey/giantrat.png', 'Statblocks/Grey/badger.png', 'Statblocks/Grey/boar.png', 'Statblocks/Grey/panther.png', 'Statblocks/Grey/gitant badger.png', 'Statblocks/Grey/dire wolf.png', 'Statblocks/Grey/giant elk.png'], rust: ['Statblocks/Rust/rat.png', 'Statblocks/Rust/owl.png', 'Statblocks/Rust/mastiff.png', 'Statblocks/Rust/goat.png', 'Statblocks/Rust/giant goat.png', 'Statblocks/Rust/giant boar.png', 'Statblocks/Rust/lion.png', 'Statblocks/Rust/brown bear.png'], tan: ['Statblocks/Tan/jackal.png', 'Statblocks/Tan/ape.png', 'Statblocks/Tan/baboon.png', 'Statblocks/Tan/axe beak.png', 'Statblocks/Tan/black bear.png', 'Statblocks/Tan/giant weasel.png', 'Statblocks/Tan/giant hyena.png', 'Statblocks/Tan/tiger.png'] }; function changeBall (e) { const urls = urlsByColor[e.target.id]; const randomIndex = Math.floor(Math.random() * urls.length); const randomUrl = urls[randomIndex]; const associatedBall = e.target.closest('.column').querySelector('.ball'); console.log(`change ${e.target.id} to ${randomUrl}`); associatedBall.src = randomUrl; console.log(associatedBall); } [...document.querySelectorAll('.color.button')].forEach(button => button.addEventListener('click', changeBall) );
 <div class="row"> <div class="column"> <h1>Grey Bag of Tricks</h1> <button class="button color" id='grey'>Draw from the Bag</button> <img src="" alt="" class="ball" id="greyBall"> </div> <div class="column"> <h1>Rust Bag of Tricks</h1> <button class="button color" id='rust'>Draw from the Bag</button> <img src="" alt="" class="ball" id="rustBall"> </div> <div class="column"> <h1>Tan Bag of Tricks</h1> <button class="button color" id='tan'>Draw from the Bag</button> <img src="" alt="" class="ball" id="tanBall"> </div> </div>

Ok so a few things changed.好的,所以有些事情发生了变化。

  • I extracted the lists of urls out to a map, that can use the id of the button to lookup what urls to use我将 url 列表提取到 map,它可以使用按钮的 id 来查找要使用的 url
  • The markup for the buttons and balls changed to have common classes for finds and lookups按钮和球的标记更改为具有查找和查找的通用类
  • When a click happens, we get the urls by the button id当点击发生时,我们通过按钮 id 获取 url
  • We then get a random index like was done before然后我们得到一个像以前一样的随机索引
  • We get the random assoicated url for that index我们得到该索引的随机关联 url
  • We find the ball that is associated with the button contextually by the parent column class我们通过父列 class 在上下文中找到与按钮关联的球
  • And finally we change the ball's url最后我们改变球的 url

In general, you put the similar repeated part in a function, then you abstract all the parts that are different in each usage by replacing them with parameters to the function:通常,您将相似的重复部分放在 function 中,然后通过将其替换为 function 的参数来抽象出每种用法中不同的所有部分:

function addHandler(buttonSelector, ballImages, ballId) {
  const button = document.querySelector(buttonSelector);
  button.addEventListener('click', e => {
    for (let i=0; i<ballImages.length; i++) {
      let ball = ballImages[Math.floor(Math.random() * ballImages.length)];
      document.getElementById(ballId).src = ball;
    }
  });
}

so that you can call it like这样你就可以这样称呼它

addHandler('#grey', ['Statblocks/Grey/badger.png', 'Statblocks/Grey/giantrat.png', 'Statblocks/Grey/badger.png', 'Statblocks/Grey/boar.png', 'Statblocks/Grey/panther.png', 'Statblocks/Grey/gitant badger.png', 'Statblocks/Grey/dire wolf.png', 'Statblocks/Grey/giant elk.png'], 'greyBall');
addHandler('#rust', ['Statblocks/Rust/rat.png', 'Statblocks/Rust/owl.png', 'Statblocks/Rust/mastiff.png', 'Statblocks/Rust/goat.png', 'Statblocks/Rust/giant goat.png', 'Statblocks/Rust/giant boar.png', 'Statblocks/Rust/lion.png', 'Statblocks/Rust/brown bear.png'], 'rustBall');
addHandler('#tan', ['Statblocks/Tan/jackal.png', 'Statblocks/Tan/ape.png', 'Statblocks/Tan/baboon.png', 'Statblocks/Tan/axe beak.png', 'Statblocks/Tan/black bear.png', 'Statblocks/Tan/giant weasel.png', 'Statblocks/Tan/giant hyena.png', 'Statblocks/Tan/tiger.png'], 'tanBall');

That's still some duplication though.不过,这仍然是一些重复。 We can avoid that by doing extra processing on the data so that we can pass simpler values:我们可以通过对数据进行额外处理来避免这种情况,以便我们可以传递更简单的值:

function addHandler(id, imageNames) {
  const buttonSelector = '#' + id;
  const ballImages = imageNames.map(name => `Statblocks/${id[0].toUpperCase()+id.slice(1)}/${name}.png}`);
  const ballId = id + 'Ball';

  … // rest as before
}

addHandler('grey', ['badger', 'giantrat', 'badger', 'boar', 'panther', 'gitant badger', 'dire wolf', 'giant elk']);
addHandler('rust', ['rat', 'owl', 'mastiff', 'goat', 'giant goat', 'giant boar', 'lion', 'brown bear']);
addHandler('tan', ['jackal', 'ape', 'baboon', 'axe beak', 'black bear', 'giant weasel', 'giant hyena', 'tiger']);

Last I'd change the querySelector to a getElementById lookup, and remove the unnecessary loop, and we arrive at最后,我将querySelector更改为getElementById查找,并删除不必要的循环,我们到达

function addHandler(id, imageNames) {
  const ballImages = imageNames.map(name => `Statblocks/${id[0].toUpperCase()+id.slice(1)}/${name}.png}`);
  const button = document.getElementById(id);
  button.addEventListener('click', e => {
    let ball = ballImages[Math.floor(Math.random() * ballImages.length)];
    document.getElementById(id + 'Ball').src = ball;
  });
}

addHandler('grey', ['badger', 'giantrat', 'badger', 'boar', 'panther', 'gitant badger', 'dire wolf', 'giant elk']);
addHandler('rust', ['rat', 'owl', 'mastiff', 'goat', 'giant goat', 'giant boar', 'lion', 'brown bear']);
addHandler('tan', ['jackal', 'ape', 'baboon', 'axe beak', 'black bear', 'giant weasel', 'giant hyena', 'tiger']);

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

相关问题 如何让一页上的多个滑块相互分离? - How do I let multiple sliders on one page function separate from each other? 如何在 JavaScript 中的一个函数中显示每个按钮 - How to display each buttons in one function in JavaScript Javascript:将多个单独的数组合二为一 - Javascript: Group Multiple Separate Arrays into One 如何在一个HTML文档中为每种表单创建单独的Javascript窗口 - How do I create separate Javascript windows for each form in one HTML document 如何在javascript中编写自己的确认对话框? - How do I write my own confirm dialog in javascript? 如何编写自己的`reduce` function? - How do I write my own `reduce` function? 使用 jquery 和 thymeleaf 如何创建具有自己的事件侦听器的动态按钮 - Using jquery and thymeleaf how do I create dynamic buttons each with their own event listener 如何为每个班级应用一个功能的效果? - How to apply effect of one function for each class? 如何使用javascript正则表达式将此文本分成几组,以便每组都有一组说明及其下面的项目? - How do I use javascript regex to separate this text into groups such that each group has one set of instructions and the item(s) below it? 如何在Javascript中推送多个数组并从函数返回它们? - How do I push multiple arrays in Javascript and return them from a function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM