2014-02-05 286 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