Bir tuval öğesine nasıl basit bir onClick olay işleyicisi eklerim?


128

Deneyimli bir Java programcısıyım, ancak yaklaşık on yıldır ilk kez bazı JavaScript / HTML5 şeylerine bakıyorum. Şimdiye kadarki en basit şeyin ne olması gerektiğine tamamen şaşırdım.

Örnek olarak bir şey çizmek ve ona bir olay işleyicisi eklemek istedim. Eminim aptalca bir şey yapıyorum, ama her yerde aradım ve önerilen hiçbir şey (örneğin, bu sorunun cevabı: JavaScript ile girmek için onclick özelliğini ekleyin ) çalışmıyor. Firefox 10.0.1 kullanıyorum. Kodum takip ediyor. Birkaç yorum satırı göreceksiniz ve her birinin sonunda neyin (veya neyin olmadığının) bir açıklaması var.

Buradaki doğru sözdizimi nedir? Deliriyorum!

<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>


8
onclickBunun yerine kullanınonClick
noob

1
Bu girişimlerin neden işe yaramadığını ayrıntılarıyla açıklamak için ... İlk birkaç yorum , arayacak bir işlev tanımlamak yerine, alert()doğrudan aradığınız için hemen bir uyarı görüntüler . Geri kalanı, büyük harf kullanımı nedeniyle hiçbir şey yapmaz . <script>alert()onclick
LarsH

Yanıtlar:


223

Bir canvasöğeye çizim yaptığınızda, anlık modda basitçe bir bitmap çizersiniz .

Elementler çizilir (şekiller, çizgiler, görüntüler) kullandıkları piksel ve onların rengine dışında herhangi bir beyan var.

Bu nedenle, almak için tıklayın bir olayı canvas elemanı (şekil), üzerinde yakalama tıklama olayları gerekir canvas, HTML öğesi ve tıklandığı eleman belirlemek için bazı matematik kullanmak size elemanların genişlik / yükseklik depolamak ve x / y ofset sağlanan .

Öğenize bir clicketkinlik eklemek için şunu canvaskullanın ...

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

Hangi öğenin tıklandığını belirlemek için ...

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 .

Bu kod click, canvasöğeye bir olay ekler ve ardından bir şekli (kodumda adı verilir element) bir elementsdiziye iter . Buraya dilediğiniz kadar ekleyebilirsiniz.

Bir nesne dizisi oluşturmanın amacı, daha sonra özelliklerini sorgulayabilmemizdir. Tüm öğeler diziye gönderildikten sonra, her birini özelliklerine göre döngüye sokar ve işleriz.

Zaman clickolay tetiklenir, kod elementleri döngüsü ve tıklama öğelerin herhangi birinin üzerine ise tespit elementsdizisi. Eğer öyleyse, bu bir patlar alert()kolayca ayrı gerekiyordu bu durumda, dizi öğeyi kaldırmak böyle bir şey yapmak için değiştirilmiş olabilir, hangi hale güncellemek için işlevi canvas.


Tamlık için, girişimleriniz neden işe yaramadı ...

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

Bu dönüş değeri atamak olduğunu alert()için onClickmülkiyet elem. Hemen alert().

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

JavaScript'te, 've "anlamsal olarak aynıdır, lexer muhtemelen ['"]alıntılar için kullanır .

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

onClickÖzelliğine bir dize atıyorsunuz elem.

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

JavaScript büyük / küçük harfe duyarlıdır. onclickÖzelliği, olay işleyicileri bağlama eski bir yöntemdir. Özelliğe yalnızca bir olayın eklenmesine izin verir ve HTML serileştirilirken olay kaybolabilir.

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

Yine ' === ".


Hmm ... yanlış anladıysam beni affet - ama tuval öğesindeki tıklama olaylarını yakalamıyor muyum? Hangi öğenin tıklandığını kastettiğinden emin değilim . Bu sayfada sadece bir öğe var, değil mi?
Jer

"Tuvalin içindeki hangi öğe" yi kastetti - yani "şekil" dir.
Jovan Perovic

1
Teşekkürler, çok çok - yine de sonuncusunda tam olarak net değilim. Buradaki örneği takip ediyorum: developer.mozilla.org/en/DOM/element.onclick (tanımladıkları anonim işlevi kullanarak) ve aralığı bir tuvale değiştirsem bile çalışıyor. Bu yüzden neyi yanlış yaptığımı görmek için onların örneğini yavaş yavaş benimkine dönüştürmek benim için zor olmayacak. Ayrıntılı yanıt için teşekkür ederiz! Çeşitli girişimlerimin neden yanlış olduğunun açıklaması özellikle yardımcı oldu.
Jer

1
@Jer Endişelenmeyin, daha fazla sorunuz varsa, Twitter'a @alexdickson gönderebilir ve ping atabilirsiniz .
alex

1
@HashRocketSyntax İyi çalışmalı, sadece nesnelerinizin hafızadaki konumlarını güncelleyin ve bu tanımları kullanarak
alex

4

Muhtemelen cevaba geç kaldım ama bunu 70-480sınava hazırlanırken okudum ve işe yaradığını buldum -

var elem = document.getElementById('myCanvas');
elem.onclick = function() { alert("hello world"); }

Olayı onclickyerine olarak görün onClick.

JS Bin örneği.


3

Şu makaleyi tavsiye ediyorum: HTML5 Canvas için Hit Bölge Algılaması ve Çeşitli durumlardan geçen Tuval Şekillerinde Tıklama Olaylarının Nasıl Dinleneceği .

Bununla birlikte, addHitRegionen iyi yol olması gereken API'yi kapsamaz (matematik fonksiyonları ve / veya karşılaştırmaları kullanmak oldukça hataya açıktır). Bu yaklaşım, developer.mozilla'da ayrıntılı olarak açıklanmıştır .


"[ addHitRegion] artık kullanılmıyor. Bazı tarayıcılarda hala çalışabilmesine rağmen, herhangi bir zamanda kaldırılabileceği için kullanımı önerilmez. Kullanmaktan kaçının." - başkalarına bir tıklama kaydetmek için dahil ettiğiniz dev.moz bağlantısından.
Chris,


1

Ayrıca div, tuval öğelerinizi temsil edecek ve aynı şekilde konumlandırılacak tuvalin üstüne gibi DOM öğelerini de yerleştirebilirsiniz .

Artık bu div'lere olay dinleyicileri ekleyebilir ve gerekli eylemleri çalıştırabilirsiniz.


1

Biraz statik tuval üzerine başka bir ucuz alternatif olarak, bir usemap tanımına sahip üst üste binen bir img öğesi kullanmak hızlı ve kirli. Özellikle pasta grafik gibi çokgen tabanlı tuval öğelerinde iyi çalışır.


0

Alex Answer oldukça derli toplu ama bağlam döndürmeyi kullanırken x, y koordinatlarını izlemek zor olabilir, bu yüzden bunu nasıl takip edeceğimi gösteren bir Demo yaptım .

Temel olarak bu işlevi kullanıyorum ve ona açı ve nesneyi çizmeden önce o meleğin kat ettiği mesafe miktarını veriyorum.

function rotCor(angle, length){
    var cos = Math.cos(angle);
    var sin = Math.sin(angle);

    var newx = length*cos;
    var newy = length*sin;

    return {
        x : newx,
        y : newy
    };
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.