我有一个网页,其中显示了FullCalendar的日历
日历被托管在公共Salesforce社区页面中。
我希望能够使用touch
和drag
通过移动设备在日历中创建事件。
Salesforce社区和FullCalendar均支持移动设备。
还有FullCalendar has touch support
但是当我使用移动设备访问社区页面时,无法使用touch
和drag
创建日历条目。
Salesforce社区页面/框架创建了touch
个事件处理程序:
document
代表touchstart
,touchend
和touchcancel
window
for touchmove
似乎覆盖了FullCalendar touch
事件。
这是调试示例日历:
如何删除touch
和document
上的window
事件处理程序?
我尝试添加:
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);
但是我只是在控制台中收到此错误:
[干预]由于目标被视为被动,因此无法阻止被动事件侦听器中的Default。
并且所有日历按钮都不再起作用。
答案 0 :(得分:8)
如果添加新的侦听器,则无法删除该侦听器。所有侦听器将添加到队列中。例如,您可以在这里看到它:
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()
中的相同。指向侦听人员的指针应该与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种方法:
getEventListeners(Object);
。例如,在第一个示例中,对于我们的窗口,您将具有以下输出:如果侦听器添加了匿名功能,则它没有名称。
// 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脚本 here 。使用此脚本,您甚至可以得到匿名侦听器,但是您必须先添加它,然后才能在代码中添加一些侦听器。
祝你好运!
答案 1 :(得分:1)
不确定您(OP)遇到什么问题。在运行Safari的iPad上查看时,https://sfse-developer-edition.eu16.force.com/FullCalendar/s/最适合我。我发现了一些错误(请参阅下文),但是也许您接触的时间不够长。
根据FullCalendar documentation:“在触摸设备上,为了使用户开始拖放事件,他们必须先按住该事件才能“选择” ”((强调原始内容))。您可以使用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
是无效的引用,它抛出未捕获的TypeError
。可以通过将var params;
替换为var params = {};
来解决此问题,但我不确定。
答案 2 :(得分:0)
也许尝试将“ SFDC” touch
事件转发到FullCalendar事件
document.addEventListener("touchstart", function (event) {
myFullCalendarEvent.OnTouch(event);
}, false);
尽管一般来说,当我仍然希望它在较低级别运行时,我从未尝试过删除此类事件……鉴于您当前的方法存在问题,这就是我接下来要去的地方。 >
答案 3 :(得分:0)
EventTarget.removeEventListener()方法从EventTarget中删除先前已向EventTarget.addEventListener()注册的事件侦听器。使用事件类型,事件侦听器功能本身以及可能影响匹配过程的各种可选选项的组合来标识要删除的事件侦听器;请参阅匹配事件侦听器以进行删除。
有关https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener的更多信息