I have the following function to add a span tag with selected text.
function Add() {
var selObj = window.getSelection();
var selRange = selObj.getRangeAt(0);
var newElement = document.createElement("span");
newElement.setAttribute("class", "cls1");
var documentFragment = selRange.extractContents();
newElement.appendChild(documentFragment);
selRange.insertNode(newElement);
selObj.removeAllRanges();
}
It works fine. But I want to prevent adding a new span inside another one.
<a href="#" onclick="Add()">Add Span</a>
<div id="content">
Lorem ipsum dolor sit amet, <span class="cls1">consectetur adipisicing</span> elit,
</div>
If the user selects "adipisicing elit" I don't want to create a new span as "adipisicing" is inside another one. So how can I know whether the selected text includes any part of other span?
Thanks.
Here's one approach, that tests if the current selection is directly part of a <span class="cls1">
. You can add it after the first line of your function, since it uses selObj
as a starting point.
if ("cls1"!==selObj.anchorNode.parentNode.className) {
If it has to be a span:
if ("span"!==selObj.anchorNode.parentNode.tagName.toLowerCase()) {
To make sure BOTH ends of the selection are outside a span, use focusNode
as well:
if ("span"!==selObj.anchorNode.parentNode.tagName.toLowerCase() &&
("span"!==selObj.focusNode.parentNode.tagName.toLowerCase()) {
Combining everything:
if ("cls1"!==selObj.anchorNode.parentNode.className &&
"span"!==selObj.anchorNode.parentNode.tagName.toLowerCase() &&
"cls1"!==selObj.focusNode.parentNode.className &&
"span"!==selObj.focusNode.parentNode.tagName.toLowerCase()) {
http://jsfiddle.net/mblase75/Zg5LW/
https://developer.mozilla.org/en-US/docs/DOM/Selection/anchorNode
https://developer.mozilla.org/en-US/docs/DOM/Selection/focusNode
At last I figured out how to achieve this. To sum up I need to check :
1. Whether selection is inside a specific class ("cls1") element.
2. Whether selection contains one or more specific class ("cls1") element.
3. Whether selection contains some part of a specific class ("cls1") element.
Thanks to @Blazemonger's code I could achieve 1. and 3. items:
if ("cls1" == selObj.anchorNode.parentNode.className || "cls1" == selObj.focusNode.parentNode.className)
{ return true; }
And two I added the following part which checks for 2. and 3. items:
var docFrag = selRange.cloneContents();
var childNodes = docFrag.childNodes;
for (var i = 0; i < childNodes.length; i++) {
var nodee = childNodes[i];
if ($(nodee).hasClass("cls1") || $(nodee).find(".cls1").length > 0)
{ return true; }
}
So I wrote a checking function combining the two:
function ContainsDiv(selRange)
{
var docFrag = selRange.cloneContents();
var childNodes = docFrag.childNodes;
for (var i = 0; i < childNodes.length; i++) {
var nodee = childNodes[i];
if ($(nodee).hasClass("cls1") || $(nodee).find(".cls1").length > 0)
{ return true; }
if ("cls1" == selObj.anchorNode.parentNode.className || "cls1" == selObj.focusNode.parentNode.className)
{ return true; }
}
And I used this function inside Add() :
function Add() {
var selObj = window.getSelection();
var selRng = selObj.getRangeAt(0);
if (ContainsDiv(selRng)) {
return;
}
var newElement = document.createElement("span");
newElement.setAttribute("class", "cls1");
var documentFragment = selRng.extractContents();
newElement.appendChild(documentFragment);
selRng.insertNode(newElement);
selObj.removeAllRanges();
}
var parentNode = selObj.parentNode;
if (parentNode.nodeName == "SPAN")
{
//don't add
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.