iOS 16.3.1及以下版本Safari中JavaScript代码失效问题求助
部分iPhone Safari浏览器中JavaScript完全失效的问题求助
我的网页JavaScript代码在桌面端、Android设备上运行正常,但在部分iPhone的Safari浏览器中完全失效,输入、点击等交互事件均无法触发。
兼容情况
可正常运行的iPhone机型及版本
- iPhone 13 Safari 16.6版本
- iPhone 12 Safari 16.6版本
- iPhone 13 Safari 16.5.1版本
- iPhone 11 Safari 16.5版本
无法正常运行的iPhone机型及版本
- iPhone 11 Safari 16.1版本
- iPhone 11 Safari 16.3.1版本
- iPhone XS Max Safari 16.5.1版本
- iPhone Xr Safari 16.5.1版本
- iPhone XR Safari 16.3.1版本
代码示例
document.addEventListener("DOMContentLoaded", function() { const header = document.querySelector(".header"); const langSelect = document.querySelector("#lang_select"); const langList = document.querySelector(".lang_list"); header.addEventListener("click", function(event) { langList.style.display = langList.style.display === "none" ? "block" : "none"; event.stopPropagation(); }); document.addEventListener("click", function(event) { if (!langSelect.contains(event.target)) { langList.style.display = "none"; } }); const fieldInputs = document.querySelectorAll(".field input"); fieldInputs.forEach(function(input) { input.addEventListener("focus", function() { this.parentElement.classList.add("active"); }); input.addEventListener("blur", function() { if (this.value === "") { this.parentElement.classList.remove("active"); } }); }); let isFirstOpen = false; const firstBtn = document.querySelector("#firstBtn"); const firstDrop = document.querySelector("#firstDrop"); firstBtn.addEventListener("click", function(event) { isFirstOpen = !isFirstOpen; if (isFirstOpen) { firstDrop.style.display = "block"; } else { firstDrop.style.display = "none"; } event.stopPropagation(); }); document.addEventListener("click", function(event) { if ( !event.target.closest("#firstBtn") && !event.target.closest("#firstDrop") ) { const firstDropElement = document.querySelector("#firstDrop"); if (firstDropElement.style.display !== "none") { firstDropElement.style.display = "none"; isFirstOpen = false; } } }); document.querySelector("#firstInput input").addEventListener("input", function() { const inputVal = this.value; let num = inputVal.replace(/[^0-9.]+/g, ""); let regex = /^[+-]?(\d*\.\d+|\d+\.\d*)([eE][+-]?\d+)?$/; if (!regex.test(num)) { if (num === ".") { num = ""; } else { num = num.replace(/(?<=\..*)\./, ""); } } this.value = num; const firstCryptoCurrencySymbol = document.querySelector("#currency1 a").dataset.cur; const secondCryptoCurrencySymbol = document.querySelector("#currency2 a").dataset.cur; fetch("/calculateExchangeRate", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ firstCryptoCurrencySymbol: firstCryptoCurrencySymbol, secondCryptoCurrencySymbol: secondCryptoCurrencySymbol }) }) .then(res => res.json()) .then(data => { const exchangeRate = data.rate; document.querySelector("#secondInput input").value = num * exchangeRate; }); }); document.querySelector("#secondInput input").addEventListener("input", function() { const inputVal = this.value; let num = inputVal.replace(/[^0-9.]+/g, ""); let regex = /^[+-]?(\d*\.\d+|\d+\.\d*)([eE][+-]?\d+)?$/; if (!regex.test(num)) { if (num === ".") { num = ""; } else { num = num.replace(/(?<=\..*)\./, ""); } } this.value = num; const firstCryptoCurrencySymbol = document.querySelector("#currency1 a").dataset.cur; const secondCryptoCurrencySymbol = document.querySelector("#currency2 a").dataset.cur; fetch("/calculateExchangeRate", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ firstCryptoCurrencySymbol: firstCryptoCurrencySymbol, secondCryptoCurrencySymbol: secondCryptoCurrencySymbol }) }) .then(res => res.json()) .then(data => { const exchangeRate = data.rate; document.querySelector("#firstInput input").value = num / exchangeRate; }); }); const optionElements = document.querySelectorAll(".option"); optionElements.forEach(function(option) { option.addEventListener("click", function(event) { if ('ontouchstart' in window || navigator.maxTouchPoints) { event.preventDefault(); } let dataCur = this.dataset.cur; let imageUrl = this.querySelector(".pm_select_img img").src; let optionText = this.querySelector("span").textContent; document.querySelector("#firstBtn .pm_select_img img").src = imageUrl; document.querySelector("#firstBtn span").textContent = optionText; document.querySelector("#firstBtn").dataset.cur = dataCur; document.querySelector("#currency1 .pm_select_child").dataset.cur = dataCur; document.querySelector("#currency1 .pm_select_child").textContent = dataCur; document.querySelector("#hiddenInput").value = dataCur; document.querySelector("#amount_send1").dataset.cur = dataCur; document.querySelector("#amount_send1 ~ .addons").textContent = dataCur; const secondDataCur = document.querySelector("#currency2 a").dataset.cur; fetch("/calculateExchangeRate", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ firstCryptoCurrencySymbol: dataCur, secondCryptoCurrencySymbol: secondDataCur }) }) .then(res => res.json()) .then(data => { const exchangeRate = data.rate; document.querySelector(".rate_info").textContent = `1 ${dataCur} = ${exchangeRate} ${secondDataCur}`; }); event.stopPropagation(); }); }); document.addEventListener("click", function() { document.querySelector("#firstDrop").style.display = "none"; }); const optionElementsFirst = document.querySelectorAll(".option1"); optionElementsFirst.forEach(function (option) { option.addEventListener("click", function (event) { if ("ontouchstart" in window || navigator.maxTouchPoints) { event.preventDefault(); } let dataCur = this.dataset.cur; let imageUrl = this.querySelector(".pm_select_img img").src; let optionText = this.querySelector("span").textContent; document.querySelector("#secondBtn .pm_select_img img").src = imageUrl; document.querySelector("#secondBtn span").textContent = optionText; document.querySelector("#secondBtn").dataset.cur = dataCur; document.querySelector("#currency2 .pm_select_child").dataset.cur = dataCur; document.querySelector("#currency2 .pm_select_child").textContent = dataCur; document.querySelector("#hiddenInput2").value = dataCur; document.querySelector("#amount_send2").dataset.cur = dataCur; document.querySelector("#amount_send2 ~ .addons").textContent = dataCur; const secondDataCur = document.querySelector("#currency1 a").dataset.cur; fetch("/calculateExchangeRate", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ firstCryptoCurrencySymbol: dataCur, secondCryptoCurrencySymbol: secondDataCur, }), }) .then((res) => res.json()) .then((data) => { const exchangeRate = data.rate; document.querySelector(".rate_info").textContent = `1 ${dataCur} = ${exchangeRate} ${secondDataCur}`; }); document.querySelector("#secondDrop").style.display = "none"; event.stopPropagation(); }); }); document.addEventListener("click", function () { document.querySelector("#secondDrop").style.display = "none"; }); let isOpen = false; const secondBtn = document.querySelector("#secondBtn"); const secondDrop = document.querySelector("#secondDrop"); secondBtn.addEventListener("click", function(event) { isOpen = !isOpen; if (isOpen) { secondDrop.style.display = "block"; } else { secondDrop.style.display = "none"; } event.stopPropagation(); }); document.addEventListener("click", function(event) { const secondBtn = document.querySelector("#secondBtn"); const secondDrop = document.querySelector("#secondDrop"); const isOpen = secondDrop.style.display !== "none"; if ( !event.target.closest("#secondBtn") && !event.target.closest("#secondDrop") ) { if (isOpen) { secondDrop.style.display = "none"; } } }); })
已尝试的排查步骤
- 检查代码无语法错误;
- 改用Bubble重构代码,问题依旧;
- 添加触摸事件,无改善;
- Mac模拟器测试正常;
- BrowserStack模拟器复现问题。
恳请提供解决方案。
内容的提问来源于stack exchange,提问作者Banahez
相关产品推荐
相关产品推荐

