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」を実装していないブラウザでこれを動作させたい。したがって、divをtextareaまたは他のbasiv要素に置き換えたいと思います。どうすればいいですか?(JavaScriptを使用してもかまいません)。
  2. スペルチェッカーを無効にするにはどうすればよいですか?spellcheck=false動作しません。この例では、テキストボックスに注目すると、バグのある赤い線が表示されます。Firefoxを使用しています。
  3. 集中しているときにどうすれば境界線を取り除くことができますか?-解決済み

これらの問題を解決するためにJavaScriptを使用してもかまいません。

それらの質問に対するどんな答えも私を助けます。

ありがとう

更新:
@Oylexは3で私を助けました

4

7 に答える 7

9

#1

動作するフィドルはここにあります:http://jsfiddle.net/d9H9w/11/(IE8、Chrome、Firefoxでテスト済み)

必要なのは、ユーザーがテキストボックス内に入力しているときに、幅と高さの属性を設定することです。

身長

これは非常に簡単です。

  1. textareaのコンテンツを取得します
  2. 改行文字に一致
  3. emの改行文字の総数(プラス1行目は1文字、ウィグルルームは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つの落とし穴でかなり簡単です。

  1. textareaのコンテンツを取得します
  2. 改行文字で分割して、テキストエリアの行で構成される配列を取得します
  3. 並べ替えて最長の行を取得
  4. 幅をemの最長の文字列の長さに設定し、約.6(私のコードではemRatio)を掛け、さらにバッファスペースとして2emを掛けます。

その最後の部分はキッカーです。'em'の測定値は、1つの文字が占める幅と高さを表す正方形であると想定されています。これはカーニングを考慮に入れていないため、文字の高さは通常正確ですが、幅は周囲の文字によって異なります。したがって、推測と確認により、0.6emはカーニング後の文字の平均幅とほぼ同じであることがわかりました。.6はかなり近いので、少しのバッファスペースのために幅に2emを追加します。

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に変更し、幅に2emのバッファーを追加しました。これは、@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)属性が効果的です。

実際には、これらのブラウザでは、テキストエリアに対してのみデフォルトで「スペルチェック」が有効になっている傾向があります。テキストエリアには通常、人間の言語のテキストが含まれているため、オフにすると便利ではありません。いずれの場合もユーザーが制御できます(ユーザーはスイッチをオフにするか、言語を選択できます)。

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フォームでのスペルチェックの制御で説明されているように機能するはずです。これは、Firefox13.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同様のスタイルのp要素にコピーし、に設定してから、のfloat: left;サイズにtextarea基づいてサイズを変更しpます。これは、幅と高さの両方を処理します。

Mac 10.8.1 FF 18.0、Safari 6.0、Chrome 25.0.1362.0カナリア、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;
 });

右側と下部に余分なスペースを追加しています。これは、そのようにするとより一貫して実行されるように見えるためです。また、HTMLwrap="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 に答える