【问题标题】:Javascript form script works Chrome but nowhere elseJavascript 表单脚本适用于 Chrome,但其他任何地方都没有
【发布时间】:2015-09-04 22:16:44
【问题描述】:

2015 年 9 月 6 日第二次更新

这就是我想出的解决方案——它肯定要短得多,并且适用于我所有的 Mac 浏览器,所以我假设它也适用于其他地方。有没有办法进一步浓缩它还是我应该把它留在这里?

var myForm = document.form1;
var radioNames = [myForm.proSpeed, myForm.ram, myForm.storage, myForm.graphics, myForm.cursorControl];
var lastPrice = [0, 0, 0, 0, 0];
var total = 2299;
var result = document.getElementById('result');
result.innerHTML = "$" + total + ".00";

function getLastPrice(radios, lastPriceIndex) {    
    for (var index = 0; index < radios.length; index++) {
        if (radios[index].checked) {
            var price = parseInt(radios[index].value);
            total = total + lastPrice[lastPriceIndex] + price;
            result.innerHTML = "$" + total + ".00";
            lastPrice[lastPriceIndex] = -price;
        }
    }    
}

function getProPrice() {
    getLastPrice(myForm.proSpeed, 0);
}
function getRamPrice() {
    getLastPrice(myForm.ram, 1);
}
function getStoPrice() {
    getLastPrice(myForm.storage, 2);
}
function getGraPrice() {
    getLastPrice(myForm.graphics, 3);
}
function getCurPrice() {
    getLastPrice(myForm.cursorControl, 4);
}

var priceFunctions = [getProPrice, getRamPrice, getStoPrice, getGraPrice, getCurPrice];

function addRadioListeners(radios, priceFunction) {
    for (var index = 0; index < radios.length; index++) {
        radios[index].addEventListener("change", priceFunction);
    }
}

for (var index = 0; index < 5; index++) {
    addRadioListeners(radioNames[index], priceFunctions[index]);
}

2015 年 9 月 5 日更新

@Barmar 再次感谢您的所有帮助。我现在正在组合 addPrice 函数:

function addPrice(price, radios) {
    for (var index = 0; index < radios.length; index++) {
        if (radios[index].checked) {
            total = total - price + parseInt(radios[index].value);
            price = parseInt(radios[index].value);
            result.innerHTML = "$" + total + ".00";
            break;
        }
    }
}

proPrice = addPrice(proPrice, myForm.proSpeed);

只是不知道下一步该怎么做才能删除其他功能并保持表单正常工作。换句话说,proPrice 去哪里了,既然 addProPrice 不再存在,我应该在change eventListener 中添加什么? proPrice 以未定义的形式返回。谢谢。


原帖

我正在做一个 javascript 练习,让我创建一个自己构建的计算机商店页面,所以我决定尝试模仿 Apple Store 中的一个页面。这是我要复制的页面:

Retina 5k iMac

这是我的(非常)简单的版本:mock-up of iMac store page

我的版本适用于 Chrome,但不适用于 Firefox 或 Safari。我不知道问题是什么。有什么想法吗?非常感谢!

杰克

(以下是完整代码,以防您不想点击链接)

HTML:

<!DOCTYPE html>

<html lang="en">
<head>
    <title>Apple Store Sim</title>
</head>

<body>

