使用JavaScript/jQuery打开选择框?

30

有没有一种方法可以使用 JavaScript(和 jQuery)打开选择框?

<select style="width:150px;">
    <option value="1">1</option>
    <option value="2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc arcu nunc, rhoncus ac dignissim at, rhoncus ac tellus.</option>
    <option value="3">3</option>
</select>

因为IE的bug,我必须打开我的select标签。所有版本的IE(6,7,8)都会截断我的选项。 据我所知,这个问题没有CSS解决方法。 目前,我尝试做以下操作:

var original_width = 0;
var selected_val = false;

if (jQuery.browser.msie) {
    $('select').click(function(){
        if (selected_val == false){
            if(original_width == 0)
                original_width = $(this).width();

            $(this).css({
                'position' : 'absolute',
                'width' : 'auto'
            });
        }else{
            $(this).css({
                'position' : 'relative',
                'width' : original_width
            });
            selected_val = false;
        }
    });

    $('select').blur(function(){
        $(this).css({
            'position' : 'relative',
            'width' : original_width
        });
    });

    $('select').blur(function(){
        $(this).css({
            'position' : 'relative',
            'width' : original_width
        });
    });
            
    $('select').change(function(){
        $(this).css({
            'position' : 'relative',
            'width' : original_width
        });
    });

    $('select option').click(function(){
        $(this).css({
            'position' : 'relative',
            'width' : original_width
        });
    
        selected_val = true;
    });

}

但第一次点击我的选择框会改变其宽度,但我必须再次点击才能打开它。


请查看http://api.jqueryui.com/selectmenu/#method-open。 - Hayden Thring
13个回答

7
我知道这个问题很老,而且已经有答案了,但是在Safari和iOS UIWebView中,这对我有效 - 我将其隐藏,但希望在单击不同的按钮时显示并打开。
$('#select-id').show().focus().click();

谢谢!经过6个小时的尝试和错误,这个方法解决了一个 JQM/Cordova/FastClick 堆栈的问题!!! - Paranoid Android
在Chrome上,当选择框是keydown事件的目标时,这个功能非常好用!感谢Matt H的提示。 - Beartums

7
尝试这个:

var myDropDown=$("#myDropDown");
var length = $('#myDropDown> option').length;
//open dropdown
myDropDown.attr('size',length);

and this to close:

//close dropdown
myDropDown.attr('size',0);

6

你可以使用mousedown处理程序来捕获mousedown事件,而不是使用click。因为mousedownclick先触发,所以你可以调用stopPropogation来中断事件队列。


4

试试这个:

dropDown = function (elementId) {
    var dropdown = document.getElementById(elementId);
    try {
        showDropdown(dropdown);
    } catch(e) {

    }
    return false;
};

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

然后调用该函数:
dropDown('elementId');

如果您正在使用jQuery,您还可以使用trigger()命令。 - kiwicomb123
1
jQuery触发器不起作用。您应该尝试像答案一样创建事件。 - Mahmood

2

不需要使用jQuery的解决方案。

<SCRIPT>
    function toggleDropdown(element){
        if(element.size == 0) {
            element.size = element.length;
            element.focus();
            }
        else element.size = 0;
        }
</SCRIPT>

Found this here.


这会打开下拉菜单,但不允许在列表中进行后续箭头键导航。 - Jan Croonen

1
首先,我感受到IE的限制之痛 - 呃! 只是想分享一下,因为这对我似乎有效。我采取了几乎相同的方法,但是针对每个选择元素。在我的情况下,我知道哪些列表可能具有长数据。
我没有将选择元素设为绝对定位,而是保持它们内联,并将它们包装在一个带有隐藏溢出的DIV中,因为外观需要保持一致,而且仅在IE且扩展宽度大于当前宽度时才应用此“hack”。
要将其用于所有选择框,您可以使用类似以下内容的东西:
$("select").each(function(){ 
        $(this).IELongDropDown(); 
     });

或者显然可以通过id逐个元素进行设置。 这是jQuery插件:

(function($) {
    $.fn.IELongDropDown = function(cln) {
        if (jQuery.browser.msie) { //only IE has problems with long select boxes
            var el = this;
            var previousWidth = el.width();
            var divWrapper = "<div style='padding:0;margin:0;overflow:hidden;width:"+ previousWidth +"px'></div>";
            el.wrap(divWrapper);
            var newWidth = el.width("auto").width();
            el.width(previousWidth);
            if(newWidth > previousWidth) {
                el.bind("mousedown", function(){ return el.width("auto").focus(); }); 
                el.bind("blur", function(){ return el.width(previousWidth); });
                el.bind("change", function(){ return el.width(previousWidth); });
            }
        }
        return this;
    };
})(jQuery);

希望这能帮助到某个人。

1

