Placing each character in a document model object is not as obnoxious as it sounds.  HTML parsing, DOM representation, and event handling is quite efficient in terms of memory and processing in modern browsers.  A similar mechanism is used at a low level to render the characters too.  To simulate what the browser does at that level takes much work.
- Most documents are constructed with variable width characters
 
- Wrapping can be justified or aligned in a number of ways
 
- There is not a one to one mapping between characters and bytes
 
- To be a truly internationalized and robust solution, surrogate pairs must be supported too 1
 
This example is lightweight, loads quickly, and is portable across common browsers.  Its elegance is not immediately apparent, much reliability is gained by establishing a one to one correspondence between international characters and event listeners.
  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="utf-8">
      <title>Character Click Demo</title>
      <script type='text/javascript'>
          var pre = "<div onclick='charClick(this, ";
          var inf = ")'>";
          var suf = "</div>"; 
          function charClick(el, i) {
              var p = el.parentNode.id;
              var s = "para '" + p + "' idx " + i + " click";
              ele = document.getElementById('result');
              ele.innerHTML = s; }
          function initCharClick(ids) {
              var el; var from; var length; var to; var cc;
              var idArray = ids.split(" ");
              var idQty = idArray.length;
              for (var j = 0; j < idQty; ++ j) {
                  el = document.getElementById(idArray[j]);
                  from = unescape(el.innerHTML);
                  length = from.length;
                  to = "";
                  for (var i = 0; i < length; ++ i) {
                      cc = from.charAt(i);
                      to = to + pre + i + inf + cc + suf; }
                  el.innerHTML = to; } }
      </script>
      <style>
          .characters div {
              padding: 0;
              margin: 0;
              display: inline }
      </style>
  </head>
  <body class='characters' onload='initCharClick("h1 p0 p2")'>
      <h1 id='h1'>Character Click Demo</h1>
      <p id='p0'>æ€ – ࿗Ø —</p>
      <p id='p1'>Next  E para.</p>
      <p id='p2'>© 2017</p>
      <hr>
      <p id='result'> </p>
  </body>
  </html>
[1] This simple example does not have handling for surrogate pairs, but such could be added in the body of the i loop.