Divs met klikevent achter elkaar
Mijn eerste vraag.
Als ik 2 divs heb die voor een groot gedeelte over elkaar staan en je klikt op de plek waar de divs over elkaar staan, hoe kun je dan met javascript een funtie laten uitvoeren als er op 2 divs tegelijk wordt geklikt?
Ik weet dat alleen de bovenste div zal meetellen, dus als je de bovenste div een onClick event geeft heeft dat niets met de onderliggene div te maken. (omdat de bovenliggende div eigenlijk een soort overlay is) Ik wil juist dat allebei de divs een onClick event hebben en dat als je op de plek klikt waar de divs elkaar overlappen, dat dan dus ook de 2 events worden uitgevoerd.
Als je op de plek klikt op de bovenliggende div, waar de andere div niet onder zit, dan wordt alleen het event uitgevoerd van de div die dus bovenligt.
En dan mijn tweede vraag.
Als je een afbeelding hebt, is deze altijd vierkant of rechthoekig. Als je bijvoorbeeld de achtergrond van een afbeelding doorzichtig maakt, dan lijkt het net alsof de afbeelding niet vierkant/rechthoekig is, maar de vorm heeft van wat er op de afbeelding staat.
Ik heb bijvoorbeeld een afbeelding van een bal, ik maak de achtergrond doorzichtig (onzichtbaar) en het lijkt dan net alsof de afbeelding rond is, maar dat is niet zo.
Nu heb ik op die afbeelding een onClick event, en als je dus op het onzichtbare gedeelte van de afbeelding klikt dan wordt dat event dus uitgevoerd. Ik wil dus dat het event alleen wordt uitgevoerd als je op het niet-onzichtbare gedaalte klikt.
Dit lijken me 2 moeilijke vragen. Ik vraag me af of deze twee problemen wel op te lossen zijn.
Gewijzigd op 26/12/2012 14:00:28 door Jan terhuijzen
area en map elementen.
1. leuke opgave, ik ga me er eens in verdiepen.
2. Dit doe je met 1. leuke opgave, ik ga me er eens in verdiepen.
Ik had idd al gedacht aan een soort image map.
Maar let op, nu komt het. het zijn 235 afbeeldingen! die haal ik uit de database. En er komen er op verschillened plekken op een pagina te staan. Mensen kunnen ze namelijk op hun profielpagina verslepen en ze opslaan. Dit is een groot probleem.
En in het element gooi je die area/map.
De posities van het klikbare zijn relatief, dus vanaf linksboven van de img.
Formaat van de afbeelding sla je ook op in je database.
En voor 235 afbeeldingen.... 235 area's maken dus.
Vraag 1: Als je niets beter weet ... je zou je eigen click event kunnen definiëren.
Je detecteert hover events (= mouseIn, mouseOut) en logt de toestand. Je houdt dus ergens een array bij
var mouseHoveringImages = Array(false, false, ....) en bij elke mouseIn of mouseOut wordt de toestand aangepast.
Dan detecteer je een click op window. Bij elke click zie je in de array welke items een true hebben (= de muis staat er over).
Vraag 2: Detecteer de kleur van de pixel waar je muis over staat. Daaruit moet je de transparante pixels kunnen weten.
Nu, twee bedenkingen:
- Gaat het om .gif of .png ? (ik moet nog eens nagaan hoe dat moet)
- Dat lijkt me vrij traag te gaan; je zou een goed systeem moeten vinden om dat op te vangen.
Nog een simpele vraag: zijn de images geroteerd?
----------
EDIT:
Oplossing vraag twee. Het werkt beter dan ik gedacht had. Bij mij ook super vlug (Nog niet IE proof).
Getest met "test.gif" en "test.png", beide met transparante delen
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script>
// @see (gebaseerd op) http://stackoverflow.com/questions/2878511/hit-detection-on-non-transparent-pixel
function pixelTransparant(img, e) {
// muiscordinaten opvangen
var x = e.clientX;
var y = e.clientY;
// tijdelijk <canvas> element genereren
var canvas = document.createElement("canvas"); //Create HTML5 canvas: supported in latest firefox/chrome/safari/konquerer. Support in IE9
canvas.width = img.width; //Set width of your rendertarget
canvas.height = img.height; // \ height \ \ \
var ctx = canvas.getContext("2d"); //Get the 2d context [the thing you draw on]
ctx.drawImage(img, 0, 0); //Draw the picture on it.
var id = ctx.getImageData(0,0, img.width, img.height); //Get the pixelData of image
//id.data[(y*width+x)*4+3] for the alpha value of pixel at x,y, 0->255
var width = canvas.width;
return (id.data[(y*width+x)*4+3]) === 0 ? true : false;
}
/*
* uiteraard kan je hier meer nuttige dingen doen dan de alert...
*/
function doSomething(img, e) {
if (pixelTransparant(img, e)) {
alert('transparant');
}
else {
alert('niet transparant');
}
}
</script>
<img onclick="doSomething(this, event)" src="test.gif">
<img onclick="doSomething(this, event)" src="test.png">
// @see (gebaseerd op) http://stackoverflow.com/questions/2878511/hit-detection-on-non-transparent-pixel
function pixelTransparant(img, e) {
// muiscordinaten opvangen
var x = e.clientX;
var y = e.clientY;
// tijdelijk <canvas> element genereren
var canvas = document.createElement("canvas"); //Create HTML5 canvas: supported in latest firefox/chrome/safari/konquerer. Support in IE9
canvas.width = img.width; //Set width of your rendertarget
canvas.height = img.height; // \ height \ \ \
var ctx = canvas.getContext("2d"); //Get the 2d context [the thing you draw on]
ctx.drawImage(img, 0, 0); //Draw the picture on it.
var id = ctx.getImageData(0,0, img.width, img.height); //Get the pixelData of image
//id.data[(y*width+x)*4+3] for the alpha value of pixel at x,y, 0->255
var width = canvas.width;
return (id.data[(y*width+x)*4+3]) === 0 ? true : false;
}
/*
* uiteraard kan je hier meer nuttige dingen doen dan de alert...
*/
function doSomething(img, e) {
if (pixelTransparant(img, e)) {
alert('transparant');
}
else {
alert('niet transparant');
}
}
</script>
<img onclick="doSomething(this, event)" src="test.gif">
<img onclick="doSomething(this, event)" src="test.png">
-----------
EDIT 2:
Ik denk dat ik heb wat je nodig hebt.
Ik heb het getest met transparante .gif 's.
Probeer dit eens uit (voorlopig letterlijk copy/pasten; enkel de src van de <img> aanpassen)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<style>
body {
background-color: #555555;
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
$(function() {
// cache elements
var images = $('#images img');
var container = $('#images');
var mouseHoveringImages = Array();
var length = images.length;
for (var i=0; i<length; i++) {
mouseHoveringImages[i] = false;
}
// events
container.click(function(e) {
var msg = '';
var length = images.length;
var hovering;
for (var i=0; i<length; i++) {
mouseHoveringImages[i] =
isHovering(images[i], e) // zien of de muis over de image staat
&& !pixelTransparant(images[i], e); // en over een pixel die niet transparant is
if (mouseHoveringImages[i]) {
msg += (msg === '' ? '' : ', ') + i.toString();
}
}
msg = 'Aan het Hoveren over: ' + msg;
document.getElementById('message').innerHTML = msg;
//alert(msg);
});
});
/*
* returns true: mouse is over the element; false: not...
* regardless if an other element is above the element
*/
function isHovering(elm, e) {
return (
(e.clientX >= elm.offsetLeft && e.clientX < (elm.offsetLeft + elm.clientWidth))
&&
(e.clientY >= elm.offsetTop && e.clientY < (elm.offsetTop + elm.clientHeight))
);
}
/*
* @see (gebaseerd op) http://stackoverflow.com/questions/2878511/hit-detection-on-non-transparent-pixel
* Houdt rekening met:
* e is de click event op de parent container ! De parent container heeft position: relative, de images hebben position: absolute
*/
function pixelTransparant(img, e) {
// muiscordinaten opvangen
var x = e.clientX - img.offsetLeft ;
var y = e.clientX - img.offsetTop ;
// tijdelijk <canvas> element genereren
var canvas = document.createElement("canvas"); //Create HTML5 canvas: supported in latest firefox/chrome/safari/konquerer. Support in IE9
canvas.width = img.width; //Set width of your rendertarget
canvas.height = img.height; // \ height \ \ \
var ctx = canvas.getContext("2d"); //Get the 2d context [the thing you draw on]
ctx.drawImage(img, 0, 0); //Draw the picture on it.
var id = ctx.getImageData(0,0, img.width, img.height); //Get the pixelData of image
//id.data[(y*width+x)*4+3] for the alpha value of pixel at x,y, 0->255
var width = canvas.width;
return (id.data[(y*width+x)*4+3]) === 0 ? true : false;
}
</script>
<style>
#images {
position: relative;
width: 100%;
}
#images img {
position: absolute;
}
#img000 {top: 20px; left: 50px;}
#img001 {top: 200px; left: 75px;}
#img002 {top: 40px; left: 300px;}
#img003 {top: 100px; left: 0px;}
</style>
<div id="message">messages from javascript ...</div>
<div id="images">
<img id="img000" src="test000.gif">
<img id="img001" src="test001.gif">
<img id="img002" src="test002.gif">
<img id="img003" src="test003.gif">
</div>
body {
background-color: #555555;
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
$(function() {
// cache elements
var images = $('#images img');
var container = $('#images');
var mouseHoveringImages = Array();
var length = images.length;
for (var i=0; i<length; i++) {
mouseHoveringImages[i] = false;
}
// events
container.click(function(e) {
var msg = '';
var length = images.length;
var hovering;
for (var i=0; i<length; i++) {
mouseHoveringImages[i] =
isHovering(images[i], e) // zien of de muis over de image staat
&& !pixelTransparant(images[i], e); // en over een pixel die niet transparant is
if (mouseHoveringImages[i]) {
msg += (msg === '' ? '' : ', ') + i.toString();
}
}
msg = 'Aan het Hoveren over: ' + msg;
document.getElementById('message').innerHTML = msg;
//alert(msg);
});
});
/*
* returns true: mouse is over the element; false: not...
* regardless if an other element is above the element
*/
function isHovering(elm, e) {
return (
(e.clientX >= elm.offsetLeft && e.clientX < (elm.offsetLeft + elm.clientWidth))
&&
(e.clientY >= elm.offsetTop && e.clientY < (elm.offsetTop + elm.clientHeight))
);
}
/*
* @see (gebaseerd op) http://stackoverflow.com/questions/2878511/hit-detection-on-non-transparent-pixel
* Houdt rekening met:
* e is de click event op de parent container ! De parent container heeft position: relative, de images hebben position: absolute
*/
function pixelTransparant(img, e) {
// muiscordinaten opvangen
var x = e.clientX - img.offsetLeft ;
var y = e.clientX - img.offsetTop ;
// tijdelijk <canvas> element genereren
var canvas = document.createElement("canvas"); //Create HTML5 canvas: supported in latest firefox/chrome/safari/konquerer. Support in IE9
canvas.width = img.width; //Set width of your rendertarget
canvas.height = img.height; // \ height \ \ \
var ctx = canvas.getContext("2d"); //Get the 2d context [the thing you draw on]
ctx.drawImage(img, 0, 0); //Draw the picture on it.
var id = ctx.getImageData(0,0, img.width, img.height); //Get the pixelData of image
//id.data[(y*width+x)*4+3] for the alpha value of pixel at x,y, 0->255
var width = canvas.width;
return (id.data[(y*width+x)*4+3]) === 0 ? true : false;
}
</script>
<style>
#images {
position: relative;
width: 100%;
}
#images img {
position: absolute;
}
#img000 {top: 20px; left: 50px;}
#img001 {top: 200px; left: 75px;}
#img002 {top: 40px; left: 300px;}
#img003 {top: 100px; left: 0px;}
</style>
<div id="message">messages from javascript ...</div>
<div id="images">
<img id="img000" src="test000.gif">
<img id="img001" src="test001.gif">
<img id="img002" src="test002.gif">
<img id="img003" src="test003.gif">
</div>
Gewijzigd op 27/12/2012 15:05:36 door Kris Peeters