Jump to content
  • 0

click fallthrough


cy6erGn0m
 Share

Question

Собственно проблема в том, что если один див закрывает собой другой, то даже если у него нет фона, то click мыши не проходит в тот див, что ниже, хотя body.onclick срабатывает.

Код иллюстрирует проблему:

<html>
<head>
<style type="text/css">
.reddiv {
position: absolute;
left: 200px;
top: 200px;
background-color: red;
width: 150px;
height: 150px;
z-index: 1;
}
.bdiv {
position: absolute;
left: 150px;
top: 150px;
width: 250px;
height: 250px;
border: 1px dotted orange;
z-index: 2;

text-align: center;
color: white;
}
.bdiv .holdplace {
height: 50%;
}
</style>
</head>
<body>
<div class="reddiv" onclick="alert('hello');">
AA
</div>
<div class="bdiv">
<div class="holdplace"></div>
BB
</div>
</body>
</html>

Можно ли обойти ограничение и заставить срабатывать onclick у красного дива?

Проблема воспроизводится в FF и в Konqueror. IE можно игнорировать в моём случае (не target).

Link to comment
Share on other sites

7 answers to this question

Recommended Posts

  • 0

Можно ли обойти ограничение и заставить срабатывать onclick у красного дива?

Проблема воспроизводится в FF и в Konqueror. IE можно игнорировать в моём случае (не target).

Нет, нельзя.

Это не проблема, а правильно поведение браузера. Почитай про z-index;

Link to comment
Share on other sites

  • 0

Может и правильное, однако с тем что это не проблема - не соглашусь. Единственный способ обойти этот идотизм - это сделать bdiv маленького размера, сделать его inline и сдвинуть его так чтобы он оказался над красным. Однако это уродливо и имеет серьёзное ограничение: содержимое bdiv должно быть как можно более маленьким.

Edited by cy6erGn0m
Link to comment
Share on other sites

  • 0
Может и правильное, однако с тем что это не проблема - не соглашусь. Единственный способ обойти этот идотизм - это сделать bdiv маленького размера, сделать его inline и сдвинуть его так чтобы он оказался над красным. Однако это уродливо и имеет серьёзное ограничение: содержимое bdiv должно быть как можно более маленьким.

Тогда ты сам придумал решение.

Link to comment
Share on other sites

  • 0

Решение-то придумал, но оно дурацкое как я думаю. Это только частичное решение, так как если не дай бог понадобиться засунуть в bdiv больше чем мелкую надпись, то решение перестанет быть достаточным.

Link to comment
Share on other sites

  • 0
Решение-то придумал, но оно дурацкое как я думаю. Это только частичное решение, так как если не дай бог понадобиться засунуть в bdiv больше чем мелкую надпись, то решение перестанет быть достаточным.

Согласен.

Link to comment
Share on other sites

  • 0

Нашёл ещё решение. Не слишком шикарное, но зато всегда работает. Основная идея - ручная маршрутизация событий. На черновую это выглядит примерно так. Ясно что нужны ещё доработки чтобы работало в разных браузерах, но пока в FF3.6 и в Konqueror сработало.

<html>
<head>
<style type="text/css">
.reddiv {
position: absolute;
left: 200px;
top: 200px;
background-color: red;
width: 150px;
height: 150px;
z-index: 1;
}
.bdiv {
position: absolute;
left: 150px;
top: 150px;
width: 250px;
height: 250px;
border: 1px dotted orange;
z-index: 2;

text-align: center;
color: white;
}
.bdiv .holdplace {
height: 50%;
}
</style>
<script type="text/javascript">
$ = function(id) {
return document.getElementById(id);
};
getDivs = function() {
return document.getElementsByTagName('div');
};
getAbsoluteTop = function(element) {
var top = 0;
var node = element;
do {
top += node.offsetTop;
node = node.offsetParent;
} while(node);
return top;
};
getAbsoluteLeft = function(element) {
var left = 0;
var node = element;
do {
left += node.offsetLeft;
node = node.offsetParent;
} while(node);
return left;
};
getEventTarget = function(e) {
return e.target || e.srcElement;
};
isIntoDiv = function(x, y, div) {
var left = getAbsoluteLeft(div);
if( x < left || x > (left + div.offsetWidth) ) {
return false;
}
var top = getAbsoluteTop(div);
if( y < top || y > (top + div.offsetHeight) ) {
return false;
}
return true;
};
routeClick = function(e, div) {
if(div.onclick) {
div.onclick.call(div, e);
}
};
bodyClick = function(e) {
if(isIntoDiv(e.pageX, e.pageY, $('baddiv'))) {
for( var divs = getDivs(), i = 0, m = divs.length; i < m; ++i ) {
var div = divs[i];
if(div.className != 'bdiv') {
if(isIntoDiv(e.pageX, e.pageY, div)) {
routeClick(e, div);
}
}
}
}
};
reactLoad = function() {
document.body.onclick = bodyClick;
};
</script>
</head>
<body onload="reactLoad();">
<div id="reddiv" class="reddiv" onclick="alert('hello');">
AA
</div>
<div id="baddiv" class="bdiv">
<div class="holdplace"></div>
BB
</div>
</body>
</html>

Очевидно, что routeClick должна быть хитрее и заполнять объект event правильными значениями, но это за кадром. Главное - идея в данном случае.

Edited by cy6erGn0m
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy