Bagaimana Anda bisa secara terprogram memberi tahu HTML SELECT untuk drop-down (misalnya, karena gerakan mouse)?

106

Bagaimana Anda bisa secara terprogram memberi tahu HTML selectuntuk turun (misalnya, karena gerakan mouse)?

Corey Trager
sumber
6
Saya sarankan untuk tidak mengacaukan perilaku default <select>, karena orang mengharapkannya berperilaku dengan cara tertentu dan Anda akan mencegah orang di platform lain (seperti seluler) untuk menggunakan situs Anda.
Brian Donovan
1
@BrianDonovan Ini tidak seperti Anda tidak dapat menambahkan penanganan untuk itu.
Morg.
@shasikanth: biola Anda tidak berfungsi baik di Firefox 37 nr di Chrome
rubo77
Oke, saya pikir biolanya berfungsi sebelumnya. Bagaimanapun saya akan menghapus komentar saya di sini.
shasi kanth
@BrianDonovan Sebenarnya, seluler adalah kasus penggunaan yang baik untuk ini ... secara terprogram menghasilkan pilihan dan kemudian opsinya secara otomatis muncul.
Michael

Jawaban:

16

Anda tidak dapat melakukannya dengan tag pemilihan HTML, tetapi Anda dapat melakukannya dengan JavaScript dan HTML. Ada berbagai kontrol yang melakukan ini - misalnya, daftar "saran" yang dilampirkan ke entri "tag menarik / diabaikan" SO, atau pencarian Gmail untuk alamat email.

Ada banyak kontrol JavaScript + HTML yang menyediakan kemampuan ini - cari kontrol pelengkapan otomatis untuk ide.

Lihat tautan ini untuk kontrol Pelengkapan Otomatis ... http://ajaxcontroltoolkit.codeplex.com/

rp.
sumber
6
ini sungguh memalukan - browser seluler menyediakan daftar gulir khusus OS, dan saya memerlukannya untuk muncul secara otomatis.
Michael
120

Ini dulunya benar-benar dimungkinkan dengan HTML + Javascript, meskipun di tempat lain orang mengatakan tidak, tetapi itu sudah usang nanti dan tidak berfungsi sekarang.

Namun, ini hanya berfungsi di Chrome. Baca lebih lanjut jika Anda tertarik.


Menurut Draf Kerja W3C untuk HTML5, Bagian 3.2.5.1.7. Konten Interaktif :

Elemen tertentu dalam HTML memiliki perilaku aktivasi, yang berarti pengguna dapat mengaktifkannya. Ini memicu urutan kejadian yang bergantung pada mekanisme aktivasi [...] misalnya menggunakan keyboard atau input suara, atau melalui klik mouse .

Saat pengguna memicu elemen dengan perilaku aktivasi yang ditentukan selain dengan mengkliknya, tindakan default dari peristiwa interaksi tersebut harus menjalankan langkah aktivasi klik sintetis pada elemen tersebut.

<select>menjadi Konten Interaktif, saya percaya bahwa mungkin untuk menampilkan secara terprogram <option>. Setelah beberapa jam bermain-main, saya menemukan bahwa menggunakan document.createEvent()dan .dispatchEvent()bekerja.

Konon, waktu demo. Ini Biola yang berfungsi.


HTML:

<select id="dropdown">
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" onclick="runThis()">Show dropdown items</button>​

Javascript:

// <select> element displays its options on mousedown, not click.
showDropdown = function (element) {
    var event;
    event = document.createEvent('MouseEvents');
    event.initMouseEvent('mousedown', true, true, window);
    element.dispatchEvent(event);
};

// This isn't magic.
window.runThis = function () { 
    var dropdown = document.getElementById('dropdown');
    showDropdown(dropdown);
};

Jika ada yang menemukan cara untuk melakukan hal yang sama tetapi tidak di Chrome, silakan memodifikasi biola ini . </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> orang </s>

Xavier Ho
sumber
2
Terima kasih untuk ini! Saya perlu meniru perilaku ALT + DOWN ARROW IE tepatnya di Chrome.
J Bryan Harga
3
Saya berharap saya bisa menambah karunia Anda untuk ini. Terima kasih banyak.
Adam Tuttle
7
Tidak bekerja pada: IE10, FF 24. Bekerja pada: Chrome 30, Safari 6.0.5,Opera 16
hitautodestruct
2
@AdamTuttle Itu tidak berfungsi di Android 4.4.2 juga
Mirko
42
Sekarang sudah tidak berlaku lagi di Chrome 53+
Washington Guedes
47

Jawaban Xavier Ho mencakup cara mengatasi masalah tersebut di sebagian besar browser yang ada saat ini. Tapi, praktik yang baik adalah 'tidak mengirim / mengubah' acara dengan JavaScript lagi . (Seperti, mousedowndalam kasus ini)

