2017-07-26 5 views
5

में पाठ पर क्लिक करते समय चरित्र स्थिति कैसे प्राप्त करें मेरे पास पाठ पर क्लिक करते समय कर्सर की स्थिति प्राप्त करने के लिए यह फ़ंक्शन है, यह केवल मोनोस्पेस वर्णों के लिए काम करता है जो ठीक है, लेकिन यह स्पष्ट रूप से वर्णों के साथ काम नहीं करता है जो चीनी या जापानी लोगों की तरह व्यापक हैं।जावास्क्रिप्ट

:

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(/\t/g, '\x00\x00\x00\x00').replace(/\n/, ''); 
     var before = text.slice(0, try_pos); 
     var len = before.replace(/\x00{4}/g, '\t').replace(/\x00+/, '').length; 
     return len > command.length ? command.length : len; 
    } 

मैं एक समारोह wcwidth पुस्तकालय (कि वापसी 2 व्यापक अक्षर और सामान्य पत्र के लिए 1 के लिए), लेकिन यह ठीक से काम नहीं करते हैं का उपयोग कर बनाने के लिए कोशिश की है, यहाँ डेमो के साथ कोड है

var self = $('pre'); 
 
var offset = self.offset(); 
 
var command = 'チトシタテイトチトシイスチトシタテイトチトシイスチトシタテイトチトシイス\nfoo bar baz\nfoo bar baz\nチトシタテイトチトシイ'; 
 
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('\n'); 
 
} 
 
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(/\t/g, '\x00\x00\x00\x00').replace(/\n/, ''); 
 
    var before = text.slice(0, try_pos); 
 
    var len = before.replace(/\x00{4}/g, '\t').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>

मैं प्रत्येक अक्षर के लिए फैला उपयोग नहीं कर सकते, क्योंकि मैं 3 फैला में पाठ विभाजन से पहले, कर्सर और कर्सर के बाद की है। और मेरे पास स्टाइल के लिए भी स्पैन है जो कंटेनर में हो या नहीं हो सकता है।

कोई भी सहायता इस फ़ंक्शन को ठीक करने के लिए कैसे सराहना की जाती है।

समाधान:

यहाँ मेरी कोड @Will के आधार पर है कि मैं अपने कोड है कि एक से अधिक तत्वों (किसी कारण के साथ काम में उपयोग किया है क्रोम मुद्दे हैं जब आप तत्व केवल एक ही चरित्र है पर क्लिक करें

function get_focus_offset() { 
     var sel; 
     if ((sel = window.getSelection()) && (sel.focusNode !== null)) { 
      return sel.focusOffset; 
     } 
    } 
    function get_char_pos(e) { 
     var focus = get_focus_offset(); 
     if ($.isNumeric(focus)) { 
      var node = $(e.target); 
      // [role="presentation"] is my direct children that have 
      // siblings that are other nodes with text 
      var parent = node.closest('[role="presentation"]'); 
      var len = node.text().length; 
      focus = len === 1 ? 0 : Math.min(focus, len); 
      return focus + parent.prevUntil('.prompt').text_length() + 
       node.prevAll().text_length(); 
     } else { 
      return command.length; 
     } 
    } 

अद्यतन:, और सिर्फ मामले में ध्यान देने के लिए और अधिक तो पाठ की लंबाई) नहीं है, लेकिन जब आप यदि आप पहली छमाही पर चरित्र इसे सही ढंग से चयनित हो क्लिक करें पर क्लिक के साथ इस मुद्दे है दूसरे आधे पर क्लिक करें, यह अगले charac का चयन करें ter तो मैं एक चरित्र प्रति तत्व दृष्टिकोण के साथ समाप्त हो गया।

+1

इस के लिए उपयोग के मामले में क्या है? – charlietfl

+1

आप कितने अक्षर देख रहे हैं? क्या प्रत्येक व्यक्ति को अपने ही समय में लपेटना संभव होगा? –

+0

@charlietfl मुझे कर्सर को क्लिक पर ले जाने के लिए jQuery टर्मिनल के लिए इसकी आवश्यकता है। मेरे पास पहले से ही यह काम कर रहा है लेकिन यह व्यापक पात्रों के लिए काम नहीं करता है। – jcubic

उत्तर

0

तीसरा प्रयास। एक कर्सर होने का नाटक करने के लिए वहां एक पाइप चरित्र भरें।

https://developer.mozilla.org/en-US/docs/Web/API/Selection

window.addEventListener('DOMContentLoaded',() => { 
 
document.querySelectorAll('.charPosition').forEach(el => { 
 
    let clean, cursor; 
 
    el.addEventListener('click', e => { 
 
     let position = window.getSelection().focusOffset; 
 
     if (cursor && position > cursor) 
 
      position--; 
 
     if (clean) 
 
      el['innerText'] = clean; 
 
     let textnode = el.firstChild['splitText'](position); 
 
     clean = textnode.wholeText; 
 
     cursor = position; 
 
     el.insertBefore(document.createTextNode('|'), textnode); 
 
     el['innerText'] = textnode.wholeText; 
 
    }); 
 
}); 
 
});
<div class="charPosition">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>

+0

डाउनवोट के लिए कोई स्पष्टीकरण? – Will

+0

यह मैं नहीं था, शायद क्योंकि आपने 2 उत्तरों जोड़े हैं। – jcubic

+0

क्या आप 'फोकस ऑफसेट' के लिए क्रॉस-ब्राउज़र समाधान जानते हैं? – jcubic

3

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>

+0

आपके समाधान के लिए धन्यवाद, लेकिन मैं स्पैन का उपयोग नहीं कर सकता क्योंकि शायद मेरे कंटेनर में स्पैन हो सकता है जिसमें स्टाइल है और मेरे पास कर्सर द्वारा विभाजित दो हिस्सों में टेक्स्ट विभाजित है, माफ करना इसका उल्लेख नहीं किया गया। – jcubic

संबंधित मुद्दे