jQuery .hide()在某些浏览器中无法正常工作

11

我们正在使用jQuery .hide()来在选择输入中隐藏选项 - 当一个月中少于31天时。它在Google Chrome和FireFox中运行良好,但在Internet Explorer、Opera和Safari中不起作用。以下是我们使用的JavaScript代码:

$(function() {
    // Show and hide days according to the selected year and month.
    function show_and_hide_days(fp_form) {
        var select_year= $(fp_form).find("select.value_year");
        var select_month= $(fp_form).find("select.value_month");
        var select_day= $(fp_form).find("select.value_day");
        var selected_year= parseInt($(select_year).val());
        var selected_month= parseInt($(select_month).val());
        var selected_day= parseInt($(select_day).val());
        var days_in_month= new Date(selected_year, selected_month, 0).getDate();
        if ((days_in_month >= 28))
        {
            // If selected day is bigger than the number of days in the selected month, reduce it to the maximal day in this month.
            if (selected_day > days_in_month)
            {
                $(select_day).val(days_in_month);
            }
            // Show all the days in this month and hide days which are not in this month.
            $(select_day).find("option").each(function() {
                var day= parseInt($(this).val());
                if (day <= days_in_month)
                {
                    $(this).show();
                }
                else
                {
                    $(this).hide();
                }
            });
        }
    }

    // Show and hide all days in this page.
    function show_and_hide_all_days() {
        $("select.value_day").each(function() {
            var form= $(this).closest("form");
            // Show and hide days according to the selected year and month.
            show_and_hide_days(form);
        });
    }

    // Show and hide all days in this page.
    show_and_hide_all_days();

    $("select.value_year, select.value_month").live("change", function() {
        var form= $(this).closest("form");
        // Show and hide days according to the selected year and month.
        show_and_hide_days(form);
        return false;
    });
});

这里是 HTML 代码:

<select class="value_year">
    <option value="2000">2000</option>
    <option value="2001">2001</option>
    <option value="2002">2002</option>
    <option value="2003">2003</option>
    <option value="2004">2004</option>
    <option value="2005">2005</option>
    <option value="2006">2006</option>
    <option value="2007">2007</option>
    <option value="2008">2008</option>
    <option value="2009">2009</option>
    <option value="2010">2010</option>
    <option value="2011">2011</option>
    <option value="2012" selected="selected">2012</option>
    <option value="2013">2013</option>
</select>
/
<select class="value_month">
    <option value="1">01</option>
    <option value="2">02</option>
    <option value="3">03</option>
    <option value="4">04</option>
    <option value="5">05</option>
    <option value="6">06</option>
    <option value="7">07</option>
    <option value="8">08</option>
    <option value="9">09</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12" selected="selected">12</option>
</select>
/
<select class="value_day">
    <option value="1">01</option>
    <option value="2">02</option>
    <option value="3">03</option>
    <option value="4">04</option>
    <option value="5">05</option>
    <option value="6">06</option>
    <option value="7">07</option>
    <option value="8">08</option>
    <option value="9">09</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12">12</option>
    <option value="13">13</option>
    <option value="14">14</option>
    <option value="15">15</option>
    <option value="16">16</option>
    <option value="17">17</option>
    <option value="18" selected="selected">18</option>
    <option value="19">19</option>
    <option value="20">20</option>
    <option value="21">21</option>
    <option value="22">22</option>
    <option value="23">23</option>
    <option value="24">24</option>
    <option value="25">25</option>
    <option value="26">26</option>
    <option value="27">27</option>
    <option value="28">28</option>
    <option value="29">29</option>
    <option value="30">30</option>
    <option value="31">31</option>
</select>

我们正在使用jQuery v1.8.3(我升级到此版本以测试是否可以解决问题,但没有成功)。

谢谢, Uri。


