Javascript 仅检测伪元素上的单击事件

Javascript 仅检测伪元素上的单击事件,javascript,jquery,css,Javascript,Jquery,Css,请看这把小提琴: 我的代码是: p{ 位置:相对位置; 背景颜色:蓝色; } p:以前{ 内容:''; 位置:绝对位置; 左:100%; 宽度:10px; 身高:100%; 背景色:红色; } Lorem ipsum door sit amet,继续成为精英。埃尼安·康莫多·利古拉·埃吉特·多洛。埃尼安·马萨。在自然社会中,因怀孕而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特

请看这把小提琴:

我的代码是:

p{
位置:相对位置;
背景颜色:蓝色;
}
p:以前{
内容:'';
位置:绝对位置;
左:100%;
宽度:10px;
身高:100%;
背景色:红色;
}

Lorem ipsum door sit amet,继续成为精英。埃尼安·康莫多·利古拉·埃吉特·多洛。埃尼安·马萨。在自然社会中,因怀孕而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯,因饥饿而死亡的蒙特斯。Donec quam felis、ultricies nec、pellentesque eu、pretium quis、sem。这是一个很好的例子。Donec pede justo、fringilla vel、aliquet nec、vulputate…

这是不可能的;伪元素根本不是DOM的一部分,所以不能直接将任何事件绑定到它们,只能绑定到它们的父元素


如果必须仅在红色区域上有一个单击处理程序,则必须创建一个子元素,如
span
,将其放置在打开的
标记之后,将样式应用于
p span
而不是
p:before
,并绑定到它。

实际上,这是可能的。您可以检查单击的位置是否在元素外部,因为只有在单击
::之前
::之后才会发生这种情况

本例仅检查右侧的元素,但这在您的情况下应该有效

span=document.querySelector('span');
span.addEventListener('click',函数(e){
如果(e.offsetX>span.offsetWidth){
span.className='c2';
}否则{
span.className='c1';
}
});
div{margin:20px;}
span:after{content:'after';position:absolute;}
span.c1{背景:黄色;}
span.c2:在{背景:黄色;}之后

元素
这些答案都不可靠,我的答案也不会可靠得多

除此之外,如果您进入了一个幸运的场景,您试图单击的元素没有填充(因此元素的所有“内部”空间都被子元素完全覆盖),那么您可以对照容器本身检查单击事件的目标。如果匹配,则表示您单击了:before或:after元素


显然,这对于这两种类型(之前和之后)都不可行,但是我已经将其作为一种黑客/速度修复程序来实现,并且它工作得非常好,没有一系列的位置检查,这可能是不准确的,取决于大约一百万个不同的因素。

我的答案适用于任何想要单击页面某个确定区域的人。这对我的绝对定位:在

由于这一点,我意识到(使用jQuery)我可以使用
e.pageY
e.pageX
,而不用担心浏览器之间的
e.offsetY/X
e.clientY/X
问题

通过反复试验,我开始在jQuery事件对象中使用clientX和clientY鼠标坐标。这些坐标给出了鼠标相对于浏览器视图端口左上角的X和Y偏移量。然而,当我阅读Karl Swedberg和Jonathan Chaffer的jQuery1.4参考指南时,我发现他们经常提到pageX和pageY坐标。在检查更新的jQuery文档后,我发现这些是jQuery标准化的坐标;我看到他们给了我鼠标相对于整个文档(不仅仅是视图端口)的X和Y偏移量

我喜欢这个
事件.pageY
想法,因为它总是一样的,因为它相对于文档来说是。我可以使用offset()将其与my:after的父元素进行比较,后者返回其相对于文档的X和Y

因此,我可以在整个页面上找到一系列永不改变的“可点击”区域


这是我的


或者,如果对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');
  }
});
var-box=$('.box');
//可点击范围-永不更改
var max=box.offset().top+box.outerHeight();
var最小值=最大值-30;//30是:之后的高度
var检查范围=功能(y){

return(y>=min&&y在现代浏览器上您可以尝试使用指针事件css属性(但这会导致无法在父节点上检测鼠标事件):

当事件目标是您的“p”元素时,您知道它是您的“p:before”

如果您仍然需要在主P上检测鼠标事件,则可以考虑修改HTML结构的可能性。可以添加<强>跨度<强>标签和以下样式:

p span {
    background:#393;
    padding:0px 10px;
    pointer-events:auto;
}
事件目标现在是“span”和“p:before”元素

没有jquery的示例:

jquery的示例:


以下是支持指针事件的浏览器列表:

在单击事件中添加条件以限制可单击区域

    $('#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
       }
     });
$(“#东西”)。单击(函数(e){
如果(e.clientX>$(this).offset().left+90&&
e、 clientY<$(this).offset().top+10){
//在元素后单击时的操作
//你的代码在这里
}
});
这对我很有用:

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

不,但你可以这样做

p div.arrow {
    content: '';
    position: absolute;
    left:100%;
    width: 10px;
    height: 100%;
    background-color: red;
} 
在html文件中添加此部分

<div class="arrow">
</div>

希望它能帮助你

简短回答:

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

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

  };      

}
我做到了。 我为所有的小人物写了一个动态使用的函数

长答案:

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

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

  };      

}
……还是这样

我花了一段时间才这样做,因为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;

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

  };      

}
工作原理:

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

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

  };      

}
它抓住了高度,