কয়েকটি উত্তেজনার ঝাঁকুনি যা আমি অন্য উত্তরে সম্বোধন করতে দেখছি না:
- উপাদানটিতে শিশু নোডের একাধিক স্তর থাকতে পারে (উদাঃ শিশু নোডগুলিতে শিশু নোড রয়েছে এমন শিশু নোড রয়েছে ...)
- একটি নির্বাচন বিভিন্ন শুরু এবং শেষ অবস্থান নিয়ে গঠিত হতে পারে (যেমন একাধিক অক্ষর নির্বাচিত হয়)
- ক্যারেট শুরু / শেষ সমেত নোড উপাদান বা এর সরাসরি বাচ্চাদের নাও হতে পারে
উপাদানটির পাঠ্য বিষয়বস্তুর মান হিসাবে অফসেট হিসাবে শুরু এবং শেষ পজিশনের একটি উপায় এখানে রয়েছে:
// node_walk: walk the element tree, stop when func(node) returns false
function node_walk(node, func) {
var result = func(node);
for(node = node.firstChild; result !== false && node; node = node.nextSibling)
result = node_walk(node, func);
return result;
};
// getCaretPosition: return [start, end] as offsets to elem.textContent that
// correspond to the selected portion of text
// (if start == end, caret is at given position and no text is selected)
function getCaretPosition(elem) {
var sel = window.getSelection();
var cum_length = [0, 0];
if(sel.anchorNode == elem)
cum_length = [sel.anchorOffset, sel.extentOffset];
else {
var nodes_to_find = [sel.anchorNode, sel.extentNode];
if(!elem.contains(sel.anchorNode) || !elem.contains(sel.extentNode))
return undefined;
else {
var found = [0,0];
var i;
node_walk(elem, function(node) {
for(i = 0; i < 2; i++) {
if(node == nodes_to_find[i]) {
found[i] = true;
if(found[i == 0 ? 1 : 0])
return false; // all done
}
}
if(node.textContent && !node.firstChild) {
for(i = 0; i < 2; i++) {
if(!found[i])
cum_length[i] += node.textContent.length;
}
}
});
cum_length[0] += sel.anchorOffset;
cum_length[1] += sel.extentOffset;
}
}
if(cum_length[0] <= cum_length[1])
return cum_length;
return [cum_length[1], cum_length[0]];
}