<form action="" name="form1" id="form1">
    <h1>iMac with Retina 5K display</h1>
    <p>1. Choose Processor</p>
    <p>
        <input type="radio" name="proSpeed" checked="checked" value="0" />
        <label>3.5GHz Quad-core Intel Core i5, Turbo Boost up to 3.9GHz</label><br />
        <input type="radio" name="proSpeed" value="250" />
        <label>4.0GHz Quad-core Intel Core i7, Turbo Boost up to 4.4GHz</label>
    </p>
    <p>2. Choose Memory</p>
    <p>
        <input type="radio" name="ram" checked="checked" value="0" />
        <label>8GB 1600MHz DDR3 SDRAM - 2x4GB</label><br />
        <input type="radio" name="ram" value="200" />
        <label>16GB 1600MHz DDR3 SDRAM - 2x8GB</label><br />
        <input type="radio" name="ram" value="600" />
        <label>32GB 1600MHz DDR3 SDRAM - 4x8GB</label>
    </p>
    <p>3. Choose Storage</p>
    <p>
        <input type="radio" name="storage" checked="checked" value="0" />
        <label>1TB Fusion Drive</label><br />
        <input type="radio" name="storage" value="150" />
        <label>3TB Fusion Drive</label><br />
        <input type="radio" name="storage" value="0" />
        <label>256GB Flash Storage</label><br />
        <input type="radio" name="storage" value="300" />
        <label>512GB Flash Storage</label><br />
        <input type="radio" name="storage" value="800" />
        <label>1TB Flash Storage</label>
    </p>
    <p>4. Choose Graphics</p>
    <p>
        <input type="radio" name="graphics" checked="checked" value="0" />
        <label>AMD Radeon R9 M290X 2GB GDDR5</label><br />
        <input type="radio" name="graphics" value="250" />
        <label>AMD Radeon R9 M295X 4GB GDDR5</label>
    </p>
    <p>5. Choose Mouse and Magic Trackpad</p>
    <p>
        <input type="radio" name="cursorControl" checked="checked" value="0" />
        <label>Apple Magic Mouse</label><br />
        <input type="radio" name="cursorControl" value="0" />
        <label>Magic Trackpad</label><br />
        <input type="radio" name="cursorControl" value="0" />
        <label>Apple Mouse</label><br />
        <input type="radio" name="cursorControl" value="69" />
        <label>Apple Magic Mouse + Magic Trackpad</label><br />
    </p>
    <p>6. Choose Apple Keyboard and Documentation</p>
    <p>
        <select name="keyboard" size="1">
            <option value="0" selected="selected">Apple Wireless Keyboard (English) &amp; User's Guide</option>
            <option value="0">Apple Wireless Keyboard (Arabic) &amp; User's Guide</option>
            <option value="0">Apple Wireless Keyboard (British) &amp; User's Guide</option>
        </select>
    </p>
</form>
<div id="result"></div>
<script src="appleStoreSim.js"></script>
</body>
</html>

Javascript:

var myForm = document.form1;
var proPrice = 0;
var ramPrice = 0;
var stoPrice = 0;
var graPrice = 0;
var curPrice = 0;
var total = 2299;
var result = document.getElementById('result');
result.innerHTML = "$" + total + ".00";

function addProPrice(radio) {
    var radios = myForm.proSpeed;

    for (var index = 0; index < radios.length; index++) { 
        if (radios[index].checked) {
            total = total - proPrice + parseInt(radios[index].value);
            result.innerHTML = "$" + total + ".00";
            addProListener();
        }
    }    
}

function addProListener(radio) {
    var radios = myForm.proSpeed;

    for (var index = 0; index < radios.length; index++) {
        if (radios[index].checked) {
            radios[index].removeEventListener("click", addProPrice);
            proPrice = radios[index].value;
        } else {
            radios[index].addEventListener("click", addProPrice)
        }
    }
}

for (var index = 0; index < myForm.proSpeed.length; index++) { 
    myForm.proSpeed[index].addEventListener("focus", addProListener);
}

function addMemPrice(radio) {
    var radios = myForm.ram;

    for (var index = 0; index < radios.length; index++) { 
        if (radios[index].checked) {
            total = total - ramPrice + parseInt(radios[index].value);
            result.innerHTML = "$" + total + ".00";
            addMemListener();
        }
    }
}

function addMemListener(radio) {
    var radios = myForm.ram;

    for (var index = 0; index < radios.length; index++) {
        if (radios[index].checked) {
            radios[index].removeEventListener("click", addMemPrice);
            ramPrice = radios[index].value;
        } else {
            radios[index].addEventListener("click", addMemPrice)
        }
    }
}

for (var index = 0; index < myForm.ram.length; index++) { 
    myForm.ram[index].addEventListener("focus", addMemListener);
}

function addStoPrice(radio) {
    var radios = myForm.storage;

    for (var index = 0; index < radios.length; index++) { 
        if (radios[index].checked) {
            total = total - stoPrice + parseInt(radios[index].value);
            result.innerHTML = "$" + total + ".00";
            addStoListener();
        }
    }
}

function addStoListener(radio) {
    var radios = myForm.storage;

    for (var index = 0; index < radios.length; index++) {
        if (radios[index].checked) {
            radios[index].removeEventListener("click", addStoPrice);
            stoPrice = radios[index].value;
        } else {
            radios[index].addEventListener("click", addStoPrice)
        }
    }
}

for (var index = 0; index < myForm.storage.length; index++) { 
    myForm.storage[index].addEventListener("focus", addStoListener);
}

function addGraPrice(radio) {
    var radios = myForm.graphics;

    for (var index = 0; index < radios.length; index++) { 
        if (radios[index].checked) {
            total = total - graPrice + parseInt(radios[index].value);
            result.innerHTML = "$" + total + ".00";
            addGraListener();
        }
    }
}

