【问题标题】:Javascript mouse event handlers not functioning properly on my android touch phoneJavascript 鼠标事件处理程序在我的 android 触摸手机上无法正常运行
【发布时间】:2016-05-29 23:59:54
【问题描述】:

我正在用 javascript 创建一个刮刮卡脚本 鼠标事件处理程序在 pc 上正常工作,但它不在我的触摸手机上。 在电脑上,我按住鼠标左键并移动它来刮卡。 在触摸手机上,只有当我在手机屏幕上不断触摸并松开手指时才会刮擦。

;(function() {
  var global = this;
  function ScratchCard(element, options, ownerDocument) {

    // apply default arguments.
    var defaultOptions = {
      'color': 'gray',
      'radius': 20
    };
    if (options) {
      for (var key in defaultOptions) {
        if (!(key in options)) {
          options[key] = defaultOptions[key];
        }
      }
    } else {
      options = defaultOptions;
    }
    ownerDocument = ownerDocument || global.document;
    
    // canvas validate.
    var canvas = document.createElement('canvas');
    if (typeof canvas.getContext != 'function')
      return console.log('Canvas not supported.');

    // apply canvas offset & size of element
    var rect = element.getBoundingClientRect();
    canvas.width = rect.width || rect.right - rect.left
    canvas.height = rect.height || rect.bottom - rect.top;
    canvas.style.top = rect.top + 'px';
    canvas.style.left = rect.left + 'px';
    canvas.style.position = 'absolute';
    canvas.style.zIndex = +element.style.zIndex + 1;

    // fill the canvas
    var context = canvas.getContext('2d');
    context.fillStyle = options.color;
    context.fillRect(0, 0, canvas.width, canvas.height);
    context.globalCompositeOperation = "destination-out";
    context.strokeStyle = "rgba(0,0,0,1)";

    // add mouse events to canvas
    // TODO: supply touch events
    // TODO: scratch from the outside
    function scratchStart(event) {
      if (event.button != 0) // not left button
        return;

      var x = event.offsetX || event.layerX;
      var y = event.offsetY || event.layerY;

      context.beginPath();
      context.arc(x, y, options.radius, 0, Math.PI * 2);
      context.fill();

      canvas.addEventListener('mousemove', scratchMove);
      canvas.addEventListener('touchmove', scratchMove);
      document.addEventListener('mouseup', scratchEnd);
      document.addEventListener('touchend', scratchEnd);
    }

    function scratchMove(event) {
      var x = event.offsetX || event.layerX;
      var y = event.offsetY || event.layerY;

      context.beginPath();
      context.arc(x, y, options.radius, 0, Math.PI * 2);
      context.fill();
    }

    function scratchEnd(event) {
      canvas.removeEventListener('mousemove', scratchMove);
      canvas.removeEventListener('touchmove', scratchMove);
      document.removeEventListener('mouseup', scratchEnd);
      document.removeEventListener('touchend', scratchEnd);

    }

    canvas.addEventListener('mousedown', scratchStart);
    canvas.addEventListener('touchstart', scratchStart);

    // disable element interaction
    ['MozUserSelect',
     'msUserSelect',
     'oUserSelect',
     'webkitUserSelect',
     'pointerEvents']
      .filter(function (cssProp) {
        return cssProp in element.style;
      }).forEach(function (cssProp) {
        element.style[cssProp] = 'none';
      });

    // append canvas to body.
    document.body.appendChild(canvas);
  }

  if (typeof module == 'object' && module.exports) {
    // Node.js module
    module.exports = ScratchCard;
  } else if (typeof define == 'function' && (define.amd || define.cmd)) {
    // AMD or CMD module
    define(ScratchCard);
  } else if (typeof jQuery == 'function' && typeof jQuery.extend == 'function') {
    // jQuery plugin
    jQuery.fn.extend({
      'ScratchCard': function (options) {
        return this.each(function (element) {
          ScratchCard(element, options);
        });
      }
    });
  } else if (typeof angular == 'object' && typeof angular.module == 'function') {
    // AngularJS module
    // TODO: modify it to a directive.
    angular.module('ScratchCard', [])
      .value('ScratchCard', ScratchCard);
  } else {
    // Apply to a global variable.
    if (global.ScratchCard) {
      (function (oldScratchCard) {
        ScratchCard.noConflict = function () {
          global.ScratchCard = oldScratchCard;
          return ScratchCard;
        };
      }) (global.ScratchCard);
    }
    global.ScratchCard = ScratchCard;
  }
}).call(this);
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
  <!--<script type="text/javascript" src="jquery-1.11.2.min.js"></script> -->
  <!-- <script type="text/javascript" src="touch.js"></script> -->
  <title>ScratchCard Demo</title>
  <style>
  div {
  	display: inline-block;
  	padding: 5px;
  	border: 1px solid black;
  }
  p {
  	margin: 0;
  	/*padding: 5px;*/
  	font-size: 20px;
  }

  img {
    width: 200px;
    height: 200px;
    border:10px solid #557FFF;
  }
  </style>
</head>
<body>
  
  <div><p id="scratchable"><img src="sc4.jpg"></img></p></div>
  <script src="ScratchCard.js"></script>
  <script>ScratchCard(document.querySelector('p'));</script>
  <script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-60834029-1', 'auto');
  ga('send', 'pageview');

  </script>
</body>
</html>

我不知道这段代码有什么问题,但我真的需要帮助。

【问题讨论】:

    标签: javascript events mouse scratchcard


    【解决方案1】:

    为确保您不会出现意外行为,请检测正在使用的设备并仅为该设备添加事件侦听器。如果您使用的是触摸屏,则不要添加鼠标事件侦听器,反之亦然。

    其余部分在技术上看起来是正确的,您使用touchstart 创建touchmove 事件侦听器,然后在touchend 上删除touchmove 侦听器。 touchmove 将是唯一包含 scratchMove 代码的事件,所以这一切都很好。

    我将主要集中在此处的第一段,并且只设置与设备/环境相关的事件侦听器。

    在你的javascript中,你可以添加这个赋值:

    var isTouch = 'ontouchstart' in document.documentElement;
    

    然后在您分配事件的每个地方,执行以下操作:

       if(isTouch) {
          canvas.addEventListener('touchmove', scratchMove);
          document.addEventListener('touchend', scratchEnd);
       } else {
          canvas.addEventListener('mousemove', scratchMove);
          document.addEventListener('mouseup', scratchEnd);
       }
    

    【讨论】:

    • 但我希望能够在这两种设备、PC 和触摸屏手机上使用该代码。
    • 你可以同时使用它,它会在运行时检测当前正在加载页面的设备,并且只在运行时使用适合该设备的事件。
    • 所以这里的代码是正确的?如果是这样,为什么它不能正常运行??
    • 因为,就像我说的那样,由于同时具有点击和触摸事件,事件可能会被交叉。一些设备可能会同时注册两者,并且可能会以不可预知的方式触发事件。请参阅上面的编辑。
    • in var isTouch 是 documentElement 这里是画布??
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2015-04-19
    相关资源
    最近更新 更多