LoginSignup
6
5

More than 5 years have passed since last update.

AngularUI Calendar (FullCalendar) dayClick が iOS上で期待通りに呼ばれない

Last updated at Posted at 2015-07-02

bowerで入れた angularUI Calendar 1.0.0, FullCalendar 2.1.1での話です。

Angular WEBアプリでカレンダーを使いたいというニーズを完璧なまでに満たす
AngularUI Calendar
http://angular-ui.github.io/ui-calendar/

ですが、月(month)表示から日セルクリックで日(agendaDay)表示に切り替えようとしてdayClickを使用した場合、なぜかiPhoneではうまく動作しません。

正確にいえば、タップではなく一秒ほど長押しするか、軽く日セルをドラッグしようとするとdayClickが呼ばれます。

なんでどぅあぁぁぁーーーー!

と3日ほど頭を悩ませた結果、なんとか対処できたのでおすそ分けします。
ちなみにAngularUI CalendarはFullCalendarのラッパーなので、FullCalendarで同じような問題に悩んでいる方にも効くはず....です。

原因

dragイベントの扱いの違いに起因しています。
dayClickはclickイベントで呼ばれていません。dragの終了を検知して呼ばれています。
iOS上のSafari(というかwebkit?)以外では、タップして指を離した瞬間に drag開始、drag終了のイベントが発生するのですが、iOSではdragするか、しばしタップし続けないとdrag終了イベントが発生しないためのようです。

どうにもならんのでタップイベントでdayClickを呼ぶようFullCalendar.jsを修正しました。

FullCalendar.js

...

4038行目付近

    coordMap: null, // a GridCoordMap that converts pixel values to datetimes
    cellDuration: null, // a cell's duration. subclasses must assign this ASAP
+   isTouch : false, // separate touch and scroll.

    // Renders the grid into the `el` element.


...


4093行目付近
        this.el.on('mousedown', function(ev) {
            if (
                !$(ev.target).is('.fc-event-container *, .fc-more') && // not an an event element, or "more.." link
                !$(ev.target).closest('.fc-popover').length // not on a popover (like the "more.." events one)
            ) {
                _this.dayMousedown(ev);
            }
        });

+       this.el.on('touchstart', function (ev) {
+           this.isTouch = true;
+       });
+
+       this.el.on('touchmove', function (ev) {
+           this.isTouch = false;
+       });
+
+       this.el.on('touchend', function (ev) {
+               if (this.isTouch == false) {
+                   //may be scroll.
+                   return;
+               }
+               if (
+                   !$(ev.target).is('.fc-event-container *, .fc-more') && // not an an event element, or "more.." link
+                   !$(ev.target).closest('.fc-popover').length // not on a popover (like the "more.." events one)
+               ) {
+                   _this.touchEnd(ev);
+               }
+           }
+       );

        this.bindSegHandlers(); // attach event-element-related handlers. in Grid.events.js
    },

+   touchEnd: function(ev){
+       console.log("touch end called.");
+       var _this = this;
+       var view = this.view;
+
+       this.coordMap.build();
+       var cell = _this.coordMap.getCell(ev.originalEvent.pageX, ev.originalEvent.pageY);
+       var dayEl = _this.getCellDayEl(cell);
+       view.trigger('dayClick', dayEl[0], cell.date, ev);
+   },

    // Process a mousedown on an element that represents a day. For day clicking and selecting.
    dayMousedown: function(ev) {


...



単にtouchendだけ捕まえるとドラックされた時に挙動がおかしくなる場合があるので、touchstart,touchmove も捕まえてドラックとタップを識別しています。

参考になれば!

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5