Only Detect Click Event on Pseudo-Element

Only detect click event on pseudo-element

This is not possible; pseudo-elements are not part of the DOM at all so you can't bind any events directly to them, you can only bind to their parent elements.

If you must have a click handler on the red region only, you have to make a child element, like a span, place it right after the opening <p> tag, apply styles to p span instead of p:before, and bind to it.

Is it possible to detect a click of an :after or :before pseudo element with jQuery?

Maybe. Depending on how you structure your pseudo content you would have to rely on calculating mouse position for clicks on the actual div. The event handlers would all go on the div, and not the pseudo element because it doesn't exist in the DOM.

See Manipulating CSS :before and :after pseudo-elements using jQuery
for some more info. Especially BoltClock's answer.

Also see Felix's comment for another possible solution without mouse position: Only detect click event on pseudo-element

Use javascript to click on a pseudo-element?

A workaround for this would be to dynamically append a <span> to the item and assigning a click method to it. Like this fiddle.

var item = $('<span />');
item.click(function() { alert('click'); });
$('div').append(item);

CSS

div { position:relative; background-color:#333;
padding:20px; margin:20px; float:left;
}

div span { content:""; display:block;
padding:5px; background-color:#f60; border:2px solid white;
position: absolute; top:-2px; right:-2px; border-bottom-left-radius: 10px;
}

Detect if element clicked is a pseudo element

Since you can't detect events on pseudo elements you can insert separate elements into the headerDiv and check the target of the click event to accomplish the same objective. (Or only apply events to the new child elements)

Here I created two spans for "add notes" and "button" texts which get appended to the new div. A new css rule for the button span applies the margin and pointer cursor

window.addEventListener('load', () => {
// sticky profile notes
const notes = document.querySelector('#textarea-notes'); // Get textarea element
const headerDiv = document.createElement("div"); // Create a <div> element
headerDiv.id = 'div-header';

// Create two spans to insert in headerDiv
const notesTitle = document.createElement('span')
notesTitle.innerHTML = 'Add Notes'; // Insert instructions
// this span could also be a real <button>
const notesBtn = document.createElement('span');
notesBtn.textContent = 'button';
notesBtn.className = 'notes-btn'

headerDiv.append(notesTitle)
headerDiv.append(notesBtn)

// add header on top
notes.parentNode.insertBefore(headerDiv, notes);
// minimize sticky
headerDiv.addEventListener('click', e => {
let msg = 'Parent clicked';
if(e.target.matches('.notes-btn')){
msg = 'Button clicked';
}
console.log(msg)
});
});
#div-header {
padding: 10px;
cursor: move;
background-color: #ffffcc;
}

/*#div-header:after {
margin-left: 10px;
cursor: pointer;
content: 'button';
}*/

#div-header .notes-btn{
margin-left: 10px;
cursor: pointer;
}

#textarea-notes {
background-color: #ffffcc;
width: 100%;
}
<textarea id="textarea-notes">
</textarea>

How to detect if a psudo-element (::after) was clicked in React.js

I don't believe there's a way to distinguish click events from an element and it's pesduo element(s) - the same event handler will fire when the user clicks on either.

One thing you can do though is use CSS to disable pointer-events on the host element, while allowing pointer-events on the element's pseduo element(s). That would give you a "half-way-there" mechanism for detecting clicks on pseduo element(s) only:

div:after{
content:"X";
display:block;
pointer-events: initial;
}

div{
pointer-events:none;
}

With that, you would then use the regular onClick handler which should now only fire when the ::after element is clicked:

class PseudoExample extends Component{
render(){
return(
<div onClick={() => { console.log("after clicked"); }}>
I host a pseduo elements
</div>
)
}
}

Hope that helps!

clickable after pseudo element

UPDATE

I've had a little play and reckon I've come up with something that solves this issue for the original provided code.

Essentially I have assigned the same :after CSS to a "dummy" class and then create and destroy an element with the dummy class on the fly. Between the create and destroy we are able to get the necessary dimensions (width, height, positioning). Finally we can compare these values to the click co-ordinates...

DEMO: http://jsfiddle.net/gvee/gNDCV/6/

CSS

#main {
background-color: red;
width: 100%;
height: 200px;
position: relative;
}
#main:after, .mainafter {
position: absolute;
bottom: -100px;
right: 50%;
background-color: blue;
width: 40%;
height: 20px;
content:" ";
}

JQuery

$('#main').click(function (e) {
var pseudoElement = $('<div></div>').addClass('mainafter');
$(this).append(pseudoElement);
var w = pseudoElement.width();
var h = pseudoElement.height();
var x = pseudoElement.position().left;
var y = pseudoElement.position().top;
pseudoElement.remove();

if (e.pageY - $(this).position().top > y &&
e.pageY - $(this).position().top < y + h &&
e.pageX - $(this).position().left > x &&
e.pageX - $(this).position().left < x + w
) {
alert('Not red');
}

});

If statement illustrated:

Illustration of if statement

PageX is the horizontal co-ordinate of the cursor.
X is the co-ordinate of the left-hand edge of the blue box.
W is the width of the blue box.

Therefore we can work out the right-hand edge of the blue box by simple addition: X+W.

The same logic can be applied on the vertical co-ordinates (top=Y, bottom=Y+H).

The if statement in our JQuery above checks if PageX falls between the left and right-hand edges of the blue box and that PageY is between the top and bottom.
i.e. is the cursor in the blue box!


There is a [kludgy] workaround to your provided code (where the :after content is positioned below it's container)...

Work out the co-ordinate of the mouse click and see if that exceeds the height of the #main div...

DEMO: http://jsfiddle.net/gvee/gNDCV/3/

CSS

#main {
background-color: red;
width: 100%;
height: 200px;
position: relative;
margin-bottom: 20px; /* to clear content:after */
}
#main:after {
position: absolute;
bottom: -20px; /* -(this.height) */
background-color: blue;
width: 20px;
height: 20px;
content:" ";
}

JQuery

$('#main').click(function (e) {
if (e.pageY - $(this).offset().top > $(this).height()) {
alert('Not red');
}
});

Firefox: Click on CSS pseudo element doesn't trigger click event

I think the easiest solution would be to extend the padding to cover the pseudo-element.

.btn-close{
padding: 0 32px 0 0;
}

.btn-close:after {
right: 0;
}


Related Topics



Leave a reply



Submit