Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
724 views
in Technique[技术] by (71.8m points)

jquery - How to get character position when click on text in javascript

I have this function to get position of the cursor when you click on the text, it only works for monospace characters which is fine, but it obviously don't work with characters that are wider like Chinese or Japanese ones.

    function get_char_pos(point) {
        var prompt_len = self.find('.prompt').text().length;
        var size = get_char_size();
        var width = size.width;
        var height = size.height;
        var offset = self.offset();
        var col = Math.floor((point.x - offset.left) / width);
        var row = Math.floor((point.y - offset.top) / height);
        var lines = get_splited_command_line(command);
        var try_pos;
        if (row > 0 && lines.length > 1) {
            try_pos = col + lines.slice(0, row).reduce(function(sum, line) {
                return sum + line.length;
            }, 0);
        } else {
            try_pos = col - prompt_len;
        }
        // tabs are 4 spaces and newline don't show up in results
        var text = command.replace(//g, 'x00x00x00x00').replace(/
/, '');
        var before = text.slice(0, try_pos);
        var len = before.replace(/x00{4}/g, '').replace(/x00+/, '').length;
        return len > command.length ? command.length : len;
    }

I've tried to create a function using wcwidth library (that return 2 for wider characters and 1 for normal letters) but it don't work quite right, here is the code with demo:

var self = $('pre');
var offset = self.offset();
var command = 'チトシタテイトチトシイスチトシタテイトチトシイスチトシタテイトチトシイス
foo bar baz
foo bar baz
チトシタテイトチトシイ';
self.html(command);
function get_char_size() {
    var span = $('<span>&nbsp;</span>').appendTo(self);
    var rect = span[0].getBoundingClientRect();
    span.remove();
    return rect;
}
var length = wcwidth;
// mock
function get_splited_command_line(string) {
    return string.split('
');
}
function get_char_pos(point) {
    var size = get_char_size();
    var width = size.width;
    var height = size.height;
    var offset = self.offset();
    var col_count = Math.floor((point.x - offset.left) / width);
    var row = Math.floor((point.y - offset.top) / height);
    var lines = get_splited_command_line(command);
    var line = lines[row];
    var col = 0;
    var i = col_count;
    while (i > 0) {
        i -= length(line[col]);
        col++;
    }
    var try_pos;
    if (row > 0 && lines.length > 1) {
        try_pos = col + lines.slice(0, row).reduce(function(sum, line) {
            return sum + length(line);
        }, 0);
    } else {
        try_pos = col;
    }
    // tabs are 4 spaces and newline don't show up in results
    var text = command.replace(//g, 'x00x00x00x00').replace(/
/, '');
    var before = text.slice(0, try_pos);
    var len = before.replace(/x00{4}/g, '').replace(/x00+/, '').length;
    var command_len = command.length;
    return len > command_len ? command_len : len;
}
self.click(function(e) {
  var pos = get_char_pos({
      x: e.pageX,
      y: e.pageY
  });
  self.html(command.substring(0, pos-1) + '<span>' +
            command[pos] + '</span>' +
            command.substring(pos+1));
});
span {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/jcubic/leash/master/lib/wcwidth.js"></script>
<pre></pre>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

window.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('.charPosition').forEach(el => {
        let characters = el['innerText'].split('');
        el.innerHTML = '';
        characters.forEach(char => {
            let span = document.createElement('span');
            span.innerText = char;
            span.addEventListener('click', function () {
                let position = 0;
                let el = this;
                while (el.previousSibling !== null) {
                    position++;
                    el = el.previousSibling;
                }
                console.log(this.innerHTML + ':' + position);
            });
            el.appendChild(span);
        });
    });
});
<div class="charPosition">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...