12

我有这个 html 和 css:http: //jsfiddle.net/b7rDL/6/

HTML:

<div class="text-block" contenteditable="true" spellcheck="false">Some Text</div>

CSS:

.text-block {
    resize: none;
    font-size:40px;
    border: none;
    line-height: 1;
    -moz-appearance: textfield-multiline;
    -webkit-appearance: textarea;
    min-width: 30px;
    overflow: visible;
    white-space: nowrap;
    display: inline-block;
}

此代码允许我编写没有宽度限制或高度限制的文本。它不显示滚动条,并随文本增长。这些基本上是我需要的功能。

  1. 如何将其转换为具有相同作用的常规文本区域?我希望这适用于未实现“contenteditable”的浏览器。因此,我想用 textarea 或其他基本元素替换 div。我该怎么做?(我不介意使用 JavaScript)。
  2. 如何禁用拼写检查器?spellcheck=false不起作用。在示例中,当我专注于文本框时,我得到了那条错误的红线。我正在使用火狐。
  3. 当我专注时如何摆脱边界?- 解决了

我不介意使用 JavaScript 来解决这些问题。

这些问题的任何答案都会对我有所帮助。

谢谢

更新:
@Oylex 帮了我 3

4

7 回答 7

9

#1

工作小提琴在这里:http: //jsfiddle.net/d9H9w/11/(在 IE8、Chrome 和 Firefox 中测试)

您需要在用户在文本框中键入时设置宽度和高度属性。

高度

这很简单:

  1. 获取textarea的内容
  2. 匹配换行符
  3. 将高度设置为 em 中换行符的总数(第一行加一个,摆动空间加 1.5)。

在 em 中设置高度使这个字体大小不可知,因此它可以与多种字体大小一起使用。

function getNewlines(){
    // get the value(text) of the textarea
    var content = textEl.value;

    //use regex to find all the newline characters
    var newLines = content.match(/\n/g);

    // use the count of newlines(+1 for the first line + 1 for a buffer)
    // to set the height of the textarea.
    textEl.style.height = ((newLines && newLines.length || 0)+2.5)+'em';
};

宽度

这也相当容易,只需一个陷阱。

  1. 获取textarea的内容
  2. 拆分换行符以获得由 textarea 行组成的数组
  3. 排序以获得最长的行
  4. 将宽度设置为 em 中最长字符串的长度,乘以大约 .6(我的代码中的 emRatio),再加上 2 个 em 作为缓冲区空间。

最后一部分是踢球者。'em' 测量值应该是一个正方形,表示单个字符占用的宽度和高度。这没有考虑字距调整,因此字符的高度通常是准确的,但宽度取决于它周围的字符。因此,通过猜测和检查,我发现 0.6 em 大约是字距调整后字符的平均宽度。.6 非常接近,所以我在宽度上添加 2 em 以获得一点缓冲空间。

var emRatio = .6;
function longestLine(){
    // get the value(text) of the textarea
    var content = textEl.value;

    // split on newline's. this creates an array, where each item in
    // the array is the text of one line
    var a = content.split('\n');

    // use a sorting function to order the items in the array:
    // longest string to shortest string
    a.sort(function(a,b){return b.length - a.length});

    // use the longest string * the emRatio to set the width
    // Due to kerning, the letters aren't ever really 1em x 1em
    // So I'm multiplying by an approximate ratio here (guess and check)
    textEl.style.width = (a[0].length * emRatio + 2)+ 'em';
};

此实现存在的问题

  • 为了支持在长按按键期间调整大小,还必须包含一个 onkeydown 处理程序(这对于不包括长按键的所有情况都不是最佳的)

考虑到所有因素,我认为这符合您的需求。

编辑

我没有将 emRatio 设为 .7,而是将其更改为 .6,并在宽度上添加了 2 em 的缓冲区。这解决了@Naor 在他的评论中提到的两个问题。

