突出显示文本事件d3.js

时间:2014-02-05 11:52:03

标签: javascript jquery d3.js

不是d3.js的专家,环顾四周,无法找到/理解如何实现这一点:

<p class='my-text'> Hi! this is a paragraph!</p>

用户突出显示该段落中的几个单词,这会触发一个事件,该事件从突出显示的中上部分创建一条线,然后直接进入一个框供用户评论。

如何在d3.js中执行此操作? 有没有一个资源,我可以看看用d3.js操纵文本?

感谢阅读!

1 个答案:

答案 0 :(得分:1)

有趣的问题。我担心d3无法做任何独特的事情,只能按照你想象的方式解决这个问题,但标准的Javascript API中有一些方法可以提供帮助。

文档或窗口的.getSelection()方法返回所选文本,其中包含有关文档树在selection object中的位置的信息。但请注意,它似乎在IE8或以下版本中不受支持。

在那里工作,并使用.splitText()方法和其他基本Javascript函数,可以在所选文本中的某个点插入浮动的,可编辑的<div>元素(或输入文本) 。

在这个小提琴中,我在原始文本中标记与评论相关的点,并在您将鼠标悬停在或编辑评论时显示红色星号:

http://fiddle.jshell.net/5sT7t/3/

密码:

function checkSelection(d,i) {
    var sel = document.getSelection();

    if (sel.isCollapsed) return;
      // The selection doesn't have any content,
      // i.e., it's just the cursor location,
      // so don't do anything.

    var commentBox = document.createElement("div");
    var commentMarker = document.createElement("span");
    //create new elements, not currently attached to anything

    d3.select(commentBox)
        .attr("class", "commentBox")
        .datum( sel.toString() ) //save for later reference??
        .text("Comment on \"" + sel.toString() + "\"")
        .attr("contentEditable", "true")
        .on("mouseup", stopEvent)
        .on("keyup", stopEvent); //don't trigger comments within comments!

    d3.select(commentMarker)
       .attr("class", "commentMarker");

    var split = sel.anchorNode.splitText( sel.anchorOffset );
    //split the text node containing the start of the selection
    //into two text nodes, and save the second one

    sel.anchorNode.parentNode.insertBefore(commentMarker, split);  
    sel.anchorNode.parentNode.insertBefore(commentBox, commentMarker);
    //insert the comment marker into the paragraph just before
    //the split point; insert the box just before the marker;
    //order is important, so that the marker's CSS can be 
    //dependent on the box's hover/focus state

    sel.anchorNode = split;
    sel.anchorOffset = 0;
    //shift the selection to only include content after the split
    //(this doesn't actually work...)
}

为了尝试更接近你所要求的东西,我用一个带有顶部边框作为“线”的长块替换了星号。但是,没有办法轻松设置该块的宽度以填充从文本中的任意点到边框上的注释框的空间,因此我不得不超调,然后使用包装器来隐藏溢出。如果有多个注释,则该行的高度也不匹配,这会导致注释框不再与它们所附加的文本行对齐。但这是你可以玩的东西:
http://fiddle.jshell.net/5sT7t/4/