चयन चिह्नों के बीच चौराहे को संभालना


9

मेरे पास UI पर एक मार्क बटन है, जिस पर क्लिक करने पर, किसी भी उपयोगकर्ता के चयन को लाल रंग से चिह्नित किया जाता है। यहां कोई समस्या नहीं। मैं इसे हासिल करता हूंdocument.execCommand("insertHTML")

लेकिन मुझे एक अतिरिक्त आवश्यकता है कि यदि नया चयन बनाया जाता है जो पुराने चयन चिह्नों का चौराहा है, तो पुराने चयन का लाल निशान गायब हो जाना चाहिए।

उदहारण के लिए:

निम्नलिखित छवि में: यह और परीक्षण चिह्नित हैं। अब यदि मैं चयन करता हूं तो वह प्रारंभ और क्लिक चिह्न से tes है, इस के पुराने चिह्नों और परीक्षण को दूर जाना चाहिए और केवल tes को चिह्नित किया जाना चाहिए क्योंकि एक चौराहा है।

यहां छवि विवरण दर्ज करें

कोड:

const button = document.getElementById("button");

button.addEventListener('click', ()=>{
	const s = window.getSelection();
  const selectionStr = s.toString();
  document.execCommand("insertHTML", false, `<span class="bg-red">${selectionStr}<span>`);
})
.bg-red {  
background: red;
}
<div contenteditable="true">
 this is testing  this is testing  this is testing
</div>

<button id="button">mark</button>

जवाबों:


4

आप चयनित पाठ के startContainer& endContainerके साथ getRangeAt, और उनकी तुलना कर सकते हैं contentContainer। और अगर वे समान नहीं हैं contentContainer, तो bg-redकक्षा को हटा दें ।

const button = document.getElementById("button");

button.addEventListener('click', ()=>{
  let contentContainer = document.getElementById("contentContainer");
  const selection = window.getSelection();
  if (selection.rangeCount > 0){
    let startContainer =  selection.getRangeAt(0).startContainer.parentNode;
    let endContainer =  selection.getRangeAt(0).endContainer.parentNode;
    if(startContainer != contentContainer)
      startContainer.classList.remove('bg-red')
    if(endContainer != contentContainer)
      endContainer.classList.remove('bg-red')
  }
  const selectionStr = selection.toString();
  document.execCommand("insertHTML", false, `<span class="bg-red">${selectionStr}<span>`); 
})
.bg-red {  
  background: red;
}
<div id="contentContainer" contenteditable="true">
 this is testing  this is testing  this is testing
</div>

<button id="button">mark</button>


4

यदि आपको IE समर्थन की आवश्यकता नहीं है, तो आप चयन का उपयोग कर सकते हैं। चयन : नोड : https://developer.mozilla.org/en-US/docs/Web/API/Selection/containsNode

यह आपको नोड्स को चिह्नित करने की अनुमति देता है जो चयन में निहित हैं। आपको आंशिक पुन: प्राप्ति ध्वज को सही पर सेट करने की आवश्यकता है, इसलिए यह उन नोड्स का पता लगाएगा जो केवल आंशिक रूप से चुने गए हैं।

तो पहली बार में आप उन नोड्स को चिह्नित करते हैं जो एक विशिष्ट वर्ग नाम के साथ चयन द्वारा निहित होते हैं। फिर आप अपने स्टाइल को लागू करने के लिए अपने एक्ज़ीकॉम को करते हैं। उसके बाद, आप टैग की स्थापना द्वारा पहले से चिह्नित किये थे नष्ट कर दिया outerHTML करने के लिए इन नोड्स पर innerHTML । आप अपने द्वारा लागू की गई शैली को रखेंगे, लेकिन पिछले वाले को निकाल देंगे। ऐशे ही:

const button = document.getElementById("button");

button.addEventListener('click', () => {
  const s = window.getSelection();
  const selectionStr = s.toString();

  tagIntersection(s)
  document.execCommand("insertHTML", false, `<span class="bg-red">${selectionStr}<span>`);
  removeIntersection(s)
})

function tagIntersection(s) {
  const redSpans = document.getElementsByClassName('bg-red')
  for (let i = 0; i < redSpans.length; i++) {
    if (s.containsNode(redSpans[i], true)) {
      redSpans[i].classList.add('to-remove');
    }
  }
}

function removeIntersection(s) {
  // using querySelector because getElements returns a live nodelist 
  // which is a problem when you manipulate the nodes
  const toRemovespans = document.querySelectorAll('.to-remove')
  for (let i = 0; i < toRemovespans.length; i++) {
    toRemovespans[i].outerHTML = toRemovespans[i].innerHTML;
  }
}
.bg-red {
  background: red;
}
<div contenteditable="true" id="editableDiv">
  this is testing this is testing this is testing
</div>

<button id="button">mark</button>


0

मैंने यह पता लगाने की कोशिश की है कि क्या 'getSelection'.anchorNode.parentNode में वर्ग bg-red है, और इसे प्रतिस्थापित करें, लेकिन बहुत सारे दुष्प्रभाव दिखाई देते हैं।

तो, regexp के साथ समाधान ...

(* 1) - यदि आप सामग्री-संपादन योग्य तत्व के कोड का निरीक्षण करते हैं, तो आप देखेंगे कि यह संरचना है: प्रत्येक नई पंक्ति एक अलग div है। \nबहु-पंक्ति चयन की अनुमति देने के लिए, आपको प्रत्येक नई-पंक्ति के प्रतीक को "लाइन-ब्रेकिंग" HTML से बदलना होगा ।

(* 2) - ब्राउज़र सम्मिलित करता है कि यह HTML का अपना सुधार है और सही प्रतिस्थापन को रोकता है। मुझे किसी भी गैर-HTML स्ट्रिंग को सम्मिलित करने के लिए मजबूर किया गया था, जो पाठ में दिखाई देने की संभावना नहीं है। और सभी प्रतिस्थापन के बाद - वैध HTML डालें।

(* 3) - मैं यहाँ सभी नियमित अभिव्यक्तियों का विश्लेषण करने की सलाह देता हूँ → https://regex101.com/r/j88wc0/1 मुख्य विचार यह है कि सभी दोहरे दिखावे को प्रतिस्थापित किया जाए <span class="bg-red"> anything instead of closing span <span class="bg-red">या </span> anything instead of starting span tag </span>।

ध्यान दें, कि यह कोड सभी आंतरिक HTML को ताज़ा करता है, हर बार जब आप बटन दबाते हैं। यह कुछ हजार लाइनों से पाठ के साथ भी काम नहीं करेगा)

let button = document.getElementById("button");
let block = document.getElementById("block");

button.addEventListener('click', function(){
  let s = window.getSelection();
  let str = s.toString().replace(/\n/g,'</span></div><div><span class="bg-red">'); // (*1)

  document.execCommand("insertHTML", false, `bubufication`); // (*2)

  block.innerHTML = block.innerHTML
    .replace(/bubufication/, `<span class="bg-red">${str}</span>`)
    .replace(/<span class="bg-red">(.*?)<\/span><span class="bg-red">/g,'$1<span class="bg-red">')
    .replace(/<span class="bg-red">(((?!<\/span>).)*?<span class="bg-red">)/g,"$1")
    .replace(/(<\/span>((?!<span class="bg-red">).)*)<\/span>/g,"$1"); // (*3)
});
.bg-red {
  background-color: red;
}
<div id="block" contenteditable="true">
  <div>this is testing  this is testing  this is testing</div>
  <div>this is testing  this is testing  this is testing</div>
</div>

<button id="button">mark</button>

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.