Detectar solo evento de clic en pseudoelemento

Resuelto Randomblue asked hace 13 años • 13 respuestas

Consulte este violín: http://jsfiddle.net/ZWw3Z/5/

Mi código es:

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

p:before {
    content: '';
    position: absolute;
    left:100%;
    width: 10px;
    height: 100%;
    background-color: red;
}
    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate...</p>
Expandir fragmento

Me gustaría activar un evento de clic solo en el pseudoelemento (el bit rojo). Es decir, no quiero que el evento de clic se active en el bit azul.

Randomblue avatar Sep 20 '11 06:09 Randomblue
Aceptado

Esto no es posible; Los pseudoelementos no forman parte del DOM en absoluto, por lo que no puede vincular ningún evento directamente a ellos, solo puede vincularse a sus elementos principales.

Si debe tener un controlador de clic solo en la región roja, debe crear un elemento secundario, como span, colocarlo justo después de la <p>etiqueta de apertura, aplicar estilos p spanen lugar de p:beforey vincularlo.

BoltClock avatar Sep 19 '2011 23:09 BoltClock

En realidad, es posible. Puede verificar si la posición en la que se hizo clic estaba fuera del elemento, ya que esto solo sucederá si se hizo clic en ::beforeo ::after.

Este ejemplo solo verifica el elemento de la derecha, pero debería funcionar en su caso.

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

JSFiddle

Linus Unnebäck avatar Apr 23 '2014 12:04 Linus Unnebäck

En los navegadores modernos , puede probar con la propiedad CSS pointer-events (pero conduce a la imposibilidad de detectar eventos del mouse en el nodo principal):

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

Cuando el objetivo del evento es su elemento "p", sabrá que es su "p:antes".

Si aún necesita detectar eventos del mouse en la página principal, puede considerar la posibilidad de modificar su estructura HTML. Puede agregar una etiqueta span y el siguiente estilo:

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

Los objetivos del evento ahora son los elementos "span" y "p:before".

Ejemplo sin jquery: http://jsfiddle.net/2nsptvcu/

Ejemplo con jquery: http://jsfiddle.net/0vygmnnb/

Aquí está la lista de navegadores que admiten eventos de puntero: http://caniuse.com/#feat=pointer-events

Fasoeu avatar Oct 07 '2015 13:10 Fasoeu

Respuesta corta:

Lo hice. Escribí una función para uso dinámico para todas las personas pequeñas...

Ejemplo de trabajo que se muestra en la página.

Ejemplo práctico de inicio de sesión en la consola

Respuesta larga:

...Aun así lo hice.

Me tomó un tiempo hacerlo, ya que un pseudoelemento no está realmente en la página. Si bien algunas de las respuestas anteriores funcionan en ALGUNOS escenarios, TODAS no son dinámicas ni funcionan en un escenario en el que un elemento es inesperado en tamaño y posición (como elementos en posición absoluta que se superponen a una parte del elemento principal). El mío no.

Uso:

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

});

Cómo funciona:

Toma las posiciones de altura, ancho, superior e izquierda (según la posición lejos del borde de la ventana) del elemento principal y toma las posiciones de altura, ancho, superior e izquierda (según el borde del contenedor principal). ) y compara esos valores para determinar dónde está el pseudoelemento en la pantalla.

Luego compara dónde está el mouse. Siempre que el mouse esté en el rango de variables recién creado, devuelve verdadero.

Nota:

Es aconsejable colocar el elemento padre en una posición RELATIVA. Si tiene un pseudoelemento con posición absoluta, esta función solo funcionará si se coloca según las dimensiones del padre (por lo que el padre tiene que ser relativo... tal vez adhesivo o fijo también funcione... No lo sé).

Código:

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

  };      

}

Apoyo:

No lo sé... parece que es tonto y a veces le gusta devolver auto como un valor calculado. PARECE FUNCIONAR BIEN EN TODOS LOS NAVEGADORES SI LAS DIMENSIONES SE ESTABLECEN EN CSS. Entonces... establece la altura y el ancho de tus pseudoelementos y muévelos solo hacia arriba y hacia la izquierda. Recomiendo usarlo en cosas en las que estás de acuerdo con que no funcione. Como una animación o algo así. Chrome funciona... como siempre.

 avatar Apr 13 '2018 22:04