如何在文本段落中最好地使内联跨度可拖动?

时间:2014-08-12 19:39:52

标签: javascript jquery html5 selection rangy

我有一段文字,用户可以在其中放置一个“图钉”来标记一个位置。一旦放置了一个引脚,我想允许用户通过将其拖动到段落中的新位置来移动其位置。这对块元素来说很简单,但我还没有看到使用内联元素的好方法。我怎么能做到这一点?

我已经使用window.selection实现了它作为在段落中找到光标位置的方法,但它并不像我想的那样顺畅。

作为一个注释,我使用Rangy库来包装本机Range和Selection功能,但它的工作方式与本机函数相同。

以下是代码:

$(document).on("mousedown", '.pin', function () {
    //define what a pin is
    var el = document.createElement("span");
    el.className = "pin";
    el.id = "test";
    //make it contain an empty space so we can color it
    el.appendChild(document.createTextNode("d"));
    $(document).on("mousemove", function () {
        //get the current selection
        var selection = rangy.getSelection();
        //collapse the selection to either the front
        //or back, since we do not want the user to see it.
        if (selection.isBackwards()) {
            selection.collapseToStart();
        } else {
            selection.collapseToEnd();
        }
        //remove the old pin
        $('.pin').remove();
        //place the new pin at the current selection
        selection.getAllRanges()[0].insertNode(el);
    });
    //remove the handler when the user has stopped dragging it
    $(document).on("mouseup", function () {
        $(document).off("mousemove");
    });
});

这是一个有效的演示:http://jsfiddle.net/j1LLmr5b/22/

正如您所看到的,它(通常)有效,但用户可以看到正在进行的选择。有没有关于如何移动跨度而没有显示选择突出显示的想法?我也会接受一种根本不使用选择的替代方法。目标是尽可能干净地移动跨度。

3 个答案:

答案 0 :(得分:1)

试试这个我的朋友

el.appendChild(document.createTextNode("d"));

您已创建空的span标记,这就是您找到空的原因。

答案 1 :(得分:1)

之后添加      el.id =“test”;

这个

 var value = $('.pin').text();
 $(el).text(value);

您可以使用css隐藏选择

 ::selection {color:red;background:yellow;}
 ::-moz-selection {color:red;background:yellow;} 

这就是我现在可以为现在提供的帮助

答案 2 :(得分:1)

您可以使用范围代替使用与this answer类似的代码来执行此操作。不幸的是,代码有点长于理想,因为IE还没有实现document.caretPositionFromPoint()。然而,IE 11中仍然存在的旧的专有TextRange对象正在拯救。

这是一个演示:

http://jsfiddle.net/j1LLmr5b/26/

以下是相关代码:

var range, textRange, x = e.clientX, y = e.clientY;

//remove the old pin
$('.pin').remove();

// Try the standards-based way first
if (document.caretPositionFromPoint) {
    var pos = document.caretPositionFromPoint(x, y);
    range = document.createRange();
    range.setStart(pos.offsetNode, pos.offset);
    range.collapse();
}
// Next, the WebKit way
else if (document.caretRangeFromPoint) {
    range = document.caretRangeFromPoint(x, y);
}
// Finally, the IE way
else if (document.body.createTextRange) {
    textRange = document.body.createTextRange();
    textRange.moveToPoint(x, y);
    var spanId = "temp_" + ("" + Math.random()).slice(2);
    textRange.pasteHTML('<span id="' + spanId + '">&nbsp;</span>');
    var span = document.getElementById(spanId);
    //place the new pin
    span.parentNode.replaceChild(el, span);
}
if (range) {
    //place the new pin
    range.insertNode(el);
}