2011-01-11 5 views
26

내 페이지에 div가 하나 있다고 가정합니다. 사용자가 div 또는 JavaScript 또는 JQuery를 통해 div 콘텐츠 외부를 클릭하는 것을 감지하는 방법. 작은 코드 스 니펫으로 도와주세요. 덕분에 .단일 이벤트 핸들러로 요소의 안쪽/바깥 쪽 클릭 감지

편집 : 아래 답변 중 하나에서 언급했듯이 이벤트 처리기를 본문에 연결하고 클릭 한 요소를 알고 싶을뿐입니다.

답변

63

자바 스크립트 (jQuery를 통해) :

$(function() { 
 
    $("body").click(function(e) { 
 
    if (e.target.id == "myDiv" || $(e.target).parents("#myDiv").length) { 
 
     alert("Inside div"); 
 
    } else { 
 
     alert("Outside div"); 
 
    } 
 
    }); 
 
})
#myDiv { 
 
    background: #ff0000; 
 
    width: 25vw; 
 
    height: 25vh; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="myDiv"></div>

+4

이렇게하면 사용자가 div의 하위 항목을 클릭하는 경우는 처리되지 않습니다. 그것은 ""div 외부에보고 할 것입니다. – Phrogz

+0

니스. 부모님()을 사용하면 더 많은 jQuery를 사용하고 이전 학교 순회를 덜 사용하도록 내 답변을 업데이트 할 수있었습니다. – Phrogz

+0

div가 아닌 stopPropagation을 사용하는 요소가있는 경우에는 작동하지 않습니다. 여기의 예제를 참조하십시오. http://jsfiddle.net/Flandre/YdrTA/ – Andre

12

jQuery를 사용하여, 당신은 <div id="foo">을 가지고 있다고 가정 :

jQuery(function($){ 
    $('#foo').click(function(e){ 
    console.log('clicked on div'); 
    e.stopPropagation(); // Prevent bubbling 
    }); 
    $('body').click(function(e){ 
    console.log('clicked outside of div'); 
    }); 
}); 

편집 :이 약

