2014-02-05 66 views
0

不是专家在d3.js,环顾四周,找不到/了解如何实现这一点:突出显示文本事件d3.js

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

用户突出显示该段,其中火灾几句话一个事件,从高亮的顶部中间部分创建一行,然后直接进入供用户评论的框。

在d3.js中如何做到这一点? 是否有一个资源,我可以看看用d3.js操作文本?

感谢您的阅读!

+0

我不认为你将能够获得“行”的评论框工作;您将使用SVG绘图元素(总是绝对定位)混合HTML内容(包含基于窗口和字体大小的行逐行显示的文本)。 – AmeliaBR

回答

1

有趣的问题。恐怕d3无法按照您想象的方式做任何独特的工作,但标准JavaScript API中有一些方法可以提供帮助。

文档或窗口的.getSelection()方法将所选文本与关于文档树中的位置信息返回为selection object。但是,请注意,它似乎不支持在IE8或以下。

从那里开始工作,并使用.splitText()方法和其他基本的Javascript函数,可以在选定文本中的某一点处插入浮动的,可编辑的元素(或输入文本)。

在这个小提琴,我标志着,涉及到有红色星号显示,当你将鼠标悬停在或编辑评论的评论原文的观点:

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/

+0

感谢您的支持!我猜想,d3可能是不可能的,我做了类似于你在这里的事情,本质上是连续的,约80%的宽度用于文本,其余的20%只是空白。使用getSelection和一些基本的范围操作,可以找到从文档顶部到突出显示的单词/单词的距离,一旦获得高度,就可以轻松地在20%的区域中绘制一条简单的边界线在一边做一个盒子,使其与文档顶部的高度相同,以便出现在右边! – user1323136