28

我有一个带有文本框和按钮的表单:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title></title>
</head>
<body>

<p><textarea rows="4" cols="30">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</textarea></p>
<p><input type="button" value="Click me"></p>

</body>
</html>

用户进行文本选择,然后单击按钮。由于 textarea 失去焦点,选择不再可见。

有没有办法让选择保持可见?它不需要可用(即,不需要例如键入删除选择或Ctrl+C复制它),但我希望文本区域包含选择的某种视觉反馈。

小样

演示:小提琴

4

8 回答 8

4
<textarea onblur="this.focus()">this is a test</textarea>
<p><input type="button" value="Click me"></p>

这在 IE/Chrome 上可以正常工作。但不是FF。


所以这是一个通用的解决方案:

<textarea onblur="doBlur(this)">this is a test</textarea>
<p><input type="button" value="Click me"></p>

<script>
function doBlur(obj) {
  setTimeout(function() { obj.focus(); }, 10);
}
</script>
于 2013-03-20T13:30:44.753 回答
4

在挖掘了 jsFiddle 之后,我发现CodeMirror拥有创建高度自定义的 textarea 所需的一切。它是为编写代码而构建的,但有一个小技巧,它可以应用于一般的文本区域。

演示

首先准备好一个textarea:

<textarea id="a">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</textarea>

然后在其后放置以下脚本以创建 CodeMirror 文本区域,并提供其他设置以将其转换为普通文本区域。

  • mode: 我"none"在这里使用删除语法高亮。
  • lineWrapping:用于true换行长行。
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("a"), {
    mode: "none",
    lineWrapping: true
});

最后,使用 CSS 来控制大小,让它看起来像一个标准的 textarea:

.CodeMirror {
    font-family: monospace;
    font-size: 12px;
    width: 300px;
    height: 100px;
    border: solid 1px #000;
}
于 2013-03-21T13:10:01.173 回答
3

您可以将 包装在textareaiframe,单击按钮时仍会在框架内显示选择。

此小提琴使用srcdoc仅 Chrome 和 Safari 6 支持的属性。不过,您仍然可以使用iframe没有该属性的 an 。

编辑:这是一个新的甚至更黑客的小提琴,它使用 jquery 添加,至少在 Chrome 和 FF 中有效(出于安全原因iframe,IE 不允许数据 URI )iframe

于 2013-03-20T12:52:26.287 回答
3

我知道这在技术上不是你想要的,但无论如何我都会作弊。

Javascript:

var textarea = document.getElementById('textarea');
var div = document.getElementById('holder');

var original_value = textarea.value;
textarea.onblur = function () {
    var start = textarea.selectionStart;
    var end = textarea.selectionEnd;
    textarea.style.display = "none";
    div.innerHTML = textarea.value.splice(end, 0, "</span>").splice(start, 0, "<span>");
    div.style.display = "block";
}

div.onclick = function () {
    div.style.display = "none";
    textarea.style.display = "block";
    textarea.value = original_value;
}

String.prototype.splice = function( idx, rem, s ) {
    return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
};

HTML:

<p><textarea id="textarea" rows="4" cols="30">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</textarea></p>
<div id="holder"></div>
<p><input id="click" type="button" value="Click me"></p>

CSS:

textarea, #holder{
    height: 120px;
    width: 300px;
    border: 1px solid black;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    padding: 3px;
    font-size: 10pt;
    font-family: Arial;
}
#holder{    
    display: none;
}
#holder span{
    background-color: #b4d5ff;
}

演示:http: //jsfiddle.net/Mb89X/4/

于 2013-03-20T13:17:52.033 回答
2

使用 textarea 无法实现您想要做的事情。

我建议不要使用 textarea ,而是使用divwithcontenteditable="true"rangy。然后包装选定的文本或选择焦点和模糊事件上的文本。

这个 rangy 演示演示了如何选择文本: http ://rangy.googlecode.com/svn/trunk/demos/highlighter.html

于 2013-03-20T13:16:37.793 回答
2

借鉴@Prisoner 的想法,我想进一步改进,直到它感觉像是具有滚动和调整大小功能的自然行为。

主要思想是一样的。我还在这里做了完整的演示和评论。我在下面重新发布这个问题的背景。

var input = document.getElementById('input');
var div = document.getElementById('holder');

function syncSize() {
    div.style.width = (input.scrollWidth - 4) + "px";
    div.style.height = input.style.height;
}

new MutationObserver(syncSize).observe(input, {
    attributes: true,
    attributeFilter: ["style"]
});

syncSize();

input.onchange = () => syncSize();

input.onblur = () => {
    var start = input.selectionStart;
    var end = input.selectionEnd;
    var text = input.value;
    div.innerHTML = text.substring(0, start) +
        "<span>" + text.substring(start, end) +
        "</span>" + text.substring(end);
    div.style.display = "block";
}

input.onfocus = () => div.style.display = "none";

input.onscroll = () => div.style.top = -input.scrollTop + "px";

input.value = "Lorem ipsum dolor sit amet";

input.select();
#container {
  position: relative; 
  overflow: hidden;
}

#input {
  width: 400px;
  height: 150px;
}

#holder, #input {
    padding: 2px;
    font: 400 13.3333px monospace;
    border: 1px solid #a9a9a9;
    white-space: pre-wrap;
    word-wrap: break-word;
}

#holder {
    display: none;
    position: absolute;
    left: 0;
    top: 0;
    color: transparent;
    pointer-events: none;
    border-color: transparent;
}

#holder span {
    background-color: #c8c8c8;
    color: black;
}
<div id="container">
  <textarea id="input"></textarea>
  <div id="holder"></div>
</div>

于 2018-03-02T08:34:57.157 回答
1

如果:focus按钮的无关紧要,您可以使用

$('input[type=button]').click(function () {
    $('textarea').focus();
});

这是小提琴

于 2013-03-20T13:12:48.557 回答
0

尝试这个:

var element = document.getElementById('text')
if(element.setSelectionRange)
{
    element.focus();
    element.setSelectionRange(2, 10);    
}
else if(element.createTextRange)
{

    var selRange = element.createTextRange();
          selRange.collapse(true);
          selRange.moveStart('character', 2);
          selRange.moveEnd('character', 10);
          selRange.select();
          field.focus();
} else if( typeof element.selectionStart != 'undefined' ) {
      element.selectionStart = 2;
      element.selectionEnd = 10;
      element.focus();
}

http://jsfiddle.net/inser/YJzvb/2/

于 2013-03-20T12:48:44.730 回答