我更新了小提琴链接和宽度部分以反映更改。

于 2012-12-19T16:20:58.170 回答
4

编辑 0

请求 #1 更新

工作解决方案:http: //jsfiddle.net/7aeU2/

jQuery

$(function() {
    //  changes mouse cursor when highlighting loawer right of box
    $("textarea").mousemove(function(e) {
        var myPos = $(this).offset();
        myPos.bottom = $(this).offset().top + $(this).outerHeight();
        myPos.right = $(this).offset().left + $(this).outerWidth();

        if (myPos.bottom > e.pageY && e.pageY > myPos.bottom - 16 && myPos.right > e.pageX && e.pageX > myPos.right - 16) {
            $(this).css({ cursor: "nw-resize" });
        }
        else {
            $(this).css({ cursor: "" });
        }
    })
    //  the following simple make the textbox "Auto-Expand" as it is typed in
    .keyup(function(e) {
        //  the following will help the text expand as typing takes place
        while($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))) {
            $(this).height($(this).height()+1);
        };
    });
});​

请求 #2 更新

此外,这里很好地解释了为什么您不能完全禁用拼写检查。

这不属于 CSS 领域(这是可选的展示建议)。它不是关于呈现数据的风格特征,而是关于交互式处理数据。

在支持“拼写检查”(可能涉及语法和样式检查)的浏览器上spellcheck,可在 JavaScript 中设置的 HTML 属性或相应的 IDL (DOM) 属性是有效的。

在实践中,这些浏览器倾向于默认仅对 textareas 启用“拼写检查”,并且由于 textareas 通常包含人类语言文本,因此将其关闭听起来没什么用。在任何情况下,它都是用户可控的(用户可以将其关闭或选择语言)。

通过https://stackoverflow.com/a/9209791/1085891


请求 #1

  1. 简单的解决方案非常简单。

    工作示例:http: //jsfiddle.net/b7rDL/12/

    jQuery

    $("#Solution0").keyup(function(e) {   
        while($(this).outerHeight() < this.scrollHeight) {
            $(this).width($(this).width()+50);
        };
    });
    

    HTML

    <textarea id="Solution0" rows="1" style="height: 1.2em;"></textarea>
    
  2. 如果您想要扩展宽度而不是高度,则需要一些更新的更高级的解决方案。不过,还是很不错的。

  3. 其他解决方案- 我知道这些都扩大了高度。如果您需要以下解决方案之一的宽度实施,请告诉我。

请求 #2

spellcheck="true"应该按照 Mozilla 文档中的描述工作:控制 HTML 表单中的拼写检查。它适用于我在 Firefox 13.0.1 中运行的第一个简单示例。你运行的是什么版本?

于 2012-12-18T00:50:50.020 回答
3

对于#3,您正在寻找的 css 选项是:outline: none;

于 2012-12-13T17:09:00.550 回答
2

请求 #2

工作演示

<body spellcheck="false">
<div class="text-block" contenteditable="true">    
Some Text SpellCheck</div>

嗨 Naor,这个东西的唯一问题是它会禁用标签中所有元素的拼写检查。<body>如果你没关系,那么你可以随它去。

你的问题真的很有趣,很有挑战性,真的很喜欢。我希望这可以帮助你..!!

于 2012-12-20T07:16:36.970 回答
2

textarea我在确定' 内容的范围时遇到了麻烦,因此通过这种方法textarea,我将 这处理宽度和高度。pfloat: left;textareap

我已经在 Mac 10.8.1 FF 18.0、Safari 6.0、Chrome 25.0.1362.0 canary、iOS Safari 6.0.1 和 iOS Simulator 5.1 (272.21) 上进行了测试。我手边没有 PC 或 IE。

http://jsfiddle.net/b7rDL/34/

HTML

<textarea id="tx" class="text-block" spellcheck="false"></textarea>
<p id="dupe" class="text-block"></p>

CSS