我认为你需要从事件处理程序(click、blur等)中返回true,这样在处理程序执行后,浏览器会继续传播事件并打开选择框。

这与href链接类似,如果它们有一个onclick处理程序并且处理程序返回false,则链接不会被跟踪(浏览器在处理程序执行后停止事件)。

编辑:根据您的评论和答案,似乎您的处理程序只有在浏览器决定打开框之后才有第一次执行的机会。
我建议您尝试使用focus事件处理程序,它可能比click处理程序更早地运行,并且也更一致(适用于鼠标和键盘导航)。


1
我试图在事件操作后返回true,但没有成功。看起来select在第一次点击时会打开,但它不会改变其样式。释放鼠标后,select将关闭并添加样式。所以我必须再次点击才能打开它。 - Newbie

0

我更喜欢在CSS文件中设置我的CSS,然后使用“addClass”,但即使如此,您的代码(部分)

   $('select').blur(function(){ 
        $(this).css({ 
            'position' : 'relative', 
            'width' : original_width 
        }); 
    }); 

    $('select').blur(function(){ 
        $(this).css({ 
            'position' : 'relative', 
            'width' : original_width 
        }); 
    }); 

看起来是重复的

我会这样做:

$('select').blur().css({ 
        'position' : 'relative', 
        'width' : original_width 
}); 

不确定你是否真的需要在这里使用 .blur(),因为已经有了 .change() 事件(尝试将其删除,看看是否解决了你的问题……我经常在 IE 上使用 select,并没有遇到问题。


0

好的,我找到了另一种解决这个问题的方法。 以下是修复方法:

请给我反馈!我有点为自己感到骄傲 ;)

$(document).ready(function() {
    if (jQuery.browser.msie) {
            select_init();
    }
});


function select_init () {
    var selects = $('select');
    for (var i = 0; i < selects.length; i++) {
        _resizeselect.init(selects[i]);
    }
}


var _resizeselect = {
    obj : new Array(),
    init : function (el) {
        this.obj[el] = new resizeselect (el);
    }
}

function resizeselect (el) {

    this.el = el;
    this.p = el.parentNode;
    this.ht = el.parentNode.offsetHeight;
    var obj = this;
    this.set = false;

    el.onmousedown = function () {
        obj.set_select("mousedown");
    }
    el.onblur = function () {
        obj.reset_select("blur");
    }
    el.onchange = function () {
        obj.reset_select("change");
    }

}

resizeselect.prototype.set_select = function (str) {

    if (this.set) {
        this.set = false;
        return;
    }

    this.el.style.width = "auto";
    this.el.style.position = "absolute";
    this.p.style.height = this.ht + "px";
    this.p.style.zIndex = 100;
    this.set = true;
    this.el.focus();
}

resizeselect.prototype.reset_select = function (str) {
    this.el.style.width = "";
    this.el.style.position = "";
    this.p.style.height = "";
    this.p.style.zIndex = 1;
    this.set = false;
    window.focus();
}

0

mousedown事件在click事件之前触发:

  1. 第一次mousedown触发 -> 将宽度设置为“auto”(如果下拉菜单的状态为“关闭”)
  2. click触发 -> 存储下拉菜单的状态:'open'
  3. 我们选择一个值,第二次mousedown被触发:无需操作
  4. click触发 -> 我们需要恢复下拉菜单的原始宽度并将变量的状态更改为:“close”

如果用户在下拉菜单外单击,则需要使用模糊和更改事件关闭下拉菜单。

这里是Brendan代码的完整解决方案:

(function ($) {
var open = {}
$.fn.IELongDropDown = function (cln) {
    if (jQuery.browser.msie) { //only IE has problems with long select boxes
        var el = this;
        var id = el.attr('id');
        var margin = 2; //Need to set a margin however the arrow is cut
        var previousWidth = el.width() + margin;
        var divWrapper = "<div style='padding:0;margin:0;overflow:hidden;width:" + previousWidth + "px'></div>";
        el.wrap(divWrapper);
        var newWidth = el.width("auto").width();
        el.width(previousWidth);
        if (newWidth > previousWidth) {
            el.mousedown(function () {
                if (!open[id]) {
                    el.width("auto");
                    el.focus();
                }
            });
            el.click(function () {
                if (!open[id])
                    open[id] = true;
                else {
                    open[id] = false;
                    return el.width(previousWidth);
                }
            });
            el.blur(function () {
                open[id] = false;
                return el.width(previousWidth);
            });
            el.change(function () {
                open[id] = false;
                return el.width(previousWidth);
            });
        }
    }
    return this;
};
})(jQuery);

调用函数:

<script type="text/javascript" language="javascript">
    $(document).ready(function () {
        $('#mydropdownlist').IELongDropDown();
    });
</script>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接