将代码放入我的Javascript数组中

3

我有以下问题,

我制作了一个有很多输入字段的表单。如果用户输入1,它将立即显示其旁边的价格。我的代码如下:

var priceMargherita = 7;
    var numPizzaMargheritaInput = document.getElementById('countMargherita');
    var priceMargheritaLabel    = document.getElementById('totalMargherita');

    function onNumPizzaMargheritaInputChange(e){

        var totalMargherita = priceMargherita * parseInt(e.target.value);
        var formattedPrice = '\u20ac '+totalMargherita.toFixed(2);

        priceMargheritaLabel.innerHTML = '';
        priceMargheritaLabel.appendChild(document.createTextNode(formattedPrice));
    }
    numPizzaMargheritaInput.addEventListener('change', onNumPizzaMargheritaInputChange, false);

而它会以这样的方式呈现价格:
<td>Pizza Margherita</td>
<td><input type="number" id="countMargherita" class="formnumbers" name="PizzaMargherita" onChange="validateForm(this)" min="1" max="99"/></td>
<td><span id="totalMargherita"></span></td>

现在我的问题是,我有11个像这样的产品Pizza Margherita。目前我有11个类似于顶部的代码。我认为这可以通过数组来完成,因为唯一改变的只是一些名称。

如果我错了,请纠正我,因为我对JS和数组都没有经验。

任何帮助都将不胜感激!


我必须说,这确实是一段精彩的代码。 - DontVoteMeDown
4个回答

1

对我来说,最简单的方法是不使用数组或ID。

如果您可以更改HTML,则应将价格添加为数据属性,然后您可以使用通用代码:

<td>Pizza Margherita</td>
<td><input type="number" class="formnumbers" name="PizzaMargherita"
           onChange="changeTotalFromCount(this)" min="1"
           max="99" data-unitPrice="7" /></td>
<td></td>

JS:
function changeTotalFromCount(input) {
    var unitPrice = parseFloat(input.getAttribute("data-unitPrice"));
    var count = input.value;

    var price = unitPrice * count;
    var formattedPrice = '\u20ac ' + price.toFixed(2);

    var label = input.parentNode.nextElementSibling;
    label.innerHTML = '';
    label.appendChild(document.createTextNode(formattedPrice));
}

有一个问题,我已经在使用名为validateForm(this)的onChange事件了。我可以像那样仅添加另一个事件到onChange中吗? - Déjà vu
没事了,我搞定了,而且它很正常地工作了,非常感谢。 - Déjà vu

0

与其使用数组,我认为你要找的词是循环。以下是一种使用对象和循环来重构程序的方法:

var prices = {
  Margherita: 7,
  Hawaiian: 7,
  NewYork: 8
};

for (var pizzaType in prices) {
  var inputElement = document.getElementbyId('count' + pizzaType);
  var labelElement = document.getElementbyId('total' + pizzaType);

  inputElement.addEventListener('change', function(event) {
    var total = prices[pizzaType] * parseInt(event.target.value);
    var formattedPrice = '\u20ac ' + total.toFixed(2);

    labelElement.innerHTML = '';
    labelElement.appendChild(document.createTextNode(formattedPrice));
  }, false);
}

我选择使用匿名函数而不是命名函数,因为这是事件监听器中最常见的做法。


0

数组并不是解决这个问题最有效的方式。你最好使用一个更通用的函数,将必要的信息(事件、价格和显示价格元素的ID)作为参数传递进去。然后使用对象数组来初始化所有内容。类似于这样:

var pizzas = [
    {
        pizza: 'margherita',
        price: 7,
        input: 'countMargherita',
        label: 'totalMargherita'
    },
    {
        pizza: 'pepperoni',
        price: 10,
        input: 'countPepperoni',
        label: 'totalPepperoni'
    }
]

function calculatePrice(e, price, label) {
    var total = price * parseInt(e.target.value);
    var formattedPrice = '\u20ac '+total.toFixed(2);

    var outputElement = document.getElementById(label);
    outputElement .innerHTML = '';
    outputElement .appendChild(document.createTextNode(formattedPrice));
}

然后遍历该pizza数组以绑定所有内容:

for(var i = 0, l = pizzas.length; i < l; i++) {
    (function(pizza) {
        document.getElementById(pizza.input).addEventListener('change', function(e) {
            calculatePrice(e, pizza.price, pizza.label);
        }, false);
    })(pizzas[i]);
}

上述代码使用闭包来避免由于 JavaScript 变量作用域而引起的问题;因为没有块级作用域,所以变量 i 的作用域是函数作用域。由于事件处理程序本质上是一个延迟操作,如果不使用闭包,当它执行时,变量 i 的值也将是最后一个值。

我不知道我是否做错了什么,但是它无法正常工作。它只是显示空的价格跨度。 - Déjà vu
@Farewyth 你可能是对的,或者我在编写代码时犯了错误(我没有测试它,那只是我的想法)。我会尝试抛出一个 fiddle 并找出问题所在。编辑:fiddle 看起来运行良好。 - Anthony Grist
没事了,问题出在我这里,感谢你的努力! - Déjà vu

0
创建一个更通用的计算价格函数,例如 onNumPizzChange 函数,它接受基本元素名称,例如“玛格丽特”。在此函数中,提取您的元素。
var inputElm = document.getElementById('count'+elmBase);

然后通过将此函数包装在另一个函数中来设置您的事件,如下所示:

document.getElementById('numPizzaMargheritaCount').addEventListener('change', function(){ onNumPizzaChange('Margherita')}, false);

这有意义吗?

祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接