单选框通过ajax实现懒加载选项的正确方法

3

我有一个选择框,只有在点击时才应该填充。所涉及的查询需要很长时间,因此我将其从页面上显示的标准数据中分离出来。

我实现了函数loadMyData(element, id),它执行ajax请求并以JSON格式返回数据。然后它填充选择框。

该事件绑定到元素如下:

<select onclick="loadMyData(this, 1)">
</select>

选择框的选项将会被填充为如下内容:

$.each(data, function(index, optionData) {
  select.options[element.options.length] 
             = new Option(optionData.Text, optionData.Value);
});

在基于Gecko的浏览器上可以正常工作,但在Webkit浏览器(Safari和Chrome)上,当我点击选择框时,在ajax请求之前会显示一个空的下拉框,在响应后,下拉框不会刷新。必须在选择框外单击并再次单击才能看到更新的“选项”。
有没有办法强制它刷新内容?或者只是自动选择第一个并隐藏下拉框?
**尝试了onfocus并发现相同的结果。 onmouseover可以工作,但“不可用”。 由于选择框在其初始状态下为空,因此无法使用onchange。

你考虑过在这个请求中使用同步请求吗?这可能会消除任何时间延迟,并使选择框有机会正确更新!另外,为什么要基于onclick的加载?是否可以根据用户与到达下拉菜单之前与其他UI元素的交互来执行更新?如果选择不依赖于任何其他UI选择,为什么不事先填充它呢? - miCRoSCoPiC_eaRthLinG
或者作为一个想法...为什么不在DOM准备好后以异步模式触发加载函数呢?这样,初始页面会立即加载,而无需执行长时间的查询和浏览器也不会冻结...当用户准备好使用UI元素时,选择框已经被静默地填充了! - miCRoSCoPiC_eaRthLinG
3个回答

2

一些想法:

  1. 不要使用标准的html选择框 - 无论如何,您的应用程序都不会优雅地降级。

  2. 使用一些点击劫持技术 - 在选择框上方放置一个透明的div - 在IE中可能会出现问题。

  3. 使用复选框允许“非标准”答案,这将填充选择框并使其可点击(而非禁用)。

  4. 我最喜欢的方法:缓存查询结果并立即填充选择框。在选择框附近提供另一个“刷新选项”按钮,通过AJAX重新加载选项。


我放弃缓存,因为它应该显示新鲜数据。我本来想使用点击劫持技术,但感觉有点不太好,所以我打算使用标准按钮,一旦点击后就用“新鲜”的选择框替换它。 - knoopx

1

通常情况下,糟糕的浏览器是IE 6及以下版本,因为它在选择选项上有只读属性,所以唯一的处理方式是替换整个选择框。

index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>lazy loading thing</title>
        <script src="js/jquery.js" type="text/javascript"></script>
        <script src="js/script.js" type="text/javascript"></script>
    </head>
    <body>
        <form>
            <p>
                <span id="replaceMe"><select name="drinks">
                    <option>oh well... click me...</option>
                </select></span>
            </p>
        </form>
    </body>
</html>

script.js

$(function() {
     $('#replaceMe').one('click', replaceIt);
});

function replaceIt(e) {
    $(this).html('now wait...');
    $.post('options.php', {}, replaceItHandler, 'json');
}

function replaceItHandler(options) {
    var select = '<select name="drinks">';
    $.each(options, function(i, option) {
        select += '<option value="' + option.data + '">' + option.label + '</option>';
    });
    select += '</select>';
    $('#replaceMe').html(select);
}

options.php

<?php
$options[] = array('data' => 0, 'label' => 'Water');
$options[] = array('data' => 0, 'label' => 'Wine');
$options[] = array('data' => 0, 'label' => 'Beer');
$options[] = array('data' => 0, 'label' => 'Coke');
echo json_encode($options);
?>

显然,您可以使用PHP或其他语言以及像这样的JSON,或者发送整个选择,这是您的选择。


它在ie8上运行良好,唯一不工作的浏览器是基于webkit的浏览器(chrome和safari)。替换整个选择框是一个想法,但我更愿意显示一个按钮,点击后用选择框替换它。我不想使用额外的HTML元素来加载选择框的内容,但我想在使用标准HTML选择框时没有其他方法。 - knoopx
正在我的Google Chrome (1.0.154.65) 以及Opera(9.64)上工作,我就在一分钟前测试过。 - coma

0

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