11

I want to select pseudo-element :after

This is my css :

show-more:after
{
    content : (" > ");
}

JQuery code

$(function(){
    $('.show-more:after').click(function() {
        alert("Yes");
    }); 
});
Daryl Bennett
  • 462
  • 10
  • 22
AiD
  • 977
  • 3
  • 15
  • 41

4 Answers4

13

It's not possible to bind directly to pseudo-elements, since those are not part of the DOM, but the desired effect can be approximated by binding to a parent element and testing for an offset related to the element that the :after acts upon:

The following renders as ELEMENT++, where clicking on "ELEMENT" and "++" each triggers different behavior:

<span>ELEMENT</span>
span::after {
  content: '++';
  position: absolute;
}

span.c1 {
  background: yellow;
}

span.c2::after {
  background: orange;
}
const span = document.querySelector('span');

span.addEventListener('click', function (e) {
    if (e.offsetX > span.offsetWidth) {
        span.className = 'c2';
    } else {
        span.className = 'c1';
    }
});

Interactive: http://jsfiddle.net/wC2p7/1/

jmromer
  • 2,212
  • 1
  • 12
  • 24
MartaGom
  • 501
  • 6
  • 27
7

Edit, Updated

Try

(function($) {
  jQuery.fn.extend({
    getPseudo: function(pseudo, prop) {
      var props = window.getComputedStyle(
        $(this).get(0), pseudo
      ).getPropertyValue(prop);
      return String(props);
    },
    setPseudo: function(_pseudo, _prop, newprop) {
      var elem = $(this);
      var s = $("style");
      var p = elem.getPseudo(_pseudo, _prop);
      var r = p !== "" ? new RegExp(p) : false;
      var selector = $.map(elem, function(val, key) {
        return [val.tagName
                , val.id 
                  ? "#" + val.id : null
                , val.className ? "." + val.className : null]
      });
      var _setProp = "\n" + selector.join("")
        .toLowerCase()
        .concat(_pseudo)
        .concat("{")
        .concat(_prop + ":")
        .concat(newprop + "};");
      return ((!!r ? r.test($(s).text()) : r) 
              ? $(s).text(function(index, prop) {
                  return prop.replace(r, newprop)
                }) 
              : $(s).append(_setProp)
      );
    }
  })
})(jQuery);

i.e.g., initial css:

.show-more:after {
    content : ' > ';
}

set pseudo element

$(".show-more-after").on("click", function() {
  $(this).setPseudo(":after", "content", "'123'")
})

github pseudo.js

(function($) {
  jQuery.fn.extend({
    getPseudo: function(pseudo, prop) {
      var props = window.getComputedStyle(
        $(this).get(0), pseudo
      ).getPropertyValue(prop);
      return String(props);
    },
    setPseudo: function(_pseudo, _prop, newprop) {
      var elem = $(this);
      var s = $("style");
      var p = elem.getPseudo(_pseudo, _prop);
      var r = p !== "" ? new RegExp(p) : false;
      var selector = $.map(elem, function(val, key) {
        return [val.tagName
                , val.id 
                  ? "#" + val.id : null
                , val.className ? "." + val.className : null]
      });
      var _setProp = "\n" + selector.join("")
        .toLowerCase()
        .concat(_pseudo)
        .concat("{")
        .concat(_prop + ":")
        .concat(newprop + "};");
      return ((!!r ? r.test($(s).text()) : r) 
              ? $(s).text(function(index, prop) {
                  return prop.replace(r, newprop)
                }) 
              : $(s).append(_setProp)
      );
    }
  })
})(jQuery);

$(".show-more-after").on("click", function() {
  $(this).setPseudo(":after", "content", "'123'");
})
.show-more-after:after {
    content : ' > ';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="show-more-after">click</div>
guest271314
  • 1
  • 15
  • 104
  • 177
  • It is working with only one pseudo element like .one:before but not working for 2 pseudo elements like .one:hover:before. For ex. it works for $(this).setPseudo(":after", "content", "'123'"); but same code not working for $(this).setPseudo(":hover:after", "content", "'123'"); – Chirag Shah Aug 14 '19 at 10:21
4

Do something like this instead:

$(function(){
    $('.show-more').after().click(function() {
        alert("Yes");
    }); 
});
.show-more {
Width: 100px;
Height: 40px;
Position: relative; /* Helps you define the area you want to be clickable */
Overflow: hidden;
}


.show-more:after {
 content: 'Click me';
Left:0;
Top: 0;
width: 100%;
height: 100%;
background: red;
color: white;
padding: 15px;
line-height: 40px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="show-more"> </div>
Sleek Geek
  • 4,638
  • 3
  • 27
  • 42
  • 1
    If you change the HTML to `
    INSIDE
    ` then click on "INSIDE" it breaks. Your code can't differentiate between clicks on the element and on the after pseudo element.
    – Stephen Ostermiller Aug 16 '16 at 18:44
  • 1
    It actually works by clicking any part `.show-more` class. Not particularly for `::after` – Thamaraiselvam Feb 17 '17 at 06:51
  • 1
    Setting a fixed width and height with position property with value relative solves the problem of "any part" triggering the click event. See the jsfiddle. – Sleek Geek Feb 19 '17 at 01:11
0

use this to add text after show more

$(function(){
    $('.show-more').text($('.show-more').text()+">");
});
A.B
  • 20,110
  • 3
  • 37
  • 71