Range
वस्तुओं और document.execCommand
बहुत आसानी से चयन में हेरफेर करने के लिए अनुमति देते हैं। आपके मामले में मुख्य समस्या श्रेणी वस्तु में रेंज ऑब्जेक्ट को सहेज रही है।
मूल रूप से आपको क्या चाहिए पाने के लिए है startContainer
, startOffset
, endContainer
और endOffset
, जो मूल्यों रेंज वस्तुओं बनाने के लिए आवश्यक हैं। Offsets
संख्या है इसलिए यह बहुत सरल है। कंटेनर नोड्स हैं, जिन्हें आप स्ट्रिंग के रूप में सीधे सहेज नहीं सकते हैं, इसलिए यह मुख्य समस्या है। एक चीज जो आप कर सकते हैं वह आपके डोम में कुंजी जोड़ती है और कुंजी को सेव करती है। लेकिन फिर, जब श्रेणी कंटेनर टेक्स्ट नोड्स हैं, तो आपको टेक्स्ट नोड की अनुक्रमणिका को सहेजने की आवश्यकता होगी। यह हो जाने पर, आप एक वस्तु है कि आप एक स्ट्रिंग के रूप में सहेज सकते हैं करने के लिए सीमा वस्तुओं में बदल सकते हैं
function addKey(element) {
if (element.children.length > 0) {
Array.prototype.forEach.call(element.children, function(each, i) {
each.dataset.key = key++;
addKey(each)
});
}
};
addKey(document.body);
: कुछ इस तरह कुंजी के साथ डोम टैग करने के लिए, एक पुनरावर्ती समारोह का उपयोग कर अनुमति चाहिए। इस तरह:
function rangeToObj(range) {
return {
startKey: range.startContainer.parentNode.dataset.key,
startTextIndex: Array.prototype.indexOf.call(range.startContainer.parentNode.childNodes, range.startContainer),
endKey: range.endContainer.parentNode.dataset.key,
endTextIndex: Array.prototype.indexOf.call(range.endContainer.parentNode.childNodes, range.endContainer),
startOffset: range.startOffset,
endOffset: range.endOffset
}
}
इसका उपयोग करके, आप प्रत्येक चयन को सहेज सकते हैं जिसे उपयोगकर्ता सरणी में बनाता है। इस तरह:
document.getElementById('textToSelect').addEventListener('mouseup', function(e) {
if (confirm('highlight?')) {
var range = document.getSelection().getRangeAt(0);
selectArray.push(rangeToObj(range));
document.execCommand('hiliteColor', false, 'yellow')
}
});
हाइलाइट्स को सहेजने के लिए, आप प्रत्येक ऑब्जेक्ट को JSON पर सहेजते हैं। इसका परीक्षण करने के लिए, आप बस अपनी रेंज ऑब्जेक्ट सरणी से JSON स्ट्रिंग प्राप्त कर सकते हैं। इस तरह (यह शीर्ष पर प्राप्त seletion बटन का उपयोग किया जाता है):
document.getElementById('getSelectionString').addEventListener('click', function() {
alert('Copy string to save selections: ' + JSON.stringify(selectArray));
});
फिर जब खाली एचटीएमएल लोड हो रहा है, तो आप एक रिवर्स समारोह है कि वस्तुओं आप JSON में सहेजा से लेकर पैदा करेगा उपयोग कर सकते हैं। इस तरह:
function objToRange(rangeStr) {
range = document.createRange();
range.setStart(document.querySelector('[data-key="' + rangeStr.startKey + '"]').childNodes[rangeStr.startTextIndex], rangeStr.startOffset);
range.setEnd(document.querySelector('[data-key="' + rangeStr.endKey + '"]').childNodes[rangeStr.endTextIndex], rangeStr.endOffset);
return range;
}
तो तुम तार कि आप वस्तुओं में बदलने में पर्वतमाला की एक सरणी हो सकता था, और फिर वस्तुओं है कि आप जोड़ सकते हैं श्रृंखला के लिए कनवर्ट करें। फिर execCommand का उपयोग करके, आप कुछ स्वरूपण सेट करते हैं।
document.getElementById('setSelection').addEventListener('click', function() {
var selStr = prompt('Paste string');
var selArr = JSON.parse(selStr);
var sel = getSelection();
selArr.forEach(function(each) {
sel.removeAllRanges();
sel.addRange(objToRange(each));
document.execCommand('hiliteColor', false, 'yellow')
})
});
देखें: https://jsfiddle.net/sek4tr2f/3/
वहाँ मामलों में जहां यह काम नहीं कर रहे हैं ध्यान दें कि, मुख्य इस तरह (यह शीर्ष पर सेट चयन बटन का उपयोग कर रहा है, आप बेला ताज़ा करने के बाद ऐसा करने) समस्याग्रस्त मामला तब होता है जब उपयोगकर्ता पहले से हाइलाइट की गई सामग्री में सामग्री का चयन करता है। इन मामलों को संभाला जा सकता है, लेकिन आपको अधिक स्थितियों की आवश्यकता होगी।
आप एक सरणी में हाइलाइट किए गए शब्द का सूचकांक, और उनके लंबाई क्यों नहीं बचा सकता हूं? –
मैं @ मोहम्मदसेम से सहमत हूं, एक सरणी बनाएं ताकि उपयोगकर्ता 'xyz' को हाइलाइट करने वाला एक सरणी में 'xyz' जोड़ देगा और यह भी इंगित करेगा कि 'xyz' का कौन सा विशिष्ट उदाहरण था (यानी यदि यह तीसरा था तब 'xyz' का उदाहरण तब सूचकांक होगा 3. – tamak
मुझे संदेह है कि 'innerHTML.indexOf (टेक्स्ट)' कुछ भी वितरित करेगा, अकेले एक इंडेक्स दें। 'संदर्भ त्रुटि' अधिक संभावना है। – KooiInc