2011-01-11 21 views
26

Załóżmy, że mam jedną jednostkę div na mojej stronie. jak wykryć użytkownika kliknij na zawartość div lub poza zawartość div za pomocą JavaScript lub JQuery. pomóż z małym fragmentem kodu. dzięki.Wykryj kliknięcie wewnątrz/na zewnątrz elementu za pomocą pojedynczej procedury obsługi zdarzenia

Edycja: Jak skomentowałem w jednej z poniższych odpowiedzi, chcę tylko dołączyć do mojego ciała obsługę zdarzeń, a także chcę wiedzieć, który element został kliknięty.

Odpowiedz

63

W JavaScript (przez 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

Nie zajmie się przypadkami, w których użytkownik kliknie na dziecko div; zgłasza '' poza div "'. – Phrogz

+0

Nice. Twoje użycie 'parent()' zainspirowało mnie do zaktualizowania mojej odpowiedzi, aby użyć więcej jQuery i mniej old-schoolowego przejścia. – Phrogz

+0

To nie zadziała, jeśli istnieją elementy poza elementem div, które używają metody stopPropagation, zobacz przykład: http://jsfiddle.net/Flandre/YdrTA/ – Andre

12

jQuery, i zakładając, że masz <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'); 
    }); 
}); 

Edit: Dla pojedynczego Handler:

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

podziękować za wysiłek, ale chcę go w inny sposób.Chcę przechwycić identyfikator elementu, w którym nastąpiło kliknięcie i chcę go obsłużyć na poziomie treści, ale nie chcę dołączać obsługi zdarzeń kliknięcia za pomocą elementu div. – Thomas

+0

jeśli kliknę na #foo, które również uruchamia procedury obsługi ciała, ponieważ foo znajduje się wewnątrz ciała – amosrivera

+0

@amosrivera Nie, nie robi tego, ponieważ wywołanie 'stopPropagation' zapobiega jej bulgotaniu. Możesz to sprawdzić tutaj: http://jsfiddle.net/Qh2MN/ – Phrogz

4

Co na ten temat?

<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> 

(od http://bytes.com/topic/javascript/answers/151689-detect-click-inside-div-mozilla, korzystając z Google.)

+1

To szalona ilość kodu dla czegoś, co można teraz zrobić w jednym wierszu: http://stackoverflow.com/a/28432139/288906 –

-1

zamiast używania ciało można stworzyć zasłonę z z-index z 100 (aby wybrać liczbę) i nadaj elementowi wewnętrznemu wyższy z-index, a wszystkie inne r elementy mają niższy indeks Z niż kurtyna.

patrz przykład pracuje tutaj: 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

Zamiast używać funkcji jQuery .parents (jak zasugerowano w przyjętym odpowiedź), to lepiej do użycia w tym celu .closest. Jako explained in the jQuery api docs, .closest sprawdza przekazany element i wszystkich jego rodziców, podczas gdy .parents sprawdza tylko rodziców. W związku z tym prace:

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

Oto jeden liner, który nie wymaga korzystania 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'); 
    } 
}); 

Jeśli zastanawiasz się o sprawie krawędziowej sprawdzenie, czy kliknięcie na sam element, Node.contains zwraca true dla samego elementu (np. element.contains(element) === true), więc ten fragment powinien zawsze działać.

Obsługa przeglądarki wydaje się obejmować prawie wszystko zgodnie z tą stroną MDN.

0

To pytanie można odpowiedzieć współrzędne X i Y i bez JQuery:

 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'))) 
     }); 
Powiązane problemy