如何向画布元素添加一个简单的 onClick 事件处理程序? [英] How do I add a simple onClick event handler to a canvas element?

查看:21
本文介绍了如何向画布元素添加一个简单的 onClick 事件处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一名经验丰富的 Java 程序员,但我在大约十年内第一次研究了一些 JavaScript/HTML5 内容.我完全被什么应该是有史以来最简单的事情难住了.

I'm an experienced Java programmer but am looking at some JavaScript/HTML5 stuff for the first time in about a decade. I'm completely stumped on what should be the simplest thing ever.

举个例子,我只是想画一些东西并给它添加一个事件处理程序.我确定我在做一些愚蠢的事情,但我已经搜索了所有内容,没有任何建议(例如这个问题的答案:添加 onclick 属性以使用 JavaScript 输入) 有效.我正在使用 Firefox 10.0.1.我的代码如下.您会看到几行带注释的行,每行末尾都有对发生(或不发生)情况的描述.

As an example I just wanted to draw something and add an event handler to it. I'm sure I'm doing something stupid, but I've searched all over and nothing that is suggested (e.g. the answer to this question: Add onclick property to input with JavaScript) works. I'm using Firefox 10.0.1. My code follows. You'll see several commented lines and at the end of each is a description of what (or what doesn't) happen.

这里的正确语法是什么?我要疯了!

What's the correct syntax here? I'm going crazy!

<html>
<body>
    <canvas id="myCanvas" width="300" height="150"/>
    <script language="JavaScript">
        var elem = document.getElementById('myCanvas');
        // elem.onClick = alert("hello world");  - displays alert without clicking
        // elem.onClick = alert('hello world');  - displays alert without clicking
        // elem.onClick = "alert('hello world!')";  - does nothing, even with clicking
        // elem.onClick = function() { alert('hello world!'); };  - does nothing
        // elem.onClick = function() { alert("hello world!"); };  - does nothing
        var context = elem.getContext('2d');
        context.fillStyle = '#05EFFF';
        context.fillRect(0, 0, 150, 100);
    </script>

</body>

推荐答案

当您绘制到 canvas 元素时,您只是在 立即模式.

When you draw to a canvas element, you are simply drawing a bitmap in immediate mode.

绘制的元素(形状、线条、图像)除了它们使用的像素和颜色之外没有任何表示.

The elements (shapes, lines, images) that are drawn have no representation besides the pixels they use and their colour.

因此,要在 canvas element(形状)上获取 click 事件,您需要捕获 上的点击事件canvas HTML 元素并使用一些数学运算来确定点击了哪个元素,前提是您要存储元素的宽度/高度和 x/y 偏移量.

Therefore, to get a click event on a canvas element (shape), you need to capture click events on the canvas HTML element and use some math to determine which element was clicked, provided you are storing the elements' width/height and x/y offset.

要将 click 事件添加到您的 canvas 元素,请使用...

To add a click event to your canvas element, use...

canvas.addEventListener('click', function() { }, false);

要确定点击了哪个元素...

To determine which element was clicked...

var elem = document.getElementById('myCanvas'),
    elemLeft = elem.offsetLeft + elem.clientLeft,
    elemTop = elem.offsetTop + elem.clientTop,
    context = elem.getContext('2d'),
    elements = [];

// Add event listener for `click` events.
elem.addEventListener('click', function(event) {
    var x = event.pageX - elemLeft,
        y = event.pageY - elemTop;

    // Collision detection between clicked offset and element.
    elements.forEach(function(element) {
        if (y > element.top && y < element.top + element.height 
            && x > element.left && x < element.left + element.width) {
            alert('clicked an element');
        }
    });

}, false);

// Add element.
elements.push({
    colour: '#05EFFF',
    width: 150,
    height: 100,
    top: 20,
    left: 15
});

// Render elements.
elements.forEach(function(element) {
    context.fillStyle = element.colour;
    context.fillRect(element.left, element.top, element.width, element.height);
});​

jsFiddle.

此代码将 click 事件附加到 canvas 元素,然后将一个形状(在我的代码中称为 element)推送到elements 数组.您可以在此处添加任意数量的内容.

This code attaches a click event to the canvas element, and then pushes one shape (called an element in my code) to an elements array. You could add as many as you wish here.

创建对象数组的目的是为了以后可以查询它们的属性.在所有元素都被推入数组后,我们循环遍历并根据它们的属性渲染每个元素.

The purpose of creating an array of objects is so we can query their properties later. After all the elements have been pushed onto the array, we loop through and render each one based on their properties.

click 事件被触发时,代码循环遍历元素并确定点击是否在 elements 数组中的任何元素上.如果是这样,它会触发一个 alert(),可以很容易地修改它以执行诸如删除数组项之类的操作,在这种情况下,您需要一个单独的 render 函数更新画布.

When the click event is triggered, the code loops through the elements and determines if the click was over any of the elements in the elements array. If so, it fires an alert(), which could easily be modified to do something such as remove the array item, in which case you'd need a separate render function to update the canvas.

为了完整起见,为什么您的尝试没有奏效...

For completeness, why your attempts didn't work...

elem.onClick = alert("hello world"); // displays alert without clicking

这是将alert() 的返回值分配给elemonClick 属性.它立即调用 alert().

This is assigning the return value of alert() to the onClick property of elem. It is immediately invoking the alert().

elem.onClick = alert('hello world');  // displays alert without clicking

在 JavaScript 中,'" 在语义上是相同的,词法分析器可能使用 ['"] 作为引号.

In JavaScript, the ' and " are semantically identical, the lexer probably uses ['"] for quotes.

elem.onClick = "alert('hello world!')"; // does nothing, even with clicking

您正在为 elemonClick 属性分配一个字符串.

You are assigning a string to the onClick property of elem.

elem.onClick = function() { alert('hello world!'); }; // does nothing

JavaScript 区分大小写.onclick 属性是附加事件处理程序的古老方法.它只允许一个事件附加到该属性,并且在序列化 HTML 时该事件可能会丢失.

JavaScript is case sensitive. The onclick property is the archaic method of attaching event handlers. It only allows one event to be attached with the property and the event can be lost when serialising the HTML.

elem.onClick = function() { alert("hello world!"); }; // does nothing

再次,' === ".

这篇关于如何向画布元素添加一个简单的 onClick 事件处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