Solo detectar evento de clic en pseudo-elemento


Mi código es:

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

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

Por favor vea este violín: http://jsfiddle.net/ZWw3Z/5 /

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

Author: Randomblue, 2011-09-20

9 answers

Esto no es posible; los pseudo-elementos no son parte del DOM en absoluto, por lo que no puede enlazar ningún evento directamente a ellos, solo puede enlazar a sus elementos padre.

Si debe tener un controlador de clics solo en la región roja, debe hacer un elemento hijo, como span, colocarlo justo después de la etiqueta de apertura <p>, aplicar estilos a p span en lugar de p:before, y vincularlo.

 185
Author: BoltClock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-19 23:08:20

En Realidad, es posible. Puede verificar si la posición en la que se hizo clic estaba fuera del elemento, ya que esto solo ocurrirá si se hizo clic en ::before o ::after.

Este ejemplo solo comprueba el elemento de la derecha, pero eso 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>

JSFiddle

 108
Author: Linus Unnebäck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-07 22:03:04

En navegadores modernos puede probar con la propiedad css pointer-events (pero esto conduce a la imposibilidad de detectar eventos del ratón en el nodo padre):

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 tu elemento "p", sabes que es tu "p:before".

Si todavía necesita detectar eventos del ratón en la p 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 destinos de eventos son ahora tanto los "span "y los elementos" p:before".

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

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

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

 52
Author: Fasoeu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-13 11:44:02

Mi respuesta funcionará para cualquiera que quiera hacer clic en un área definitiva de la página. Esto funcionó para mí en mi absolutamente posicionado: después de

Gracias a este artículo , me di cuenta (con jQuery) que puedo usar e.pageY y e.pageX en lugar de preocuparme por e.offsetY/X y e.clientY/X problema entre navegadores.

A través de mi ensayo y error, comencé a usar las coordenadas clientX y clientY mouse en el objeto de evento jQuery. Estas coordenadas me dieron el desplazamiento X e Y de el ratón relativo a la esquina superior izquierda del puerto de vista del navegador. Mientras leía la Guía de Referencia jQuery 1.4 de Karl Swedberg y Jonathan Chaffer, sin embargo, vi que a menudo se referían a las coordenadas pageX y pageY. Después de revisar la documentación actualizada de jQuery, vi que estas eran las coordenadas estandarizadas por jQuery; y, vi que me dieron el desplazamiento X e Y del ratón en relación con todo el documento (no solo el puerto de vista).

Me gustó esto event.pageY idea porque siempre sería lo mismo, ya que era en relación con el documento. Puedo compararlo con el elemento padre de my :after usando offset(), que devuelve sus X e Y también en relación con el documento.

Por lo tanto, puedo llegar a un rango de región "clickable" en toda la página que nunca cambia.


Aquí está mi demo en codepen.


O si es demasiado perezoso para codepen, aquí está la JS:

* Solo me importaban los valores Y para mi ejemplo.

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');
  }
});
 7
Author: amurrell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-09 22:34:51

Esto funciona para mí:

$('#element').click(function (e) {
        if (e.offsetX > e.target.offsetLeft) {
            // click on element
        }
         else{
           // click on ::before element
       }
});
 3
Author: Rick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-09 15:56:16

Respuesta Corta:

Lo hice. Incluso lo hice en javascript puro y escribí una función para uso dinámico para todas las personas pequeñas que hay...

Ejemplo de Trabajo con la función que puede robar

Respuesta larga:

...Todavía lo hice.

Me tomó un tiempo hacerlo, ya que un elemento psuedo no está realmente en la página. Si bien algunas de las respuestas anteriores funcionan en ALGUNOS escenarios, todas no son dinámicas y funcionan en un escenario en el que un elemento es inesperado tanto en tamaño como en posición(como los elementos posicionados absolutos que superponen una parte del elemento padre). 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:

Agarra las posiciones height, width, top y left (basadas en la posición alejada del borde de la ventana) del elemento padre y agarra las posiciones height, width, top y left (basadas en el borde del contenedor padre) y compara esos valores con determine dónde está el elemento psuedo en la pantalla.

Luego compara dónde está el ratón. Mientras el ratón esté en el rango de variables recién creado, devuelve true.

Nota:

Es aconsejable hacer que el elemento padre esté en posición RELATIVA. Si tiene un elemento psuedo posicionado absoluto, esta función solo funcionará si se posiciona en función de las dimensiones del padre(por lo que el padre tiene que ser relativo...tal vez pegajoso o fijo funcionaría también....Yo no saber).

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

  };      

}

Soporte:

No know....it parece que ie es tonto y le gusta devolver auto como un valor calculado a veces. PARECE FUNCIONAR BIEN EN TODOS LOS NAVEGADORES SI LAS DIMENSIONES SE ESTABLECEN EN CSS. Tan...establece tu altura y anchura en tus elementos psuedo y solo muévelos con la parte superior e izquierda. Recomiendo usarlo en cosas en las que estás de acuerdo con que no funcione. Como una animación o algo así. Cromo works...as lo de siempre.

 2
Author: Aaron Loften,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-13 22:25:48

Agregue condición en el evento de clic para restringir el área en la que se puede hacer clic .

    $('#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
       }
     });

DEMO

 1
Author: Abdennour TOUMI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-25 13:37:01

Ninguna de estas respuestas es confiable, y la mía no será mucho más confiable.

Dejando de lado las advertencias, si entras en el afortunado escenario donde el elemento en el que intentas hacer clic no tiene relleno (de modo que todo el espacio "interno" del elemento está completamente cubierto por subelementos), entonces puedes verificar el destino del evento de clic contra el contenedor en sí. Si coincide, significa que has hecho clic en un elemento: before o: after.

Obviamente, esto no sería factible con ambos tipos (antes y después) sin embargo, lo he implementado como una corrección de hack/velocidad y está funcionando muy bien, sin un montón de comprobación de posición, que puede ser inexacta dependiendo de alrededor de un millón de factores diferentes.

 0
Author: dudewad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-29 19:02:05

No, pero puedes hacer así

En el archivo html agregue esta sección

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

En css se puede hacer así

p div.arrow {
content: '';
position: absolute;
left:100%;
width: 10px;
height: 100%;
background-color: red;

} Espero que te ayude

 -2
Author: Gopal Bogati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-26 10:19:51