Dari versi 53+, Google Chrome tidak akan melakukan tindakan default untuk acara tidak tepercaya . Seperti acara yang dibuat atau diubah oleh skrip, atau dikirim melalui dispatchEventmetode. Perubahan ini untuk menyelaraskan dengan Firefox dan IE yang menurut saya sudah tidak melakukan aksinya.

Untuk tujuan pengujian, Fiddle memberikan jawaban Xavier tidak akan berfungsi di chrome 53+. (Saya tidak mengujinya FF dan IE).

Tautan untuk referensi:

https://www.chromestatus.com/features/5718803933560832 https://www.chromestatus.com/features/6461137440735232

Dan initMouseEvent juga tidak digunakan lagi

Asim KT
sumber
Bisakah itu dilakukan dengan menggunakan MouseEvents? developer.mozilla.org/en-US/docs/Web/API/MouseEvent
Shamal Perera
Saya kira tidak. apakah kamu mencoba sesuatu?
Asim KT
28

Ini yang paling dekat yang bisa saya dapatkan, ubah ukuran elemen onmouseover, dan pulihkan ukuran onmouseout:

       <select onMouseOut="this.size=1;" onMouseOver="this.size=this.length;">
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
        <option>5</option>
      </select>

CMS
sumber
13
atau <SELECT onMouseOut = "this.size = 1;" onMouseOver = "this.size = this.length;"> ... </SELECT>
RealHowTo
1
Juga perlu menambahkan onchange = "this.size = 1" sehingga menu tersebut segera runtuh setelah pemilihan dibuat. Aturan CSS elemen juga perlu dikonfigurasi.
gm2008
Sepertinya berhasil. Lebar pemilihan menyusut dan kemudian itu menyebabkan peristiwa mouse out mengatur ulang pemilihan ke lebar aslinya. Ini menyebabkan efek kejang. Menetapkan lebar tetap tampaknya memperbaikinya. Dengan lebih dari beberapa item, daftar melebar melewati tampilan.
1,21 gigawatt
16

saya memiliki masalah yang sama dan cara yang lebih mudah saya temukan untuk solusi ini dengan html dan css.

select{
  opacity: 0;
  position: absolute;
}
<select>
  <option>option 1</option>
  <option>option 2</option>
  <option>option 3</option>
</select>
<button>click</button>

Rafael Umbelino
sumber
2
Sudah lama sekali saya tidak melihat pendekatan ini, dan merupakan referensi yang ingin saya temukan. Lebih baik dengan CSS tambahan untuk mencocokkan ukuran pilih yang tersembunyi untuk memicu (tombol, img, div, dll) ... 1) Memastikan pemicu pengisian wilayah yang dapat diklik 2) Menu terbuka tepat di bawah pemicu. Catatan: Mungkin juga perlu menambahkan indeks-z untuk memastikan wilayah yang dapat diklik adalah elemen paling atas di beberapa tata letak.
Mavelo
namun, jika pengguna menggulir halaman ke bawah, tombol akan bergerak sesuai tetapi pilihan tetap pada posisi yang sama; tidak seperti yang diharapkan. ada solusi untuk ini?
David Portabella
Solusi yang tepat. Tetapi lebih baik mungkin tombol bungkus dan pilih pada div seperti ini <div style='position:relative'><select> <option>option 1</option> <option>option 2</option> <option>option 3</option> </select> <button>click</button></div>@DavidPortabella
Muhammet Can TONBUL
8

Saya pikir ini tidak mungkin lagi di Chrome.

Tampaknya chrome versi 53 menonaktifkan fungsi ini seperti yang dinyatakan oleh Asim K T.

Menurut spesifikasi http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events

Peristiwa Tepercaya tidak boleh mengaktifkan tindakan default (kecuali peristiwa klik).

Namun mereka telah mengaktifkannya di tampilan web, tetapi saya belum menguji ini.

Kami telah menemukan bahwa beberapa tampilan web menggunakan fastclick di dalamnya dan karena risiko kerusakan, kami akan mengizinkan mousedown pada pilihan meskipun tidak tepercaya.

Dan dalam diskusi ini , ide untuk membiarkan developer membuka dropdown secara terprogram ditinggalkan.

Mengerti
sumber
7

Jika ada yang masih mencari ini:

<select id="dropdown">
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" >Show dropdown items</button>

Javascript:

var is_visible=false; 

$(document).ready(function(){

    $('#fire').click(function (e) { 
    var element = document.getElementById('dropdown');


    if(is_visible){is_visible=false; return;}
    is_visible = true;

    var event;
    event = document.createEvent('MouseEvents');
    event.initMouseEvent('mousedown', true, true, window);
    element.dispatchEvent(event);

    /* can be added for i.e. compatiblity.
      optionsSelect.focus();
       var WshShell = new ActiveXObject("WScript.Shell");
       WshShell.SendKeys("%{DOWN}");
    */
    e.stopPropagation();
    return false;
});


$(document).click(function(){is_visible=false; });
});

Memperbarui:

