从jQuery UI触发click事件到knockout.js

lnvxswe2  于 2022-11-23  发布在  jQuery
关注(0)|答案(1)|浏览(115)

使用Jquery-ui sortable doesn't work on touch devices based on Android or IOS中的代码示例在iOS设备上触摸启用jQuery UI可排序项,在相同元素上注册knockout.js单击处理程序和jQuery UI可排序项时会出现问题。knockout.js处理程序在启用触摸的设备上不会触发,但在台式机/笔记本电脑上会触发。
添加一个名为 moved 的标志,可以跟踪何时需要触发单击处理程序,下面用// TRIGGER HERE标记:

/*
 * Content-Type:text/javascript
 *
 * A bridge between iPad and iPhone touch events and jquery draggable,
 * sortable etc. mouse interactions.
 * @author Oleg Slobodskoi
 *
 * modified by John Hardy to use with any touch device
 * fixed breakage caused by jquery.ui so that mouseHandled internal flag is reset
 * before each touchStart event
 *
 */
(function( $ ) {

  $.support.touch = typeof Touch === 'object';

  if (!$.support.touch) {
      return;
  }

  var proto =  $.ui.mouse.prototype,
  _mouseInit = proto._mouseInit
  moved = true;

  $.extend( proto, {
    _mouseInit: function() {
      this.element
      .bind( "touchstart." + this.widgetName, $.proxy( this, "_touchStart" ) );
      _mouseInit.apply( this, arguments );
    },

    _touchStart: function( event ) {
      if ( event.originalEvent.targetTouches.length != 1 ) {
        return false;
      }

      this.element
      .bind( "touchmove." + this.widgetName, $.proxy( this, "_touchMove" ) )
      .bind( "touchend." + this.widgetName, $.proxy( this, "_touchEnd" ) );

      this._modifyEvent( event );

      $( document ).trigger($.Event("mouseup")); //reset mouseHandled flag in ui.mouse
      this._mouseDown( event );

      moved = false;

      return false;
    },

    _touchMove: function( event ) {
      this._modifyEvent( event );
      this._mouseMove( event );
      moved = true;
    },

    _touchEnd: function( event ) {
      this.element
      .unbind( "touchmove." + this.widgetName )
      .unbind( "touchend." + this.widgetName );
      this._mouseUp( event );
      if (! moved) {
        // TRIGGER HERE
      }
    },

    _modifyEvent: function( event ) {
      event.which = 1;
      var target = event.originalEvent.targetTouches[0];
      event.pageX = target.clientX;
      event.pageY = target.clientY;
    }

  });

})( jQuery );

问题是,如何触发 click 事件从jQuery UI中敲除. js?
我已经尝试了this.element.click()this.element.get().click()this.element.trigger("click")等,但都无济于事。

更新日期:

破解代码:

  • 跟踪实际目标,因为html.element看起来不正确
  • 在正确的目标上触发点击事件

现在,它可以很好地处理knockout.js的click事件。

/*
 * Content-Type:text/javascript
 *
 * A bridge between iPad and iPhone touch events and jquery draggable,
 * sortable etc. mouse interactions.
 * @author Oleg Slobodskoi
 *
 * modified by John Hardy to use with any touch device
 * fixed breakage caused by jquery.ui so that mouseHandled internal flag is reset
 * before each touchStart event
 *
 */
(function( $ ) {

  $.support.touch = typeof Touch === 'object';

  if (!$.support.touch) {
      return;
  }

  var proto =  $.ui.mouse.prototype,
  _mouseInit = proto._mouseInit
  moved = true,
  currentTarget = null;

  $.extend( proto, {
    _mouseInit: function() {
      this.element
      .bind( "touchstart." + this.widgetName, $.proxy( this, "_touchStart" ) );
      _mouseInit.apply( this, arguments );
    },

    _touchStart: function( event ) {
      if ( event.originalEvent.targetTouches.length != 1 ) {
        return false
      }

      this.element
      .bind( "touchmove." + this.widgetName, $.proxy( this, "_touchMove" ) )
      .bind( "touchend." + this.widgetName, $.proxy( this, "_touchEnd" ) );

      this._modifyEvent( event );

      $( document ).trigger($.Event("mouseup")); //reset mouseHandled flag in ui.mouse
      this._mouseDown( event );

      moved = false;

      return false;
    },

    _touchMove: function( event ) {
      this._modifyEvent( event );
      this._mouseMove( event );
      moved = true;
    },

    _touchEnd: function( event ) {
      this.element
      .unbind( "touchmove." + this.widgetName )
      .unbind( "touchend." + this.widgetName );
      this._mouseUp( event );
      if (! moved) {
        $(currentTarget).click();
      }
    },

    _modifyEvent: function( event ) {
      event.which = 1;
      var target = event.originalEvent.targetTouches[0];
      currentTarget = target.target;
      event.pageX = target.clientX;
      event.pageY = target.clientY;
    }

  });

})( jQuery );
v6ylcynt

v6ylcynt1#

在您发布的代码中,您从touchstart事件返回false。在支持触摸功能的设备中,touchstart事件首先触发,click在大约300ms后触发。
如果从事件处理程序返回false,这与调用event.preventDefault()event.stopPropagation()相同,因此touchstart实际上取消了单击。这在桌面上不是问题,因为touchstart从不触发。
http://jsfiddle.net/madcapnmckay/HkbwV/2/
可能的解决方案。

  • 只需调用event.stopPropagation()(如果可以的话),而不是返回false。使用事件绑定来绑定touchstart,而不是click。

<div data-bind="event : { touchstart: somfunction }"></div>

  • 在您标记trigger的位置中,会有一个由事件系结订阅的自订事件。

您还可以考虑编写一个touchOrClick自定义绑定,用于检测touchstart是否可用,并选择性地绑定到它或click事件。
希望这对你有帮助。

相关问题