質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

666閲覧

コンソール画面では同じ値に見えるのに、「===」での比較が「false」になってしまう

nikuatsu

総合スコア177

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2022/03/22 11:02

編集2022/03/22 11:35

実現したいこと

次のように<p><textarea>に置換しています。後に<textarea>の入力値が変更されたかどうかを判定したいです。

html

1<p>私は "太郎" です</p> 2 3<script> 4// p を textarea に置換 5const val = $('p').text(); 6const placeholder = htmlsce(val); 7$('p').replaceWith( `<textarea class="inp_name" placeholder="${placeholder}">${val}</textarea>` ); 8</script>

発生している問題

後に<textarea>の入力値が変更されたかどうかを判定したいので、初期値をplaceholderにセットしておき「<textarea>の入力値 === placeholderの値」での比較をしているのですが、

変更がないのにも関わらず「false」になってしまいます。

該当のソースコード

全体のソースコードはこちらで、isSameが「false」となるのが問題です。

https://jsfiddle.net/moch3pyt/

html

1<p>私は "太郎" です</p> 2 3<script> 4// HTML特殊文字変換(通常文字 → 特殊文字) 5var htmlsce = (function() { 6 const map = {' ':'&nbsp;','<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;',"'":'&apos;','©':'&copy;'}; 7 return function(text, charset) { 8 charset = charset && charset.replace(/([\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F])/g, '\\$&') || ''; 9 return text.replace(new RegExp('[ <>&"\'©'+charset+']', 'g'), function(match) { 10 if (map.hasOwnProperty(match)) { 11 return map[match]; 12 } else { 13 return '&#'+match.charCodeAt(match)+';'; 14 } 15 }); 16 }; 17})(); 18 19// HTML特殊文字変換(特殊文字 → 通常文字) 20var htmlscd = (function() { 21 const re = /&#x([0-9A-Fa-f]+);|&#(\d+);|&\w+;/g; 22 const map = {'&nbsp;':' ','&lt;':'<','&gt;':'>','&amp;':'&','&quot;':'"','&apos;':"'",'&copy;':'©'}; 23 return function(text) { 24 return text.replace(re, function(match, p1, p2) { 25 if (match.charAt(1) == '#') { 26 // 数値文字参照 27 if (match.charAt(2) == 'x') { 28 return String.fromCharCode(parseInt(p1, 16)); 29 } else { 30 return String.fromCharCode(p2-0); 31 } 32 } else if (map.hasOwnProperty(match)) { 33 // 定義済み文字実体参照 34 return map[match]; 35 } 36 return match; 37 }); 38 }; 39})(); 40 41// p を textarea に置換 42const val = $('p').text(); 43const placeholder = htmlsce(val); 44$('p').replaceWith( `<textarea class="inp_name" placeholder="${placeholder}">${val}</textarea>` ); 45 46// 「placeholderの初期値」と「textareaの入力値」が同じかどうか 47const inpName = $('.inp_name').val(); 48const iniName = htmlscd( $('.inp_name').attr('placeholder') ); 49const isSame = inpName === iniName; 50console.log( inpName ); // 私は "太郎" です 51console.log( iniName ); // 私は "太郎" です 52console.log( isSame ); // false 53</script>

試したこと

ご覧のようにコンソール画面で確認しており、明らかにinpNameiniNameも同じ値に見えます。
つまりHTML特殊文字変換の関数はいずれも正常に思われます。

ではなぜ「===」での比較が「false」になるのか疑問です。

JavaScript

1console.log( inpName ); // 私は "太郎" です 2console.log( iniName ); // 私は "太郎" です 3console.log( isSame ); // false

シンプルに以下にしても「fales」でした。(itagagakiさんのご指摘により訂正)
シンプルに以下にしたら「true」でした。

JavaScript

1const text = '私は "太郎" です'; 2const sce = htmlsce(text); 3const scd = htmlscd(sce); 4const isSame = scd === text; //(itagagakiさんのご指摘により訂正) 5 6console.log( sce ); // 私は "太郎" です 7console.log( scd ); // 私は "太郎" です 8console.log( isSame ); // true

また<textarea>ではなくcontenteditable=trueへの置換も試みてみたのですが、細かい仕様に対処できず断念致しました。