function addGraListener(radio) {
    var radios = myForm.graphics;

    for (var index = 0; index < radios.length; index++) {
        if (radios[index].checked) {
            radios[index].removeEventListener("click", addGraPrice);
            graPrice = radios[index].value;
        } else {
            radios[index].addEventListener("click", addGraPrice)
        }
    }
}

for (var index = 0; index < myForm.graphics.length; index++) { 
    myForm.graphics[index].addEventListener("focus", addGraListener);
}

function addCurPrice(radio) {
    var radios = myForm.cursorControl;

    for (var index = 0; index < radios.length; index++) { 
        if (radios[index].checked) {
            total = total - curPrice + parseInt(radios[index].value);
            result.innerHTML = "$" + total + ".00";
            addCurListener();
        }
    }
}

function addCurListener(radio) {
    var radios = myForm.cursorControl;

    for (var index = 0; index < radios.length; index++) {
        if (radios[index].checked) {
            radios[index].removeEventListener("click", addCurPrice);
            curPrice = radios[index].value;
        } else {
            radios[index].addEventListener("click", addCurPrice)
        }
    }
}

for (var index = 0; index < myForm.cursorControl.length; index++) { 
    myForm.cursorControl[index].addEventListener("focus", addCurListener);
}

【问题讨论】:

  • 具体是什么不起作用?
  • @AdamBuchananSmith 价格没有更新
  • 我猜,你是 Mac 用户?它在 PC 上运行良好.... :) Safari 是垃圾,几乎像 IE,不确定 Firefox for Mac...但是,控制台中的任何错误?
  • 浏览器控制台出错?
  • 我可以确认 Arch Linux 上的 Firefox 40.0.3 一切正常,价格更新正常

标签: javascript html forms javascript-events


【解决方案1】:

当您单击单选按钮时,Mac 上的 Firefox 不会触发 focus 事件。我没有研究这是否违反标准,但有一种更简单的方法可以做你正在做的事情。不要使用focus 事件来添加click 处理程序,只需使用change 事件即可。每当您单击尚未选中的单选按钮时,都会触发此操作。这可以直接绑定到addXXXPrice 函数。

顺便说一句,您所有的 addXXXPrice 函数都使用它们从不使用的 radio 参数声明。事件处理程序的实际参数是event 对象,而不是单选按钮;事件的目标是this

所有这些addXXXPrice 函数都是相同的,除了它们循环的按钮集和它们更新的xxxPrice 变量。我建议您将其提取到一个将这些内容作为参数的单个函数中,这样您就可以这样做:

proPrice = addPrice(proPrice, myForm.proSpeed);

这是您的代码的修改版本:

var myForm = document.form1;
var proPrice = 0;
var ramPrice = 0;
var stoPrice = 0;
var graPrice = 0;
var curPrice = 0;
var total = 2299;
var result = document.getElementById('result');
result.innerHTML = "$" + total + ".00";
//total = parseFloat(total).toFixed(2);

console.log(result);

function addProPrice(radio) {
  var radios = myForm.proSpeed;

  for (var index = 0; index < radios.length; index++) {
    if (radios[index].checked) {
      total = total - proPrice + parseInt(radios[index].value);
      proPrice = parseInt(radios[index].value);
      result.innerHTML = "$" + total + ".00";
      break;
    }
  }
}

for (var index = 0; index < myForm.proSpeed.length; index++) {
  myForm.proSpeed[index].addEventListener("change", addProPrice);
}

function addMemPrice(radio) {
  var radios = myForm.ram;

  for (var index = 0; index < radios.length; index++) {
    if (radios[index].checked) {
      total = total - ramPrice + parseInt(radios[index].value);
      ramPrice = parseInt(radios[index].value);
      result.innerHTML = "$" + total + ".00";
      break;
    }
  }
}

for (var index = 0; index < myForm.ram.length; index++) {
  myForm.ram[index].addEventListener("change", addMemPrice);
}

function addStoPrice(radio) {
  var radios = myForm.storage;

  for (var index = 0; index < radios.length; index++) {
    if (radios[index].checked) {
      total = total - stoPrice + parseInt(radios[index].value);
      stoPrice = parseInt(radios[index].value);
      result.innerHTML = "$" + total + ".00";
      break;
    }
  }
}

for (var index = 0; index < myForm.storage.length; index++) {
  myForm.storage[index].addEventListener("change", addStoPrice);
}

function addGraPrice(radio) {
  var radios = myForm.graphics;

  for (var index = 0; index < radios.length; index++) {
    if (radios[index].checked) {
      total = total - graPrice + parseInt(radios[index].value);
      graPrice = parseInt(radios[index].value);
      result.innerHTML = "$" + total + ".00";
      break;
    }
  }
}

