2011-01-11 2 views
26

Предположим, у меня есть один div на моей странице. как определить, как пользователь нажимает на содержимое div или вне содержимого div через JavaScript или JQuery. пожалуйста, помогите с небольшим фрагментом кода. спасибо.Обнаружение щелчка внутри/вне элемента с помощью одного обработчика событий

Редактировать: Как указано в одном из приведенных ниже ответов, я хочу только привязать обработчик событий к своему телу, а также узнать, на какой элемент был нажат.

ответ

63

В JavaScript (с помощью 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

Nice. Ваше использование 'parents()' вдохновило меня на обновление моего ответа, чтобы использовать больше 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'); 
    }); 
}); 

Edit: Для одного обработчика:

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

спасибо за ваши усилия, но я хочу его по-разному.Я хочу захватить идентификатор элемента, где произошел щелчок, и я хочу обрабатывать его на уровне тела, не хочу присоединять обработчик события click с div. – Thomas

+0

, если я нажимаю на #foo, который также запускает обработчики тела, потому что foo находится внутри тела. – 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, используя Google.)

+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

Вот один вкладыш, который не требует использования JQuery Node.contains:

// 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'); 
    } 
}); 

Если вы задаетесь вопросом о ребре случае проверки, если щелчок на element, Node.contains возвращает true для самого элемента (например, element.contains(element) === true), поэтому этот фрагмент должен всегда работать.

Поддержка браузера, похоже, охватывает почти все, что соответствует этой странице MDN.

0

Этот вопрос может быть решен с координатами х и у и без 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'))) 
     }); 
Смежные вопросы