HTML选择控件行为

时间:2015-08-19 20:37:36

标签: javascript html drop-down-menu

我试图让HTML Select控件在单击(或打开)时显示与选择项目后显示的字符串不同的字符串。例如,当我打开时,我想看到"一个",两个","三个"显示为选择。但如果用户选择了两个,我想要" 2"显示为所选项目。我的onclick处理程序使用长字符串重新加载Select选项列表,onchange处理程序使用短字符串重新填充控件,然后重新选择所选项。这适用于Firefox,但不适用于IE,Safari和Chrome。自从我上次使用JavaScript编码愉快以来已经差不多10年了。任何帮助,将不胜感激。这是我的代码:



var selectedIndex = -1;
function onChanged() {
  //once selected, replace verbose with terse forms
  var myList = document.getElementById("myList");
  selectedIndex = myList.selectedIndex;
  var optionArray = ["One|1", "Two|2", "Three|3"];
  myList.options.length = 0;
  for (var option in optionArray) {
    var pair = optionArray[option].split("|");
    var newOption = document.createElement("option");
    newOption.value = pair[1];
    newOption.innerHTML = pair[1];
    myList.options.add(newOption);
  }
  myList.selectedIndex = selectedIndex;
}

function onClicked() {
  var myList = document.getElementById("myList");
  var optionArray = ["1|One", "2|Two", "3|Three"];
  myList.options.length = 0;
  for (var option in optionArray) {
    var pair = optionArray[option].split("|");
    var newOption = document.createElement("option");
    newOption.value = pair[1];
    newOption.innerHTML = pair[1]; 
    myList.options.add(newOption);
  }
  if (selectedIndex > -1)
    myList.selectedIndex = selectedIndex;
}

<select id="myList" onchange="onChanged()" onclick="onClicked()">
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
</select>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:0)

这是一个时间问题。

<德尔>更改:

<select id="myList" onchange="onChanged()" onclick="onClicked()">

<德尔>到

<select id="myList" onchange="onChanged()" onmousedown="onClicked()">

如果用户打开列表并离开列表而不点击,则除非您同时在onChanged()上致电onmouseout,否则列表不会还原为原始列表。

<select id="myList" onchange="onChanged()" onmousedown="onClicked()" onmouseout="onChanged()">

更新为了实现最佳的跨浏览器(在FF上需要onfocus,但是打破了IE)支持,而浏览器没有嗅探我们这个组合:

<select id="myList" onchange="onChanged()" onblur="onChanged()" onfocus="onClicked()" onmousedown="onClicked()">

这也将纠正同一事件的第二次选择,但仅在用户点击该元素后才会更正。

更新

解决了 ......我想。

我重写了您用来更改选项的功能。由于您删除了所有onchange元素并添加了新的option元素,因此IE未触发option。如果用户更改了选择索引,则导致IE无法引用。该函数现在只修改当前option元素的值和innerHTML。我正在使用浏览器嗅探消除onmouseout对FF的调用。如果您将光标移动到下拉菜单,FireFox正在调用onmouseout。这确实会导致FF的副作用。如果用户在FF中选择相同的选项,则在onblur被触发之前,选项不会返回到原始状态。

演示: http://jsfiddle.net/hopkins_matt/3m1syk6c/

<强> JS:

function changeOptions() {
    var selectedIndex = -1;
    var click = 0;
    var myList = document.getElementById("myList");
    var optionArray = ["One|1", "Two|2", "Three|3"];

    var fireFox = /Firefox/i.test(navigator.userAgent);
    console.log(fireFox);
    if (fireFox == false) {
        myList.onmouseout=function(){changeList(false)};
    }
    myList.onblur=function(){changeList(false)};
    myList.onchange=function(){changeList(false)};
    myList.onmousedown=function(){changeList(true)};

    function changeList(listOpen) {
        var isListOpen = listOpen;

        if (isListOpen == true) {
            for (i = 0; i < myList.options.length; i++) { 
                var pair = optionArray[i].split("|");
                myList.options[i].value = pair[0];
                myList.options[i].innerHTML = pair[0];
            }
        }
        if (isListOpen == false) {
            for (i = 0; i < myList.options.length; i++) { 
                var pair = optionArray[i].split("|");
                myList.options[i].value = pair[1];
                myList.options[i].innerHTML = pair[1];
            }
        }
    }
}
changeOptions();

<强> HTML:

<select id="myList">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
</select>

答案 1 :(得分:0)

另一种方法是让每个选项都存储完整版本的文本,并且只在选择时将所选项目的显示文本更改为缩写版本。

(function() {
  var valueMap = {
    "1": "One (1)",
    "2": "Two (2)",
    "11": "Eleven (11)",
    "ITAR": "International Traffic in Arms Regulation (ITAR)",
    "ACA": "Affordable Care Act (ACA)",
    "FUBAR": "Fluffed Up Beyond All Recognition (FUBAR)"
  };
  var myList = document.getElementById("myList");
  for (var prop in valueMap) { // populate the dropdown from our object
    var opt = document.createElement("option");
    opt.value = prop;
    opt.text = valueMap[prop];
    myList.add(opt);
  }
  myList.selectedIndex = -1; // nothing selected by default

  myList.addEventListener("change", function() {
    this.options[this.selectedIndex].text = this.options[this.selectedIndex].value;
    this.blur();
  });

  myList.addEventListener("mousedown", function() {
    if (this.selectedIndex > -1) {
      var newValue = valueMap[this.options[this.selectedIndex].value];
      if (this.options[this.selectedIndex].text !== newValue) {
        this.options[this.selectedIndex].text = newValue;
      }
    }
  });
})();
<select id="myList" style="width:6em"></select>

这会让你大部分时间都在那里,但仍然有@ hopkins-matt提到的烦人问题;即,如果用户打开下拉列表并选择已选择的项目或从列表中移除而未选择任何内容,则选择将保留文本的长版本。

这种方法的另一个缺点是你需要指定select元素的宽度,以防止它扩展到隐藏选项元素的最大长度。