.text-block {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    resize: none;
    font-size:14px;
    border: none;
    line-height: 1;
    min-width: 30px;
    overflow: hidden;
    white-space: pre;
    display: block;
    outline: none;
    width: 30px;
    height: auto;
    border: 1px solid #ddd;
    background-color: #f7f7f7;
}

#dupe {
    float: left;
    display: none;
    width: auto;
    height: auto;
}

我添加了背景和边框,所以我可以看到发生了什么。

JavaScript

// no `var` so they are global and easier to work
// with in the inspector when using jsFiddle

$tx = $('#tx');
$dupe = $('#dupe');
lineH = Number($tx.css('line-height').replace('px',''));

update();

$tx.on('keydown', function() {
    setTimeout(update, 0);
});
$tx.on('propertychange input keyup change', update);

function update() {
    $dupe.text($tx.val());
    $tx.css({
        width: $dupe.width() + 7,
        height: $dupe.height() + lineH
    });
}

// not sure if this is needed, leaving it because
// I don't have many browsers to test on
 $tx.on('scroll', function() {
     tx.scrollLeft = 0;
     tx.scrollTop = 0;
 });

我在右侧和底部添加了额外的空间,因为它似乎以这种方式表现得更加一致。此外,在 HTML 中,wrap="off"对于我正在使用的 Firefox 版本,这是必需的。

我从这篇博文中得到了一些很好的建议。

于 2012-12-22T20:18:27.737 回答
0

当我过去做了一些非常接近的事情时,对我来说最有效的方法是div使用与 textarea 完全相同的样式创建隐藏的流。而不是根据来自 textarea 的信息设置超时以更新其 html 源。这听起来有点吓人,但是,经过一些测试和玩耍,没有什么比这更好的了,这已经被建议了,所以只是我的变体。

http://jsfiddle.net/f2gAD/16/

和基于 jQuery 的脚本:

var textarea = $('textarea'),
    textBlock = $('div.text-block'),
    interval, value, freq = 10,
    doTextAreaAdjust = function(){
       textarea.css({
          height: textBlock.outerHeight(),
          width: textBlock.outerWidth()
       });
    };
doTextAreaAdjust();
textarea
.focus(function(){
    interval = window.setInterval(
        function() {
          value = textarea.val().replace(/(\r\n|\n|\r)/gm, '[rnnr]');
          value = value.replace(/</gm, '||'); // break html tags
          value = value.replace(/\[rnnr\]/gm, '<br>');
          value = value + '|'; // or <span>|</span> for better pixel perfect
          textBlock.html(value);
          doTextAreaAdjust();
        }, freq
    );console.log(interval);
})
.blur(function(){
    window.clearInterval(interval);
});
​

出于性能方面的考虑,它作为焦点/模糊的自启动/停止超时,尽管这里还需要一些解决方法。在 Chrome 中进行测试时注意到,如果您通过单击另一个选项卡进行模糊处理,则间隔不会正确停止。所以可能将自调用函数替换为setTimeout会更好。

它在 IE 7-8 中或多或少地工作正常,假设主要目标但仍然不时发生一些文本跳转,而对于其他人来说没关系,但猜测您将使用现代浏览器的可编辑功能。建议使用现代化器进行检测。

于 2012-12-23T14:37:55.303 回答
-1

在这里工作 http://jsfiddle.net/H2GSx/

此处代码:HTML:

<div style="overflow: scroll; width: 200px; height: 100px;">
    <div class="text-block" contenteditable="true" spellcheck="false">Some Text</div>
</div>​

CSS:

.text-block {
    resize: none;
    font-size:40px;
    border: none;
    line-height: 1;
    -moz-appearance: textfield-multiline;
    -webkit-appearance: textarea;
    min-width: 30px;
    overflow: visible;
    white-space: nowrap;
    display: inline-block;
}
​
于 2012-12-17T10:58:21.777 回答