Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/452.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将文本/HTML插入所见即所得编辑器_Javascript_Jquery_Wysiwyg - Fatal编程技术网

Javascript 将文本/HTML插入所见即所得编辑器

Javascript 将文本/HTML插入所见即所得编辑器,javascript,jquery,wysiwyg,Javascript,Jquery,Wysiwyg,我试图在文本编辑器中添加非常特定的功能。我的用户不需要任何实际的文本格式或样式,但是通过能够将HTML元素放入文本编辑器,界面得到了极大的改进 我从在表单的文本区域顶部使用开始。我去掉了标题中的所有格式按钮,所以它基本上只是一个呈现html的文本区域。我的用户将像文本编辑器一样键入或粘贴多行文本。对我来说,棘手的部分是将HTML插入文本区域。我在页面的其他地方有一些事件,单击这些事件时,会尝试在jqte文本区域中的当前光标位置添加一个按钮 我找到了一个方法来帮助我定位插入符号的位置。从div中拉

我试图在文本编辑器中添加非常特定的功能。我的用户不需要任何实际的文本格式或样式,但是通过能够将HTML元素放入文本编辑器,界面得到了极大的改进

我从在表单的文本区域顶部使用开始。我去掉了标题中的所有格式按钮,所以它基本上只是一个呈现html的文本区域。我的用户将像文本编辑器一样键入或粘贴多行文本。对我来说,棘手的部分是将HTML插入文本区域。我在页面的其他地方有一些事件,单击这些事件时,会尝试在jqte文本区域中的当前光标位置添加一个按钮

我找到了一个方法来帮助我定位插入符号的位置。从div中拉出插入符号位置,我就可以在正确的位置插入第一个按钮。为了维护我的按钮元素,我必须提取文本字段的html(),但我不知道如何在html中获取我的角色的位置,而只是在文本中。如何实现此功能

我创建了一个示例来演示我在做什么。添加第一个按钮可以很好地工作,但是一旦我添加了第二个按钮,从文本字段的文本中获取html的子字符串就会使整个过程崩溃

感谢您的帮助,谢谢

我没有意识到没有代码就无法链接到JSFIDLE,所以下面是我的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>
JS

.jqte_editor{
    height: 300px;
}
$('#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;
}

花了一点时间,但找到了一个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();
}
总的来说,整个解决方案仍然存在一些小问题(按钮名称在文本区域中,可以更改),但这对于我现在的工作来说已经足够了