如何在选择期间停止javascript自动添加标签?

时间:2014-07-22 09:20:09

标签: javascript jquery html

请参阅Fiddle Here

基本上它是一款近乎完美的文字荧光笔。

<p><br> 等标记在选择范围内时,问题就出现了。

JavaScript似乎自动添加标签

如果你去 filterHtmlLevels 并添加alert(htmlStr);, 然后,当您选择两个段落中的文本区域时,您可以看到它已添加 <p> 标记,而不应该是

我可以使用 .replace ,但不确定如何安全地保留DOM结构。

修改

我发现它发生在函数getSel()期间,它在选择周围包裹div。不确定如何更改此项以不添加额外标签 - 即将html视为字符串

1 个答案:

答案 0 :(得分:0)

修正(仅测试铬):

http://jsfiddle.net/6L58X/

请评论任何更新/改进,或编辑!

记录链接是否死亡:

JS:

$('#highlightable').bind('mouseup', function () {
    highlight();
});


function highlight() {
    // not IE case
    var selHtml;
    if (window.getSelection) {
        selHtml = getSel();
    }
    // IE case
    else if (document.selection && document.selection.createRange && document.selection.type != "None") {
        selHtml = getSelIE();
    }
    else { return; }
    if(selHtml.length == 0) { return; }
    var allhtml = $('#highlightable').html().toString();
    var temphhtml = '<div class="temph">';
    var pos = allhtml.indexOf(temphhtml);
    var endpos = pos + selHtml.length;

    var preSelStr = allhtml.substring(0, pos);
    var postSelStr = allhtml.substring((pos + temphhtml.length + selHtml.length + 6), allhtml.length);

    preSelStr = cleanEnd(preSelStr);
    postSelStr = cleanStart(postSelStr);

    //alert(preSelStr+'          '+postSelStr);
    var prepend = '<span class="highlighted">';
    var postpend = '</span>';

    var cs = countSpans(preSelStr);
    if (cs > 0) {
        prepend = '';

        var insSS = locations('<span class="highlighted">', selHtml);
        var insSE = locations('</span>', selHtml);

        if (insSS.length > insSE.length) {
            postpend = postpend + '<span class="highlighted">';
        } else if (insSS.length == insSE.length) {
            postpend = '';
        }
    }
    var newSelStr = filterHtmlLevels(selHtml, allhtml);
   // alert(newSelStr);
    var newHtml = preSelStr + prepend + newSelStr + postpend + postSelStr;
    //  alert(newHtml);
    $('#highlightable').html(newHtml);

}

function cleanEnd(preSelStr) {
    var tags = ["</p>", "</ p>"];
    if (typeof String.prototype.endsWith != 'function') {
        String.prototype.endsWith = function (str) {
            return this.slice(-str.length) == str;
        };
    }
    for (var i = 0; i < tags.length; i++) {
        if (preSelStr.endsWith(tags[i])) {
            var len = tags[i].length;
            var cleanStr = preSelStr.substring(0, preSelStr.length - len);
            return cleanStr;
        }
    }
    return preSelStr;
}

function cleanStart(postSelStr) {
    if (typeof String.prototype.startsWith != 'function') {
        String.prototype.startsWith = function (str) {
            return this.slice(0, str.length) == str;
        };
    }
    var tags = ["<p>", "<br />", "<br/>"];
    for (var i = 0; i < tags.length; i++) {
        if (postSelStr.startsWith(tags[i])) {
            var len = tags[i].length;
            var cleanStr = postSelStr.substring(len, postSelStr.length);
            return cleanStr;
        }
    }
    return postSelStr;
}

function filterHtmlLevels(htmlStr, allhtml) {
    var newStr = htmlStr.replace(/<span class="highlighted">/g, "");
    newStr = newStr.replace(/<\/span>/g, '');
    newStr = cleanEnd(newStr);
    newStr = cleanStart(newStr);
   // alert(htmlStr);
     newStr = newStr.replace(/<p>/g, '</span><p><span class="highlighted">');
      newStr = newStr.replace(/<\/p>/g, '</span></p><span class="highlighted">');
    return newStr;
}

