2014-04-16 182 views
0

我試圖在文本編輯器中添加非常具體的功能。我的用戶不需要任何實際的文本格式或樣式,但通過將HTML元素放置到文本編輯器中,界面得到了極大的改進。將文本/ HTML插入所見即所得編輯器

我開始在我的表單的textarea的頂部使用jQuery Text Editor。我從頭文件中刪除了所有的格式化按鈕,所以它基本上只是一個textarea來呈現html。我的用戶將像文本編輯器一樣鍵入或粘貼多行文本。對我來說,棘手的部分來自將HTML插入該textarea。我在頁面上的其他地方有事件,單擊時,嘗試在jqte textarea中的當前光標位置添加一個按鈕。

我找到了jQuery snippet來幫我找到插入位置。將脫字符位置從div中拉出可讓我將第一個按鈕插入正確的位置。爲了維護我的按鈕元素,我必須提取文本字段的html(),但我不知道如何在html中僅獲取我的字符的位置,僅在文本中。我怎樣才能實現這個功能?

我創建了一個jsFiddle來演示我在做什麼。添加第一個按鈕可以正常工作,但是一旦我添加第二個按鈕,從文本字段的文本中獲取html子字符串就會使整個事情崩潰。

任何幫助表示讚賞,謝謝!

我不知道你離不開的代碼鏈接到的jsfiddle,所以這裏是我的HTML,CSS,和JS:

HTML

<div class='buttons'> 
    <button>Item A</button> 
    <button>Item B</button> 
</div> 
<textarea id='text'></textarea> 

<div class='btn-group hidden cloneable'> 
    <button type='button' class='btn btn-default dropdown-toggle' data-toggle='dropdown'> 
     <span class='name'></span> <span class='caret'></span> 
    </button> 
    <ul class='dropdown-menu' role='menu'> 
     <li><a href='#'>Function 1</a></li> 
     <li class='divider'></li> 
     <li><a href='#'>Function 2</a></li> 
    </ul> 
</div> 

CSS

.jqte_editor{ 
    height: 300px; 
} 

JS

$('#text').jqte({ 
    b: false, 
    center: false, 
    color: false, 
    fsize: false, 
    format: false, 
    i: false, 
    link: false, 
    left: false, 
    ol: false, 
    remove: false, 
    right: false, 
    rule: false, 
    source: false, 
    sub: false, 
    strike: false, 
    sup: false, 
    u: false, 
    ul: false, 
    unlink: false, 
    indent: false, 
    outdent: false 
}); 

var $jqte = $('div.jqte_editor'); 

$('.buttons').on('click', 'button', function(e){ 
    e.preventDefault(); 
    insertHtmlAtCaret($(this).text()); 
}); 

function insertHtmlAtCaret(text){ 
    var position = getCaretCharacterOffsetWithin($jqte.get(0)); 
    var front = $jqte.html().substring(0, position); 
    var back = $jqte.html().substring(position, $jqte.text().length); 

    var $group = $('div.cloneable').clone(); 
    $group.find('span.name').text(text); 
    $group.removeClass('hidden cloneable'); 
    $jqte.html(front).append($group).append(back); 
} 

function getCaretCharacterOffsetWithin(element){ 
    var caretOffset = 0; 
    var doc = element.ownerDocument || element.document; 
    var win = doc.defaultView || doc.parentWindow; 
    var sel; 
    if (typeof win.getSelection != "undefined") { 
     var range = win.getSelection().getRangeAt(0); 
     var preCaretRange = range.cloneRange(); 
     preCaretRange.selectNodeContents(element); 
     preCaretRange.setEnd(range.endContainer, range.endOffset); 
     caretOffset = preCaretRange.toString().length; 
    } else if ((sel = doc.selection) && sel.type != "Control") { 
     var textRange = sel.createRange(); 
     var preCaretTextRange = doc.body.createTextRange(); 
     preCaretTextRange.moveToElementText(element); 
     preCaretTextRange.setEndPoint("EndToEnd", textRange); 
     caretOffset = preCaretTextRange.text.length; 
    } 
    return caretOffset; 
} 

回答

2

花了一點時間,但找到了一個JS例子,足以讓我獲得我正在尋找的功能。有範圍的先驗知識,這似乎是解決方案的主要部分:

function insertButtonAtCaret(name) { 
    var node = document.createElement('div'); 
    node.innerHTML = $('div.cloneable').html(); 

    $(node).addClass('btn-group'); 
    $(node).find('span.name').text(name); 

    var selection = document.getSelection(); 
    selection.getRangeAt(0).insertNode(node); 
    selection.removeAllRanges(); 
} 

還有與一般的整個解決方案的一些小問題(按鈕名稱是在文本區域,可以更改),但這對我來說現在已經足夠了。