当textarea失去焦点时显示选择

时间:2013-03-20 12:33:22

标签: javascript jquery html css

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

<!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 复制它)但我期望某种视觉反馈,textarea包含选择

Mockup

演示:Fiddle

8 个答案:

答案 0 :(得分: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>

答案 1 :(得分:3)

您可以将textarea包裹在iframe中,当点击该按钮时,该srcdoc仍显示框架内的选择。

This fiddle使用iframe属性,该属性仅受Chrome和Safari 6支持。但您仍然可以使用不含该属性的iframe

编辑:这是使用jquery添加iframe的{​​{3}},至少在Chrome和FF中有效(出于安全原因,IE不允许{{1}}中的数据URI )

答案 2 :(得分: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/

答案 3 :(得分:2)

使用textarea无法实现您的目标。

我建议您使用div contenteditable="true"rangy,而不是使用textarea。然后包装所选文本或选择焦点上的文本并模糊事件。

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

答案 4 :(得分:2)

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

请参阅DEMO

首先准备好textarea:

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

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

  • mode:我在此处使用"none"删除语法突出显示。
  • lineWrapping:使用true换行。{/ li>
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;
}

答案 5 :(得分:1)

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

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

这是Fiddle

答案 6 :(得分:1)

从@Prisoner那里得到这个想法,我想进一步改进,直到它感觉像滚动和调整大小功能的自然行为。

主要观点是一样的。我还制作了完整的演示文稿,评论为 here 。我在下面转发这个问题的背景。

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>

答案 7 :(得分: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/