Làm cách nào để bạn có thể lập trình yêu cầu một HTML SELECT thả xuống (ví dụ: do di chuột qua)?


105

Làm cách nào bạn có thể lập trình yêu cầu HTML selectthả xuống (ví dụ: do di chuột qua)?


6
Tôi khuyên bạn không nên làm phiền hành vi của mặc định <select>, vì mọi người mong đợi nó hoạt động theo một cách nhất định và bạn sẽ ngăn mọi người trên các nền tảng khác (như thiết bị di động) sử dụng trang web của bạn.
Brian Donovan

1
@BrianDonovan Nó không giống như bạn không thể thêm một số xử lý cho điều đó.
Morg.

@shasikanth: fiddle của bạn không hoạt động không phải trong Firefox 37 nr trong Chrome
rubo77

Ok, tôi nghĩ fiddle đã hoạt động trước đây. Dù sao thì tôi sẽ xóa bình luận của mình ở đây.
shasi kanth

@BrianDonovan Trên thực tế, điện thoại di động là một trường hợp sử dụng tốt ... lập trình tạo một lựa chọn và sau đó các tùy chọn của nó tự động bật lên.
Michael

Câu trả lời:


15

Bạn không thể làm điều này với thẻ chọn HTML, nhưng bạn có thể làm điều đó với JavaScript HTML. Có nhiều điều khiển hiện tại thực hiện điều này - ví dụ: danh sách "đề xuất" được đính kèm với mục nhập SO "thẻ thú vị / thẻ bị bỏ qua" hoặc tra cứu địa chỉ email của Gmail.

Có nhiều điều khiển JavaScript + HTML cung cấp khả năng này - hãy tìm kiếm các điều khiển tự động hoàn thành để có ý tưởng.

Xem liên kết này để biết điều khiển Tự động điền ... http://ajaxcontroltoolkit.codeplex.com/


6
đây là một sự xấu hổ đáng khóc - các trình duyệt di động cung cấp một danh sách cuộn dành riêng cho hệ điều hành và tôi cần nó tự động bật lên.
Michael

120

Điều này từng thực sự có thể thực hiện được với HTML + Javascript, mặc dù ở mọi nơi mọi người nói rằng không, nhưng sau này nó không còn được dùng nữa và không hoạt động nữa.

Tuy nhiên, điều này chỉ hoạt động trong Chrome. Đọc thêm nếu bạn quan tâm.


Theo Dự thảo làm việc của W3C cho HTML5, Phần 3.2.5.1.7. Nội dung tương tác :

Một số phần tử nhất định trong HTML có hành vi kích hoạt, có nghĩa là người dùng có thể kích hoạt chúng. Điều này kích hoạt một chuỗi các sự kiện phụ thuộc vào cơ chế kích hoạt [...], chẳng hạn như sử dụng bàn phím hoặc nhập liệu bằng giọng nói hoặc thông qua các cú nhấp chuột .

Khi người dùng kích hoạt phần tử có hành vi kích hoạt xác định theo cách khác với cách nhấp vào phần tử đó, hành động mặc định của sự kiện tương tác phải là chạy các bước kích hoạt nhấp chuột tổng hợp trên phần tử.

<select>là Nội dung tương tác, tôi tin rằng có thể hiển thị theo chương trình của nó <option>. Sau một vài giờ chơi xung quanh, tôi phát hiện ra rằng cách sử dụng document.createEvent().dispatchEvent()hoạt động.

Điều đó nói rằng, thời gian demo. Đây là một Fiddle đang hoạt động.


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);
};

Nếu ai đó tìm thấy cách làm tương tự nhưng không có trong Chrome, vui lòng sửa đổi cách làm này . Các bác sĩ cho biết:


2
Cảm ơn vì điều này! Tôi cần mô phỏng chính xác hành vi ALT + MŨI TÊN XUỐNG của IE trong Chrome.
J Bryan Price

3
Tôi ước tôi có thể thêm vào tiền thưởng của bạn cho điều này. Cảm ơn bạn rất nhiều.
Adam Tuttle,

7
Không hoạt động trên: IE10, FF 24. Hoạt động trên: Chrome 30, Safari 6.0.5,Opera 16
hitautodestruct

2
@AdamTuttle Nó cũng không hoạt động trên Android 4.4.2
Mirko

42
Nó hiện không được dùng nữa trên Chrome 53+
Washington Guedes

47

Câu trả lời của Xavier Ho là đề cập đến cách giải quyết vấn đề trong hầu hết các trình duyệt hiện có. Tuy nhiên, thực hành tốt là 'không gửi / sửa đổi' các sự kiện bằng JavaScript nữa . (Giống như, mousedowntrong trường hợp này)

Từ phiên bản 53+, Google Chrome sẽ không thực hiện tác vụ mặc định cho các sự kiện không đáng tin cậy . Chẳng hạn như các sự kiện được tạo hoặc sửa đổi bằng tập lệnh, hoặc được gửi qua dispatchEventphương thức. Thay đổi này là để căn chỉnh với Firefox và IE mà tôi nghĩ rằng đã không thực hiện hành động.

Vì mục đích thử nghiệm, Fiddle đã cung cấp câu trả lời của Xavier sẽ không hoạt động trong chrome 53+. (Tôi không kiểm tra nó FF và IE).

Liên kết để tham khảo:

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

Và initMouseEvent cũng không được dùng nữa


Nó có thể được thực hiện bằng cách sử dụng MouseEvents không? developer.mozilla.org/en-US/docs/Web/API/MouseEvent
Shamal Perera

Tôi không nghĩ vậy. bạn đã thử gì chưa?
Asim KT

28

Đây là cách gần nhất mà tôi có thể nhận được, thay đổi kích thước của phần tử onmouseover và khôi phục kích thước 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>


13
hoặc <SELECT onMouseOut = "this.size = 1;" onMouseOver = "this.size = this.length;"> ... </SELECT>
RealHowTo

1
Cũng cần thêm onchange = "this.size = 1" để menu thu gọn ngay khi lựa chọn được thực hiện. Các quy tắc CSS của phần tử cũng cần được định cấu hình.
gm2008

Nó dường như hoạt động. Chiều rộng vùng chọn sẽ thu hẹp và sau đó gây ra sự kiện di chuột ra ngoài khiến vùng chọn về chiều rộng ban đầu. Điều này gây ra hiệu ứng co giật. Đặt chiều rộng cố định dường như sẽ khắc phục được điều đó. Với nhiều hơn một số mục, danh sách sẽ mở rộng qua chế độ xem.
1,21 gigawatts

16

tôi có cùng một vấn đề này và cách dễ dàng hơn mà tôi tìm thấy để giải quyết vấn đề này là với html và css.

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


2
Đã lâu rồi tôi không thấy cách tiếp cận này và là tài liệu tham khảo mà tôi hy vọng sẽ tìm thấy. Tốt hơn với CSS bổ sung để phù hợp với kích thước của vùng chọn ẩn để kích hoạt (nút, img, div, v.v.) ... 1) Đảm bảo vùng có thể nhấp lấp đầy kích hoạt 2) Trình đơn mở ngay bên dưới trình kích hoạt. Lưu ý: Cũng có thể cần thêm chỉ mục z để đảm bảo vùng có thể nhấp là phần tử cao nhất trong một số bố cục.
Mavelo

tuy nhiên, nếu người dùng cuộn xuống trang, thì nút sẽ di chuyển tương ứng nhưng vùng chọn vẫn ở vị trí cũ; không thực sự như mong đợi. bất kỳ giải pháp cho điều này?
David Portabella

Giải pháp hoàn hảo. Nhưng tốt hơn có thể nút quấn và chọn trên div như thế này <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

Tôi nghĩ rằng điều này không còn khả thi trong Chrome.

Có vẻ như phiên bản 53 của chrome vô hiệu hóa chức năng này như Asim K T. đã nêu.

Theo thông số http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events

Sự kiện đáng tin cậy không được kích hoạt hành động mặc định (ngoại trừ sự kiện nhấp chuột).

Tuy nhiên, họ đã kích hoạt nó trong webview, nhưng tôi chưa thử nghiệm điều này.

Chúng tôi nhận thấy rằng một số chế độ xem web đang sử dụng fastclick bên trong chúng và do nguy cơ bị hỏng, chúng tôi sẽ cho phép bỏ qua các lựa chọn ngay cả khi chúng không đáng tin cậy.

Và trong cuộc thảo luận này , ý tưởng để các nhà phát triển mở một trình đơn thả xuống theo chương trình đã bị bỏ rơi.


7

Nếu bất kỳ ai vẫn đang tìm kiếm điều này:

<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; });
});

Cập nhật:

