2008-12-30 38 views
13

के साथ टेक्स्टरेरा चयन के साथ क्या चल रहा है यह समझना मैं textarea के भीतर एक इन-ब्राउज़र संपादक पर काम कर रहा हूं। मैंने textarea चयन से निपटने के बारे में कुछ जानकारी खोजना शुरू कर दिया है और this jQuery plugin, fieldSelection पाया है जो कुछ सरल हेरफेर करता है।जावास्क्रिप्ट

हालांकि, यह समझा नहीं रहा कि क्या हो रहा है।

मैं जावास्क्रिप्ट में टेक्स्टरेरा चयन पर अधिक समझना चाहता हूं, अधिमानतः पूर्व-डीओएम 3 और पोस्ट-डीओएम 30 परिदृश्यों के विवरण के साथ।

उत्तर

10

पीपीके के introduction to ranges के साथ शुरू करें। मोज़िला डेवलपर कनेक्शन में W3C selections पर जानकारी है। माइक्रोसॉफ्ट के पास उनकी प्रणाली documented on MSDN है। कुछ और चालें in the answers here मिल सकती हैं।

असंगत इंटरफेस के अतिरिक्त आपको यह जानकर ख़ुशी होगी कि textarea नोड्स के साथ अतिरिक्त विचित्रता चल रही है। यदि मुझे सही ढंग से याद है तो वे IE में उन्हें चुनते समय किसी भी अन्य नोड्स के रूप में व्यवहार करते हैं, लेकिन अन्य ब्राउज़रों में उनके पास एक स्वतंत्र चयन सीमा होती है जिसे .selectionEnd और .selectionStart नोड पर गुणों के माध्यम से उजागर किया जाता है।

इसके अतिरिक्त, आपको वास्तव में चीजों को संपादित करने के साधन के रूप में .contentEdiable पर एक नज़र रखना चाहिए। फ़ायरफ़ॉक्स 3 की रिलीज से, अब यह सभी ब्राउज़रों द्वारा समर्थित है।

+0

धन्यवाद बोर्गर! मैंने पहले सामग्री के बारे में कभी नहीं सुना है। जल्दबाजी के बाद मैं इससे परिचित हो जाऊंगा! – brad

29
function get_selection(the_id) 
{ 
    var e = document.getElementById(the_id); 

    //Mozilla and DOM 3.0 
    if('selectionStart' in e) 
    { 
     var l = e.selectionEnd - e.selectionStart; 
     return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) }; 
    } 
    //IE 
    else if(document.selection) 
    { 
     e.focus(); 
     var r = document.selection.createRange(); 
     var tr = e.createTextRange(); 
     var tr2 = tr.duplicate(); 
     tr2.moveToBookmark(r.getBookmark()); 
     tr.setEndPoint('EndToStart',tr2); 
     if (r == null || tr == null) return { start: e.value.length, end: e.value.length, length: 0, text: '' }; 
     var text_part = r.text.replace(/[\r\n]/g,'.'); //for some reason IE doesn't always count the \n and \r in the length 
     var text_whole = e.value.replace(/[\r\n]/g,'.'); 
     var the_start = text_whole.indexOf(text_part,tr.text.length); 
     return { start: the_start, end: the_start + text_part.length, length: text_part.length, text: r.text }; 
    } 
    //Browser not supported 
    else return { start: e.value.length, end: e.value.length, length: 0, text: '' }; 
} 

function replace_selection(the_id,replace_str) 
{ 
    var e = document.getElementById(the_id); 
    selection = get_selection(the_id); 
    var start_pos = selection.start; 
    var end_pos = start_pos + replace_str.length; 
    e.value = e.value.substr(0, start_pos) + replace_str + e.value.substr(selection.end, e.value.length); 
    set_selection(the_id,start_pos,end_pos); 
    return {start: start_pos, end: end_pos, length: replace_str.length, text: replace_str}; 
} 

function set_selection(the_id,start_pos,end_pos) 
{ 
    var e = document.getElementById(the_id); 

    //Mozilla and DOM 3.0 
    if('selectionStart' in e) 
    { 
     e.focus(); 
     e.selectionStart = start_pos; 
     e.selectionEnd = end_pos; 
    } 
    //IE 
    else if(document.selection) 
    { 
     e.focus(); 
     var tr = e.createTextRange(); 

     //Fix IE from counting the newline characters as two seperate characters 
     var stop_it = start_pos; 
     for (i=0; i < stop_it; i++) if(e.value[i].search(/[\r\n]/) != -1) start_pos = start_pos - .5; 
     stop_it = end_pos; 
     for (i=0; i < stop_it; i++) if(e.value[i].search(/[\r\n]/) != -1) end_pos = end_pos - .5; 

     tr.moveEnd('textedit',-1); 
     tr.moveStart('character',start_pos); 
     tr.moveEnd('character',end_pos - start_pos); 
     tr.select(); 
    } 
    return get_selection(the_id); 
} 

function wrap_selection(the_id, left_str, right_str, sel_offset, sel_length) 
{ 
    var the_sel_text = get_selection(the_id).text; 
    var selection = replace_selection(the_id, left_str + the_sel_text + right_str); 
    if(sel_offset !== undefined && sel_length !== undefined) selection = set_selection(the_id, selection.start + sel_offset, selection.start + sel_offset + sel_length); 
    else if(the_sel_text == '') selection = set_selection(the_id, selection.start + left_str.length, selection.start + left_str.length); 
    return selection; 
} 
+1

