web-dev-qa-db-ja.com

onSelectイベントまたはそれに相当するHTMLの<select>はありますか?

私は複数のオプションから選択することを可能にする入力フォームを持っていて、そしてユーザーが選択を変更したときに何かをする。例えば、

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

現在、doSomething()は選択範囲が変更されたときにのみトリガされます。

ユーザーが任意のオプションを選択したとき、おそらくは同じのオプションが選択されたときにdoSomething()をトリガーします。

"onClick"ハンドラを使用しようとしましたが、ユーザーが選択プロセスを開始する前にトリガーされます。

それで、ユーザーが選択するたびに機能を起動する方法はありますか?

更新:

ダリルによって提案された答えはうまくいくように見えたが、それは一貫して働かない。ユーザーが選択プロセスを終了する前であっても、ユーザーがドロップダウンメニューをクリックするとすぐにイベントが発生することがあります。

181
ePharaoh

これが最も簡単な方法です。

<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>

マウス選択とキーボードの上下キーの両方で機能します。

80
freezethrower

私は全く同じものが必要でした。これは私のために働いたものです:

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

これをサポートします。

ユーザーが任意のオプションを選択したとき、おそらくは同じオプションもあります

54
Alex

数ヶ月前にデザインを作成していたときにも同じ問題がありました。私が見つけた解決策は、あなたが使っている要素に.live("change", function()).blur()と組み合わせて使うことでした。

ユーザーが変更するのではなくクリックするだけで何かをしたい場合は、changeclickに置き換えてください。

ドロップダウン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/

編集:.liveではなくonセレクタを使用してください。 jQuery .on()を参照してください。

11
Cody

単なるアイデアですが、<option>の各要素をクリックすることは可能ですか?

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

別の選択肢はselectにonblurを使用することです。これは、ユーザーが選択範囲から離れてクリックしたときに発生します。この時点で、どのオプションが選択されたかを判断できます。これを正しいタイミングで起動させるには、オプションをクリックするとフィールドがぼやける可能性があります(他のものをアクティブにするか、jQueryで単に.blur()を実行します)。

8
Darryl Hein

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>
6
user1845327

Jitbitの答えを拡大していきます。何も選択せずにドロップダウンをクリックしてからドロップダウンをクリックしたときに奇妙に感じました。次の行に沿って何かで終わった。

var lastSelectedOption = null;

DDChange = function(Dd) {
  //Blur after change so that clicking again without 
  //losing focus re-triggers onfocus.
  Dd.blur();

  //The rest is whatever you want in the change.
  var tcs = $("span.on_change_times");
  tcs.html(+tcs.html() + 1);
  $("span.selected_index").html(Dd.prop("selectedIndex"));
  return false;
};

DDFocus = function(Dd) {
  lastSelectedOption = Dd.prop("selectedIndex");
  Dd.prop("selectedIndex", -1);

  $("span.selected_index").html(Dd.prop("selectedIndex"));
  return false;
};

//On blur, set it back to the value before they clicked 
//away without selecting an option.
//
//This is what is typically weird for the user since they 
//might click on the dropdown to look at other options,
//realize they didn't what to change anything, and 
//click off the dropdown.
DDBlur = function(Dd) {
  if (Dd.prop("selectedIndex") === -1)
    Dd.prop("selectedIndex", lastSelectedOption);

  $("span.selected_index").html(Dd.prop("selectedIndex"));
  return false;
}; 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<select id="Dd" onchange="DDChange($(this));" onfocus="DDFocus($(this));" onblur="DDBlur($(this));">
  <option>1</option>
  <option>2</option>
</select>
<br/>
<br/>Selected index: <span class="selected_index"></span>
<br/>Times onchange triggered: <span class="on_change_times">0</span>

これはユーザーにとってもう少し意味があり、JavaScriptが以前のオプションを含むオプションを選択するたびに実行されることを可能にします。

このアプローチのマイナス面はドロップダウンにタブ移動して値を選択するのに矢印キーを使うことができないことです。すべてのユーザーが永遠の終わりまでずっとすべてのものをクリックするので、これは私にとって許容範囲でした。