後に<textarea>の入力値が変更されたかどうかを判定するためには、上記の流れのどこを直すべきでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2022/03/22 11:04

== ではどうでしょうか。
takasima20

2022/03/22 11:20

エンコードしたやつとデコードしたやつを比較したらフツーに不一致では?
itagagaki

2022/03/22 11:26

const text = '私は "太郎" です'; const sce = htmlsce(text); const scd = htmlscd(sce); const isSame = sce === scd; これは本当は const isame = scd === text; をやってみたかったのかな?
nikuatsu

2022/03/22 11:31

itagagakiさん、意図を汲み取って頂きありがとうございます。仰る通りです。
guest

回答2

0

なんというか、その独自のエンコード、デコード関数を作るのはやめた方がいいと思います。その独自関数がバグっています。

投稿2022/03/22 11:42

arcxor

総合スコア2859

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nikuatsu

2022/03/22 11:57

ありがとうございます。attrはそのようにオブジェクトで書けるんですね。いいですね。こうすればダブルクオートがあっても問題ないですね。 関数はいつかどこかで拾ったものを何も考えずに使っていたので大いに反省です…。 でもコンソール画面には同じ値に見えるのにどうして、というのはやはり少し疑問です。
arcxor

2022/03/22 13:58

> でもコンソール画面には同じ値に見えるのにどうして、というのはやはり少し疑問です。 コードポイントを確認してください。空白が nbsp になっています。 https://codepen.io/arcxor/pen/BaJLqdR // [object Array] (10) [31169,12399,32,34,22826,37070,34,32,12391,12377] // [object Array] (10) [31169,12399,160,34,22826,37070,34,160,12391,12377]
nikuatsu

2022/03/22 15:41

すごい、こんな風に確認するんですね!どうもありがとうございます。大変勉強になりました。
guest

0

ベストアンサー

普通にやれば問題ないと思いますが・・・

javascript

1<script> 2window.addEventListener('DOMContentLoaded', ()=>{ 3 const p=document.querySelector('p'); 4 p.parentNode.insertBefore(Object.assign(document.createElement('textarea'),{placeholder:p.textContent,textContent:p.textContent}),p); 5 p.remove(); 6 document.querySelector('textarea').addEventListener('input',e=>{ 7 const t=e.target; 8 console.log(t.getAttribute('placeholder')===t.value); 9 }); 10}); 11</script> 12<p>私は &quot;太郎&quot; です</p>

念の為

javascript

1window.addEventListener('DOMContentLoaded', ()=>{ 2 const p=document.querySelector('p'); 3 const ta=document.createElement('textarea'); 4 ta.setAttribute('placeholder',p.textContent); 5 ta.value=p.textContent; 6 p.parentNode.insertBefore(ta,p); 7 p.remove(); 8 document.querySelector('textarea').addEventListener('input',e=>{ 9 const t=e.target; 10 console.log(t.getAttribute('placeholder')===t.value); 11 }); 12});

投稿2022/03/22 11:26

編集2022/03/22 12:22
yambejp

総合スコア114839

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nikuatsu

2022/03/22 12:00 編集

ありがとうございます。コード参考にさせていただきます。 「入力値」のダブルクオートと、「plaeholder=""」のダブルクオートとが衝突しないかと心配だったので質問のように変換関数を使ったのですが、Object.assignでplaceholderを指定すれば変換関数は不要だったのですね。勉強になりました。
yambejp

2022/03/22 12:03

> Object.assignでplaceholderを指定すれば変換関数は不要 普通にdocument.createElement('textarea')した上で、setAttribute('placeholder',値)でも行けるはずです。 その場合textareaのvalueプロパティを更新するほうが楽です
nikuatsu

2022/03/22 12:12

ご返信ありがとうございます。なるほど、私のテンプレートリテラルの方法が普通じゃなかったんですねwテンプレートリテラルでやろうとしてダブルクオートがネックになり、妙な変換関数を使おうとして、余計な混乱を招いてしまったようですね…呆れちゃいます(*´д`)=з
nikuatsu

2022/03/22 12:59

setAttribute版ありがとうございます。そちらも参考にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問