触发事件以调用闭包内部的函数

时间:2016-05-03 04:00:14

标签: javascript javascript-events closures

我正在根据项目下载和修改的其他人sample canvas drawing app处理项目。我们需要允许用户单击页面上其他位置的按钮(不是画布的一部分),并让它运行示例应用程序附带的功能。但是,该函数位于闭包内。因为我无法直接调用该函数(对吗?闭包可以防止这种情况?我不经常使用闭包),我想我能够通过触发鼠标事件来实现这一点。用户单击以完成相同的操作的位置。它没有用,我也不知道为什么不这样做。

我在this fiddle发布了一个大大简化的版本。简单的HTML代码:

<div id="canvasDiv"></div>
<div id="buttonDiv">
  <button>why can't I send a click to the canvas?</button>
</div>

下载的示例应用的简化版本,以及我尝试使用jQuery的.trigger方法触发事件:

var WM = {};

WM.drawingApp = function(options) {
  "use strict";
  var canvas, context,
    // Add mouse and touch event listeners to the canvas
    createUserEvents = function() {
      var getElementPos = function(element) {
        // straight-forward stuff removed for brevity's sake
        return pos;
      };
      var press = function(e) {
        // Mouse down location
        var sizeHotspotStartX, toolIndex,
          mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX),
          mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY);

        var elementPos = getElementPos(document.getElementById(options.canvasElementId || 'canvasDiv'));
        mouseX -= elementPos.x;
        mouseY -= elementPos.y;
        announce(mouseX, mouseY);
      };
      var announce = function(x,y) { alert('press at: ' + x + ', ' + y); }
      // Add mouse event listeners to canvas element
      canvas.addEventListener("mousedown", press, false);
    },
    // Creates a canvas element, etc
    init = function() {
      // Create the canvas 
      canvas = document.createElement('canvas');
      canvas.setAttribute('width', 100);
      canvas.setAttribute('height', 100);
      canvas.setAttribute('id', 'canvas');
      document.getElementById(options.canvasElementId || 'canvasDiv').appendChild(canvas);
      context = canvas.getContext("2d"); // Grab the 2d canvas context
      createUserEvents();
    };
  init();
  return {};
};

jQuery(document).ready(function() {
  jQuery('#buttonDiv').on('click', 'button', function() {
    var down = jQuery.Event("mousedown", {
      pageX: 50,
      pageY: 50
    });
    jQuery('#canvasDiv canvas').trigger(down);
  });
});

正如您可以通过运行小提琴看到的那样,如果您在框内单击,则会收到一条警告,通知您单击的位置。但是,如果您点击该按钮,则不会收到提醒。在写这个问题时,我想到jQuery的.trigger方法可能不是发送点击的充分方式。其文档页面明确指出.trigger&#34;并不完全复制自然发生的事件&#34;。我们对不涉及jQuery的解决方案持开放态度。

1 个答案:

答案 0 :(得分:2)

您可以在var press;WM之外定义变量WM,在var之前移除press并设置press = function() {}。然后,您应该可以点击press(down)

来致电button
var press;
press = function(e) {
          console.log(e);
          // Mouse down location
          var sizeHotspotStartX, toolIndex,
          mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX),
          mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY);

          var elementPos = getElementPos(
            document.getElementById(options.canvasElementId 
            || 'canvasDiv')
          );
          mouseX -= elementPos.x;
          mouseY -= elementPos.y;
          announce(mouseX, mouseY);
        };
jQuery(document).ready(function() {
  jQuery('#buttonDiv').on('click', 'button', function() {
    var down = jQuery.Event("mousedown", {
      pageX: 50,
      pageY: 50
    });
    press(down); // call `press` at `button` click
    //jQuery('#canvasDiv canvas').trigger(down);
  });
});

&#13;
&#13;
// based on http://www.williammalone.com/projects/html5-canvas-javascript-drawing-app-with-bucket-tool/

var press;

var WM = {};

WM.drawingApp = function(options) {
  "use strict";
  var canvas, context,
    // Add mouse and touch event listeners to the canvas
    createUserEvents = function() {
      var getElementPos = function(element) {
        var parentOffset, pos;
        if (!element) {
          pos = {
            x: 0,
            y: 0
          };
        } else {
          pos = {
            x: element.offsetLeft,
            y: element.offsetTop
          };
          if (element.offsetParent) {
            parentOffset = getElementPos(element.offsetParent);
            pos.x += parentOffset.x;
            pos.y += parentOffset.y;
          }
        }
        return pos;
      };
      press = function(e) {
        console.log(e)
        // Mouse down location
        var sizeHotspotStartX, toolIndex,
          mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX),
          mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY);

        var elementPos = getElementPos(document.getElementById(options.canvasElementId || 'canvasDiv'));
        mouseX -= elementPos.x;
        mouseY -= elementPos.y;
        announce(mouseX, mouseY);
      };
      var announce = function(x,y) { alert('press at: ' + x + ', ' + y); }
      // Add mouse event listeners to canvas element
      canvas.addEventListener("mousedown", press, false);
    },
    // Creates a canvas element, loads images, adds events, and draws the canvas for the first time.
    init = function() {
      // Create the canvas (Neccessary for IE because it doesn't know what a canvas element is)
      canvas = document.createElement('canvas');
      canvas.setAttribute('width', 100);
      canvas.setAttribute('height', 100);
      canvas.setAttribute('id', 'canvas');
      document.getElementById(options.canvasElementId || 'canvasDiv').appendChild(canvas);
      context = canvas.getContext("2d"); // Grab the 2d canvas context
      createUserEvents();
    };
  init();
  return {};
};

jQuery(document).ready(function() {
  jQuery('#buttonDiv').on('click', 'button', function() {
    var down = jQuery.Event("mousedown", {
      pageX: 50,
      pageY: 50
    });
    press(down)
    //jQuery('#canvasDiv canvas').trigger(down);
  });
});

var drawingApp = WM.drawingApp({
  canvasElementId: "canvasDiv"
});
&#13;
 #canvasDiv canvas {
   border: solid black 1px;
 }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div id="canvasDiv"></div>
<div id="buttonDiv">
  <button>why can't I send a click to the canvas?</button>
</div>
&#13;
&#13;
&#13;

jsfiddle https://jsfiddle.net/gkvdha3h/5/

相关问题