Satu sampai tidak ada solusi tepat untuk masalah ini, Tetapi Anda dapat mencoba menghindari skenario ini. Mengapa Anda ingin melakukan ini. Saya bertanya-tanya solusi beberapa bulan yang lalu untuk membuat plugin pilihan untuk perangkat seluler

https://github.com/HemantNegi/jquery.sumoselect

Akhirnya berakhir dengan menutupi div khusus (atau elemen lainnya) dengan elemen pilih transparan, sehingga dapat langsung berinteraksi dengan pengguna.

Hemant_Negi
sumber
1
Plugin seperti github.com/HemantNegi/jquery.sumoselect adalah satu-satunya solusi lintas-browser yang benar-benar terlihat lebih baik daripada kontrol default.
Justin
iniMouseEventtampaknya berhasil, tetapi mengapa $(select).trigger('mousedown')tidak berhasil?
coding_idiot
3

Inilah cara terbaik yang saya temukan. CATATAN Ini hanya bekerja dengan IE di Windows dan web Anda mungkin perlu berada di zona aman - karena kami mengakses shell. Triknya adalah ALT-Panah Bawah adalah tombol pintas untuk membuka drop down pilih.

<button id="optionsButton" style="position:absolute;top:10px;left:10px;height:22px;width:100px;z-index:10" onclick="doClick()">OPTIONS</button>
<select id="optionsSelect" style="position:absolute;top:10px;left:10px;height:20px;width:100px;z-index:9">
    <option>ABC</option>
    <option>DEF</option>
    <option>GHI</option>
    <option>JKL</option>
</select>
<script type="text/javascript">
   function doClick() {
       optionsSelect.focus();
       var WshShell = new ActiveXObject("WScript.Shell");
       WshShell.SendKeys("%{DOWN}");
   }
</script>
sproketboy.dll
sumber
3
Ini tidak akan berhasil kecuali Anda melakukan ini .
Knu
1
@Knu Internet Explorer secara otomatis menambahkan ID elemen sebagai referensi ke elemen untuk cakupan global.
pengguna2428118
@Klaselambon. Mereka mencoba membuat browser mereka lebih sesuai sekarang. Gunakan solusi "ukuran" yang disebutkan.
sproketboy
2

Berhentilah berpikir bahwa satu hal tidak mungkin, tidak ada yang mustahil untuk dilakukan, ketika Anda ingin melakukannya.

Gunakan fungsi perluasan JS yang dibuat oleh seorang pria.

http://code.google.com/p/expandselect/

Sertakan JS ini dan panggil saja itu meneruskan param sebagai id pilihan Anda, seperti itu:

ExpandSelect(MySelect)
Paulo Roberto Rosa
sumber
2
Untuk lebih jelasnya, JS itu tidak menyebabkan <SELECT>drop down. Karena secara eksplisit menyatakan "Browser tidak mengizinkan perluasan <select> dalam javascript murni, kontrol tersebut hanya dapat diperluas dengan mengklik secara langsung menggunakan mouse". Jadi adalah "tidak mungkin"! Sebaliknya JS menyatakan "Kami meniru kontrol <select> yang diperluas dengan membuat pilihan lain dengan beberapa opsi yang ditampilkan sekaligus ..." Yang sangat berbeda, dan mungkin atau mungkin tidak dapat diterima untuk kasus penggunaan Anda ....
JonBrave
1

Saya mungkin salah, tapi saya tidak percaya itu mungkin dengan kotak pilih default. Anda bisa melakukan sesuatu dengan JS & CSS yang mencapai hasil yang diinginkan, tetapi tidak (sepengetahuan saya) vanilla SELECT.

Membuang
sumber
0

Membuka "pemilihan HTML" dimungkinkan melalui beberapa solusi yang disebutkan dalam pertanyaan ini dan yang serupa. Namun cara yang lebih bersih untuk melakukan ini adalah dengan menambahkan perpustakaan pilihan ke proyek Anda seperti "select2" atau "dipilih". Misalnya, membuka select2 secara terprogram semudah:

$('#target-select').select2('open');
Kasra Ebrahimi
sumber
-2

Ini bukan yang Anda minta, tetapi saya suka solusi ini karena kesederhanaannya. Dalam kebanyakan kasus di mana saya ingin memulai dropdown, itu karena saya memvalidasi bahwa pengguna benar-benar telah membuat pilihan. Saya mengubah ukuran dropdown dan memfokuskannya, yang dengan baik menyoroti apa yang telah mereka lewati:

$('#cboSomething')[0].size = 3;
$('#cboSomething')[0].focus();
Rob3C
sumber
Tidak yakin mengapa Anda mendapat suara negatif karena itu bukan cara "terburuk" untuk melakukannya. Saya akan menghindari ini hanya karena itu menggeser tata letak elemen sekitarnya. Meskipun menurut saya solusi dari @CMS lebih mudah dipahami dengan peristiwa fokus / blur di kontrol.
Mavelo