我怎么可能完成这种Javascript突出显示技术

How can I possibly accomplish this Javascript highlighting technique?

本文关键字:显示 技术 Javascript 怎么可能      更新时间:2023-09-26
<div id="content" contenteditable="false" style="margin:-0.2em 1em; font-family:New Century Schoolbook; font-size:20; color:black; line-height:170%">
        <span style="margin-left:1.7em">Jenny was cute!</span>
        <span style="margin-left:1.7em">She looked happy with the instructor.</span>
        <span style="margin-left:1.7em">Can we meet her again?</span><br>
        <span style="margin-left:18em">Sakura</span>
    </div>

这是我为满足客户需求而创建的一些 HTML。 每个句子之间的左边距是这样我就可以在每个句子之间插入一个单独的图像(当图像在HTML中时,用户选择变得完全奇怪(。 用户需要能够选择、突出显示备忘录并将其添加到 iBook App 中的分区。 但是,与iBook应用程序不同,它需要使用格式化文本。 因此,它需要是可选的、可编辑的,并且在同一视图中支持粗体、斜体和下划线。 这是我想出的Javascript(HTML和Javascript的结果不符合标准,但我不在乎,因为这不会是一个网页,我受够了(:

function addHighlight(className, id)
{
    var html = '';
    var sel = window.getSelection().getRangeAt(0);
    var container = document.createElement('JimSpan');
    container.id = id;
    container.className = className;
    container.appendChild(sel.extractContents());
    var arrElements = document.getElementsByTagName('span');
    for(i = 0; i < arrElements.length-1; i++)
    {
        if(!arrElements[i].innerText.match(/'S/))
        {
            arrElements[i].parentNode.removeChild(arrElements[i]);
        }
    }
    sel.insertNode(container); 
    return 'js: ADDED HIGHLIGHT';
}

我必须使用"JimSpan"而不是"Span"的原因是用户还需要能够在页面未显示时删除注释,这意味着我必须使用正则表达式手动编辑它。 由于有大量的跨度,我不知道我的跨度何时真正结束。 除了一个例外,这很有效。 如果用户选择一个元素的所有内容和另一个元素的一部分,则结果如下:

<div id="content" contenteditable="false" style="margin:-0.2em 1em; font-family:New Century Schoolbook; font-size:20; color:black; line-height:170%">
    <jimspan id="memo0" class="pinkHilite"><span style="margin-left:1.7em">Jenny was cute!</span>
    <span style="margin-left:1.7em">She</span></jimspan><span style="margin-left:1.7em"> looked happy with the instructor.</span>
    <span style="margin-left:1.7em">Can we meet her again?</span><br>
    <span style="margin-left:18em">Sakura</span>
</div>

正如你在中间看到的,分裂导致了句子她看起来很高兴,导师被分成两个跨度,每个跨度都有左边距,而我在句子中间留下了一个巨大的空白。 我将接受以下任一情况:

1(一种让我生成以下(技术上无效,但显示正常(HTML(如果有办法的话,我不介意用正则表达式编辑当前范围(:

<div id="content" contenteditable="false" style="margin:-0.2em 1em; font-family:New Century Schoolbook; font-size:20; color:black; line-height:170%">
    <jimspan id="memo0" id="pinkHilite"><span style="margin-left:1.7em">Jenny was cute!</span>
    <span style="margin-left:1.7em">She</jimspan> looked happy with the instructor.</span>
    <span style="margin-left:1.7em">Can we meet her again?</span><br>
    <span style="margin-left:18em">Sakura</span>
</div>

2( 一种强制用户选择仅包含 1 个跨度内部的方法(选择必须更改,而不仅仅是受影响的突出显示区域(。

请帮助保存我的理智-__-;

选项 2 是最简单的解决方案,并且使用RangeSelection对象可以实现(排除 IE <9,这对UIWebView无关紧要,但对于想要在浏览器中做类似事情的人来说可以(。以下内容会将选择限制为包含用户开始选择的点的元素(注意:为了便于说明,它仅适用于基于鼠标的选择(:

现场演示:http://jsfiddle.net/U4smu/

法典:

function isOrIsDescendantOf(node, ancestor) {
    while (node) {
        if (node === ancestor) {
            return true;
        }
        node = node.parentNode;
    }
}
function selectionIsBackwards(sel) {
    var range = document.createRange();
    range.setStart(sel.anchorNode, sel.anchorOffset);
    range.setEnd(sel.focusNode, sel.focusOffset);
    var backwards = range.collapsed;
    range.detach();
    return backwards;
}    
document.onmouseup = function() {
    var sel = window.getSelection();
    var containerEl = sel.anchorNode;
    if (containerEl ) {
        if (containerEl .nodeType == 3) {
            containerEl = containerEl.parentNode;
        }
        if (!isOrIsDescendantOf(sel.focusNode, containerEl)) {
            var backwards = selectionIsBackwards(sel);
            var range = document.createRange();
            if (backwards) {
                range.setStart(containerEl, 0);
                range.setEnd(sel.anchorNode, sel.anchorOffset);
            } else {
                range.setStart(sel.anchorNode, sel.anchorOffset);
                range.setEnd(containerEl, containerEl.childNodes.length);
            }
            sel.removeAllRanges();
            sel.addRange(range);
        }
    }
};