3
这并不是 jQuery 的问题,而是浏览器的限制。<option> 元素无法以跨浏览器的方式支持许多样式属性,其中就包括 jQuery 的 .hide() 设置的 display 属性。你最好的选择是将这些选项分离(detach)而不是隐藏它们。 - Fabrício Matté
1
此外,在使用 parseInt 时,始终提供基数,因为如果没有它,它在不同的浏览器中的行为会不一致。 - skalee
尝试使用 _.attr('disabled') == 'disabled'; 和 _.removeAttr('disabled');。 - Anujith
为什么不在更改时禁用/启用这些选项呢? - Moseleyi
我还有一些代码风格的建议:不要写成 if (condition) { $(sth).show() } else { $(sth).hide() },而是写成 $(sth).toggle(condition)。这样更易读且更短。jQuery文档 - skalee
2个回答

10

这是一个浏览器的问题,有些浏览器无法隐藏选项,因为$('.selector').hide();类似于$('.selector').css('display', 'none');,有些浏览器无法隐藏它。

你需要使用$('.selector').remove();$('.selector').append();

将代码改为:

 if ((days_in_month >= 28))
        {
            // If selected day is bigger than the number of days in the selected month, reduce it to the maximal day in this month.
            if (selected_day > days_in_month)
            {
                $(select_day).val(days_in_month);
            }
            // Show all the days in this month and hide days which are not in this month.
            $(select_day).find("option").each(function() {
                var day= parseInt($(this).val());
                if (day <= days_in_month)
                {
                    $(this).show();
                }
                else
                {
                    $(this).hide();
                }
            });
        }

to

// Remove days 29 - 31
$(select_day).find("option[value='29'], option[value='30'], option[value='31']").remove();
var daysOptions = "";

if (days_in_month >= 29) {
    daysOptions += '<option value="29">29</option>';
}
if (days_in_month >= 30) {
    daysOptions += '<option value="30">30</option>';
}
if (days_in_month == 31) {
    daysOptions += '<option value="31">31</option>';
}

$(select_day).append(daysOptions);

http://jsfiddle.net/sL4jY/10/ 在IE,Chrome和Firefox中已经测试过。


1
谢谢,你的回答很好。但是不要忘记恢复所选的日期。如果所选日期大于该月的天数,则应选择该月的最后一天。 - Uri

2
感谢您的回答,我使用了您的代码,但稍微修改了一下,以处理具有28天和29天(2月份)的月份。以下是函数代码:
// Show and hide days according to the selected year and month.
function show_and_hide_days(fp_form) {
    var select_year= $(fp_form).find("select.value_year");
    var select_month= $(fp_form).find("select.value_month");
    var select_day= $(fp_form).find("select.value_day");
    var selected_year= $.parse_int($(select_year).val());
    var selected_month= $.parse_int($(select_month).val());
    var selected_day= $.parse_int($(select_day).val());
    var days_in_month= new Date(selected_year, selected_month, 0).getDate();
    // If the number of days in the selected month is less than 28, change it to 31.
    if (!(days_in_month >= 28))
    {
        days_in_month= 31;
    }
    // If the selected day is bigger than the number of days in the selected month, reduce it to the last day in this month.
    if (selected_day > days_in_month)
    {
        selected_day= days_in_month;
    }
    // Remove days 29 to 31, then append days 29 to days_in_month.
    for (var day= 31; day >= 29; day--)
    {
        $(select_day).find("option[value='" + day + "']").remove();
    }
    for (var day= 29; day <= days_in_month; day++)
    {
        $(select_day).append("<option value=\"" + day + "\">" + day + "</option>");
    }
    // Restore the selected day.
    $(select_day).val(selected_day);
}

现在它可以在我测试的所有五个浏览器上使用(我没有测试早期版本的Internet Explorer)。

我添加了一个名为$.parse_int的jQuery插件 - 如果没有指定,它将返回基数为10的parseInt。以下是该插件的代码:

// Add functions to the jQuery object.
(function( $ ) {
    // Return parseInt with radix 10 if not specified.
    $.parse_int= function(fp_string, fp_radix) {
        var radix= ((typeof(fp_radix) !== "undefined") ? fp_radix : 10);
        return parseInt(fp_string, radix);
    };
})( jQuery );

Uri.


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