【问题标题】:Javascript date filter improvingJavascript 日期过滤器改进
【发布时间】:2013-11-04 19:35:35
【问题描述】:

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);            
        });
    })

【问题讨论】:

  • 请在此处发布您的代码,而不仅仅是指向小提琴的链接。
  • 一个经验法则是,如果您在一个函数中多次发现 $(this),缓存该对象以减少额外的函数调用以创建一个您已经创建并丢弃的新 jQuery 对象.与任何重复的选择器相同 var $this= $(this)... $this.doSomething() ..also.... this.id &amp; this.valueattr() 快得多,因为它们是本机属性。这些不会对您的代码有很大的改进,但会有所帮助
  • 感谢这一点。我将了解有关缓存的更多信息。

标签: javascript jquery date jquery-ui-datepicker


【解决方案1】:

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

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

【讨论】:

  • 我将尝试弄清楚如何在不将其解析为数组的情况下以 JavaScript 可能使用的格式制作输入数据。好点子,谢谢。
猜你喜欢
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-03
  • 1970-01-01
  • 2015-08-30
  • 2014-10-20
  • 2013-04-17
相关资源
最近更新 更多