Một cho đến khi không có giải pháp hoàn hảo cho vấn đề này, Nhưng bạn có thể cố gắng tránh trường hợp này. Tại sao bạn muốn làm việc này. Tôi đã tự hỏi một giải pháp cách đây vài tháng để tạo một plugin chọn lọc cho thiết bị di động

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

Cuối cùng, kết thúc bằng việc che dấu div tùy chỉnh (hoặc bất kỳ phần tử nào khác) bằng một phần tử chọn trong suốt, để nó có thể tương tác trực tiếp với người dùng.


1
Các plugin như github.com/HemantNegi/jquery.sumoselect là giải pháp trình duyệt chéo duy nhất thực sự trông đẹp hơn điều khiển mặc định.
Justin

iniMouseEventdường như hoạt động, nhưng tại sao $(select).trigger('mousedown')không hoạt động?
coding_idiot

3

Đây là cách tốt nhất mà tôi tìm thấy. LƯU Ý Nó chỉ hoạt động với IE trên Windows và web của bạn có thể cần phải ở trong vùng an toàn - vì chúng tôi truy cập shell. Bí quyết là ALT-Mũi tên Xuống là một phím tắt để mở một danh sách thả xuống được chọn.

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

3
Nó sẽ không hoạt động trừ khi bạn làm điều này .
Knu

1
@Knu Internet Explorer tự động thêm ID của các phần tử làm tham chiếu đến phần tử vào phạm vi toàn cầu.
user2428118

@KlasMellbourn có lẽ. Họ đang cố gắng làm cho trình duyệt của họ tuân thủ hơn. Sử dụng giải pháp "kích thước" đã đề cập.
gerketboy

2

Ngừng nghĩ rằng một điều là không thể, không có gì là không thể làm được, khi bạn muốn làm.

Sử dụng chức năng JS mở rộng này được tạo bởi một anh chàng.

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

Bao gồm JS này và chỉ cần gọi nó chuyển param làm id đã chọn của bạn, như sau:

ExpandSelect(MySelect)

2
Để rõ ràng, JS đó không gây ra <SELECT>thả xuống. Vì nó tuyên bố rõ ràng "Các trình duyệt không cho phép mở rộng <select> trong javascript thuần, điều khiển đó chỉ có thể được mở rộng bằng cách nhấp trực tiếp vào nó bằng cách sử dụng chuột". Vì vậy, nó "không thể"! Thay vào đó, JS tuyên bố "Chúng tôi bắt chước điều khiển <select> mở rộng bằng cách tạo một lựa chọn khác với nhiều tùy chọn được hiển thị cùng một lúc ..." Điều này khá khác biệt và có thể được hoặc có thể không được chấp nhận đối với trường hợp sử dụng của bạn ....
JonBrave

1

Tôi có thể sai, nhưng tôi không tin rằng điều đó có thể xảy ra với hộp chọn mặc định. Bạn có thể làm điều gì đó với JS & CSS để đạt được kết quả mong muốn, nhưng không phải (theo hiểu biết của tôi) với vanilla SELECT.


0

Có thể mở "HTML select" thông qua một số cách giải quyết được đề cập trong câu hỏi này và những cách giải quyết tương tự. Tuy nhiên, một cách tốt hơn để làm điều này là thêm một thư viện chọn lọc vào dự án của bạn như "select2" hoặc "selected". Ví dụ: mở select2 theo chương trình sẽ dễ dàng như sau:

$('#target-select').select2('open');

-2

Đây không phải là chính xác những gì bạn yêu cầu, nhưng tôi thích giải pháp này vì sự đơn giản của nó. Trong hầu hết các trường hợp khi tôi muốn bắt đầu một trình đơn thả xuống, đó là bởi vì tôi đang xác thực rằng người dùng đã thực sự lựa chọn. Tôi thay đổi kích thước của menu thả xuống và tập trung vào nó, điều này làm nổi bật độc đáo những gì họ đã bỏ qua:

$('#cboSomething')[0].size = 3;
$('#cboSomething')[0].focus();

Không chắc tại sao bạn lại bị bỏ phiếu vì đó không phải là cách "tồi tệ nhất" để làm điều đó. Tôi sẽ tránh điều này đơn giản vì nó thay đổi bố cục của các yếu tố xung quanh. Mặc dù tôi nghĩ rằng giải pháp từ @CMS dễ hiểu hơn với các sự kiện lấy nét / làm mờ ở điều khiển.
Mavelo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.