JavaScript动态生成的PayPal费率选项在iOS端不显示问题求助
PayPal费用计算器iOS兼容性及DOCTYPE依赖问题
我开发了一个基于HTML和JavaScript的PayPal费用计算器,在Android和Windows平台运行正常,但**iOS系统(即使使用Chrome浏览器)**中,选择货币后动态生成的费率选项无法显示。
iOS端异常截图:
另外,移除<DOCTYPE html>标签后,Android和PC端的费率选项也会消失,求解决方法。
现有代码
HTML部分
<label for="amount">Amount:</label> <input type="number" placeholder="0.00" id="amount" name="amount"><br><br> <label for="currency">Country or Region (Currency):</label> <select id="currency" name="currency" onchange="updateFeeOptions()"> <option value="">Select</option> <option value="INR">India (INR)</option> <option value="USD">United States (USD)</option> <option value="GBP">United Kingdom (GBP)</option> </select><br><br> <label for="fee-option">Fee Rate:</label> <br/> <br/> <select id="fee-option" name="fee-option"> <option value="">Automatic Selection</option> <!-- Fee options will be dynamically generated based on currency selection --> </select><br><br> <button onclick="calculateFees()">Calculate Fees</button><br><br> <label for="total-fees">Total Fees:</label> <input type="text" id="total-fees" name="total-fees" readonly><br><br> <label for="you-will-receive">You Will Receive:</label> <input type="text" id="you-will-receive" name="you-will-receive" readonly><br><br> <label for="you-should-ask-for">You Should Ask For:</label> <input type="text" id="you-should-ask-for" name="you-should-ask-for" readonly><br><br>
JavaScript部分
// Define fee options based on currency const feeOptions = { USD: [{ label: "Domestic", options: [{ value: "2.9-0.30", label: "2.9% + $0.30 (online transaction)" }, { value: "2.7-0.30", label: "2.7% + $0.30 (store location)" }, { value: "2.2-0.30", label: "2.2% + $0.30 (non-profit)" }, { value: "5-0.05", label: "5% + $0.05 (micropayment)" } ] }, { label: "International", options: [{ value: "4.4-0.30", label: "4.4% + $0.30 (online transaction)" }, { value: "4.2-0.30", label: "4.2% + $0.30 (store location)" }, { value: "3.7-0.30", label: "3.7% + $0.30 (non-profit)" }, { value: "6.5-0.05", label: "6.5% + $0.05 (micropayment)" } ] }, { label: "Mobile Card Reader", options: [{ value: "2.7", label: "2.7% (swiped & check-in transactions)" }, { value: "3.5-0.15", label: "3.5% + $0.15 (keyed & scanned transactions)" }, { value: "4.2", label: "4.2% (international + 1.5% cross-border fee)" } ] }, { label: "Virtual Terminal", options: [{ value: "3.1-0.30", label: "3.1% + $0.30 (domestic)" }, { value: "4.6-0.30", label: "4.6% + $0.30 (cross-border)" } ] } ], GBP: [{ label: "Domestic", options: [{ value: "2.9-0.30", label: "2.9% + £0.30" }, ] }, { label: "International - from Europe I, Northern Europe", options: [{ value: "3.4-0.30", label: "3.4% + £0.30" }, ] }, { label: "International - from CANADA, USA, Europe II, rest of the world", options: [{ value: "4.9-0.30", label: "4.9% + £.30" }, ] }, { label: "Charity", options: [{ value: "1.4-0.20", label: "1.4% + £.20" }, ] }, { label: "Micropayment", options: [{ value: "5-0.05", label: "5% + £0.05 (domestic)" }, ] } ], INR: [{ label: "Domestic", options: [{ value: "2.5-3", label: "2.5% + ₹3" }] }, { label: "International", options: [{ value: "4.4-3", label: "4.4% + ₹3 (up to $3000 monthly sales)" }, { value: "3.9-3", label: "3.9% + ₹3 (up to $3000 to $10000 monthly sales)" }, { value: "3.7-3", label: "3.7% + ₹3 (up to ₹10000 to $100000 monthly sales)" }, { value: "3.4-3", label: "3.4% + ₹3 ($100000+ monthly sales)" } ] } ] }; function updateFeeOptions() { const currencySelect = document.getElementById("currency"); const feeOptionSelect = document.getElementById("fee-option"); // Clear existing options feeOptionSelect.innerHTML = ""; // Add new options based on selected currency const selectedCurrency = currencySelect.value; const options = feeOptions[selectedCurrency]; for (let i = 0; i < options.length; i++) { const optgroup = document.createElement("optgroup"); optgroup.label = options[i].label; for (let j = 0; j < options[i].options.length; j++) { const option = document.createElement("option"); option.value = options[i].options[j].value; option.label = options[i].options[j].label; optgroup.appendChild(option); } feeOptionSelect.appendChild(optgroup); } } function calculateFees() { const amountInput = document.getElementById("amount"); const feeOptionSelect = document.getElementById("fee-option"); const totalFeesInput = document.getElementById("total-fees"); const youWillReceiveInput = document.getElementById("you-will-receive"); const youShouldAskForInput = document.getElementById("you-should-ask-for"); const amount = amountInput.value.trim(); // remove any leading/trailing spaces if (!amount) { alert("Please enter an amount."); return; // stop the function } const feeOption = feeOptionSelect.value.split("-"); const feePercent = parseFloat(feeOption[0]) / 100; const feeFixed = parseFloat(feeOption[1]); const totalFees = (amount * feePercent) + feeFixed; const youWillReceive = amount - totalFees; const youShouldAskFor = amount / (1 - feePercent) + feeFixed; totalFeesInput.value = totalFees.toFixed(2); youWillReceiveInput.value = youWillReceive.toFixed(2); youShouldAskForInput.value = youShouldAskFor.toFixed(2); }
解决方案
1. 修复iOS动态生成选项的兼容性问题
iOS的Safari内核(包括Chrome for iOS)对动态创建<optgroup>的DOM操作存在兼容性问题,修改updateFeeOptions函数:
function updateFeeOptions() { const currencySelect = document.getElementById("currency"); const feeOptionSelect = document.getElementById("fee-option"); // 安全清空子元素(替代innerHTML="",避免iOS渲染异常) while (feeOptionSelect.firstChild) { feeOptionSelect.removeChild(feeOptionSelect.firstChild); } const selectedCurrency = currencySelect.value; if (!selectedCurrency) { // 添加默认选项 const defaultOption = document.createElement("option"); defaultOption.value = ""; defaultOption.text = "Automatic Selection"; feeOptionSelect.appendChild(defaultOption); return; } const options = feeOptions[selectedCurrency]; for (let i = 0; i < options.length; i++) { const optgroup = document.createElement("optgroup"); optgroup.label = options[i].label; for (let j = 0; j < options[i].options.length; j++) { const option = document.createElement("option"); option.value = options[i].options[j].value; // 优先设置text属性而非label,适配iOS内核 option.text = options[i].options[j].label; optgroup.appendChild(option); } feeOptionSelect.appendChild(optgroup); } // 手动触发重绘,解决iOS下拉菜单不更新的问题 feeOptionSelect.style.display = 'none'; feeOptionSelect.offsetHeight; // 触发浏览器重排 feeOptionSelect.style.display = ''; }
2. 保留标准DOCTYPE声明
移除<DOCTYPE html>后浏览器会进入怪异模式,导致DOM操作行为不一致。必须在HTML文档最开头保留标准声明,同时添加移动端适配标签:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>PayPal Fee Calculator</title> </head> <body> <!-- 你的HTML内容 --> </body> </html>
3. 修复计算函数的边界问题
处理无固定费用的选项(比如USD的"2.7"),避免feeFixed变成NaN:
function calculateFees() { // ... 原有代码 ... const feeOption = feeOptionSelect.value.split("-"); const feePercent = parseFloat(feeOption[0]) / 100; // 处理无固定费用的情况 const feeFixed = feeOption.length > 1 ? parseFloat(feeOption[1]) : 0; // ... 原有计算代码 ... }
内容的提问来源于stack exchange,提问作者Chanakya Sahu
相关产品推荐
相关产品推荐

