প্রোগ্রামিয়ালি একটি বিতর্কিত এইচটিএমএল উপাদানটিতে পাঠ্য নির্বাচন করবেন?


119

জাভাস্ক্রিপ্টে, কোনও উপাদান inputবা textareaউপাদানটিতে প্রোগ্রামগতভাবে পাঠ্য নির্বাচন করা সম্ভব । আপনি এর সাথে একটি ইনপুট ফোকাস করতে পারেন ipt.focus()এবং তার সাথে এর সামগ্রীগুলি নির্বাচন করতে পারেন ipt.select()। এমনকি আপনি এর সাথে একটি নির্দিষ্ট পরিসর নির্বাচন করতে পারেন ipt.setSelectionRange(from,to)

আমার প্রশ্ন হ'ল: কোনও contenteditableউপাদানটিতেও এটি করার কোনও উপায় আছে ?

আমি দেখেছি যে আমি কি করতে পারি elem.focus(), একটি ক্যারেট লাগাতে contenteditableউপাদান করলেও, পরের দিকে চলমান elem.select()(এবং না করে কাজ করে না setSelectionRange)। আমি এটি সম্পর্কে ওয়েবে কিছুই খুঁজে পাচ্ছি না, তবে সম্ভবত আমি ভুল জিনিসটি সন্ধান করছি ...

যাইহোক, যদি এটি কোনও পার্থক্য করে তবে আমার কেবল এটি Google Chrome এ কাজ করা দরকার, এটি ক্রোম এক্সটেনশনের জন্য।

উত্তর:


170

আপনি যদি ক্রোমে কোনও উপাদান (বিতর্কযোগ্য বা না) এর সমস্ত সামগ্রী নির্বাচন করতে চান তবে কীভাবে তা এখানে। এটি ফায়ারফক্স, সাফারি 3+, অপেরা 9+ (সম্ভবত পূর্ববর্তী সংস্করণগুলিও) এবং আইই 9 তে কাজ করবে আপনি অক্ষর স্তর পর্যন্ত নির্বাচনগুলি তৈরি করতে পারেন। আপনার যে এপিআইগুলির দরকার তা হ'ল ডোম রেঞ্জ (বর্তমান বৈশিষ্টটি ডিওএম স্তর 2 , এছাড়াও এমডিএন দেখুন ) এবং নির্বাচন, যা একটি নতুন রেঞ্জ স্পেসের ( এমডিএন ডকস ) অংশ হিসাবে নির্দিষ্ট করা হচ্ছে ।

function selectElementContents(el) {
    var range = document.createRange();
    range.selectNodeContents(el);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
}

var el = document.getElementById("foo");
selectElementContents(el);

15
অতিরিক্ত কম্প্যাটিবিলিটি জন্য আপনি কল করা উচিত selectElementContents()একটি setTimeout()বা requestAnimationFrame()যদি কোনো থেকে বলা onfocusJsfiddle.net/rudiedirkx/MgASG/1/ শো
রুডি

@ ডিলান: আমি নিশ্চিত নই: প্রশ্নটিতে উল্লেখ করা হয়েছে যে ওপি ইতিমধ্যে ব্যবহার করছে focus()
টিম ডাউন

4
@ রডি কোন অ্যাপ্লিকেশনটির জন্য সামঞ্জস্যতা ?
ইয়াকার্ট

ডেস্কটপে দুর্দান্ত কাজ করে। মোবাইল ব্রাউজারগুলিতে, কাজ করে না। কোন নির্বাচন করা হয়নি। আইফোন আইওএস ১১ এ সাফারি এবং ক্রোমের চেষ্টা করা হয়েছে
ক্যাম্পবেল

1
@ ক্যাম্পবেল: এটি কমপক্ষে আইওএস-এ সাফারিটিতে কাজ করে তবে আপনার যদি ইতিমধ্যে একটি নির্বাচন থাকে । অন্যথায় না, সম্ভবত ব্রাউজারটি জাভাস্ক্রিপ্টকে কোনও নির্বাচন দেখানোর অনুমতি দেয় না, সম্ভবত ব্যবহারকারীর অভিজ্ঞতার কারণে।
টিম ডাউন

