Reputation: 610
I have the following code: (JSFIDDLE: https://jsfiddle.net/cjpLa44m/2/)
<style>
body,
html {
width: 100%;
height: 100%;
border: 0;
padding: 0;
margin: 0;
overflow: hidden
}
.everything {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.mainImg img {
width: 100%;
height: 100%;
}
.mainImg {
width: 50vh;
height: 50vh;
position: relative
}
#canvas{
position: absolute;
top: 0;
left: 0;
}
</style>
<div class="everything">
<div class="mainImg"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/SNice.svg/1200px-SNice.svg.png"></div>
</div>
<script>
var canvas = document.createElement("canvas");
var width = innerWidth;
var height = innerHeight;
var ctx = canvas.getContext('2d');
canvas.width = width;
canvas.id = "canvas";
canvas.height = height;
ctx.fillStyle = "green";
ctx.fillRect(0,0, 50, 50);
ctx.fillRect(width / 2, height / 2, 50, 50);
window.onload = function () {
document.body.appendChild(canvas);
document.body.style.margin = "0";
document.body.style.overflow = "hidden";
};
canvas.onclick = function(){
alert("Canvas called, although it shouldn't");
}
var smile = document.getElementsByClassName("mainImg")[0];
smile.onclick = function(){
alert("i should be called");
}
</script>
I have an image which is centered upon the browser, and a canvas which is on absolute position, spreading across the entire screen. In regards to display, the canvas has display priority over the image, and that's how I want it to be because I am using some transperent parts of the canvas to display the image aswell.
The problem is the clicking priority: as you can see, when you click on the smiley image the canvas' click function gets called, since it spreads on the entire screen. but in terms of clicking priority, I want my image to be called. can it be done?
thank you for your time, I appreciate it.
Upvotes: 1
Views: 2797
Reputation: 87201
If you add pointer-events: none;
to your #canvas
rule, it will pass the click through to the image
Upvotes: 2
Reputation: 54069
The event can not bubble as you have the image and the canvas in separate unrelated elements. If you place the canvas in the same containing element as the image the click event will bubble from one to the next
Also you are best of using addEventListener
rather than directly assigning the event listener to the onclick
property.
In your HTML
<div class="everything">
<div class="mainImg" id="contain">
<img src="smile.png">
</div>
<!-- this is where the canvas will go -->
<div id="canvasContainer"></div> <!-- add this div to hold the canvas -->
</div>
Then when you add the canvas add it to the container, rather than the document.body
then add the event listeners.
window.onload = function () {
document.getElementById("canvasContainer").appendChild(canvas);
var smile = document.getElementsByClassName("mainImg")[0];
smile.addEventListener("click",imageEvent);
canvas.addEventListener("click",canvasEvent,true); // last arg true to capture the event (ie get it first)
};
When you do this and you want the canvas to get the event first you must set the event capture flag to true
.
canvas.addEventListener("click",canvasEvent,true); // last argument true
if you set it to false
canvas.addEventListener("click",canvasEvent,false); // last argument false
// or
canvas.addEventListener("click",canvasEvent); // or defaults to false
Then the image element (under the canvas) will get the event first.
The event listeners
function imageEvent(e){ alert("Image") } // not much to do
// the canvas event you need to either prevent the event bubbling
// or let it through depending on what your needs are.
function canvasEvent(e){
if( /*only for canvas */){
alert("Canvas handling it");
e.cancelBubble = true;
}else{
alert("Canvas is passing the event onto the image");
}
};
Upvotes: 1