简体   繁体   中英

How to be sure selected text doesn't contain a specific tag/class

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM