ChatGPT解决这个技术问题 Extra ChatGPT

HTML <select> 是否有 onSelect 事件或等效事件?

我有一个输入表单,可让我从多个选项中进行选择,并在用户更改选择时执行某些操作。例如,

<select onChange="javascript:doSomething();">
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

现在,doSomething() 仅在选择更改 时触发。

我想在用户选择任何选项时触发 doSomething(),可能是 same 一个。

我曾尝试使用“onClick”处理程序,但它在用户开始选择过程之前被触发。

那么,有没有办法在用户每次选择时触发一个功能?

更新:

Darryl 提出的答案似乎有效,但并不能始终如一地工作。有时,一旦用户单击下拉菜单,甚至在用户完成选择过程之前,事件就会被触发!

我能理解你为什么这么认为。我会保持简短。我的表单上有两个输入。城市(文本字段)和州(选择)。最初,会显示一个城市及其州。当用户选择一个州时,某处的搜索过滤器将其范围扩大到“全州”而不是“特定城市”。
strager,它不是一个不常见的 UI 元素。在某些情况下非常有意义。另一个示例是撰写大量电子邮件,然后您在右侧有一个带有“特殊字段”的下拉菜单,您可以快速将其添加到电子邮件中,名字,退出链接等。
作为旁注......对于onclick,onchange等内联事件,您不需要“javascript:”协议前缀。 on{event}="doSomething();"很好。
未经测试: onClick 但应用于选项标签怎么样?显然是通过一个班级,以一种不引人注目的方式
@The Disintegrator 仅使用单击事件无法处理通过键盘选择选项的用例。 (意识到这是一个古老的问题 - 为未来的访客添加......)

f
freezethrower

这是最简单的方法:

<select name="ab" onchange="if (this.selectedIndex) doSomething();">
    <option value="-1">--</option>
    <option value="1">option 1</option> 
    <option value="2">option 2</option>
    <option value="3">option 3</option>
</select>

在选择集中时,可与鼠标选择和键盘上/下键一起使用。


