【问题标题】:Programmatically select text (like as done with a mouse) that matches string in a textarea element以编程方式选择与 textarea 元素中的字符串匹配的文本(就像使用鼠标一样)
【发布时间】:2013-03-17 15:14:34
【问题描述】:

考虑以下问题:

有一个像这样的文本区域:

<textarea id="body" name="body"></textarea>

还有一些简单的 JavaScript (jQuery) 可以将一些新文本插入到文本区域中,以便用户可以嵌入图像:

$('textarea').val($('textarea').val() + '[img]path to image file[/img]');

诀窍是在插入文本后自动突出显示 [img][/img] 标记之间的文本,这样用户就可以快速复制和粘贴他们的图像 URL,而不是手动选择,然后复制和粘贴。

我绞尽脑汁在整个互联网上试图弄清楚这一点,我能做的最好的就是这个流行的 StackOverflow 问题Selecting text in an element (akin to highlighting with your mouse),它只解决了在整个元素中选择文本的问题,它不是这里想要的。问题是选择与某个字符串匹配的文本,在本例中为path to image file,因此用户只需复制/粘贴即可。 (不确定这是否是最好的方法,但我就是这么想的……)。

这可能吗?我猜我们将需要getSelection() 和createRange(),但除此之外我不知道该去哪里......任何JavaScript 向导已经想出了这个?我觉得这可能是一个受欢迎的问题。使用 jQuery 很好,因为我已经在文档的其余部分使用它。

【问题讨论】:

  • 我也想知道如果没有 contenteditable div 或许多 WYSIWYG 编辑器中使用的类似解决方案,这是否可能。
  • 这可能会有所帮助(onfocus,以编程方式选择输入中的文本范围):stackoverflow.com/questions/646611/…

标签: javascript jquery html textarea selection


【解决方案1】:

你可以使用我的 jQuery 插件。它解决了文本区域选择操作中的浏览器差异,并有一些方便的方法:

https://code.google.com/p/rangyinputs/

对于您的示例,代码将是

var $textarea = $("#body");
var text = "path to image file"
$textarea.replaceSelectedText(text, "select");
$textarea.surroundSelectedText("[img]", "[/img]");

演示:http://jsfiddle.net/P8Jrh/1/

【讨论】:

  • 这不起作用,而是打印:path to image file[img][/img],然后不突出显示任何内容。不过,这似乎是一个好方法,知道可能出了什么问题吗?我不确定我是否能够查看您的整个源代码来弄清楚这一点。
  • @wnajar:对不起,你是对的:我相当傲慢地没有测试它并且记错了 API。正在修复...
  • @wnajar:另外,API 并不像我想的那样简单。稍后我将不得不进行更新。
  • Downvote 似乎有点苛刻,特别是因为这现在有效并且比接受的答案更有意义。
  • @wnajar:我更新了我的插件以简化这一点并更新了这个答案。
【解决方案2】:

实际上我自己想出了这个...我使用了 Rangy 库 https://code.google.com/p/rangy/ 和这样的代码:

 // Add text to the reply area at the very end, and move the cursor to the very end.
function insertText(textarea, text) {
    textarea = $(textarea);
    textarea.focus();
    textarea.val(textarea.val() + text);
    textarea.focus();
    // Trigger the textarea's keyup to emulate typing.
    textarea.trigger("keyup");
}

// Add text to the reply area, with the options of wrapping it around a selection and selecting a part of it when it's inserted.
function wrapText(textarea, tagStart, tagEnd, selectArgument, defaultArgumentValue) {
textarea = $(textarea);
    // Save the scroll position of the textarea.
    var scrollTop = textarea.scrollTop();
    // Work out what text is currently selected.
    var selectionInfo = textarea.getSelection();
    if (textarea.val().substring(selectionInfo.start, selectionInfo.start + 1).match(/ /)) selectionInfo.start++;
    if (textarea.val().substring(selectionInfo.end - 1, selectionInfo.end).match(/ /)) selectionInfo.end--;
    var selection = textarea.val().substring(selectionInfo.start, selectionInfo.end);
    // Work out the text to insert over the selection.
    selection = selection ? selection : (defaultArgumentValue ? defaultArgumentValue : "");
    var text = tagStart + selection + (typeof tagEnd != "undefined" ? tagEnd : tagStart);
    // Replace the textarea's value.
    textarea.val(textarea.val().substr(0, selectionInfo.start) + text + textarea.val().substr(selectionInfo.end));
    // Scroll back down and refocus on the textarea.
    textarea.focus();
    // If a selectArgument was passed, work out where it is and select it. Otherwise, select the text that was selected
    // before this function was called.
    if (selectArgument) {
        var newStart = selectionInfo.start + tagStart.indexOf(selectArgument);
        var newEnd = newStart + selectArgument.length;
    } else {
        var newStart = selectionInfo.start + tagStart.length;
    var newEnd = newStart + selection.length;
    }
    textarea.selectRange(newStart, newEnd);
    // Trigger the textarea's keyup to emulate typing.
    textarea.trigger("keyup");
}

var bbcode = {
    bold: function(id) {wrapText($("textarea"), "[b]", "[/b]", "", "bolded text");},
};

示例用法:

bbcode.bold();

完整代码(在我做过的一个更大的项目中):https://github.com/wnajar/textarea

【讨论】:

  • 如果这是答案,请将其标记为答案,以便将来对人们更有用。谢谢。
  • 只能在2天后标记为答案,因为我自己回答了。刚刚标记为答案(已过去 2 天)。
猜你喜欢
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 2011-09-02
  • 2022-01-23
  • 1970-01-01
  • 2011-06-21
相关资源
最近更新 更多