इस समस्या के लिए मैंने जो भी समाधान देखा है, वही एकमात्र ऐसा है जो मेरे लिए काम कर रहा है। –

+1

आपको आईडी के बजाय तत्वों को पैरामीटर के रूप में ले जाना चाहिए, जो इसे बहुत अधिक लचीला बनाता है। अन्यथा शानदार! अंतर्दृष्टि के लिए बहुत बहुत धन्यवाद अन्य लोग/वेबसाइटें प्रदान करने में विफल रहीं। – Sam

+0

अच्छा काम; वे मेरी जरूरतों को अनुकूलित करने में आसान थे। एक बग है हालांकि आईई 6 और 7 को पकड़ लेगा। Set_selection फ़ंक्शन में आपके पास "e.value [i]" है। इसे "e.value.charAt (i)" में बदला जाना चाहिए। देखें: http://stackoverflow.com/questions/5943726/string-charatx-or-stringx – ChrisD

1

केवल एक चीज जो मैं जोड़ सकता हूं वह यह है कि ऐसा लगता है (यह वास्तव में कोशिश नहीं करता है) जब भी आप सामग्री का उपयोग करते हैं तो इसे सभी तरह से स्क्रॉल करना चाहिए। एक eay उपाय कॉपी और बहाल scrollTop, इसलिए की तरह करने के लिए दो पंक्तियों के साथ लाइन करता है

e.value = 

रैप करने के लिए है:

var rememberScrollTop = e.scrollTop; 
e.value = .... (same as in user357565 snippet) 
e.scrollTop = rememberScrollTop; 
5

मैं सिर्फ user357565 द्वारा प्रस्तुत समाधान को अपनाया है, और के लिए recoded jQuery प्रत्यक्ष उपयोग:

(function ($) { 
    $.fn.get_selection = function() { 
    var e = this.get(0); 
    //Mozilla and DOM 3.0 
    if('selectionStart' in e) { 
     var l = e.selectionEnd - e.selectionStart; 
     return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) }; 
    } 
    else if(document.selection) { //IE 
     e.focus(); 
     var r = document.selection.createRange(); 
     var tr = e.createTextRange(); 
     var tr2 = tr.duplicate(); 
     tr2.moveToBookmark(r.getBookmark()); 
     tr.setEndPoint('EndToStart',tr2); 
     if (r == null || tr == null) return { start: e.value.length, end: e.value.length, length: 0, text: '' }; 
     var text_part = r.text.replace(/[\r\n]/g,'.'); //for some reason IE doesn't always count the \n and \r in length 
     var text_whole = e.value.replace(/[\r\n]/g,'.'); 
     var the_start = text_whole.indexOf(text_part,tr.text.length); 
     return { start: the_start, end: the_start + text_part.length, length: text_part.length, text: r.text }; 
    } 
    //Browser not supported 
    else return { start: e.value.length, end: e.value.length, length: 0, text: '' }; 
    }; 

    $.fn.set_selection = function (start_pos,end_pos) { 
    var e = this.get(0); 
    //Mozilla and DOM 3.0 
    if('selectionStart' in e) { 
     e.focus(); 
     e.selectionStart = start_pos; 
     e.selectionEnd = end_pos; 
    } 
    else if (document.selection) { //IE 
     e.focus(); 
     var tr = e.createTextRange(); 

     //Fix IE from counting the newline characters as two seperate characters 
     var stop_it = start_pos; 
     for (i=0; i < stop_it; i++) if(e.value[i].search(/[\r\n]/) != -1) start_pos = start_pos - .5; 
     stop_it = end_pos; 
     for (i=0; i < stop_it; i++) if(e.value[i].search(/[\r\n]/) != -1) end_pos = end_pos - .5; 

     tr.moveEnd('textedit',-1); 
     tr.moveStart('character',start_pos); 
     tr.moveEnd('character',end_pos - start_pos); 
     tr.select(); 
    } 
    return this.get_selection(); 
    }; 

    $.fn.replace_selection = function (replace_str) { 
    var e = this.get(0); 
    selection = this.get_selection(); 
    var start_pos = selection.start; 
    var end_pos = start_pos + replace_str.length; 
    e.value = e.value.substr(0, start_pos) + replace_str + e.value.substr(selection.end, e.value.length); 
    this.set_selection(start_pos,end_pos); 
    return {start: start_pos, end: end_pos, length: replace_str.length, text: replace_str}; 
    }; 

    $.fn.wrap_selection = function (left_str, right_str, sel_offset, sel_length) { 
    var the_sel_text = this.get_selection().text; 
    var selection = this.replace_selection(left_str + the_sel_text + right_str); 
    if(sel_offset !== undefined && sel_length !== undefined) 
     selection = this.set_selection(selection.start + sel_offset, selection.start + sel_offset + sel_length); 
    else if(the_sel_text == '') 
     selection = this.set_selection(selection.start + left_str.length, selection.start + left_str.length); 
    return selection; 
    }; 
}(jQuery)); 

मुझे आशा है कि किसी को यह उपयोगी लगेगा!

+0

धन्यवाद आदमी! अपने कोड का इस्तेमाल किया और इसे टॉगल रैपर आदि के लिए कुछ में संशोधित किया। आप चाहते हैं कि मैं आपको नोट/लिंक शामिल करूं? – Dominik

+0

धन्यवाद लेकिन यह आवश्यक नहीं है। –

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