jQuery(function($){ 
    $('body').click(function(e){ 
    var clickedOn = $(e.target); 
    if (clickedOn.parents().andSelf().is('#foo')){ 
     console.log("Clicked on", clickedOn[0], "inside the div"); 
    }else{ 
     console.log("Clicked outside the div"); 
    }); 
}); 
+0

감사하지만 난 다른 방식으로 원하는 : – Thomas

+0

foo가 본문 내부에 있기 때문에 #foo를 클릭하면 body 핸들러가 트리거됩니다. – amosrivera

+0

@amosrivera 아니요, 'stopPropagation'을 호출하면 거품이 생기지 않으므로 그렇지 않습니다. 여기에서 직접 테스트 할 수 있습니다. http://jsfiddle.net/Qh2MN/ – Phrogz

4

무엇을 : 하나의 핸들러?

<style type="text/css"> 
div {border: 1px solid red; color: black; background-color: #9999DD; 
width: 20em; height: 40em;} 
</style> 

<script type="text/javascript"> 
function sayLoc(e) { 
e = e || window.event; 
var tgt = e.target || e.srcElement; 

// Get top lef co-ords of div 
var divX = findPosX(tgt); 
var divY = findPosY(tgt); 

// Workout if page has been scrolled 
var pXo = getPXoffset(); 
var pYo = getPYoffset(); 

// Subtract div co-ords from event co-ords 
var clickX = e.clientX - divX + pXo; 
var clickY = e.clientY - divY + pYo; 

alert('Co-ords within div (x, y): ' 
+ clickX + ', ' + clickY); 
} 

function findPosX(obj) { 
var curleft = 0; 
if (obj.offsetParent) { 
while (obj.offsetParent) { 
curleft += obj.offsetLeft 
obj = obj.offsetParent; 
} 
} else if (obj.x) { 
curleft += obj.x; 
} 
return curleft; 
} 

function findPosY(obj) { 
var curtop = 0; 
if (obj.offsetParent) { 
while (obj.offsetParent) { 
curtop += obj.offsetTop 
obj = obj.offsetParent; 
} 
} else if (obj.y) { 
curtop += obj.y; 
} 
return curtop; 
} 

function getPXoffset(){ 
if (self.pageXOffset) { // all except Explorer 
return self.pageXOffset; 
} else if (document.documentElement 
&& document.documentElement.scrollTop) {// Explorer 6 Strict 
return document.documentElement.scrollLeft; 
} else if (document.body) { // all other Explorers 
return document.body.scrollLeft; 
} 
} 

function getPYoffset(){ 
if (self.pageYOffset) { // all except Explorer 
return self.pageYOffset; 
} else if (document.documentElement 
&& document.documentElement.scrollTop) {// Explorer 6 Strict 
return document.documentElement.scrollTop; 
} else if (document.body) { // all other Explorers 
return document.body.scrollTop; 
} 
} 
</script> 

<div onclick="sayLoc(event);"></div> 

(구글을 사용하여, http://bytes.com/topic/javascript/answers/151689-detect-click-inside-div-mozilla에서.)

+1

이것은 한 줄로 처리 할 수있는 코드에 대한 미친 양입니다. http://stackoverflow.com/a/28432139/288906 –

-1

대신 당신이 커튼을 만들 수 몸을 사용하여 z-index이 100 (숫자 선택)이고 내부 요소의 값이 더 높으므로 z-index 인 반면에 r 요소는 커튼보다 z- 색인이 낮습니다. 여기

참조 작업 예 : http://jsfiddle.net/Flandre/6JvFk/

jQuery를 :

$('#curtain').on("click", function(e) { 

    $(this).hide(); 
    alert("clicked ouside of elements that stand out"); 

}); 

CSS :

.aboveCurtain 
{ 
    z-index: 200; /* has to have a higher index than the curtain */ 
    position: relative; 
    background-color: pink; 
} 

#curtain 
{ 
    position: fixed; 
    top: 0px; 
    left: 0px; 
    height: 100%; 
    background-color: black; 
    width: 100%; 
    z-index:100; 
    opacity:0.5 /* change opacity to 0 to make it a true glass effect */ 
} 
7

오히려 (허용 대답에 제안대로) jQuery를 .parents 기능을 사용하는 것보다, 그것은 더 나은 이 목적으로 .closest을 사용하십시오. explained in the jQuery api docs으로 .closest은 전달 된 요소와 모든 부모를 검사하지만 .parents은 부모를 검사합니다. 은 결과적으로,이 작품 :

여기
$(function() { 
    $("body").click(function(e) { 
     if ($(e.target).closest("#myDiv").length) { 
      alert("Clicked inside #myDiv"); 
     } else { 
      alert("Clicked outside #myDiv"); 
     } 
    }); 
}) 
22

Node.contains를 사용하여 JQuery와 필요로하지 않는 한 라이너입니다 :

// Get arbitrary element with id "my-element" 
var myElementToCheckIfClicksAreInsideOf = document.querySelector('#my-element'); 
// Listen for click events on body 
document.body.addEventListener('click', function (event) { 
    if (myElementToCheckIfClicksAreInsideOf.contains(event.target)) { 
     console.log('clicked inside'); 
    } else { 
     console.log('clicked outside'); 
    } 
}); 

클릭이에있는 경우 검사의 가장자리 사건에 대해 궁금해하는 경우 요소 자체에 대해 Node.contains는 요소 자체 (예 : element.contains(element) === true)에 대해 true를 반환하므로이 스 니펫이 항상 작동해야합니다.

브라우저 지원은 해당 MDN 페이지에 따라 거의 모든 것을 커버하는 것으로 보입니다. 당신의 노력

 var isPointerEventInsideElement = function (event, element) { 
      var pos = { 
       x: event.targetTouches ? event.targetTouches[0].pageX : event.pageX, 
       y: event.targetTouches ? event.targetTouches[0].pageY : event.pageY 
      }; 
      var rect = element.getBoundingClientRect(); 
      return pos.x < rect.right && pos.x > rect.left && pos.y < rect.bottom && pos.y > rect.top; 
     }; 

     document.querySelector('#my-element').addEventListener('click', function (event) { 
      console.log(isPointerEventInsideElement(event, document.querySelector('#my-any-child-element'))) 
     }); 
0

이 질문에

JQuery와 X와 Y 좌표 및없이 답변을 얻을 수 있습니다.클릭이 발생한 곳에서 요소 ID를 캡처하고 body 수준에서 div로 클릭 이벤트 처리기를 연결하지 않으려 고합니다.
관련 문제