Vue でのテキストエリア適応高さソリューションの実装

Vue でのテキストエリア適応高さソリューションの実装

まず解決策を提示してください。Vueスタックが必要な学生はvue-awesome-textareaを直接ダウンロードできます。

隠れた問題

ネイティブ JS とは別に、フレームワークの UI ライブラリのほとんどは、適応型テキストエリアの高さ機能をサポートしていますが、一般的に見落とされがちな機能が 1 つあります。それが適応型の高さエコーです。

これらのライブラリを使用すると、テキストエリアにコンテンツを簡単に入力でき、範囲を超えると自動的に 1 行拡張されるため、コンテンツの適応性が高まります。コンテンツを送信し、同じ UI を使用して他のページでレンダリングすると、問題が発生します。一部の UI ライブラリはアダプティブ エコーをサポートしていないため、エコーを実現するには、行の高さ、行数、さらには高さの間の基本値を計算する必要があります。

適応高さのソリューション

一般的な解決策は 2 つあります。1 つは、ページの「リモート領域」にゴースト DOM を追加して、入力の改行をシミュレートすることです。この DOM は、editable 属性が true に設定された div または同一のテキスト領域である可能性があります。
element-uiの入力コンポーネントを例にとると、コンポーネントに値を入力すると、resizeTextareaメソッドが呼び出されます。

テキストエリアのサイズ変更() {
 if (this.$isServer) が戻ります;
 const { autosize, type } = this;
 if (type !== 'textarea') return;
 自動サイズ調整の場合
  this.textareaCalcStyle = {
   最小高さ: calcTextareaHeight(this.$refs.textarea).minHeight
  };
  戻る;
 }
 定数 minRows = autosize.minRows;
 定数maxRows = autosize.maxRows;

 this.textareaCalcStyle = calcTextareaHeight(this.$refs.textarea, minRows, maxRows);
}

autosize が true に設定されている場合、テキスト領域は適応型の高さに設定されます。このとき、テキストエリアの高さは calcTextareaHeight メソッドを通じてリアルタイムで計算されます。

エクスポートデフォルト関数calcTextareaHeight(
 ターゲット要素、
 最小行数 = 1、
 最大行数 = null
){
 if (!hiddenTextarea) {
  隠しテキストエリア = document.createElement('テキストエリア');
  document.body.appendChild(隠しテキスト領域)
 }

 させて {
  パディングサイズ、
  境界サイズ、
  ボックスサイズ、
  コンテキストスタイル
 } = ノードスタイルを計算します(ターゲット要素)。

 hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`);
 hiddenTextarea.value = targetElement.value || targetElement.placeholder || '';

 height = hiddenTextarea.scrollHeight; とします。
 定数結果 = {};

 if (boxSizing === 'border-box') {
  高さ = 高さ + 境界サイズ;
 } そうでない場合 (boxSizing === 'content-box') {
  高さ = 高さ - パディングサイズ;
 }

 隠しテキストエリアの値 = '';
 singleRowHeight を hiddenTextarea.scrollHeight - paddingSize とします。

 minRows !== null の場合 {
  minHeight = singleRowHeight * minRows とします。
  if (boxSizing === 'border-box') {
   minHeight = minHeight + パディングサイズ + 境界線サイズ;
  }
  高さ = Math.max(minHeight, 高さ);
  result.minHeight = `${minHeight}px`;
 }
 maxRows !== null の場合 {
  maxHeight = singleRowHeight * maxRows とします。
  if (boxSizing === 'border-box') {
   maxHeight = maxHeight + パディングサイズ + 境界線サイズ;
  }
  高さ = Math.min(maxHeight, 高さ);
 }
 result.height = `${height}px`;
 hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);
 隠しテキストエリア = null;
 結果を返します。
};

我々は見ることができる

if (!hiddenTextarea) {
  隠しテキストエリア = document.createElement('テキストエリア');
  document.body.appendChild(隠しテキスト領域)
}

Element-ui はテキストエリア DOM を作成し、calculateNodeStyling メソッドを通じて実際のテキストエリアのスタイルを hiddenTextarea にコピーします (オーバーフローは同期されず、実際のテキストエリアは非表示になります)。次に、textarea の入力値を監視し、それを hiddenTextarea に同期します。同時に、hiddenTextarea の scrollHeight を textarea の高さに同期し、最後に dom を破棄します。

スタイルの同期に関しては、要素は getComputedStyle と getPropertyValue の 2 つの API を使用します。もちろん、自分でラップする場合は、CSS プリプロセッサ ミックスインを使用することもできます。

2 番目のソリューションは最初のソリューションと似ていますが、追加の DOM は作成されません。冒頭の vue-awesome-textarea を例に挙げます。

初期化() {
  this.initAutoResize()
},
自動サイズ変更の初期化(){
  this.autoResize && this.$nextTick(this.calcResize)
}

ページがマウントされるか、コンテンツが変更され、autoResize がオンになっている場合、this.calcResize メソッドが実行されます。

 calcResize() {
 this.resetHeight()
 this.calcTextareaH()
},

リセット高さ() {
 this.height = 'auto'
},

calcTextareaH() {
 contentHeight = this.calcContentHeight() とします。
 this.height = this.calcHeightChange(contentHeight) + 'px'
 if (this.needUpdateRows(contentHeight)) {
  this.updateRows(コンテンツの高さ)
 }
 this.oldContentHeight = コンテンツ高さ
},

calcContentHeight() {
 const { パディングサイズ } = this.calcNodeStyle(this.$el)
 これを返します。$el.scrollHeight - paddingSize
},

resetHeight() はテキストエリアの高さを初期化するために使用され、デフォルトは auto です。 calcTextareaH() メソッドは、コンテンツ領域の高さ (テキスト領域の scrollHeight からパディングの高さを引いた値) を計算し、計算された高さをテキスト領域の高さにリアルタイムで同期するために使用されます。
this.height = this.calcHeightChange(contentHeight) + 'px'

ソリューション 1 と比較すると、このソリューションは同じアイデア (高さを動的に変更する) を採用していますが、追加の DOM 作成および破棄プロセスが削減されます。
さらに、vue-awesome-textarea は、適応プロセス中の行数のコールバックもサポートしており、データエコーをより適切にサポートできます。実装方法も非常に簡単です。

計算: {
 ...
 1行の高さ() {
  this.calcContentHeight() / Number(this.rows) || 0 を返します
 }
 ...
}

computed では 1 行の高さを計算し、this.calcTextareaH() メソッドを実行するときにコンテンツの高さを記録します。

 this.oldContentHeight = コンテンツ高さ

次に、行の追加操作があるかどうかを確認します。追加されている場合、新しいコンテンツの高さは古いコンテンツの高さと異なります。

行の更新が必要です(新しいコンテンツの高さ) {
  this.oldContentHeight !== newContentHeight を返します
},

この時点で、最新の行の高さをコンポーネントの外部に出力します。

行を更新(コンテンツの高さ) {
  this.$emit('getRows', Math.round(contentHeight / this.oneRowsHeight))
}

Vue での textarea の適応型高さソリューションの実装に関するこの記事はこれで終わりです。より関連性の高い Vue textarea の適応型コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • 入力行数を固定し、テキストエリアに下線スタイルを追加するVueのアイデアの詳細な説明
  • Vueはテキストエリア内の残りの単語の動的な表示を実装します

<<:  CSS3で実装されたテキストポップアップ効果

>>:  テーブル適応とオーバーフローのいくつかの設定の詳細な説明

推薦する

HTMLおよびJSPページがキャッシュされ、Webサーバーから再取得されるのを防ぎます。

ユーザーがログアウトした後、ブラウザの戻るボタンがクリックされると、Web アプリケーションは保護さ...

HTML のブロックレベル要素と行レベル要素、特殊文字、ネスト規則

基本的な HTML Web ページ タグのネスト ルールを紹介する場合、最初に説明する必要があるのは...

ナビゲーションデザインと情報アーキテクチャ

<br />ナビゲーションについて話すときは、ほとんどの場合、ナビゲーションがコンテンツ...

js はマウスによる画像の切り替えを実装します (タイマーなし)

この記事の例では、マウス切り替え画像を実現するためのjsの具体的なコードを参考までに共有しています。...

VUE ユニアプリの基本コンポーネントの簡単な紹介

1. スクロールビュー垂直スクロールを使用する場合は、固定の高さを指定して CSS で高さを設定する...

IE8 ベータ 1 には注意が必要な 2 つの領域があります

<br />関連記事: Web スキル: 複数の IE バージョンを共存させるソリューシ...

MySQL 5.7.9 シャットダウン構文例の詳細な説明

mysql-5.7.9 では、ついにシャットダウン構文が提供されます。以前は、MySQL データベー...

Jenkins統合Dockerプラグインの問題を解決するいくつかの方法

目次背景質問1エラー 2エラー 3エラー4要約する背景テスト環境では、docker プラグインを統合...

Mailtoを使えばHTMLでメールを送るのは簡単

最近、顧客のフッターメールボックスにクリックして送信するメール機能を追加しました。Baidu で検索...

MySQL をインストールした後に調整する必要がある 10 のパフォーマンス設定項目

このブログでは、MySQL データベースをインストールした後に調整することが推奨される 10 のパフ...

JS の効率的なマジック演算子の概要

JavaScript は現在、毎年新しいバージョンがリリースされており、より便利で効率的な新しい演算...

無効にしてHTMLフォーム入力を送信した後にフォーム値が取得されない問題を解決する方法

フォーム入力ボックスの入力をdisable属性に設定して送信すると、入力ボックスの値を取得できなくな...

カルーセルの制作方法を実現するjs

この記事では、カルーセル画像の表示を実現するためのjsの具体的なコードを参考までに共有します。具体的...

Vueのvue-tree-colorコンポーネントの組織構造図の事例を詳しく解説

目次ネプローダーをインストールするプラグインのインポート始める配置折りたたみディスプレイノードをクリ...

Docker Compose で利用可能な環境変数の詳細な説明

Compose のいくつかの部分は、何らかの方法で環境変数を扱います。このチュートリアルは、必要な情...