2

我有一个显示FullCalendar日历的网页

日历托管在公共 Salesforce 社区页面中。

我希望能够通过使用touch和的移动设备在日历中创建事件drag

Salesforce 社区和 FullCalendar 都支持移动设备。

FullCalendar支持触控

但是当我使用移动设备访问社区页面时,我无法使用touchdrag创建日历条目。

Salesforce 社区页面/框架创建了一些touch事件处理程序:

  • document对于touchstarttouchendtouchcancel
  • window为了touchmove

这似乎覆盖了 FullCalendartouch事件。

这是用于调试的示例日历:

如何删除andtouch上的事件处理程序?documentwindow

我试过添加:

    document.addEventListener("touchstart", function (event) {
        event.preventDefault();
        console.log("touchstart: event.preventDefault()");
    }, false);

    document.addEventListener("touchend", function (event) {
        event.preventDefault();
        console.log("touchend: event.preventDefault()");
    }, false);

    document.addEventListener("touchcancel", function (event) {
        event.preventDefault();
        console.log("touchcancel: event.preventDefault()");
    }, false);

    window.addEventListener("touchmove", function (event) {
        event.preventDefault();
        console.log("touchmove: event.preventDefault()");
    }, false);

但是我刚刚在控制台中收到了这个错误:

[干预] 由于目标被视为被动,无法阻止被动事件侦听器内部的默认值。

而且所有日历按钮都不再起作用了。

4

4 回答 4

9

如果添加新侦听器,则无法删除侦听器。所有侦听器都将添加到队列中。例如,您可以在这里看到它:

var listenerLoad = function(e){console.log(1)};
window.addEventListener('load', listenerLoad, false);
window.addEventListener('load', listenerLoad, true);
window.addEventListener('load', function(e){console.log(3)}, false);
window.onload = function(e){console.log(4)};

但是,如果您为此使用适当的功能,则可以删除侦听器。您必须使用该功能EventTarget.removeEventListener()之前请仔细阅读本文档。参数必须与addEventListener()此事件中的初始化相同。并且指向监听器的指针应该和 in 中的一样addEventListener()。例如,如果 指向侦听器的指针,例如:

var listenerTouchStart = function(e){/**/},
    listenerTouchEnd = function(e){/**/},
    listenerTouchCancel = function(e){/**/},
    listenerTouchMove = function(e){/**/};

然后您可以删除侦听器,如下所示:

document.removeEventListener('touchstart', listenerTouchStart, false);
document.removeEventListener('touchend', listenerTouchEnd, false);
document.removeEventListener('touchcancel', listenerTouchCancel, false);
window.removeEventListener('touchmove', listenerTouchMove, false);

但不要忘记,window.removeEventListener('touchmove', listenerTouchMove, false);window.removeEventListener('touchmove', listenerTouchMove, true);不一样。如果他们添加了侦听false器并且您尝试将其删除,true那么它将无法正常工作。当心!

如果要查找侦听器函数名称,则有 3 种方法:

  1. 您可以在代码中手动搜索。
  2. 在Chrome DevTools(包括 Opera)、Safari Inspector 和 Firebug的开发者控制台getEventListeners(Object);中,您可以输入 console 。例如,对于第一个示例中的窗口,您将获得如下输出:

在此处输入图像描述

如果监听器是用匿名函数添加的,那么它就没有名字。

  1. 您可以使用 ListenerTracker 脚本。这是它的源代码(不要试图执行这个片段——它只是为了隐藏这个长代码):

// THIS SNIPPET SHOULD NOTHING DO.
// IT IS ONLY TO HIDE THIS LONG CODE

function DO_NOT_COPY_THIS_LINE() //<-DO NOT COPY THIS LINE
{
    //////////////////////////////
    //ListenerTracker Script START
    //////////////////////////////

    var ListenerTracker = new function()
    {
        var is_active=false;
        // listener tracking datas
        var _elements_  =[];
        var _listeners_ =[];
        this.init=function(){
            if(!is_active){//avoid duplicate call
                intercep_events_listeners();
            }
            is_active=true;
        };
        // register individual element an returns its corresponding listeners
        var register_element = function(element){
            if(_elements_.indexOf(element)==-1){
                // NB : split by useCapture to make listener easier to find when removing
                var elt_listeners=[{/*useCapture=false*/},{/*useCapture=true*/}];
                _elements_.push(element);
                _listeners_.push(elt_listeners);
            }
            return _listeners_[_elements_.indexOf(element)];
        };
        var intercep_events_listeners = function(){
            // backup overrided methods
            var _super_={
                "addEventListener"      : HTMLElement.prototype.addEventListener,
                "removeEventListener"   : HTMLElement.prototype.removeEventListener
            };

            Element.prototype["addEventListener"] = function(type, listener, useCapture){
                var listeners=register_element(this);
                // add event before to avoid registering if an error is thrown
                _super_["addEventListener"].apply(this,arguments);
                // adapt to 'elt_listeners' index
                useCapture=useCapture?1:0;

                if(!listeners[useCapture][type])listeners[useCapture][type]=[];
                listeners[useCapture][type].push(listener);
            };

            Element.prototype["removeEventListener"] = function(type, listener, useCapture){
                var listeners=register_element(this);
                // add event before to avoid registering if an error is thrown
                _super_["removeEventListener"].apply(this,arguments);
                // adapt to 'elt_listeners' index
                useCapture=useCapture?1:0;
                if(!listeners[useCapture][type])return;
                var lid = listeners[useCapture][type].indexOf(listener);
                if(lid>-1)listeners[useCapture][type].splice(lid,1);
            };

            Element.prototype["getEventListeners"] = function(type){
                var listeners=register_element(this);
                // convert to listener datas list
                var result=[];
                for(var useCapture=0,list;list=listeners[useCapture];useCapture++){
                    if(typeof(type)=="string"){// filtered by type
                        if(list[type]){
                            for(var id in list[type]){
                                result.push({"type":type,"listener":list[type][id],"useCapture":!!useCapture});
                            }
                        }
                    }else{// all
                        for(var _type in list){
                            for(var id in list[_type]){
                                result.push({"type":_type,"listener":list[_type][id],"useCapture":!!useCapture});
                            }
                        }
                    }
                }
                return result;
            };
        };
    }();
    ListenerTracker.init();

    //////////////////////////////
    //ListenerTracker Script END
    //////////////////////////////
}

我在这里找到了这个 ListenerTracker 脚本。使用此脚本,您甚至可以获得匿名侦听器,但您必须在他们在代码中添加一些侦听器之前添加它。

祝你好运!

于 2018-12-17T17:36:00.983 回答
1

不确定您(OP)到底遇到了什么问题。https://sfse-developer-edition.eu16.force.com/FullCalendar/s/在运行 Safari 的 iPad 上查看时主要适用于我。我发现了一些错误(见下文),但也许你只是触摸的时间不够长。

根据FullCalendar 文档:“在触摸设备上,用户要开始拖放事件,他们必须首先点击并按住该事件才能“选择”它!(强调原文)。您可以使用 配置延迟longPressDelay

无论您遇到什么问题,我都会说最好的解决方案不太可能涉及删除事件处理程序。您更有可能在 SalesForce 社区的文档中找到关于如何将其他 JavaScript 包集成到页面中的答案。

例如,我在这段代码中发现了一个错误,Chrome 说该错误来自https://sfse-developer-edition.eu16.force.com/FullCalendar/s/components/c/FullCalendar.js 但实际上似乎并非如此来自该 URL。无论如何,鉴于这console.log('loadCalendar')条线,我猜你,OP,写了它。

 "helper":{
    "loadCalendar":function(component) {
        console.log('loadCalendar');
        var params;
        var self = this;
        var calendar = component.find('calendar').getElement();
        $(calendar).fullCalendar('destroy');
        $(calendar).fullCalendar({
            header: {
                left: 'prev,next',
                center: 'title',
                right: 'month,agendaWeek,agendaDay'
            },
            schedulerLicenseKey: '0537034756-fcs-1530699190',
            defaultView: 'agendaWeek',
            // <snip> bunch of stuff omitted for brevity
            select: function (starts, ends) {
                params.starts = starts.format('x');
                params.ends = ends.format('x');

            },
            // <snip> lots more stuff omitted

这里的问题是它params永远不会被初始化,因此params.starts抛出 uncaught 的无效引用也是如此TypeError。这可能可以通过替换来解决var params;var params = {};但我不能确定。

于 2018-12-18T01:51:21.447 回答
0

EventTarget.removeEventListener() 方法从 EventTarget 中移除之前使用 EventTarget.addEventListener() 注册的事件侦听器。使用事件类型、事件侦听器函数本身以及可能影响匹配过程的各种可选选项的组合来标识要移除的事件侦听器;请参阅匹配事件侦听器以进行删除。

更多关于https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener

于 2018-12-18T18:31:47.210 回答
0

也许尝试将“SFDC”touch事件转发到 FullCalendar 事件

document.addEventListener("touchstart", function (event) {
    myFullCalendarEvent.OnTouch(event);
}, false);

虽然一般来说,当我仍然希望它在较低级别上工作时,我从未尝试过删除这样的事件......鉴于您当前的方法存在问题,这就是我接下来要去的地方......

于 2018-12-17T13:35:02.893 回答