为什么从位置哈希中选择下拉列表在 Chrome 上有效,但不适用于 Firefox、IE 或 Safari

Why does dropdown list selection from a location hash work on Chrome, but not Firefox, IE, or Safari?

本文关键字:适用于 不适用 Firefox Safari IE 有效 哈希中 位置 选择 下拉列表 Chrome      更新时间:2023-09-26

完整的JS新手。我想要一个"请求报价"按钮,以根据产品和网址在新页面上自动填充下拉菜单。 每个产品报价按钮都链接到相同的表单,但在 url 中具有不同的哈希值,该哈希值与下拉菜单中的选项匹配。

例:

  1. 用户点击"产品A"的"请求报价"

  2. 用户被发送到www.example.com/request-a-quote/#Product A

  3. 表单上的产品下拉菜单(id=product-select)已显示"产品A"

此代码适用于 Chrome,但不适用于其他任何代码。我做错了什么?

//Get select object
var objSelect = document.getElementById("product-select");
var val = window.location.hash.substr(1);
//Set selected
setSelectedValue(objSelect, val)
function setSelectedValue(selectObj, valueToSet) {
    for (var i = 0; i < selectObj.options.length; i++) {
        if (selectObj.options[i].text== valueToSet) {
            selectObj.options[i].selected = true;
            return;
        }
    }
}

我发现应用decodeURIComponent()清理了我的val变量。

此外,将链接构建为 www.example.com/request-a-quote/#Product A 也很重要。 如果正斜杠不在哈希之前,移动 Safari 将忽略哈希之后的所有内容,并且它不起作用。

以下是我的最终解决方案:

//Get select object
var objSelect = document.getElementById("product-select");
var val = decodeURIComponent(window.location.hash.substr(1));
//Set selected
setSelectedValue(objSelect, val)
function setSelectedValue(selectObj, valueToSet) {
    for (var i = 0; i < selectObj.options.length; i++) {
        if (selectObj.options[i].text== valueToSet) {
            selectObj.options[i].selected = true;
            return;
        }
    }
}

没有看到更多代码....选项标签正式支持值属性与文本,文本是用户可读的名称。 我们使用价值作为标识符:

selectObj.options[i].value == valueToSelect;

您还需要更改 select.options 标记以使用 value 属性而不是文本。

根据要求更新更多信息:

text的目的是提供用户可读的选项。 我们使用value来识别服务器的选择,在您的情况下是URL哈希。 通过使用 value 属性,可以使用 URL 安全值和用户可读文本。

您在答案中发布的修复程序确实是不好的做法,随着代码复杂性的增加,它们会变得有问题。

此示例适用于所有浏览器,并且是正确的实现方式。

//Simulate hash
window.location.hash = '2'
var val = window.location.hash.substr(1);
var selectEle = document.getElementById('select')
setSelectedValue(selectEle, val)
function setSelectedValue(selectObj, valueToSet) {
    for (var i = 0; i < selectObj.options.length; i++) {
    	var selection = selectObj.options[i]
        if (selection.value == valueToSet) {
            selection.selected = true;
        }
    }
}
<select name="selections" id="select">
  <option value="1">Product A</option>
  <option value="2">Product B</option>
  <option value="3">Product C</option>
</select>