【问题标题】:FullCalendar eventRender event freeze the browser tabFullCalendar eventRender 事件冻结浏览器选项卡
【发布时间】:2017-01-06 12:03:57
【问题描述】:

我在AngularJs 中使用FullCalendar 插件。

一切正常。在 eventRender 事件中,我为每个事件添加 background colorimagetooltiplabel,因为它冻结浏览器选项卡几秒钟

有什么方法可以加速或显示加载器或任何东西吗?

我正在使用以下代码

$scope.uiConfig = {
  calendar: {
    height: 550,
    editable: false,
    header: {
      left: 'onlyErrorButton',
      center: 'title',
      right: 'today basicDay,basicWeek,month prev,next'
    },
    timeFormat: 'H:mm',
    defaultView: 'month',
    titleFormat: 'DD MMMM YYYY',
    views: {
      day: {
        columnFormat: 'dddd D.M'
      },
      week: {
        columnFormat: 'dd D.M'
      },
      month: {
        columnFormat: 'dd',
        titleFormat: 'MMMM'
      }
    },
    loading: function( isLoading, view ) {
      if(isLoading) {// isLoading gives boolean value
        $('#wait').show();
      } else {
        $('#wait').hide();
      }
    },
    theme: false,
    themeButtonIcons: false,
    customButtons: {
      onlyErrorButton: {
        text: $rootScope.getLabel('with_errors'),
        click: function() {
          $('.fc-onlyErrorButton-button').toggleClass('fc-state-active');
          vmCurves.onlyErrorButton = false;
          update_eventSources();
        }
      },
      withoutErrorButton: {
        text: $rootScope.getLabel('without_errors'),
        click: function(event) {
          $('.fc-withoutErrorButton-button').toggleClass('fc-state-active');
          vmCurves.withoutErrorButton = false;
          update_eventSources();
        }
      }
    },
    dayClick: function(date, jsEvent, view) {
      var x = new Date(date._d);
      var y = x;
      var start = y.setHours(0,0,0,0);
      var end = x.setHours(23,59,59,59);

      vmCurves.dateFrom =  new Date(start);
      vmCurves.dateTo = new Date(end);
      vmCurves.filter.pasteur = true;
      vmCurves.filter.heat = true;
      vmCurves.filter.cool = true;
      vmCurves.filter.feed = true;
      vmCurves.filter.reinigen = true;

      CurvesServices.feedings($stateParams.taxi_id, start/1000, end/1000, 0, true,true,true,true,true, false, false).then(function (result) {
        vmCurves.feedings = (result[0].data);
        vmCurves.showTable = true;
      });
    },
    eventClick: function(date, jsEvent, view) {
      setVisibles();
      var startTime = parseInt(date.startTimestamp) * 1000;
      var x = new Date(startTime);
      var y = x;

      var start = y.setHours(0,0,0,0);  
      var end = x.setHours(23,59,59,59);  

      vmCurves.dateFrom =  new Date(start);
      vmCurves.dateTo = new Date(end);

      var pasteur = true;
      var heat = true;
      var cool = true;
      var feed = true;
      var reinigen = true;

      vmCurves.filter.pasteur = true;
      vmCurves.filter.heat = true;
      vmCurves.filter.cool = true;
      vmCurves.filter.feed = true;
      vmCurves.filter.reinigen = true;

      CurvesServices.feedings(date.taxi_id, start/1000, end/1000, 0, heat, feed, cool , pasteur, reinigen).then(function (result) {
        vmCurves.feedings = (result[0].data);
      });
      getCurves({ 'taxi_id':date.taxi_id , 'feeding_id':date.feeding_id, 'process_id' : date.process_id});
      vmCurves.showTable = true;
    },
    eventRender: function(event, element, view ) {
      i++;
      if(i == 1) {
        //alert('loading');
        $('#wait').show(); //Trying to show loader here
      }
      $('.fc-day-grid-container').css('cursor', 'pointer'); // adding css style to event container
      $('.fc-toolbar .fc-left .fc-onlyErrorButton-button').addClass('fc-state-active'); // adding class to button
      //adding Tooltip to Buttons
      $('.fc-toolbar .fc-left .fc-onlyErrorButton-button').tooltip({
        'title' : $rootScope.getLabel('only_errors')
      });
      //getting details getLabel() function getting data from database
      var action = event.action ? $rootScope.getLabel(event.action.toLowerCase() ) : $rootScope.getLabel('fuettern');
      var startTime = event.startTime ? event.startTime : '-';
      var endTime = event.endTime ? event.endTime : '-';
      var amount = event.amount ? event.amount : '-';
      var dosings = event.dosings ? event.dosings : '-';
      var action_img = event.action ? event.action : 'fuettern';
      //Image for event
      img_src = "assets/media/img/" + action_img.toLowerCase() + ".png";
      //editing event container adding class's and images
      if(view.name === 'basicDay') {
        element.find(".fc-time")
          .before($("<span class=\"fc-event-icons\"></span>")
          .html("<img src='" + img_src +   "' style=\"width:7%; float:left\" />"));
        element.find(".fc-title").html(action);
        element.find(".fc-time").css({'padding-left' : '20px'});
      } else {
        element.find(".fc-time")
          .before($("<span class=\"fc-event-icons\"></span>")
          .html("<img src='" + img_src +   "' style=\"width:30%; float:left\" />"));
        element.find(".fc-time").css({'padding-left' : '20px'});
        element.find(".fc-title").html(action);
        element.find(".fc-title").hide();

        var moment = $('#calendar').fullCalendar('getDate');
        element.find(".fc-event").addClass("TEST!_" + moment.format("MMMM") + "_" + event.start.format("MMMM"));
      }
      //adding background-color to event
      var bgcolor = event.action == 'Pasteurisieren' ? '#42ca00' : event.action == 'Heizen' ? '#fa8072' : event.action == 'Kuehlen' ? '#00bfff' : event.action == 'reinigen' ? '#00baaa' : '#ffd700';
      $(element).css('background-color', bgcolor);
      //creating Tooltip title
      if(view.name !== 'basicDay') {
        var tooltipText =  $rootScope.getLabel('action') + ': ' + action  + ' | '  + $rootScope.getLabel('start') + ': '+ startTime + ' | ' + $rootScope.getLabel('end') + ': ' + endTime;
        if(event.amount || event.dosings) { //Feeder.Dort gibt es noch Amount und Dosings
          tooltipText +=  ' | ' + 'Liter: ' + amount + ' | ' + 'Dosierung: ' + dosings;
        }
      }
      //Tooltip to event
      $(element).attr('tooltip-placement', 'bottom');  //Tooltip nach unten
      $(element).tooltip({
        'title': tooltipText,
        'container': 'body',
        'placement' : 'bottom'
      });
      $compile(element)($scope);
      if(view.name !== 'basicDay' && (moment.format("MMMM") != event.start.format("MMMM"))) {
        element.find(".fc-content").addClass("othermonth");
      }
    },
    eventAfterAllRender:function(view){
      i = 0;
      $('#wait').hide();
    },
  },
};