34

টিম ডাউনস উত্তর ছাড়াও , আমি এমন একটি সমাধান তৈরি করেছি যা পুরানোতেও কার্যকর হয়:

var selectText = function() {
  var range, selection;
  if (document.body.createTextRange) {
    range = document.body.createTextRange();
    range.moveToElementText(this);
    range.select();
  } else if (window.getSelection) {
    selection = window.getSelection();
    range = document.createRange();
    range.selectNodeContents(this);
    selection.removeAllRanges();
    selection.addRange(range);
  }
};

document.getElementById('foo').ondblclick = selectText;​

IE 8+, ফায়ারফক্স 3+, অপেরা 9+, এবং ক্রোম 2+ এ পরীক্ষিত। এমনকি আমি এটিকে একটি jQuery প্লাগইনে সেট আপ করেছি:

jQuery.fn.selectText = function() {
  var range, selection;
  return this.each(function() {
    if (document.body.createTextRange) {
      range = document.body.createTextRange();
      range.moveToElementText(this);
      range.select();
    } else if (window.getSelection) {
      selection = window.getSelection();
      range = document.createRange();
      range.selectNodeContents(this);
      selection.removeAllRanges();
      selection.addRange(range);
    }
  });
};

$('#foo').on('dblclick', function() {
  $(this).selectText();
});

... এবং কারা আগ্রহী, এখানে সমস্ত কফি-জাঙ্কিজের জন্য সমান:

jQuery.fn.selectText = ->
  @each ->
    if document.body.createTextRange
      range = document.body.createTextRange()
      range.moveToElementText @
      range.select()
    else if window.getSelection
      selection = window.getSelection()
      range = document.createRange()
      range.selectNodeContents @
      selection.removeAllRanges()
      selection.addRange range
    return

হালনাগাদ:

আপনি যদি কোনও সম্পাদনযোগ্য অঞ্চলের পুরো পৃষ্ঠা বা বিষয়বস্তু নির্বাচন করতে চান (এর সাথে পতাকাঙ্কিত contentEditable), আপনি এটিকে পরিবর্তন করে designModeএবং ব্যবহার করে আরও সহজ করতে পারেন document.execCommand:

এমডিএন এবং একটি লিটলডোকোমেন্টেশন একটি ভাল সূচনা পয়েন্ট আছে

var selectText = function () {
  document.execCommand('selectAll', false, null);
};

(আই 6+, অপেরা 9+, ফায়ারফয় 3+, ক্রোম 2+ এ ভাল কাজ করে) http://caniuse.com/#search=execCommand


10

যেহেতু বিদ্যমান সমস্ত উত্তর divউপাদানগুলির সাথে ডিল করে, আমি কীভাবে এটি spanএস এর মাধ্যমে করব তা ব্যাখ্যা করব ।

একটিতে একটি পাঠ্য সীমা নির্বাচন করার সময় একটি সূক্ষ্ম পার্থক্য রয়েছে span। পাঠ্য শুরু এবং শেষ সূচকটি পাস করতে সক্ষম হতে আপনাকে এখানেText বর্ণিত একটি নোড ব্যবহার করতে হবে :

যদি স্টার্টনোডটি পাঠ্য, মন্তব্য, বা সিডিএটিএএসসেকশন টাইপের নোড হয়, তবে স্টার্টনোডটি স্টার্টনোডের শুরু থেকে অক্ষরের সংখ্যা। অন্যান্য নোড প্রকারের জন্য, স্টার্টফট হ'ল স্টার্টনোড শুরুর মধ্যবর্তী শিশু নোডের সংখ্যা।

var e = document.getElementById("id of the span element you want to select text in");
var textNode = e.childNodes[0]; //text node is the first child node of a span

var r = document.createRange();
var startIndex = 0;
var endIndex = textNode.textContent.length;
r.setStart(textNode, startIndex);
r.setEnd(textNode, endIndex);

var s = window.getSelection();
s.removeAllRanges();
s.addRange(r);

সত্যই হওয়া উচিত: r.setStart(e.firstChild,0); r.setEnd(e.lastChild,e.lastChild.textContent.length); অবশ্যই আপনার পরীক্ষা করা উচিত যে e.firstChild আসলে নাল নয়।
ইয়োরিক

2
একটি <div>এবং একটি <span>উপাদানের মধ্যে নির্বাচন করার মধ্যে কোনও পার্থক্য নেই । অন্তত, আপনি বর্ণনা হিসাবে না।
টিম ডাউন

ডিভ এবং স্প্যানের মধ্যে পার্থক্য রয়েছে, কিছু ক্ষেত্রে ডিভের জন্য কোনও সমাধান স্প্যানে ঠিক কাজ করে না। উদাহরণস্বরূপ, আপনি ডিভ সমাধানের সাথে যদি প্রোগ্রামটিকে টেক্সট নির্বাচন করেন তবে নতুন কন্টেন্টটি পেস্ট করুন, এটি সম্পূর্ণ পাঠ্যটি প্রতিস্থাপন করবে না, কেবল একটি অংশ এবং ক্রোম এবং ফায়ারফক্সের মধ্যে পার্থক্য রয়েছে
নিউওসনে

6

রাঙ্গি আপনাকে একই কোড সহ এই ক্রস ব্রাউজারটি করার অনুমতি দেয়। রাঙ্গি নির্বাচনের জন্য ডিওএম পদ্ধতিগুলির ক্রস ব্রাউজার বাস্তবায়ন। এটি ভালভাবে পরীক্ষিত এবং এটি অনেক কম বেদনাদায়ক করে তোলে। আমি এগুলি ছাড়া সন্তুষ্টিকে স্পর্শ করতে অস্বীকার করি।

আপনি এখানে রেঞ্জ খুঁজে পেতে পারেন:

http://code.google.com/p/rangy/

আপনার প্রকল্পের রেঞ্জের সাথে, আপনি সর্বদা এটি লিখতে পারেন, এমনকি ব্রাউজারটি আইই 8 বা তার আগের এবং নির্বাচনের জন্য একেবারে আলাদা নেটিভ এপিআই রয়েছে:

var range = rangy.createRange();
range.selectNodeContents(contentEditableNode);
var sel = rangy.getSelection();
sel.removeAllRanges();
sel.addRange(range);

যেখানে "কন্টেন্টএডেটেবলনোড" হ'ল ডিওএম নোড যাটিতে সন্তোষজনক বৈশিষ্ট্য রয়েছে। আপনি এটি এ জাতীয় পেতে পারেন:

var contentEditable = document.getElementById('my-editable-thing');

অথবা যদি jQuery ইতিমধ্যে আপনার প্রকল্পের অংশ এবং আপনি এটি সুবিধাজনক বলে মনে করেন:

var contentEditable = $('.some-selector')[0];


4

আধুনিক জিনিসগুলি করার পদ্ধতি এই জাতীয়। এমডিএন সম্পর্কে আরও বিশদ

document.addEventListener('dblclick', (event) => {
  window.getSelection().selectAllChildren(event.target)
})
<div contenteditable="true">Some text</div>


ধন্যবাদ, এটি দুর্দান্ত কাজ করে! এমপিএন পৃষ্ঠাগুলি এই প্রযুক্তিটিকে পরীক্ষামূলক হিসাবে চিহ্নিত করে। কিন্তু এটা 2020 জুন মাসে Chrome এবং মুক্তিযোদ্ধা বর্তমান সংস্করণ কাজ করে
JohnK

2

[ভুল সংশোধন করার জন্য আপডেট করা হয়েছে]

এই উত্তর থেকে অভিযোজিত এমন একটি উদাহরণ যা ক্রোমে ভালভাবে কাজ করে বলে মনে হচ্ছে - কনটেটেটেবল ডিভের মধ্যে পরিসীমা নির্বাচন করুন

var elm = document.getElementById("myText"),
    fc = elm.firstChild,
    ec = elm.lastChild,
    range = document.createRange(),
    sel;
elm.focus();
range.setStart(fc,1);
range.setEnd(ec,3);
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);

এইচটিএমএল হ'ল:

<div id="myText" contenteditable>test</div>
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.