但这不会做任何“当用户再次选择......同样的”,对吗?
请注意,@KayZhu 的评论只对了一半:正确的做法是检查“selectedIndex”是否大于或等于零(或大于-1)。没有“type()”函数,而且“selectedIndex”永远不会是 undefined
@TJCrowder您是对的-不确定我在写下半部分时在想什么。我删除了原始评论,为了不混淆其他人,这里是原始评论(请注意前半部分是正确的,后半部分是错误的):这不会像预期的那样工作第一个索引为 0: 0 的选项在 JS 中为 false,因此 doSomething() 不会被执行。相反,请使用 if(type(this.selectedIndex) != undefined; doSomething()
这个答案有最多的赞成票,但它并没有解决问题!当用户选择已选择的选项时,不会触发 doSomething() 函数。请参阅此plunk,其中只有当您选择与当前选择的选项不同 选项时,背景颜色才会发生变化。
FWIW:如果您只想在选择一个特定选项时调用 doSomething(),例如上例中的“选项 3”,请使用 if (this.selectedIndex==4),其中数字“4”代表 数字索引选项,而不是指定的 value! (即“选项3”是<select name="ab">的第四个选项)。
A
Alex from Jitbit

我需要完全相同的东西。这对我有用:

<select onchange="doSomething();" onfocus="this.selectedIndex = -1;">
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

支持这个:

当用户选择任何选项时,可能再次选择相同的选项


jsfiddle.net/ecmanaut/335XK 适用于 osx Chrome 30、Safari 6、Firefox 17。
也适用于 Win8 IE10、Win7 IE9、Win7 IE8、WinXP IE7 和 IE6。 Jsfiddle 或 IE 恶作剧迫使您直接使用 fiddle.jshell.net/ecmanaut/335XK/show/light 进行测试 - 他们的编辑器视图无法加载示例中使用的 jQuery 以提高可读性。以上只是用鼠标交互测试过的;为了让这个键盘友好,这个 hack 可能需要额外的工作,因为至少旧的 IE 在你有机会选择“C”之前会愉快地触发更改事件。
真的很棒的提示,。帮我解决了无法选择第一个选项
如果已经选择了一个值,则通过此选项卡将导致问题。一旦该字段被导航到该值,该值就会消失,这是一个非常出乎意料的用户行为。此外,当您关闭选项卡时,您将丢失选择,即使您没有执行任何此类操作。否则,好主意。
使用例如 jQuery .blur() 来恢复原始选择,如果它在失去焦点时为 -1。
C
Cody

几个月前我在创建设计时遇到了同样的问题。我找到的解决方案是在您正在使用的元素上结合使用 .live("change", function()).blur()

如果您希望它在用户单击时执行某些操作,而不是更改,只需将 change 替换为 click

我为下拉列表分配了一个 ID selected,并使用了以下内容:

$(function () {
    $("#selected").live("change", function () {

    // do whatever you need to do

    // you want the element to lose focus immediately
    // this is key to get this working.
    $('#selected').blur();
    });
});

我看到这个没有选定的答案,所以我想我会给出我的意见。这对我来说效果很好,所以希望其他人在遇到困难时可以使用此代码。

http://api.jquery.com/live/

编辑:使用 on 选择器而不是 .live。请参阅jQuery .on()


谢谢! .blur() 有帮助。在 IE7 中,如果代码中没有 .blur(),jQuery 的 change 事件会被触发两次。
这如何帮助解决问题中表达的问题,即在选择更改之前什么都不会发生?
@LarsH 这个问题已经有好几年了,不确定——我可能读错了这个问题并且感到困惑。
对于现在正在查看的任何人,.live 已从 1.9 api.jquery.com/live/#live-events-handler 完全删除。使用 .change 作为快捷方式 api.jquery.com/change/#change-handler
D
Darryl Hein

只是一个想法,但是否可以在每个 <option> 元素上单击一次?

<select>
  <option onclick="doSomething(this);">A</option>
  <option onclick="doSomething(this);">B</option>
  <option onclick="doSomething(this);">C</option>
</select>

另一种选择可能是在选择上使用 onblur。这将在用户点击离开选择的任何时候触发。此时,您可以确定选择了哪个选项。为了在正确的时间触发此事件,选项的 onclick 可能会模糊该字段(使其他内容处于活动状态或只是 jQuery 中的 .blur())。


@Darryl 这实际上并没有按预期工作。有时甚至在用户完成选择之前事件就会被触发。请参阅我添加到问题中的更新。
在所有版本的 IE 中,将事件处理程序放在选项上都会失败! webbugtrack.blogspot.com/2007/11/…
在火狐中工作。
这份清单可能很长。
s
scunliffe

onclick 方法并不完全糟糕,但如前所述,当鼠标单击未更改值时,它不会被触发。然而,可以在 onchange 事件中触发 onclick 事件。

<select onchange="{doSomething(...);if(this.options[this.selectedIndex].onclick != null){this.options[this.selectedIndex].onclick(this);}}">
    <option onclick="doSomethingElse(...);" value="A">A</option>
    <option onclick="doSomethingElse(..);" value="B">B</option>
    <option onclick="doSomethingElse(..);" value="Foo">C</option>
</select>

s
scunliffe

如果你真的需要它像这样工作,我会这样做(以确保它可以通过键盘和鼠标工作)

将 onfocus 事件处理程序添加到选择以设置“当前”值

将 onclick 事件处理程序添加到选择以处理鼠标更改

将 onkeypress 事件处理程序添加到 select 以处理键盘更改

不幸的是,onclick 将运行多次(例如 onpening 选择...和选择/关闭)并且 onkeypress 可能会在没有任何变化时触发...

<script>
  function setInitial(obj){
    obj._initValue = obj.value;
  }
  function doSomething(obj){
    //if you want to verify a change took place...
    if(obj._initValue == obj.value){
      //do nothing, no actual change occurred...
      //or in your case if you want to make a minor update
      doMinorUpdate();
    } else {
      //change happened
      getNewData(obj.value);
    }
  }
</script>


<select onfocus="setInitial(this);" onclick="doSomething();" onkeypress="doSomething();">
  ...
</select>

J
Jim Buck

要在每次用户选择某些东西(即使是相同的选项)时正确触发事件,您只需要欺骗选择框。

就像其他人所说的那样,在焦点上指定一个否定的 selectedIndex 以强制更改事件。虽然这确实允许您欺骗选择框,但只要它仍然具有焦点,它就不会工作。简单的解决方法是强制选择框模糊,如下所示。

标准 JS/HTML:

<select onchange="myCallback();" onfocus="this.selectedIndex=-1;this.blur();">
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

jQuery插件:

<select>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

<script type="text/javascript">
    $.fn.alwaysChange = function(callback) {
        return this.each(function(){
            var elem = this;
            var $this = $(this);

            $this.change(function(){
                if(callback) callback($this.val());
            }).focus(function(){
                elem.selectedIndex = -1;
                elem.blur();
            });
        });
    }


    $('select').alwaysChange(function(val){
        // Optional change event callback,
        //    shorthand for $('select').alwaysChange().change(function(){});
    });
</script>

您可以看到一个 working demo here


这适用于 Chrome,但不适用于 IE9:当我单击控件时,它的文本会消失并且不会下拉。
这样做的问题是它会破坏当前的选择。如果当前选择是 B 并且我单击下拉菜单,则复选标记会显示在 A 旁边!但是 A 并没有真正被选中,因为如果我滑出菜单并释放鼠标按钮(中止菜单),则选择变为空白。如果您点击到下拉菜单,选择也会变为空白,如果您正在点击表单的其他部分,您可能很容易做到这一点,而不是期望在此过程中造成任何损坏。 (按你的jsfiddle上的标签,你会明白我的意思。)
T
Tyler Stahlhuth

将扩展 jitbit 的答案。当您单击下拉菜单然后单击下拉菜单而不选择任何内容时,我发现这很奇怪。最终得到了一些类似的东西:

var lastSelectedOption = null; DDChange = function(Dd) { //更改后模糊,以便在不丢失焦点的情况下再次单击//重新触发 onfocus。 dd.blur(); //剩下的就是你想要的变化。 var tcs = $("span.on_change_times"); tcs.html(+tcs.html() + 1); $("span.selected_index").html(Dd.prop("selectedIndex"));返回假; }; DDFocus = function(Dd) { lastSelectedOption = Dd.prop("selectedIndex"); dd.prop("selectedIndex", -1); $("span.selected_index").html(Dd.prop("selectedIndex"));返回假; }; //在模糊时,将其设置回他们单击//离开之前的值而不选择选项。 // //这对用户来说通常很奇怪,因为他们//可能会单击下拉菜单以查看其他选项,//意识到他们没有更改任何内容,并且//单击下拉菜单。 DDBlur = function(Dd) { if (Dd.prop("selectedIndex") === -1) Dd.prop("selectedIndex", lastSelectedOption); $("span.selected_index").html(Dd.prop("selectedIndex"));返回假; };

选定索引:
触发onchange的时间:0

这对用户来说更有意义,并允许 JavaScript 在他们每次选择任何选项(包括较早的选项)时运行。

这种方法的缺点是它破坏了选项卡到下拉列表并使用箭头键选择值的能力。这对我来说是可以接受的,因为所有用户一直点击所有内容,直到永恒结束。


您可以通过传入 this 而不是 $(this) 来消除道具警告。但是,我并没有从中得到所有预期的行为;当我重新选择相同的选项时,它不会发出警报。
注意: onchange 在通过 JS 向选择框添加删除选项时触发。不仅仅是当用户选择一个项目时
@Noumenon 如果它仍然有帮助,我修复了这里的错误。我想我是在应用程序本身中测试它,当我把它复制出来时,我忘了重命名一个变量。应该在编辑器中工作并且现在更有意义。
A
Austin Ethridge

我知道这个问题现在已经很老了,但是对于仍然遇到这个问题的任何人,我通过在我的选项标签中添加一个 onInput 事件,然后在那个被调用的函数中检索该选项输入的值,在我自己的网站上实现了这一点。

输出: