h5p / h5p-course-presentation

MIT License
54 stars 130 forks source link

Course presentation drag and drop activity can not work properly in Tablets/phones #202

Open aakabir opened 2 years ago

aakabir commented 2 years ago

Dear Concern, As I experienced, drag and drop activity inside tablets/phones can not work properly. I parse it as an h5p file and try to integrate it into the app.

dailez commented 2 years ago

I can confirm that drag and drop issues cannot be solved on touch devices. Is the problem recognized? It massively influences the performance of the content type!

frank-b-from-g commented 2 years ago

I worked around this issue by freezing all ancestor elements above the draggable texts and below h5p-slides-wrapper with event.stopImmediatePropagation() on touchstart event and defreezing on touchend. It is still in the testing phase.

My code in the respective page.js file of our SailsJS app looks like this:

    H5P.externalDispatcher.on('initialized', () => {
      bindDropTextEventsOnce();
      window.H5P.instances[0].on('changedSlide', () => {
        bindDropTextEventsOnce();
      });
    });

    this.boundDropTexts = [];
    const that = this;

    function bindDropTextEventsOnce() {
      const draggableTexts = $('.ui-draggable.ui-draggable-handle');
      if (!draggableTexts || draggableTexts.length === 0) {
        return;
      }
      $(draggableTexts).each((i, obj) => {
        if (!that.boundDropTexts.includes(obj)) {
          that.boundDropTexts.push(obj);
          $(obj).on('touchstart', () => {
            stopStartParentPropagation($(obj), true);
          });
          $(obj).on('touchend', () => {
            setTimeout(() => {
              stopStartParentPropagation($(obj), false);
            }, 100);
          });
        }
      });
    }

    // "freeze" or "defreeze" all ancestor elements above draggables and below slides wrapper
    function stopStartParentPropagation(jqObj, stopFlag) {
      let obj = jqObj[0];
      while (obj && obj.parentNode && obj.parentNode.className.indexOf('h5p-slides-wrapper') < 0) {
        obj = obj.parentNode;
        if (obj.className.indexOf('drag') < 0) {
          if (stopFlag) {
            $(obj).on('touchstart touchmove touchend', (event) => {
              event.stopImmediatePropagation();
            });
          } else {
            $(obj).off('touchstart touchmove touchend');
          }
        }
      }
    }