简体   繁体   English

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

[英]How to disable button bubbling in fullcalendar?

Fullcalendar version is 3.9.0. Fullcalendar 版本是 3.9.0。

When I double click button 'Prev' or 'Next' on top left corner, the view will go backward or forward two months.当我双击左上角的“上一个”或“下一个”按钮时,视图将向后或向前两个月。 That's fine.没关系。 But the events in the view retrieved through Promise are duplicate in this case.但是在这种情况下,通过 Promise 检索到的视图中的事件是重复的。 They are even trippled following quick clicks.快速点击后,它们甚至会变成三倍。 月视图中显示重复事件

I tried to use 'event.stopPropagation();'我尝试使用'event.stopPropagation();' to stop event bubbling but no luck.停止事件冒泡但没有运气。 After transformed event dblclick event into single click, Fullcalendar seemed did not respond accordingly.将事件 dblclick 事件转换为单击后,Fullcalendar 似乎没有相应的响应。 It may skip into next year or previous year if double click is triggered.如果触发双击,可能会跳到下一年或上一年。 It still skip months and showed duplicate events.它仍然跳过几个月并显示重复的事件。

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

For retrieving events in Fullcalendar, please find the code as following.在 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();
    });
}

I expect disable event dblclick for button 'Prev' or 'Next'.我希望为按钮“上一个”或“下一个”禁用事件 dblclick。 Alternately, disalbe retrieving duplicate events through Promise via Ajax call .或者,通过 Ajax 调用禁止通过 Promise 检索重复事件。

Appreciate for any suggestion.感谢任何建议。

Ok, your method is not the recommended way to add events in fullCalendar.好的,您的方法不是在 fullCalendar 中添加事件的推荐方法。 The documentation mentions three suitable ways (see https://fullcalendar.io/docs/v3/event-data ).该文档提到了三种合适的方式(请参阅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.对于您的情况,我认为“事件作为 JSON 提要”方法是合适的,并为您节省了大量代码。 See https://fullcalendar.io/docs/v3/events-json-feed for details.有关详细信息,请参阅https://fullcalendar.io/docs/v3/events-json-feed

The idea of this approach is that fullCalendar handles all the details of sending an AJAX request on your behalf.这种方法的想法是 fullCalendar 处理代表您发送 AJAX 请求的所有细节。 It will它会

a) send a new request every time the calendar moves to a new date range a) 每次日历移动到新的日期范围时发送一个新请求

b) send a start and end date automatically in the request so that your server can return a suitable set of events to be displayed (ie events which fall within those dates). b) 在请求中自动发送开始和结束日期,以便您的服务器可以返回一组合适的要显示的事件(即属于这些日期的事件)。 (Right now, your code does not send dates, so I assume your server must just be returning dates for all time, which, after you've been using your application for a while might end up being a very big list, most of which no-one will look at.) (现在,您的代码不发送日期,所以我假设您的服务器必须一直返回日期,在您使用应用程序一段时间后,这可能最终成为一个非常大的列表,其中大部分没有人会看。)

c) still allow you to add extra info to the request such as your security token c) 仍然允许您向​​请求添加额外信息,例如您的安全令牌

It's really simply to set up:设置真的很简单:

$('#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()
      }
    }
});

And that's all you need...no extra viewRender code, and no need for XHR or Promises.这就是你所需要的......没有额外的 viewRender 代码,也不需要 XHR 或 Promises。 fullCalendar will do the rest. fullCalendar 将完成剩下的工作。


NB In your original code you seem to be downloading different events based on the type of view.注意在您的原始代码中,您似乎根据视图类型下载了不同的事件。 I can't quite see the logic of this, since views are just different ways of looking at the same time period.我不太明白这其中的逻辑,因为视图只是查看同一时间段的不同方式。 If an event occurs on a particular date, then surely you would want to see it on that date, no matter what type of view is being used?如果某个事件发生在特定日期,那么无论使用哪种类型的视图,您肯定都希望在该日期看到它? It's just a matter of layout, not data.这只是布局问题,而不是数据问题。

But if you really do need that for some reason, despite also receiving relevant start/end dates automatically, you can still send that extra data to the server, you can do it (as per the docs) using the dynamic data callback:但是,如果您出于某种原因确实需要这样做,尽管也会自动接收相关的开始/结束日期,您仍然可以将额外的数据发送到服务器,您可以使用动态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
    };
}
}

You'd also need to switch off lazy fetching to make it talk to the server every time the view switches (otherwise it'll only send a request when the date range changes, so switching from month to week inside the same month wouldn't normally cause a new request):您还需要关闭延迟获取以使其在每次视图切换时与服务器通信(否则它只会在日期范围更改时发送请求,因此在同一个月内从月到周切换不会通常会导致一个新的请求):

lazyFetching: false

You may consider simply turning off the event handler and then rebinding it after a second or two.您可以考虑简单地关闭事件处理程序,然后在一两秒钟后重新绑定它。

$("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);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM