[javascript] 의사 요소에서 클릭 이벤트 만 감지

내 코드는 다음과 같습니다

p {
    position: relative;
    background-color: blue;
}

p:before {
    content: '';
    position: absolute;
    left:100%;
    width: 10px;
    height: 100%;
    background-color: red;
}

이 바이올린을 참조하십시오 : http://jsfiddle.net/ZWw3Z/5/

의사 요소 (빨간색 비트)에서만 클릭 이벤트를 트리거하고 싶습니다. 즉, 클릭 이벤트가 파란색 비트에서 트리거되는 것을 원하지 않습니다.



답변

이건 불가능 해; 의사 요소는 DOM의 일부가 아니므로 이벤트를 직접 바인딩 할 수 없으며 부모 요소에만 바인딩 할 수 있습니다.

빨간색 영역에만 클릭 핸들러가 있어야하는 경우, 같은 하위 요소를 span시작 <p>태그 바로 뒤에 배치하고 스타일 p span대신 스타일을 적용한 다음 p:before바인딩해야합니다.


답변

실제로 가능합니다. 클릭 한 위치가 요소 외부에 있는지 확인할 수 있습니다 . ::before또는 ::after클릭 한 경우에만 발생하기 때문 입니다.

이 예제는 오른쪽의 요소 만 확인하지만 귀하의 경우에는 효과가 있습니다.

span = document.querySelector('span');

span.addEventListener('click', function (e) {
    if (e.offsetX > span.offsetWidth) {
        span.className = 'c2';
    } else {
        span.className = 'c1';
    }
});
div { margin: 20px; }
span:after { content: 'AFTER'; position: absolute; }

span.c1 { background: yellow; }
span.c2:after { background: yellow; }
<div><span>ELEMENT</span></div>

JSFiddle


답변

최신 브라우저 당신은 포인터 이벤트 CSS 속성을 시도 할 수 있습니다 (하지만 부모 노드에서 마우스 이벤트를 감지하기 위해 불가능에 이르게) :

p {
    position: relative;
    background-color: blue;
    color:#ffffff;
    padding:0px 10px;
    pointer-events:none;
}
p::before {
    content: attr(data-before);
    margin-left:-10px;
    margin-right:10px;
    position: relative;
    background-color: red;
    padding:0px 10px;
    pointer-events:auto;
}

이벤트 대상이 “p”요소 인 경우 “p : before”임을 알 수 있습니다.

여전히 메인 p에서 마우스 이벤트를 감지해야하는 경우 HTML 구조를 수정할 가능성을 고려할 수 있습니다. 스팬 태그와 다음 스타일을 추가 할 수 있습니다 .

p span {
    background:#393;
    padding:0px 10px;
    pointer-events:auto;
}

이벤트 대상은 이제 “span”및 “p : before”요소입니다.

jquery가없는 예 : http://jsfiddle.net/2nsptvcu/

jquery를 사용한 예 : http://jsfiddle.net/0vygmnnb/

다음은 포인터 이벤트를 지원하는 브라우저 목록입니다. http://caniuse.com/#feat=pointer-events


답변

내 답변은 페이지의 결정적인 영역을 클릭하려는 사람에게 효과적입니다. 이것은 내 절대 위치 에 대해 나를 위해 일했습니다 : after

기사 덕분에 (jQuery를 사용 e.pageY하여 ) 브라우저간에 e.pageX걱정 e.offsetY/X하고 e.clientY/X문제 대신 사용할 수 있음을 깨달았습니다 .

시행 착오를 통해 jQuery 이벤트 객체에서 clientX 및 clientY 마우스 좌표를 사용하기 시작했습니다. 이 좌표는 브라우저보기 포트의 왼쪽 상단 모서리를 기준으로 마우스의 X 및 Y 오프셋을 나타냅니다. 그러나 Karl Swedberg와 Jonathan Chaffer의 jQuery 1.4 Reference Guide를 읽을 때 종종 pageX 및 pageY 좌표를 참조하는 것을 보았습니다. 업데이트 된 jQuery 문서를 확인한 후 이것이 jQuery에 의해 표준화 된 좌표임을 알 수있었습니다. 그리고 그들은 그들이 전체 문서 (보기 포트뿐만 아니라)에 대해 마우스의 X 및 Y 오프셋을 나에게주는 것을 보았습니다.

event.pageY아이디어 는 문서 와 관련 이 있기 때문에 항상 동일하기 때문에 좋아했습니다 . 오프셋을 사용하여 내 : after의 부모 요소와 비교할 수 있습니다 .offset ()을 사용하면 문서와 관련된 X 및 Y도 반환합니다.

따라서 전체 페이지에서 변하지 않는 “클릭 가능한”영역 범위를 만들 수 있습니다.


다음 은 codepen에 대한 데모입니다 .


또는 codepen에 너무 게으른 경우 JS는 다음과 같습니다.

* 예제의 Y 값만 고려했습니다.

var box = $('.box');
// clickable range - never changes
var max = box.offset().top + box.outerHeight();
var min = max - 30; // 30 is the height of the :after

var checkRange = function(y) {
  return (y >= min && y <= max);
}

box.click(function(e){
  if ( checkRange(e.pageY) ) {
    // do click action
    box.toggleClass('toggle');
  }
});


답변

이것은 나를 위해 작동합니다 :

$('#element').click(function (e) {
        if (e.offsetX > e.target.offsetLeft) {
            // click on element
        }
         else{
           // click on ::before element
       }
});


답변

짧은 답변:

내가 해냈어 나는 모든 작은 사람들을위한 동적 사용법을 작성했습니다 …

페이지에 표시되는 작업 예

콘솔에 작업 예제 로깅

긴 답변 :

… 아직 해냈습니다.

psuedo 요소가 실제로 페이지에 없기 때문에 시간이 좀 걸렸습니다. 위의 답변 중 일부는 일부 시나리오에서 작동하지만 요소가 크기와 위치가 예기치 않은 시나리오 (모체 요소의 일부를 오버레이하는 절대 위치 요소와 같은)에서는 모두 동적이 아니며 작동하지 않습니다. 광산은 그렇지 않습니다.

용법:

//some element selector and a click event...plain js works here too
$("div").click(function() {
    //returns an object {before: true/false, after: true/false}
    psuedoClick(this);

    //returns true/false
    psuedoClick(this).before;

    //returns true/false
    psuedoClick(this).after;

});

작동 방식 :

부모 요소의 높이, 너비, 상단 및 왼쪽 위치 (창 가장자리에서 떨어진 위치를 기준으로)를 가져오고 부모 컨테이너의 가장자리를 기준으로 높이, 너비, 상단 및 왼쪽 위치를 가져옵니다 ) 및 해당 값을 비교하여 psuedo 요소가 화면에서 어디에 있는지 판별합니다.

그런 다음 마우스 위치를 비교합니다. 마우스가 새로 작성된 변수 범위에 있으면 true를 리턴합니다.

노트 :

부모 요소를 상대적으로 배치하는 것이 좋습니다. 절대 위치가 지정된 psuedo 요소가있는 경우이 기능은 부모의 치수를 기준으로 배치 된 경우에만 작동합니다 (따라서 부모는 상대적이어야합니다 … 끈적이거나 고정되어있을 수도 있습니다 …. 모르겠습니다).

암호:

function psuedoClick(parentElem) {

    var beforeClicked,
      afterClicked;

  var parentLeft = parseInt(parentElem.getBoundingClientRect().left, 10),
      parentTop = parseInt(parentElem.getBoundingClientRect().top, 10);

  var parentWidth = parseInt(window.getComputedStyle(parentElem).width, 10),
      parentHeight = parseInt(window.getComputedStyle(parentElem).height, 10);

  var before = window.getComputedStyle(parentElem, ':before');

  var beforeStart = parentLeft + (parseInt(before.getPropertyValue("left"), 10)),
      beforeEnd = beforeStart + parseInt(before.width, 10);

  var beforeYStart = parentTop + (parseInt(before.getPropertyValue("top"), 10)),
      beforeYEnd = beforeYStart + parseInt(before.height, 10);

  var after = window.getComputedStyle(parentElem, ':after');

  var afterStart = parentLeft + (parseInt(after.getPropertyValue("left"), 10)),
      afterEnd = afterStart + parseInt(after.width, 10);

  var afterYStart = parentTop + (parseInt(after.getPropertyValue("top"), 10)),
      afterYEnd = afterYStart + parseInt(after.height, 10);

  var mouseX = event.clientX,
      mouseY = event.clientY;

  beforeClicked = (mouseX >= beforeStart && mouseX <= beforeEnd && mouseY >= beforeYStart && mouseY <= beforeYEnd ? true : false);

  afterClicked = (mouseX >= afterStart && mouseX <= afterEnd && mouseY >= afterYStart && mouseY <= afterYEnd ? true : false);

  return {
    "before" : beforeClicked,
    "after"  : afterClicked

  };

}

지원하다:

나는 모른다 …. 그것은 바보처럼 보이고 때로는 계산 된 값으로 자동을 반환하는 것을 좋아합니다. 치수가 CSS로 설정된 경우 모든 브라우저에서 잘 작동하는 것으로 보입니다. 따라서 … psuedo 요소의 높이와 너비를 설정하고 위쪽과 왼쪽으로 만 이동하십시오. 나는 그것이 작동하지 않는 괜찮은 것들에 그것을 사용하는 것이 좋습니다. 애니메이션이나 무언가처럼. Chrome은 평소와 같이 작동합니다.


답변

클릭 가능 영역을 제한하려면 클릭 이벤트에 조건을 추가하십시오.

    $('#thing').click(function(e) {
       if (e.clientX > $(this).offset().left + 90 &&
             e.clientY < $(this).offset().top + 10) {
                 // action when clicking on after-element
                 // your code here
       }
     });

데모