Mon code est:
p {
position: relative;
background-color: blue;
}
p:before {
content: '';
position: absolute;
left:100%;
width: 10px;
height: 100%;
background-color: red;
}
S'il vous plaît voir ce violon: http://jsfiddle.net/ZWw3Z/5/
Je voudrais déclencher un événement de clic uniquement sur le pseudo-élément (le bit rouge). C'est-à-dire que je ne veux pas que l'événement click soit déclenché sur le bit bleu.
Ce n'est pas possible; Les pseudo-éléments ne font pas du tout partie du DOM; vous ne pouvez donc lier aucun événement directement à eux. Vous pouvez uniquement vous lier à leurs éléments parents.
Si vous devez avoir un gestionnaire de clics uniquement sur la région rouge, vous devez créer un élément enfant, tel qu'un span
, placez-le juste après la balise <p>
d'ouverture, appliquez les styles à p span
au lieu de p:before
, et s'y lier.
En fait, c'est possible. Vous pouvez vérifier si la position cliquée était en dehors de l'élément, car cela ne se produira que si vous avez cliqué sur ::before
ou ::after
.
Cet exemple ne vérifie que l'élément à droite mais cela devrait fonctionner dans votre cas.
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>
Sur les navigateurs modernes , vous pouvez essayer avec la propriété css pointer-events (mais il est impossible de détecter les événements de souris sur le nœud parent):
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;
}
Lorsque la cible de l'événement est votre élément "p", vous savez que c'est votre "p: before".
Si vous avez toujours besoin de détecter des événements de souris sur le p principal, vous pouvez envisager la possibilité de modifier votre structure HTML. Vous pouvez ajouter une balise span span et le style suivant:
p span {
background:#393;
padding:0px 10px;
pointer-events:auto;
}
Les cibles d'événement sont maintenant les éléments "span" et "p: before".
Exemple sans jquery: http://jsfiddle.net/2nsptvcu/
Exemple avec jquery: http://jsfiddle.net/0vygmnnb/
Voici la liste des navigateurs supportant les événements de pointeur: http://caniuse.com/#feat=pointer-events
Ma réponse fonctionnera pour tous ceux qui souhaitent cliquer sur une zone définitive de la page. Cela a fonctionné pour moi sur mon position absolue: après
Grâce à cela article , j'ai réalisé (avec jQuery) que je peux utiliser le problème e.pageY
et e.pageX
au lieu de m'inquiéter pour e.offsetY/X
et e.clientY/X
entre navigateurs .
Lors d'essais et d'erreurs, j'ai commencé à utiliser les coordonnées clientX et clientY dans l'objet événement jQuery. Ces coordonnées m'ont donné les décalages X et Y de la souris par rapport au coin supérieur gauche du port d'affichage du navigateur. En lisant le Guide de référence jQuery 1.4 de Karl Swedberg et Jonathan Chaffer, j'ai toutefois constaté qu'ils se référaient souvent aux coordonnées pageX et pageY. Après avoir vérifié la documentation mise à jour de jQuery, j'ai constaté qu'il s'agissait des coordonnées normalisées par jQuery; et, j'ai vu qu'ils m'avaient donné les décalages X et Y de la souris par rapport au document entier (pas seulement le port d'affichage).
J'ai bien aimé cette idée event.pageY
parce que ce serait toujours la même chose, telle qu'elle était par rapport au document . Je peux le comparer à l'élément parent de mon: after en utilisant offset (), qui renvoie ses X et Y également par rapport au document.
Par conséquent, je peux proposer une gamme de régions "cliquables" sur la page entière qui ne change jamais.
Voici mon démo sur codepen .
ou si vous êtes trop paresseux pour codepen, voici le JS:
* Je me souciais seulement des valeurs Y pour mon exemple.
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');
}
});
Cela fonctionne pour moi:
$('#element').click(function (e) {
if (e.offsetX > e.target.offsetLeft) {
// click on element
}
else{
// click on ::before element
}
});
Réponse courte:
Je l'ai fait. J'ai écrit une fonction d'utilisation dynamique pour toutes les petites gens là-bas ...
Exemple de travail qui s'affiche sur la page
Exemple de travail se connectant à la console
Réponse longue:
... l'a encore fait.
Il m'a fallu un certain temps pour le faire, car un élément psuedo n'est pas vraiment sur la page. Certaines des réponses ci-dessus fonctionnent dans CERTAINS scénarios, mais elles échouent TOUTES être dynamiques et dans un scénario dans lequel la taille et la position d’un élément sont inattendues (telles que des éléments positionnés en absolu superposant une partie de l’élément parent). Le mien non.
Utilisation:
//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;
});
Comment ça marche:
Il saisit les positions hauteur, largeur, haut et gauche (en fonction de la position éloignée du bord de la fenêtre) de l'élément parent et saisit les positions hauteur, largeur, haut et gauche (en fonction du bord du conteneur parent). ) et compare ces valeurs pour déterminer où se trouve l'élément psuedo à l'écran.
Il compare ensuite où se trouve la souris. Tant que la souris se trouve dans la plage de variables nouvellement créée, elle renvoie true.
Remarque:
Il est sage de positionner l'élément parent RELATIVE. Si vous avez un élément psuedo à positionnement absolu, cette fonction ne fonctionnera que si elle est positionnée en fonction des dimensions du parent (le parent doit donc être relatif ... peut-être qu'il soit collant ou corrigé fonctionnerait aussi ... je ne sais pas).
Code:
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
};
}
Assistance:
Je ne sais pas .... on dirait que c'est idiot et aime parfois retourner auto comme valeur calculée. Il semble que tous les navigateurs fonctionnent correctement si les dimensions sont définies en CSS. Alors ... définissez votre hauteur et votre largeur sur vos éléments psuedo et ne les déplacez qu'en haut et à gauche. Je recommande de l'utiliser sur des choses qui ne vous dérangent pas. Comme une animation ou quelque chose. Chrome fonctionne ... comme d'habitude.
Ajoutez une condition dans l'événement Click pour restreindre la zone cliquable.
$('#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
}
});
Aucune de ces réponses n'est fiable et la mienne ne sera pas beaucoup plus fiable.
Mises en garde de côté, si vous entrez dans le scénario chanceux où l’élément sur lequel vous essayez de cliquer n’a pas de rembourrage (de sorte que tout l’espace "intérieur" de l’élément soit complètement recouvert par des sous-éléments), peut vérifier la cible de l'événement click par rapport au conteneur lui-même. Si cela correspond, cela signifie que vous avez cliqué sur un élément: avant ou: après.
Évidemment, cela ne serait pas réalisable avec les deux types (avant et après), mais je l’ai implémenté comme solution de piratage/rapidité et cela fonctionne très bien, sans une série de vérifications de position, ce qui peut être inexact en fonction d’un million de facteurs différents. .