Javascript日期过滤器改进

Javascript date filter improving

本文关键字:过滤器 日期 Javascript      更新时间:2023-09-26

jsfiddle.net

我编写了javascript/jquery UI,它按日期过滤项目列表。

一个<li class="list-group-item listItem" id="0001"> - 一个项目。

每个项目日期的每个<input type="hidden" id="01_0001" class="form-control dateItem dataField_0001" value="11/23/2012">

任务是显示项目是否至少有一个日期在日期选择器范围内。如果一个项目没有日期 - 则需要隐藏它。

所以,一切正常,但速度很慢。

大约有 300

个项目和 2000 多个日期,当我的脚本解析数据时,它需要 30 多秒。

问题:有没有办法优化我的代码,或者我应该为此任务使用任何其他方法?

请参阅帖子开头的小提琴。

此致敬意亚历克斯

/* Create dates +/- 7 for each "from" and "to" fields */
    var prevWeek = new Date();
        prevWeek.setDate( prevWeek.getDate() - 7 );
    var prevMonth = ( prevWeek.getMonth() + 1 );
    var prevDay =  prevWeek.getDate();
    var prevYear = prevWeek.getFullYear();
    var prevWeekDate = (( prevMonth < 10 ? '0' : '' ) + prevMonth + "/" + (prevDay < 10 ? '0' : '' ) + prevDay + "/" + prevYear );
    /*console.log('prevWeekDate =' + prevWeekDate);*/
    var nextWeek = new Date();
        nextWeek.setDate( nextWeek.getDate() + 7 );
    var nextMonth = ( nextWeek.getMonth() + 1 );
    var nextDay = nextWeek.getDate();
    var nextYear = nextWeek.getFullYear();
    var nextWeekDate = (( nextMonth < 10 ? '0' : '' ) + nextMonth + "/" + ( nextDay < 10 ? '0' : '' ) + nextDay + "/" + nextYear );
    /*console.log('nextWeekDate =' + nextWeekDate); */

/*function - datepicker setup*/
    $(function() {
        $( "#from" ).datepicker({
            defaultDate: "-1w",
            changeMonth: true,
            numberOfMonths: 1,
            onClose: function( selectedDate ) {
                $( "#to" ).datepicker( "option", "minDate", selectedDate );
                //console.log (selectedDate);
                filterDates();
        } });
        $( "#to" ).datepicker({
            defaultDate: "+1w",
            changeMonth: true,
            numberOfMonths: 1,
            onClose: function( selectedDate ) {
                $( "#from" ).datepicker( "option", "maxDate", selectedDate );
                //console.log (selectedDate);
                filterDates();
        } });
    });
/*parse date string to array*/
    function dateToArray(date) {
        var dateArray = date.split('/');
        return dateArray;
    }

        function filterDates() {
            var from = dateToArray($('#from').val());
            //console.log (from);
            var from = new Date(parseInt(from[2], 10),
                                parseInt(from[0], 10) - 1,
                                parseInt(from[1], 10));
            //console.log (from);
            var to = dateToArray($('#to').val());
            //console.log (to);
            var to = new Date(  parseInt(to[2], 10),
                                parseInt(to[0], 10) - 1,
                                parseInt(to[1], 10));
            //console.log (to);
            $( '.block').each( function() {
                var itemId = $(this).attr('class');
                var itemId = itemId.split('_');
                var itemId = itemId[1];
                var displayBlock = false;
                $('.dataField_'+ itemId).each( function () {
                    var inputValue = $(this).attr('value');
                    var inputId = $(this).attr('id');
                    //console.log (inputValue + ' ' +inputId);
                    var testField = ($(this).attr( 'value' )).split('/');
                    console.log (testField);
                    var testField = new Date(   parseInt(testField[2], 10),
                                                parseInt(testField[0], 10) - 1,
                                                parseInt(testField[1], 10));
                    // console.log (testField);
                    var result = (testField < from || testField > to);
                    if (!result) { displayBlock = true; }
                });
                if (displayBlock) {
                    $('.listItem#' + itemId).removeClass('hideItem');
                } else {
                    $('.listItem#' + itemId).addClass('hideItem'); 
                }
            })
        } 
    $(document).ready(function(){
        $("#checkAllBox").click(function() {
            if ($("#checkAllBox").prop('checked')) {
                $(".checkBoxItem").prop( "checked", true );
            } else {
                $(".checkBoxItem").prop( "checked", false );
            }
        });
    $("#from").val(prevWeekDate);
    $("#to").val(nextWeekDate);

        $( "#dialog" ).dialog({
            autoOpen: false,
            width: 600,
            position:['middle',120],
        });
        $( ".startDialog").click(function() {
            $( "#dialog" ).dialog( "open" );
        });
        filterDates();
        $('.listItem').click(function(){
            var itemId = $(this).attr('id');
            console.log (itemId);            
        });
    })

想到的第一个想法是将日期保留为 iso 时间戳,并摆脱日期解析。因此,每个输入都有一个 isoDate 属性,看起来像"20130101",而不是"01/01/2013"。选择边界的输入框也将返回如下时间戳。然后,您将能够比较原始字符串。试试这个,让我们知道速度是否加快。

另一个想法:您可以在页面中的某个位置放置一个数组,其中包含具有两个属性的对象:iso 时间戳和对与时间戳关联的 dom 节点的引用(需要隐藏的节点)。数组将按时间戳排序,因此更容易根据边界进行过滤。预先填充对 dom 节点的引用也意味着您不需要每次都通过 dom 查找它们。