Trying to detect if a pseudo element is clicked, this has been asked before but not quite with my set up. I have other elements inside my wrapper which also have standard click events, so I cannot use pointer-events: none
Here is my js function:
const $wrapper = $('.wrapper');
attachInformationEvent = function() {
const $elems = $wrapper.find('table td span');
$elems.off().on('click', function(e) {
e.stopPropagation();
if (e.offsetX > $(e.target).width()) {
// if the click is offset more than the element width then this should be the psuedo after element
// fire our function here
console.log('pseudo');
} else if (event.target.tagName === 'LABEL' || event.target.tagName === 'INPUT'){
// allow normal checkbox click event
// this event is firing the pseudo event above
return;
} else {
return false;
}
});
}();
This is the markup:
<table id="gridzone_0_Rep_Content_ctl00_1_cbList_1" class="checkbox-group default footable-loaded">
<tbody>
<tr>
<td>
<span data-info="Excellence Description">
<input id="gridzone_0_Rep_Content_ctl00_1_cbList_1_0_1" type="checkbox" name="gridzone_0$Rep_Content$ctl01$ctl00$cbList$0" value="Excellence">
<label for="gridzone_0_Rep_Content_ctl00_1_cbList_1_0_1">Excellence</label>
</span>
</td>
</tr>
<tr>
<td>
<span data-info="Innovation Description">
<input id="gridzone_0_Rep_Content_ctl00_1_cbList_1_1_1" type="checkbox" name="gridzone_0$Rep_Content$ctl01$ctl00$cbList$1" value="Innovation">
<label for="gridzone_0_Rep_Content_ctl00_1_cbList_1_1_1">Innovation</label>
</span>
</td>
</tr>
<tr>
<td>
<span data-info="Care Description">
<input id="gridzone_0_Rep_Content_ctl00_1_cbList_1_2_1" type="checkbox" name="gridzone_0$Rep_Content$ctl01$ctl00$cbList$2" value="Care">
<label for="gridzone_0_Rep_Content_ctl00_1_cbList_1_2_1">Care</label>
</span>
</td>
</tr>
<tr>
<td>
<span data-info="Heritage Description">
<input id="gridzone_0_Rep_Content_ctl00_1_cbList_1_3_1" type="checkbox" name="gridzone_0$Rep_Content$ctl01$ctl00$cbList$3" value="Heritage">
<label for="gridzone_0_Rep_Content_ctl00_1_cbList_1_3_1">Heritage</label>
</span>
</td>
</tr>
<tr>
<td>
<span data-info="Passion Description">
<input id="gridzone_0_Rep_Content_ctl00_1_cbList_1_4_1" type="checkbox" name="gridzone_0$Rep_Content$ctl01$ctl00$cbList$4" value="Passion">
<label for="gridzone_0_Rep_Content_ctl00_1_cbList_1_4_1">Passion</label>
</span>
</td>
</tr>
</tbody>
</table>
And some css to display a small pseudo element after the span:
.wrapper table td span::after {
content: "?";
display: inline-flex;
justify-content: center;
align-items: center;
position: relative;
background: #000000;
color: #ffffff;
border-radius: 50%;
cursor: pointer;
font-size: 1.077rem;
font-weight: 800;
height: 1.25rem;
width: 1.25rem;
left: 2.5rem;
top: -1rem;
padding: 2px;
}
I have made a JSFIDDLE.
I feel like this is close, if anyone can advise I would really appreciate it. I am not in a position to be able to change much of the markup unfortunately.
CodePudding user response:
Your issue is that you're using e.target
with a nested label
and checkbox
.
<span>
<input ...
<label ...
</span>
using $("span").click...
will receive the events for child elements, with e.target
as the element that was clicked, but with this
as the element the event was assigned to.
As the psuedo "element" is off the end of the span
the calculations for width against the input
and label
are incorrect.
Changing
if (e.offsetX > $(e.target).width()) {
to
if (e.offsetX > $(this).width()) {
will use the span
s width for the check.