jQuery 없이 상위 절대 DIV의 하위 요소를 호버링할 때 마우스 아웃 방지
에 문제가 있습니다.onmouseout
을 나누다마우스가 div의 하위 요소를 누르면 마우스 아웃 이벤트가 발생하지만 마우스가 부모인 절대 div에서 벗어날 때까지 실행되지 않도록 합니다.
할 수 요?mouseout
이벤트가 jquery 없이 하위 요소에 도달했을 때 발생하는 이벤트입니다.
이게 이벤트 버블링과 관련이 있다는 건 알지만, 이 문제를 해결할 방법이 없어요.
비슷한 게시물을 찾았습니다.하위 요소에 의해 트리거되는 마우스 아웃 이벤트를 비활성화하려면 어떻게 해야 합니다.
그러나 이 솔루션은 jQuery를 사용합니다.
onmouseleave
.
jQuery에서는 "jQuery를 사용합니다.mouseleave()
그것은 바로 당신이 찾고 있는 것입니다.예제:
<div class="outer" onmouseleave="yourFunction()">
<div class="inner">
</div>
</div>
또는 jQuery의 경우:
$(".outer").mouseleave(function(){
//your code here
});
여기 예가 있습니다.
대부분의 경우 동작하는 단순한 순수 CSS 솔루션에서는 다음과 같이 설정하여 어린이용 CSS를 제거할 수 있습니다.none
.parent * {
pointer-events: none;
}
브라우저 지원: IE11+
function onMouseOut(event) {
//this is the original element the event handler was assigned to
var e = event.toElement || event.relatedTarget;
if (e.parentNode == this || e == this) {
return;
}
alert('MouseOut');
// handle mouse event here!
}
document.getElementById('parent').addEventListener('mouseout',onMouseOut,true);
나는 모든 CSS와 HTML을 필요로 하는 JsFiddle 데모를 만들었다. 확인해봐...
크로스 사이트 지원용 EDIT FIXED 링크 http://jsfiddle.net/RH3tA/9/
이는 직계 부모만 검사하므로 부모 div에 중첩된 자녀가 있으면 어떻게든 부모 요소를 탐색하여 "Orginal 요소"를 찾아야 합니다.
중첩된 하위 항목에 대한 편집 예제
크로스 브라우저용 EDIT Fixed
function makeMouseOutFn(elem){
var list = traverseChildren(elem);
return function onMouseOut(event) {
var e = event.toElement || event.relatedTarget;
if (!!~list.indexOf(e)) {
return;
}
alert('MouseOut');
// handle mouse event here!
};
}
//using closure to cache all child elements
var parent = document.getElementById("parent");
parent.addEventListener('mouseout',makeMouseOutFn(parent),true);
//quick and dirty DFS children traversal,
function traverseChildren(elem){
var children = [];
var q = [];
q.push(elem);
while (q.length > 0) {
var elem = q.pop();
children.push(elem);
pushAll(elem.children);
}
function pushAll(elemArray){
for(var i=0; i < elemArray.length; i++) {
q.push(elemArray[i]);
}
}
return children;
}
새로운 JSFiddle, EDIT 업데이트 링크
onmouseout을 사용하는 대신 onmouseleave를 사용합니다.
아직 구체적인 코드를 보여주지 않았기 때문에 구체적인 예로는 보여줄 수 없습니다.
단, 매우 간단합니다.onmouseout을 onmouseleave로 대체하기만 하면 됩니다.
이상입니다:) 심플합니다.
방법을 모르는 경우는, 다음의 설명을 참조해 주세요.
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onmousemove_leave_out
케이크의 평화 :) 즐기세요 :)
아래 내용을 바탕으로 한 보다 우아한 솔루션을 소개합니다.그것은 한 단계 이상의 아이들로부터 일어나는 사건을 설명한다.또한 크로스 브라우저 문제도 해결됩니다.
function onMouseOut(this, event) {
//this is the original element the event handler was assigned to
var e = event.toElement || event.relatedTarget;
//check for all children levels (checking from bottom up)
while(e && e.parentNode && e.parentNode != window) {
if (e.parentNode == this|| e == this) {
if(e.preventDefault) e.preventDefault();
return false;
}
e = e.parentNode;
}
//Do something u need here
}
document.getElementById('parent').addEventListener('mouseout',onMouseOut,true);
jQuery를 사용하는 경우 이 모든 것을 처리하는 "마우스 탈퇴" 기능도 사용할 수 있습니다.
$('#thetargetdiv').mouseenter(do_something);
$('#thetargetdiv').mouseleave(do_something_else);
do_something은 마우스가 targetdiv 또는 그 자식 중 하나를 입력하면 호출되며 do_something_something은 마우스가 targetdiv 및 그 자식 중 하나에서 벗어날 때만 호출됩니다.
저에게 영감을 준 Amjad Masad 덕분입니다.
IE9, FF 및 Chrome에서 작동하는 것으로 보이는 다음과 같은 솔루션을 가지고 있으며, 코드는 매우 짧습니다(복잡한 폐쇄와 횡방향의 자작품이 없는 경우).
DIV.onmouseout=function(e){
// check and loop relatedTarget.parentNode
// ignore event triggered mouse overing any child element or leaving itself
var obj=e.relatedTarget;
while(obj!=null){
if(obj==this){
return;
}
obj=obj.parentNode;
}
// now perform the actual action you want to do only when mouse is leaving the DIV
}
Quirksmode는 필요한 모든 답변(브라우저 버블링 동작과 마우스 엔터/마우스 탈퇴 이벤트)을 가지고 있다고 생각합니다만, 이 이벤트의 버블링에 관한 가장 일반적인 결론은 JQuery나 Mootools와 같은 프레임워크(마우스 엔터 이벤트와 마우스 탈퇴 이벤트, 정확히 당신이 직감적으로 생각할 수 있는 것)를 사용하는 것이라고 생각합니다.
.
또는 이벤트 부분(및 그 종속성)만으로 커스텀 "평균" 버전의 Mootools를 생성할 수 있습니다.
★★를 해 보세요.mouseleave()
예:
<div id="parent" mouseleave="function">
<div id="child">
</div>
</div>
;)
아주 간단한 해결책을 찾았어요
onmouseleave="myfunc()" 이벤트보다 onmouseleave="myfunc()" 이벤트를 사용합니다.
내 코드로 작동했어!!
예제:
<html>
<head>
<script type="text/javascript">
function myFunc(){
document.getElementById('hide_div').style.display = 'none';
}
function ShowFunc(){
document.getElementById('hide_div').style.display = 'block';
}
</script>
</head>
<body>
<div onmouseleave="myFunc()" style='border:double;width:50%;height:50%;position:absolute;top:25%;left:25%;'>
Hover mouse here
<div id='child_div' style='border:solid;width:25%;height:25%;position:absolute;top:10%;left:10%;'>
CHILD <br/> It doesn't fires if you hover mouse over this child_div
</div>
</div>
<div id="hide_div" >TEXT</div>
<a href='#' onclick="ShowFunc()">Show "TEXT"</a>
</body>
</html>
마우스 아웃 기능을 사용한 동일한 예:
<html>
<head>
<script type="text/javascript">
function myFunc(){
document.getElementById('hide_div').style.display = 'none';
}
function ShowFunc(){
document.getElementById('hide_div').style.display = 'block';
}
</script>
</head>
<body>
<div onmouseout="myFunc()" style='border:double;width:50%;height:50%;position:absolute;top:25%;left:25%;'>
Hover mouse here
<div id='child_div' style='border:solid;width:25%;height:25%;position:absolute;top:10%;left:10%;'>
CHILD <br/> It fires if you hover mouse over this child_div
</div>
</div>
<div id="hide_div">TEXT</div>
<a href='#' onclick="ShowFunc()">Show "TEXT"</a>
</body>
</html>
도움이 되었으면 좋겠다:)
참조한 솔루션은 jquery를 사용하지만 mouseenter 및 mouseleave는 네이티브 dom 이벤트이므로 jquery 없이 사용할 수 있습니다.
이 문제를 해결하는 방법은 두 가지가 있습니다.
1) 콜백의 event.target 결과를 확인하여 부모 div와 일치하는지 확인합니다.
var g_ParentDiv;
function OnMouseOut(event) {
if (event.target != g_ParentDiv) {
return;
}
// handle mouse event here!
};
window.onload = function() {
g_ParentDiv = document.getElementById("parentdiv");
g_ParentDiv.onmouseout = OnMouseOut;
};
<div id="parentdiv">
<img src="childimage.jpg" id="childimg" />
</div>
2) 콜백 함수로 이벤트 캡처 및 콜이벤트.stopPropagation을 사용합니다.
var g_ParentDiv;
function OnMouseOut(event) {
event.stopPropagation(); // don't let the event recurse into children
// handle mouse event here!
};
window.onload = function() {
g_ParentDiv = document.getElementById("parentdiv");
g_ParentDiv.addEventListener("mouseout", OnMouseOut, true); // pass true to enable event capturing so parent gets event callback before children
};
<div id="parentdiv">
<img src="childimage.jpg" id="childimg" />
</div>
나는 이것을 마법처럼 작동시킨다:
function HideLayer(theEvent){
var MyDiv=document.getElementById('MyDiv');
if(MyDiv==(!theEvent?window.event:theEvent.target)){
MyDiv.style.display='none';
}
}
아, 아, 아, 아, 아, 아, 아, 아, 아, 아,MyDiv
을 사용하다
<div id="MyDiv" onmouseout="JavaScript: HideLayer(event);">
<!-- Here whatever divs, inputs, links, images, anything you want... -->
<div>
이렇게 해서 온마우스아웃이 아이, 손자, 손녀 등에게 돌아갈 때...style.display='none'
MyDiv 마우스 아웃, MyDiv.
전파를 정지하거나 타이머를 사용할 필요가 없습니다.
예를 들어 주셔서 감사합니다.그들로부터 이 코드를 만들 수 있었습니다.
이게 도움이 됐으면 좋겠네요.
다음과 같이 개선할 수도 있습니다.
function HideLayer(theLayer,theEvent){
if(theLayer==(!theEvent?window.event:theEvent.target)){
theLayer.style.display='none';
}
}
다음으로 DIV 태그는 다음과 같습니다.
<div onmouseout="JavaScript: HideLayer(this,event);">
<!-- Here whatever divs, inputs, links, images, anything you want... -->
<div>
더 이며, 'div'를 추가할 . "div" "div" "div"id="..."
각 층에 배치됩니다.
되어 있는 할 수 는, 「 」의 「 」를 참조해 .mouseout
방법, 방법, 방법, 방법, 방법, 방법, 방법을 사용할 수 .contains()
를 event.relatedTarget
자요소인지 아닌지를 나타냅니다.
~로event.relatedTarget
이치노자요소가아닌경우요소에서머징된요소입니다.
div.onmouseout = function (event) {
if (!div.contains(event.relatedTarget)) {
// moused out of div
}
}
Angular 5, 6, 7의 경우
<div (mouseout)="onMouseOut($event)"
(mouseenter)="onMouseEnter($event)"></div>
그럼...
import {Component,Renderer2} from '@angular/core';
...
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit, OnDestroy {
...
public targetElement: HTMLElement;
constructor(private _renderer: Renderer2) {
}
ngOnInit(): void {
}
ngOnDestroy(): void {
//Maybe reset the targetElement
}
public onMouseEnter(event): void {
this.targetElement = event.target || event.srcElement;
console.log('Mouse Enter', this.targetElement);
}
public onMouseOut(event): void {
const elementRelated = event.toElement || event.relatedTarget;
if (this.targetElement.contains(elementRelated)) {
return;
}
console.log('Mouse Out');
}
}
e.relatedTarget에 자녀 클래스가 있는지 확인하고 true일 경우 함수를 반환합니다.
if ($(e.relatedTarget).hasClass("ctrl-btn")){
return;
}
이것은 나에게 효과가 있는 코드입니다. 나는 html5 비디오 재생에 사용되었습니다.버튼의 호버 비디오 요소를 전환합니다.
element.on("mouseover mouseout", function(e) {
if(e.type === "mouseout"){
if ($(e.relatedTarget).hasClass("child-class")){
return;
}
}
});
원래 요소의 오프셋을 확인하여 요소 경계의 페이지 좌표를 가져온 다음 마우스 아웃이 해당 범위를 벗어났을 때만 마우스 아웃 작업이 트리거되는지 확인합니다.더럽지만 효과가 있다.
$(el).live('mouseout', function(event){
while(checkPosition(this, event)){
console.log("mouseovering including children")
}
console.log("moused out of the whole")
})
var checkPosition = function(el, event){
var position = $(el).offset()
var height = $(el).height()
var width = $(el).width()
if (event.pageY > position.top
|| event.pageY < (position.top + height)
|| event.pageX > position.left
|| event.pageX < (position.left + width)){
return true
}
}
var elem = $('#some-id');
elem.mouseover(function () {
// Some code here
}).mouseout(function (event) {
var e = event.toElement || event.relatedTarget;
if (elem.has(e).length > 0) return;
// Some code here
});
부모 요소에 CSS 클래스 또는 ID를 추가(또는 가지고 있는) 경우 다음과 같은 작업을 수행할 수 있습니다.
<div id="parent">
<div>
</div>
</div>
JavaScript:
document.getElementById("parent").onmouseout = function(e) {
e = e ? e : window.event //For IE
if(e.target.id == "parent") {
//Do your stuff
}
}
따라서 이벤트가 부모 div에 있을 때만 작업이 실행됩니다.
난 그냥 너와 뭔가를 나누고 싶었어.ng-mouseenter
★★★★★★★★★★★★★★★★★」ng-mouseleave
벤트입입니니다
도입 사례:
커서가 아이콘 위에 있으면 전환되는 플로팅 네비게이션 메뉴를 만들었습니다.
이 메뉴는 각 페이지의 맨 위에 있었다.
- 메뉴의 표시/숨김을 처리하기 위해 클래스를 전환합니다.
ng-class="{down: vm.isHover}"
- vm.isHover를 전환하려면 ng 마우스 이벤트를 사용합니다.
ng-mouseenter="vm.isHover = true"
ng-mouseleave="vm.isHover = false"
일단은 모든 것이 괜찮았고 예상대로 작동했다.
이치노
착신 문제:
을 사용법
커서가 목록의 요소 위에 있을 때 작업 패널을 추가했습니다.
위와 같은 코드를 사용하여 처리했습니다.
문제:
커서가 플로팅 네비게이션 메뉴에 있을 때와 엘리먼트 상단에 있을 때 서로 충돌하는 것을 알 수 있었습니다.
액션 패널이 표시되고 플로팅 내비게이션이 숨겨졌습니다.
문제는 커서가 플로팅 네비게이션 메뉴 위에 있어도 리스트 요소 ng-mouseenter가 트리거된다는 것입니다.
마우스 전파 이벤트가 자동으로 중단될 것으로 예상하기 때문에 이해가 안 됩니다.
저는 실망했고 그 문제를 알아내기 위해 시간을 좀 투자하고 있다고 말해야 합니다.
첫 번째 생각:
다음 항목을 사용하려고 했습니다.
$event.stopPropagation()
$event.stopImmediatePropagation()
포인터 이벤트(mouse move, mouveover 등)를 많이 조합했지만, 아무것도 도움이 되지 않습니다.
CSS 솔루션:
점점 더 많이 사용하는 단순한 css 속성을 가진 솔루션을 찾았습니다.
pointer-events: none;
기본적으로 (목록 요소에서) 다음과 같이 사용합니다.
ng-style="{'pointer-events': vm.isHover ? 'none' : ''}"
이 까다로운 기능을 사용하면 ng-mouse 이벤트가 더 이상 트리거되지 않으며 커서가 위에 있고 목록의 요소 위에 있을 때 내 플로팅 탐색 메뉴가 닫히지 않습니다.
더 나아가려면:
예상대로 이 솔루션은 효과가 있지만 저는 마음에 들지 않습니다.
우리는 우리의 이벤트를 통제하지 않고 그것은 나쁘다.
할 수 있다', '접근할 수 있다', '접근할 수 있다', '접근할 수 있다', '접근할 수 합니다.vm.isHover
가능하거나 불가능할 수도 있지만 어떤 식으로든 더럽힐 수도 있습니다.
누가 보고 싶으면 내가 바이올린을 켤 수 있어.
그럼에도 불구하고 다른 해결책이 없어요...
이야기가 길어서 감자를 줄 수 없으니 친구를 용서해 주세요.
어,는pointer-events: none
생이인
작동시킬 수 있는 간단한 방법이 있습니다.동일한 클래스 이름을 설정한 요소 및 모든 하위 항목:
element.onmouseover = function(event){
if (event.target.className == "name"){
/*code*/
}
}
바닐라즈도 그렇게 사용하실 수 있습니다.
document.querySelector('.product_items') && document.querySelector('.product_items').addEventListener('mouseleave', () => updateCart())
const updateCart = () => {
let total = 0;
document.querySelectorAll('input') && document.querySelectorAll('input').forEach(item => total += +item.value)
document.getElementById('total').innerHTML = total
}
<div class="product_items">
<div class="product_item">
<div class="product_name">
</div>
<div class="multiply__btn">
<button type="button">-</button>
<input name="test" type="text">
<button type="button">+</button>
</div>
</div>
<div class="product_item">
<div class="product_name">
</div>
<div class="multiply__btn">
<button type="button">-</button>
<input name="test" type="text">
<button type="button">+</button>
</div>
</div>
<div class="product_item">
<div class="product_name">
</div>
<div class="multiply__btn">
<button type="button">-</button>
<input name="test" type="text">
<button type="button">+</button>
</div>
</div>
</div>
<div id="total"></div>
mouseenter
★★★★★★★★★★★★★★★★★」mouseleave
라고 하면 '', '이벤트', '이벤트'를 사용할 수 있습니다mouseover
/mouseout
'무엇보다'
는 이벤트 핸들러가 이벤트 핸들러를 합니다.out
뒤이어 새로운 것이 있다over
~하다마우스가 실제로 떠난 경우(데바운스 기간보다 오래) 제외).이것은 모든 사건에서 돔 노드를 기어가는 것보다 간단해 보인다.
의 「Debounce」가 으로 「를 했을 .out
모든 할 수 있습니다.out
/over
아이 요소에서 부풀어 오르는 이벤트입니다.
참고! 하위 요소에도 다음 수신기가 있는 경우 이 기능은 작동하지 않습니다.over
"/"/"out
이벤트 및 그 핸들러 콜event.stopPropogation()
이벤트가 핸들러를 접속한 부모 요소에 버블하지 않도록 합니다.코드를 제어하고 있는 경우는, 반드시 문제가 되는 것은 아니지만, 주의해 주세요.
샘플 코드
자바스크립트
function mouseOverOutDebounce (element, debounceMs, mouseOverFn, mouseOutFn) {
var over = false,
debounceTimers = [];
function mouseOver (evt) {
if (over) { // already OVER, existing interaction
while (debounceTimers.length > 0) { // then we had a pending mouseout(s), cancel
window.clearTimeout(debounceTimers.shift());
}
}
else { // new OVER
over = true;
mouseOverFn(evt);
}
}
function mouseOut (evt) {
if (!over) return; // already OUT, ignore.
debounceTimers.push(window.setTimeout(function () {
over = false;
mouseOutFn(evt);
}, debounceMs));
}
function removeEventListeners () {
element.removeEventListener('mouseover', mouseOver);
element.removeEventListener('mouseout', mouseOut);
}
element.addEventListener('mouseover', mouseOver);
element.addEventListener('mouseout', mouseOut);
return removeEventListeners;
}
var someEl = document.querySelector('.container'),
textarea = document.querySelector('textarea'),
mouseOver = function (evt) { report('mouseOVER', evt); },
mouseOut = function (evt) { report('mouseOUT', evt); },
removeEventListeners = mouseOverOutDebounce(someEl, 200, mouseOver, mouseOut);
function report(msg, data) {
console.log(msg, data);
textarea.value = textarea.value + msg + '\n';
}
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
html, body {
margin: 0;
padding: 0;
}
body {
margin: 5%;
}
.container {
width: 300px;
height: 600px;
border: 10px solid red;
background-color: #dedede;
float: left;
}
.container .square {
width: 100px;
height: 100px;
background-color: #2086cf;
margin: -10px 0 0 -10px;
}
textarea {
margin-left: 50px;
width: 800px;
height: 400px;
background-color: #464646;
font-family: monospace;
color: white;
}
.bar {
width: 2px;
height: 30px;
display: inline-block;
margin-left: 2px;
background-color: pink;
}
</style>
</head>
<body>
<div class="container">
<div class="square"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</div>
<textarea></textarea>
<script src="interactions.js"></script>
</body>
</html>
만지작거리다
https://jsfiddle.net/matp/9bhjkLct/5/
언급URL : https://stackoverflow.com/questions/4697758/prevent-onmouseout-when-hovering-child-element-of-the-parent-absolute-div-withou
'programing' 카테고리의 다른 글
도커 응용 프로그램을 데이터베이스에 연결할 수 없습니다. (0) | 2022.10.22 |
---|---|
데이터베이스 사용자의 비밀번호를 한 번 설정하려면 어떻게 해야 합니까? (0) | 2022.10.22 |
Node.js에서 Python 함수를 호출하는 방법 (0) | 2022.10.22 |
if(expr) 대신 if(!(expr) 사용 (0) | 2022.10.22 |
Intelij Idea에서 사용되지 않는 모든 클래스를 찾으려면 어떻게 해야 합니까? (0) | 2022.10.22 |