5
Tyler Stahlhuth

このように動作させるためにこれが本当に必要な場合は、私はこれを実行します(キーボードとマウスで確実に機能するように)

  • Onfocusイベントハンドラをselectに追加して「現在の」値を設定します。
  • Onclickイベントハンドラをselectに追加してマウスの変更を処理します。
  • キーボードの変更を処理するために、onkeypressイベントハンドラをselectに追加します。

残念ながら、onclickは何度も実行され(例えば、select ...をオンにしたときやselection/closeをオンにしたとき)、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>
4
scunliffe

ユーザーが何かを選択するたびに(同じオプションであっても)適切にイベントを発生させるには、選択ボックスをトリックするだけです。

他の人が言っているように、changeイベントを強制するためにフォーカスに負の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>

あなたは ここで実用的なデモ を見ることができます。

4
Jim Buck

実際には、ユーザーがキーボードを使用して選択コントロールの選択を変更しても、onclickイベントは発生しません。探している動作を取得するには、onChangeとonClickを組み合わせて使用​​する必要があります。

3

したがって、私の目標は、onchange()関数を本質的に上書きし、それを便利なonclick()メソッドに変えることで、同じ値を複数回選択できるようにすることでした。

上記の提案に基づいて、私はこれを思いつきました。

<select name="ab" id="hi" onchange="if (typeof(this.selectedIndex) != undefined) {alert($('#hi').val()); this.blur();}" onfocus="this.selectedIndex = -1;">
    <option value="-1">--</option>
    <option value="1">option 1</option>
    <option value="2">option 2</option>
    <option value="3">option 3</option>
</select>

http://jsfiddle.net/dR9tH/19/

2
Sean D

似たような問題に直面したときにしたことは、新しい一般的なオプション(「オプションの選択」または類似のもの)を追加する選択ボックスに「onFocus」を追加し、それを選択オプションとしてデフォルトにすることです。

2

私のために何がうまくいく:

<select id='myID' onchange='doSomething();'>
    <option value='0' selected> Select Option </option>
    <option value='1' onclick='if (!document.getElementById("myID").onchange()) doSomething();' > A </option>
    <option value='2' onclick='if (!document.getElementById("myID").onchange()) doSomething();' > B </option>
</select>

このように、onchangeはオプションが変更されたときに 'doSomething()'を呼び出し、onchangeイベントがfalseのとき、つまり同じオプションを選択したときにonclickは 'doSomething()'を呼び出します。

1
antoniobh

これが私の解決策です。ここで説明したものとはまったく異なります。ドロップダウンを開くために選択ボックスをクリックするのではなく、オプションがクリックされたかどうかを判断するためにマウス位置を使用します。これは唯一の信頼できるクロスブラウザ変数であるため、event.screenYの位置を利用します。クリックイベントの前に画面を基準にしたコントロールの位置を把握できるように、最初にホバーイベントを添付する必要があります。

var select = $("select");

var screenDif = 0;
select.bind("hover", function (e) {
    screenDif = e.screenY - e.clientY;
});
select.bind("click", function (e) {
    var element = $(e.target);
    var eventHorizon = screenDif + element.offset().top + element.height() - $(window).scrollTop();
    if (e.screenY > eventHorizon)
        alert("option clicked");
});

これが私のjsFiddleです http://jsfiddle.net/sU7EV/4/

1
Ally

jqueryを使う:

<select class="target">
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

<script>
    $('.target').change(function() { doSomething(); });
</script>
1
ladookie
<script>
function abc(selectedguy) {
alert(selectedguy);
}
</script>

<select onchange="abc(this.selectedIndex);">
<option>option one</option>
<option>option two</option>
</select>

ここでインデックスが返されます。jsコードでは、このリターンを1つのスイッチまたは必要なもので使用できます。

1
JMFDB

(このシナリオでは)selectタグの素晴らしいところは、optionタグからその値を取得できるということです。

試してください:

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

私のためにきちんと働いた。

1
Tzshand

これを試してみてください(オプションを変更しないで、オプションを選択したときにイベントが発生します)。

$("select").mouseup(function() {
    var open = $(this).data("isopen");
    if(open) {
        alert('selected');
    }
    $(this).data("isopen", !open);
});

http://jsbin.com/dowoloka/4

1
WebBrother

option:selectedを使ってみるべきです

$("select option:selected").click(doSomething);
1

まず最初にイベントハンドラとしてonChangeを使用し、次にflag変数を使用して変更を行うたびに必要な機能を実行させます。

<select
var list = document.getElementById("list");
var flag = true ; 
list.onchange = function () {
if(flag){
document.bgColor ="red";
flag = false;

}else{
document.bgColor ="green";
flag = true;
}
}
<select id="list"> 
<option>op1</option>
<option>op2</option>
<option>op3</option>
</select>
1
Paula George
<select name="test[]" 
onchange="if(this.selectedIndex < 1){this.options[this.selectedIndex].selected = !1}">
<option>1</option>
<option>2</option>
<option>3</option>
</select>
0
xicooc

正解の1つは、選択フィールドを使用しないことです(同じ答えを再選択したときに何かする必要がある場合)。

従来のdiv、ボタン、表示/非表示メニューでドロップダウンメニューを作成します。リンク: https://www.w3schools.com/howto/howto_js_dropdown.asp

イベントリスナーをオプションに追加できれば避けられたかもしれません。 select要素にonSelectリスナーがあった場合そして、selectフィールドをクリックしても、マウスダウン、マウスダウン、そしてmousedown上で同時にすべてクリックすることを悪化させずに発火させなかったなら

0
Shinjitsu

これを試して:

<select id="nameSelect" onfocus="javascript:document.getElementById('nameSelect').selectedIndex=-1;" onchange="doSomething(this);">
    <option value="A">A</option>
    <option value="B">B</option>
    <option value="C">C</option>
</select>
0
Jesús López

私は同様のニーズに直面していて、同じことのためにangularjsディレクティブを書いてしまいました -

guthubリンク - 角度選択

Selectタグからフォーカスを外すためにelement[0].blur();を使用しました。ロジックはドロップダウンの2回目のクリックでこのぼかしを引き起こすことです。

ユーザーがドロップダウンで同じ値を選択した場合でもas-selectがトリガーされます。

デモ - リンク

0

これは直接あなたの質問に答えないかもしれませんが、この問題は単純な設計レベルの調整によって解決することができます。私はこれがすべてのユースケースに100%当てはまるわけではないことを理解していますが、私はあなたがあなたのアプリケーションのあなたのユーザーフローを再考することを検討することを強くお勧めします。

この目的のために実際には意図されていない他のイベント(blurclickなど)を使用してonChange()の代替をハッキングするよりも簡単なことをすることにしました。

私がそれを解決した方法:

単に値のないselectなどのプレースホルダオプションタグを前に付けるだけです。

そのため、次のような構造を使用するのではなく、代わりの方法が必要になります。

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

これを使用することを検討してください。

<select>
  <option selected="selected">Select...</option>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

したがって、この方法では、ユーザーがデフォルト値以外のものを選択することを決定するたびに、コードはより単純化され、onChangeは期待どおりに機能します。最初のオプションにdisabled属性を追加して選択させたくない場合は、オプションから何かを選択させることで、onChange()の起動を引き起こすこともできます。

この答えの時点で、私は複雑なVueアプリケーションを書いています、そして私はこのデザイン選択が私のコードを大いに単純化したことを知りました。私はこの問題を解決する前にこの問題に何時間も費やしました。そして私は自分のコードの多くを書き直す必要はありませんでした。しかし、私がハックな代替手段を使った場合、ajaxリクエストの二重起動などを防ぐために、Edgeのケースを考慮する必要がありました。ブラウザも同様)。

時々、あなたは一歩後退して、最も単純な解決策のための全体像について考える必要があるだけです。

0
dsignr

少し前のことですが、元の質問に答えて、これは助けになりますか? onClickSELECT行に入れるだけです。次に、各OPTIONに何をさせたいかをOPTION行に入れます。すなわち:

<SELECT name="your name" onClick>
<option value ="Kilometres" onClick="YourFunction()">Kilometres
-------
-------
</SELECT>
0
bones