function locations(substring, string) {
    var a = [],
        i = -1;
    while ((i = string.indexOf(substring, i + 1)) >= 0) a.push(i);
    return a;
}

function getSel() {
    var selObj = window.getSelection();
    var selRange = selObj.getRangeAt(0);
    var newElement = document.createElement("b");
    var documentFragment = selRange.extractContents();
    newElement.appendChild(documentFragment);
    var filteredElement = divWrap(newElement.innerHTML);
    selRange.insertNode(filteredElement);
    selObj.removeAllRanges();
    return filteredElement.innerHTML.toString();
}

function getSelIE() {
    var range = document.selection.createRange();
    var selectedText = range.htmlText;
    var newText = '<div class="temph">' + selectedText + '</div>';
    document.selection.createRange().pasteHTML(newText);
    return newText;
}

function divWrap(htmlString) {
    var wrapper = document.createElement('div');
    wrapper.className = "temph";
    wrapper.innerHTML = htmlString;
    return wrapper;
}

function countSpans(preSelStr) {
    // returns 0 if same num, > 0 if more span starts
    var StartSpans = locations(preSelStr, '<span class="highlighted">');
    var EndSpans = locations(preSelStr, '</span>');
    var count = StartSpans.length - EndSpans.length;
    return count;
}

HTML:

<div id="highlightable">
    <p id="p1">stibulum nisl orci, viverra in sollicitudin sed, iaculis vel erat. Nam lacus quam, volutpat et porta non, consequat ac tortor. Fusce non lorem vitae</p>
    <p>libero imperdiet convallis. Morbi vestibulum viverra ligula, porttitor dapibus justo dictum ut. Pellentesque eget laoreet metus. Curabitur rhoncus consectetur nulla, id imperdiet nulla pellentesque sit amet. Cras sodales arcu ac orci suscipit pulvinar sollicitudin risus gravida. Praesent condimentum erat sit amet ipsum tristique mattis. Cras dolor ante, hendrerit vel suscipit a, pellentesque sit amet felis. Vivamus suscipit, tellus ut sollicitudin pulvinar, odio urna auctor quam, ut bibendum ipsum arcu ac nibh. Phasellus sollicitudin, ipsum at pretium consectetur, arcu nisi auctor quam, a lobortis erat neque viverra diam. Nam congue libero sed est gravida dignissim. Nulla pulvinar condimentum diam in porta. Aenean id interdum odio. Fusce cursus sagittis urna dictum scelerisque. Sed nunc massa, cursus et pharetra at, ullamcorper vel est. Aliquam erat volutpat. Ut accumsan commodo lorem, gravida rutrum diam venenatis eu.</p>
    <p id="p2">stibulum nisl orci, viverra in sollicitudin sed, iaculis vel erat. Nam lacus quam, volutpat et porta non, consequat ac tortor. Fusce non lorem vitae libero imperdiet convallis. Morbi vestibulum viverra ligula, porttitor dapibus justo dictum ut. Pellentesque eget laoreet metus. Curabitur rhoncus consectetur nulla, id imperdiet nulla pellentesque sit amet. Cras sodales arcu ac orci suscipit pulvinar sollicitudin risus gravida. Praesent condimentum erat sit amet ipsum tristique mattis. Cras dolor ante, hendrerit vel suscipit a, pellentesque sit amet felis. Vivamus suscipit, tellus ut sollicitudin pulvinar, odio urna auctor quam, ut bibendum ipsum arcu ac nibh. Phasellus sollicitudin, ipsum at pretium consectetur, arcu nisi auctor quam, a lobortis erat neque viverra diam. Nam congue libero sed est gravida dignissim. Nulla pulvinar condimentum diam in porta. Aenean id interdum odio. Fusce cursus sagittis urna dictum scelerisque. Sed nunc massa, cursus et pharetra at, ullamcorper vel est. Aliquam erat volutpat. Ut accumsan commodo lorem, gravida rutrum diam venenatis eu.</p>
</div>

CSS:

.highlighted {
    color: red;
}