Пожалуйста, обратите внимание, что приведенный ниже код будет полезен для переноса тега span для всех типов тегов.Пожалуйста, пройдите код и используйте логику для своей реализации.
getSelectedText(this);
addAnnotationElement(this, this.parent);
function getSelectedText(this) {
this.range = window.getSelection().getRangeAt(0);
this.parent = this.range.commonAncestorContainer;
this.frag = this.range.cloneContents();
this.clRange = this.range.cloneRange();
this.start = this.range.startContainer;
this.end = this.range.endContainer;
}
function addAnnotationElement(this, elem) {
var text, textParent, origText, prevText, nextText, childCount,
annotationTextRange,
span = this.htmlDoc.createElement('span');
if (elem.nodeType === 3) {
span.setAttribute('class', this.annotationClass);
span.dataset.name = this.annotationName;
span.dataset.comment = '';
span.dataset.page = '1';
origText = elem.textContent;
annotationTextRange = validateTextRange(this, elem);
if (annotationTextRange == 'textBeforeRangeButIntersect') {
text = origText.substring(0, this.range.endOffset);
nextText = origText.substring(this.range.endOffset);
} else if (annotationTextRange == 'textAfterRangeButIntersect') {
prevText = origText.substring(0, this.range.startOffset);
text = origText.substring(this.range.startOffset);
} else if (annotationTextRange == 'textExactlyInRange') {
text = origText
} else if (annotationTextRange == 'textWithinRange') {
prevText = origText.substring(0, this.range.startOffset);
text = origText.substring(this.range.startOffset,this.range.endOffset);
nextText = origText.substring(this.range.endOffset);
} else if (annotationTextRange == 'textNotInRange') {
return;
}
span.textContent = text;
textParent = elem.parentElement;
textParent.replaceChild(span, elem);
if (prevText) {
var prevDOM = this.htmlDoc.createTextNode(prevText);
textParent.insertBefore(prevDOM, span);
}
if (nextText) {
var nextDOM = this.htmlDoc.createTextNode(nextText);
textParent.insertBefore(nextDOM, span.nextSibling);
}
return;
}
childCount = elem.childNodes.length;
for (var i = 0; i < childCount; i++) {
var elemChildNode = elem.childNodes[i];
if( Helper.isUndefined(elemChildNode.tagName) ||
! ( elemChildNode.tagName.toLowerCase() === 'span' &&
elemChildNode.classList.contains(this.annotationClass) ) ) {
addAnnotationElement(this, elem.childNodes[i]);
}
childCount = elem.childNodes.length;
}
}
function validateTextRange(this, elem) {
var textRange = document.createRange();
textRange.selectNodeContents (elem);
if (this.range.compareBoundaryPoints (Range.START_TO_END, textRange) <= 0) {
return 'textNotInRange';
}
else {
if (this.range.compareBoundaryPoints (Range.END_TO_START, textRange) >= 0) {
return 'textNotInRange';
}
else {
var startPoints = this.range.compareBoundaryPoints (Range.START_TO_START, textRange),
endPoints = this.range.compareBoundaryPoints (Range.END_TO_END, textRange);
if (startPoints < 0) {
if (endPoints < 0) {
return 'textBeforeRangeButIntersect';
}
else {
return "textExactlyInRange";
}
}
else {
if (endPoints > 0) {
return 'textAfterRangeButIntersect';
}
else {
if (startPoints === 0 && endPoints === 0) {
return "textExactlyInRange";
}
else {
return 'textWithinRange';
}
}
}
}
}
}