2012-06-01 37 views
25

我有一个用一个值初始化的下拉列表。当用户单击它时,单个元素将被删除,并添加一个新的元素来说明“加载”,然后向服务器发出AJAX调用,并在返回时将新值添加到控件中。用Javascript/jQuery以编程方式关闭SELECT下拉列表

问题是控件在更新时保持打开状态,我想关闭它。

这是一个例子:http://jsfiddle.net/vtortola/CGuBk/2/

的例子的AJAX没有得到的数据可能是因为一些错误,我调用的jsfiddle API时做的,但它显示了如何选择保持更新期间开放。

我想知道如何以编程方式关闭下拉列表而不用关注其他输入。

干杯。

回答

12

我不确定其他人,但我使用的是Chrome的最新稳定版本,没有涉及.blur()的其他答案适用于我。

这个问题问的倒数:Programmatically open a drop-down menu

,似乎可以得到的结论是,这是不可能的,由于浏览器处理场元素点击的方式。

更好的解决方案是用纯HTML替换下拉菜单,并在需要时使用简单的.hide()命令将其隐藏。

+0

当改变一个文本框,我打开一个“提示”框,如果改变发生时点击选择,我现在通过隐藏选择,以避免现在令人不安的下拉列表(); ... visibleselects.show(); –

12

只需在click内添加此关闭行结束即可。

$(this).blur(); 

所以它看起来像

$select.click(function(e){ 

    $select.html('<option value="-1">Loading</option>'); 

    $(this).blur(); 
    ...... 
    ... 
}); 

DEMO

HAH!如果我们有新的再版本的问题:

拿假select类似以下内容:

<select class="fake" style="display: none"> 
    <option value="-1">Loading</option> 
</select> 

,并做一些事情,如:

$select.click(function(e) { 
    $(this).hide(0); // hide current select box 

    //$select.html('<option value="-1">Loading</option>'); 

    $('select.fake').show(0); // show the fake slide 

    $.ajax({ 
      // your code 
     }).done(function(data) { 

      $('select.fake').hide(0); 
      $select.show(0); 

     }) 
     ...... 
    }): 

DEMO

+1

** + 1 **第一个回答,并与演示! – gdoron

+0

@gdoron非常感谢 – thecodeparadox

+1

如果打算关闭下拉列表,那么这在Chrome 19(最新版本)中不起作用,因此不应该依赖。 – Death

5

我认为,所有你需要做的是目标东西或者我应该说在选择失去焦点(模糊吧)

<select> 
    <option value="0">Initial Value</option> 
</select> 

var $select = $('select'); 
$select.click(function(e){ 

    $select.html('<option value="-1">Loading</option>'); 

    $.ajax({ 
     url: '/echo/json/', 
     method:'post', 
     dataType: "json", 
     contentType: "application/json; charset=utf-8", 
     data: { json: JSON.stringify([1, 2, 3]), delay:1 } 
    }).done(function(data){ 

     $.each($.map(data, function (item, i) { 
        return "<option value='" + item +"' >" + item + "</option>"; 

       }), function (i, item) { 
        $element.append(item); 
       }); 

    }).fail(function(){ 
     alert('error'); 
    }); 

    e.preventDefault(); 
    e.stopPropagation(); 
    $(this).blur();  
}); 
6

后...

$select.html('<option value="-1">Loading</option>'); 

尝试增加...

$select.blur(); 
2

我知道这是一个老问题,已经有一个答案,但我认为以下解决方案可以是一个公平的方式来实现目标。

您可以通过重新渲染来模拟选择的关闭。在jQuery中,你可以实现一个简单的插件来实现这一目标:

$.fn.closeSelect = function() { 
    if($(this).is("select")){ 
     var fakeSelect = $(this).clone(); 
     $(this).replaceWith(fakeSelect); 
    } 
}; 

,并使用这种方式:

$("#mySelect").closeSelect(); 
+0

这是一个好主意,我不知道这是如何解决绑定问题。 – vtortola

0
$('.select').on('change', function() { 
    $(this).click(); 
}); 
0

旧后我知道,但我有一个非常简单的解决方案。

$(someSelectElement).on('change', function(e) { 
    e.target.size = 0  
} 

如果您单击列表中的任何项目,这将折叠选择元素。

0

如果任何人在那里使用Angular2,是在那里工作对我来说,解决办法是增加一个(焦点)事件调用$($event.srcElement).attr("disabled","disabled");

我再添加一个超时重新启用时,我想要的元素它会再次变得活跃。

1

解决方案1 ​​ 我发现很简单的解决方案。

select.style.display = "none"; 
setTimeout(function() { 
    select.style.display = "block"; 
}, 10); 

在DOM这个隐藏元素,这因为那下拉列表将被关闭,然后用10ms的延迟(毫不拖延它不工作),将其返回到DOM。

解决方案2:稍微复杂一些,但没有延迟是totaly从DOM删除元素,然后立即返回它。

var parent = select.parentElement; 
var anchor = document.createElement("div"); 
parent.insertBefore(anchor, select); 
parent.removeChild(select); 
parent.insertBefore(select, anchor); 
parent.removeChild(anchor); 

这存储元素的parrent,然后在选择之前带锚。锚在那里用于恢复DOM中的相同位置的选择,然后再恢复。当然,它可以实现功能选择元素。

HTMLSelectElement.prototype.closeDropdown = function() { 
    var parent = this.parentElement; 
    var anchor = document.createElement("div"); 
    parent.insertBefore(anchor, this); 
    parent.removeChild(this); 
    parent.insertBefore(this, anchor); 
    parent.removeChild(anchor); 
} 

,然后就打电话

select.closeDropdown(); 

Example

相关问题