为`<select>`中选择的选项显示不同的文本

12

我希望在 <select> 中显示的文本与所选的 <option> 的文本不同。由于我的宽度有限,如果我显示 <option> 中的所有文本,则会截断某些文本。

例如,如果我的标记如下:

<select>
  <option>Open (some description)</option>
  <option>Closed (a bunch of text</option>
</select>
当选择第一个选项时,我只想显示单词“打开”,以节省空间。我不能仅使用Javascript替换文本,因为如果用户打开选择,他们将看到缩短的文本。 有没有一种方法可以使用

2
我认为如果没有JavaScript,你将无法完成这个任务。 - Zak
很不幸,我的看法是,没有 JavaScript 是不可能的 =) - Rudolf Manusachi
1
JS没问题,我是说简单的JS替换文本的解决方案行不通。也就是说,如果被选中了,你可以用“打开”来替换“打开(某个描述)”。 - Leo Jiang
4个回答

7
使用JS,您可以添加focusblur事件监听器来修改option的文本:

function focus() {
  [].forEach.call(this.options, function(o) {
    o.textContent = o.getAttribute('value') + ' (' + o.getAttribute('data-descr') + ')';
  });
}
function blur() {
  [].forEach.call(this.options, function(o) {
    console.log(o);
    o.textContent = o.getAttribute('value');
  });
}
[].forEach.call(document.querySelectorAll('.shortened-select'), function(s) {
  s.addEventListener('focus', focus);
  s.addEventListener('blur', blur);
  blur.call(s);
});
<select class="shortened-select">
  <option value="Open" data-descr="some description"></option>
  <option value="Closed" data-descr="a bunch of text"></option>
</select>


1
这是最接近的解决方案。当选择一个选项时,我也会触发 blur() - Leo Jiang
@Linksku 然后你可以添加类似 s.addEventListener('change', function(){this.blur()}); 的内容。 - Oriol

3
你可以创建第二个select元素,并缩略选项。默认显示它并隐藏具有非缩写选项的select元素。
当悬停在缩略select上时,显示另一个select元素。
当更改选项时,将缩略select元素的selectedIndex设置为匹配,这将保持两个元素同步:

document.getElementById('s2').addEventListener('input', function() {
  document.getElementById('s1').selectedIndex= this.selectedIndex;
});
#s1 {
  position: absolute;
}

#s2 {
  display: none;
}

#s2:hover, #s1:hover + select {
  position: relative;
  display: inline;
}
<select id="s1">
  <option>Open</option>
  <option>Closed</option>
</select>

<select id="s2">
  <option>Open (some description)</option>
  <option>Closed (a bunch of text</option>
</select>


这不是 OP 请求的“无 JS”选项。 - Axel Amthor
1
OP标记了JavaScript,并简单提到他不能使用JavaScript更改文本。 - Rick Hitchcock
不能仅仅使用JavaScript..因为如果这样意味着我有一些原因不想要它。 - Axel Amthor
如果需要,OP可以澄清。由于标记了JavaScript,它可能是一个选项。 - Rick Hitchcock
JavaScript很好,我只是不想使用不使用<select>的自定义选择器。 - Leo Jiang

0

最好的方法是不使用JavaScript并尝试节省空间:

<select size="5">
  <option title="(some description)">Open</option>
  <option title="(a bunch of text)">Closed</option>
</select>

title 会在鼠标悬停在选项上时显示为工具提示

fiddle: http://jsfiddle.net/1ywv0uab/


0
你可以尝试使用CSS伪元素。由于它们只是样式,不会影响关闭时不会显示。

option:after {
  content: ' (' attr(data-descr) ')';
}
<select>
  <option data-descr="some description">Open</option>
  <option data-descr="a bunch of text">Closed</option>
</select>

如果你希望 select 的宽度能够缩小到短文本的宽度,那么只有在 :focus 伪类下才能显示伪元素。

select:focus > option:after {
  content: ' (' attr(data-descr) ')';
}
<select>
  <option data-descr="some description">Open</option>
  <option data-descr="a bunch of text">Closed</option>
</select>


我猜测这段代码的问题在于文本被添加为option元素的兄弟节点(使用::after伪元素)。浏览器应该渲染的只有label属性的值或者元素的文本内容。 - Steven Liekens
1
我无法让它工作 :( 如果这个能够工作,它将是有史以来最好的解决方案!(这里是 jsfiddle https://jsfiddle.net/esL39f6g/ - Sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接