for (var index = 0; index < myForm.graphics.length; index++) {
  myForm.graphics[index].addEventListener("change", addGraPrice);
}

function addCurPrice(radio) {
  var radios = myForm.cursorControl;

  for (var index = 0; index < radios.length; index++) {
    if (radios[index].checked) {
      total = total - curPrice + parseInt(radios[index].value);
      curPrice = parseInt(radios[index].value);
      result.innerHTML = "$" + total + ".00";
      break;
    }
  }
}

for (var index = 0; index < myForm.cursorControl.length; index++) {
  myForm.cursorControl[index].addEventListener("change", addCurPrice);
}
<form action="" name="form1" id="form1">
  <h1>iMac with Retina 5K display</h1>
  <p>1. Choose Processor</p>
  <p>
    <input type="radio" name="proSpeed" checked="checked" value="0" />
    <label>3.5GHz Quad-core Intel Core i5, Turbo Boost up to 3.9GHz</label>
    <br />
    <input type="radio" name="proSpeed" value="250" />
    <label>4.0GHz Quad-core Intel Core i7, Turbo Boost up to 4.4GHz</label>
  </p>
  <p>2. Choose Memory</p>
  <p>
    <input type="radio" name="ram" checked="checked" value="0" />
    <label>8GB 1600MHz DDR3 SDRAM - 2x4GB</label>
    <br />
    <input type="radio" name="ram" value="200" />
    <label>16GB 1600MHz DDR3 SDRAM - 2x8GB</label>
    <br />
    <input type="radio" name="ram" value="600" />
    <label>32GB 1600MHz DDR3 SDRAM - 4x8GB</label>
  </p>
  <p>3. Choose Storage</p>
  <p>
    <input type="radio" name="storage" checked="checked" value="0" />
    <label>1TB Fusion Drive</label>
    <br />
    <input type="radio" name="storage" value="150" />
    <label>3TB Fusion Drive</label>
    <br />
    <input type="radio" name="storage" value="0" />
    <label>256GB Flash Storage</label>
    <br />
    <input type="radio" name="storage" value="300" />
    <label>512GB Flash Storage</label>
    <br />
    <input type="radio" name="storage" value="800" />
    <label>1TB Flash Storage</label>
  </p>
  <p>4. Choose Graphics</p>
  <p>
    <input type="radio" name="graphics" checked="checked" value="0" />
    <label>AMD Radeon R9 M290X 2GB GDDR5</label>
    <br />
    <input type="radio" name="graphics" value="250" />
    <label>AMD Radeon R9 M295X 4GB GDDR5</label>
  </p>
  <p>5. Choose Mouse and Magic Trackpad</p>
  <p>
    <input type="radio" name="cursorControl" checked="checked" value="0" />
    <label>Apple Magic Mouse</label>
    <br />
    <input type="radio" name="cursorControl" value="0" />
    <label>Magic Trackpad</label>
    <br />
    <input type="radio" name="cursorControl" value="0" />
    <label>Apple Mouse</label>
    <br />
    <input type="radio" name="cursorControl" value="69" />
    <label>Apple Magic Mouse + Magic Trackpad</label>
    <br />
  </p>
  <p>6. Choose Apple Keyboard and Documentation</p>
  <p>
    <select name="keyboard" size="1">
      <option value="0" selected="selected">Apple Wireless Keyboard (English) &amp; User's Guide</option>
      <option value="0">Apple Wireless Keyboard (Arabic) &amp; User's Guide</option>
      <option value="0">Apple Wireless Keyboard (British) &amp; User's Guide</option>
    </select>
  </p>
</form>
<div id="result"></div>

【讨论】:

  • 我可以确认即使在 Safari5 for Win 中也能正常工作,这可能是历史上最糟糕的浏览器,因此,它必须在所有现代浏览器(甚至在 Mac 上)中工作。 :)
  • 谢谢!确认可以在 Safari 和 Firefox for Mac 中工作。现在梳理一下,确保我知道它为什么有效(你的解释非常有道理,我只需要自己经历这个过程,因为我边做边学)。
  • @Barmar 您的回答非常有帮助。对此,我真的非常感激。我现在几乎已经弄清楚了所有问题,我认为还有一个问题 - 请参阅上面原始问题中的更新。再次感谢!
  • @JacobSmolowe addPrice 需要一个 return 声明,其中包含选中的单选按钮中的价格。
  • @Barmar,谢谢。我不知道如何使 return 语句起作用——对那些不太好——但我想出了一个不同的解决方案(在上面的原始帖子中)。你怎么看?
猜你喜欢
  • 1970-01-01
  • 2012-12-11
  • 1970-01-01
  • 2015-09-25
  • 2015-04-14
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多