【问题讨论】:

  • 请张贴代码。更新属性后是否调用任何 fullCalendar 方法?还可以尝试分析您的代码,看看哪一行执行时间最长。
  • 我已经添加了代码@K48
  • @Jigarb1992 我的建议是,你只显示一个开放月份数据而不是所有数据,完整日历返回一个开始日期和结束日期,只显示这些日期数据之间
  • 一次要显示多少个事件?

标签: jquery angularjs fullcalendar


【解决方案1】:

首先,我建议尽可能避免在 eventRender 处理程序期间修改 DOM。您不需要将 img 标签添加到元素中。相反,只需添加一个指定背景图像的类。所以在你的css中有一个类:

.fuettern {
   background-image: 'assets/media/img/fuettern.png';
   width: '30px';
   height: '30px';
   etc
}

然后执行 element.addClass('fuettern')。添加节点的 DOM 操作成本很高。您还可以以类似的方式优化设置背景颜色的方式。同一类(fuettern、reinigen 等)可以设置背景颜色。事实上,AFAICT,除了纯粹通过设置一个类来设置工具提示之外,你应该可以做任何事情。

其次,看看有多少对象(事件)在范围内。太多的对象是 Angular 中错误渲染延迟的主要原因。确保您只呈现需要显示的事件。

第三,您尝试显示加载程序永远不会以这种方式工作。基本上,只有在 javascript 完成它的工作后,DOM 才会重新渲染。因此,您可以在 异步 方法等待解析时显示微调器,但不能在同步方法的开头显示微调器,然后在末尾再次隐藏它。即使你发现了一些使用 $timeout 或其他东西的 hack,在 javascript 代码运行时微调器也不会旋转 - 所以视图仍然看起来是冻结的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-16
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多