我可以使用 jQuery 打开下拉列表吗

对于 HTML 中的下拉列表:

<select id="countries">
<option value="1">Country</option>
</select>

我想打开该列表(与左键单击它相同)。使用 JavaScript (或者更确切地说是 jQuery)可以做到这一点吗?

164178 次浏览

It is not possible for javascript to "click" on an element (u can trigger the attached onclick event, but you can't literally click it)

To view all the items in the list, make the list a multiple list and increase its size, like such:

<select id="countries" multiple="multiple" size="10">
<option value="1">Country</option>
</select>

You can easily simulate a click on an element, but a click on a <select> won’t open up the dropdown.

Using multiple selects can be problematic. Perhaps you should consider radio buttons inside a container element which you can expand and contract as needed.

As has been stated, you can't programmatically open a <select> using JavaScript.

However, you could write your own <select> managing the entire look and feel yourself. Something like what you see for the autocomplete search terms on Google or Yahoo! or the Search for Location box at The Weather Network.

I found one for jQuery here. I have no idea whether it would meet your needs, but even if it doesn't completely meet your needs, it should be possible to modify it so it would open as the result of some other action or event. This one actually looks more promising.

No you can't.

You can change the size to make it larger... similar to Dreas idea, but it is the size you need to change.

<select id="countries" size="6">
<option value="1">Country 1</option>
<option value="2">Country 2</option>
<option value="3">Country 3</option>
<option value="4">Country 4</option>
<option value="5">Country 5</option>
<option value="6">Country 6</option>
</select>

I was trying to find the same thing and got disappointed. I ended up changing the attribute size for the select box so it appears to open

$('#countries').attr('size',6);

and then when you're finished

$('#countries').attr('size',1);

I've come across the same problem and I have a solution. A function called ExpandSelect() that emulates mouse clicking on "select" element, it does so by creating an another <select> element that is absolutely posioned and have multiple options visible at once by setting the size attribute. Tested in all major browsers: Chrome, Opera, Firefox, Internet Explorer. Explanation of how it works, along with the code here:

Edit (link was broken).

I've created a project at Google Code, go for the code there:

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

Screenshots

There is a little difference in GUI when emulating click, but it does not really matter, see it for yourself:

When mouse clicking:

MouseClicking
(source: googlecode.com)

When emulating click:

EmulatingClicking
(source: googlecode.com)

More screenshots on project's website, link above.

Simple an easy way.

function down(what) {
pos = $(what).offset();  // remember position
$(what).css("position","absolute");
$(what).offset(pos);   // reset position
$(what).attr("size","10"); // open dropdown
}


function up(what) {
$(what).css("position","static");
$(what).attr("size","1");  // close dropdown
}

Now you can call your DropDown just like this

<select onfocus="down(this)" onblur="up(this)">

Works perfect for me.

Maybe better, because you have no problems with the position of the other elemts on the page.

function down(was) {
a = $(was).clone().attr('id','down_man').attr('disabled',true).insertAfter(was);
$(was).css("position","absolute").attr("size","10");
}


function up(was) {
$('#down_man').remove();
$(was).css("position","static");
$(was).attr("size","1");
}

Change the ID to a fix value mybe not smart but i hope you see the idee.

I tried using mrperfect's answer and i had a couple glitches. With a couple small changes, I was able to get it to work for me. I just changed it so that it would only do it once. Once you exit dropdown, it would go back to the regular method of dropdowns.

function down() {
var pos = $(this).offset(); // remember position
$(this).css("position", "absolute");
$(this).offset(pos);   // reset position
$(this).attr("size", "15"); // open dropdown
$(this).unbind("focus", down);
}
function up() {
$(this).css("position", "static");
$(this).attr("size", "1");  // close dropdown
$(this).unbind("change", up);
}
function openDropdown(elementId) {
$('#' + elementId).focus(down).blur(up).focus();
}

One thing that this doesn't answer is what happens when you click on one of the options in the select list after you have done your size = n and made it absolute positioning.

Because the blur event makes it size = 1 and changes it back to how it looks, you should have something like this as well

$("option").click(function(){
$(this).parent().blur();
});

Also, if you're having issues with the absolute positioned select list showing behind other elements, just put a

z-index: 100;

or something like that in the style of the select.

This is spruced up from the answers just above and uses the length/number of options to conform to how many options there actually are.

Hope this helps somebody get the results they need!

    function openDropdown(elementId) {
function down() {
var pos = $(this).offset(); // remember position
var len = $(this).find("option").length;
if(len > 20) {
len = 20;
}


$(this).css("position", "absolute");
$(this).css("zIndex", 9999);
$(this).offset(pos);   // reset position
$(this).attr("size", len); // open dropdown
$(this).unbind("focus", down);
$(this).focus();
}
function up() {
$(this).css("position", "static");
$(this).attr("size", "1");  // close dropdown
$(this).unbind("change", up);
$(this).focus();
}
$("#" + elementId).focus(down).blur(up).focus();
}

Super simple:

var state = false;
$("a").click(function () {
state = !state;
$("select").prop("size", state ? $("option").length : 1);
});

Maybe late, but this is how i solved it: http://jsfiddle.net/KqsK2/18/

$(document).ready(function() {
fixSelect(document.getElementsByTagName("select"));
});


function fixSelect(selectList)
{
for (var i = 0; i != selectList.length; i++)
{


setActions(selectList[i]);
}
}




function setActions(select)
{
$(select).click(function() {
if (select.getElementsByTagName("option").length == 1)
{
active(select);
}
});
$(select).focus(function() {
active(select);
});
$(select).blur(function() {
inaktiv(select);
});
$(select).keypress(function(e) {
if (e.which == 13) {


inaktiv(select);
}
});
var optionList = select.getElementsByTagName("option");


for (var i = 0; i != optionList.length; i++)
{
setActionOnOption(optionList[i], select);
}
}


function setActionOnOption(option, select)
{
$(option).click(function() {
inaktiv(select);
});
}


function active(select)
{
var temp = $('<select/>');
$('<option />', {value: 1,text:$(select).find(':selected').text()}).appendTo(temp);
$(temp).insertBefore($(select));


$(select).attr('size', select.getElementsByTagName('option').length);
$(select).css('position', 'absolute');
$(select).css('margin-top', '-6px');
$(select).css({boxShadow: '2px 3px 4px #888888'});






}


function inaktiv(select)
{
if($(select).parent().children('select').length!=1)
{
select.parentNode.removeChild($(select).parent().children('select').get(0));
}
$(select).attr('size', 1);
$(select).css('position', 'static');
$(select).css({boxShadow: ''});
$(select).css('margin-top', '0px');


}

This should cover it:

 var event;
event = document.createEvent('MouseEvents');
event.initMouseEvent('mousedown', true, true, window);
countries.dispatchEvent(event); //we use countries as it's referred to by ID - but this could be any JS element var

This could be bound for example to a keypress event, so when the element has focus the user can type and it will expand automatically...

--Context--

  modal.find("select").not("[readonly]").on("keypress", function(e) {


if (e.keyCode == 13) {
e.preventDefault();
return false;
}
var event;
event = document.createEvent('MouseEvents');
event.initMouseEvent('mousedown', true, true, window);
this.dispatchEvent(event);
});

i just added

select = $('#' + id);
length = $('#' + id + ' > option').length;
if (length > 20)
length = 20;
select.attr('size', length);
select.css('position', 'absolute');
select.focus();

and add into the select

onchange="$(this).removeAttr('size');"
onblur="$(this).removeAttr('size');"

to make the same appearance like the classic one (overlap the rest of html)