如何禁用全日历中的按钮冒泡?

How to disable button bubbling in fullcalendar?

完整日历版本为 3.9.0。

当我双击左上角的按钮'Prev'或'Next'时,视图将后退或前进两个月。没关系。但是在这种情况下,通过 Promise 检索到的视图中的事件是重复的。快速点击后,它们甚至会增加三倍。

我尝试使用 'event.stopPropagation();' 来阻止事件冒泡,但没有成功。 将事件dblclick事件转化为单击后,Fullcalendar似乎没有相应的响应。如果触发双击,它可能会跳到下一年或上一年。它仍然跳过几个月并显示重复事件。

$("button[aria-label='prev']").on('dblclick', function(e) {
    e.stopPropagation();
});

要在 Fullcalendar 中检索事件,请找到以下代码。

$('#calendar').fullCalendar({ 
    theme: true,
        header: {
        left: 'prev,next today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay,listMonth,listYear'
        },
    viewRender : function(view, element) {     
        viewRenderInit(view, element);
    },
    ... 
});

//when switch/init view, only get events related to current calendar view

let viewRenderInit = function (view, element) {

    $('#calendar').fullCalendar( 'removeEvents');

    let u = '/getbookings';
    let r = '';
    let _common_params = '_token='+$("[name=\'_token\']").val()+'&view='+view.name+'&time_frame='+ view.title;

    get(u, _common_params).then(function(response) {
        r = response;
        $('#calendar').fullCalendar( 'addEventSource', JSON.parse(r));
    }, function(error) {
        console.error("Failed!", error);
    });
}


let get = function(url, params) {
    return new Promise(function(resolve, reject) {    
        var req = new XMLHttpRequest();
        req.open('GET', url+"?"+params, true);

        req.onload = function() {      
            if (req.status == 200) {       
                resolve(req.response);
            }
            else {        
                reject(Error(req.statusText));
            }
        };

        req.onerror = function() {
            reject(Error("Network Error"));
        };

        req.send();
    });
}

我希望禁用按钮 'Prev' 或 'Next' 的事件 dblclick。 或者,禁止通过 Ajax 调用通过 Promise 检索重复事件。

感谢任何建议。

您可以考虑简单地关闭事件处理程序,然后在一两秒后重新绑定它。

$("button[aria-label='prev']").on('click', function(e) {
    $("button[aria-label='prev']").off();
    //the rest of your function here
    setTimeout(function() {
      //rebind the original function
      $("button[aria-label='prev']").on('click', yourOriginalFunction);
    }, 3000);
});

好的,您的方法不是在 fullCalendar 中添加事件的推荐方法。该文档提到了三种合适的方式(有关详细信息,请参阅 https://fullcalendar.io/docs/v3/event-data). For your case I would think the "events as JSON feed" approach would be suitable, and save you quite a bit of code. See https://fullcalendar.io/docs/v3/events-json-feed

这种方法的想法是 fullCalendar 代表您处理发送 AJAX 请求的所有细节。会

a) 每当日历移动到新的日期范围时发送一个新的请求

b) 在请求中自动发送开始和结束日期,以便您的服务器可以 return 显示一组合适的事件(即属于这些日期的事件)。 (现在,您的代码不发送日期,所以我假设您的服务器必须一直 returning 日期,这在您使用应用程序一段时间后可能会变得非常大列表,其中大部分都不会有人看。)

c) 仍然允许您向​​请求添加额外信息,例如您的安全令牌

设置真的很简单:

$('#calendar').fullCalendar({ 
    theme: true,
    header: {
        left: 'prev,next today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay,listMonth,listYear'
    },
    events: {
      url: "/getbookings",
      data: {
        _token: $("[name='_token']").val()
      }
    }
});

这就是您所需要的...不需要额外的 viewRender 代码,也不需要 XHR 或 Promises。 fullCalendar 将完成剩下的工作。


N.B。在您的原始代码中,您似乎正在根据视图类型下载不同的事件。我不太明白这其中的逻辑,因为视图只是查看同一时间段的不同方式。如果事件发生在特定日期,那么您肯定希望在该日期看到它,无论使用何种类型的视图?这只是布局问题,而不是数据问题。

但是如果出于某种原因你真的需要它,尽管也会自动接收相关的 start/end 日期,你仍然可以将额外的数据发送到服务器,你可以这样做(根据文档)使用动态 data 回调:

events: {
  url: "/getbookings",
  data: function() { // a function that returns an object
    var view = $('#calendar').fullCalendar('getView');
    return {
      _token: $("[name='_token']").val(),
      view: view.name,
      time_frame: view.title
    };
}
}

您还需要关闭 lazy fetching 以使其在每次视图切换时都与服务器通信(否则它只会在 日期范围 更改,因此在同一个月内从月切换到周通常不会导致新请求):

lazyFetching: false