現在雑談掲示板を作成しており、ヤフー知恵袋のような入力可能な文字数をカウントする機能を考えているのですが、JavascriptのDOM-based XSS対策用にコードを組むのが難しく困っております。HTMLクラスを1つにしてifで分岐表示することは可能でしょうか?
アドバイスお願い致します。
エレメント事作る=そこでDOM要素が発生の原因になるため(無限DOM)、初めは入力文字のカウントを表示させずに入力されたら残りの文字数をカウントして、制限文字数をオーバーしたら超過した文字数を表示させるようにコードを考えました。
画像のアップロードが名前、メッセージの前になるので、参考サイトのどちらのコードを使えばよいのか分からず前者を使うようにしております。
※window.onload = function() {} は動かない原因になりうるため
window.addEventListener('DOMContentLoaded', function() {} を代用するように変更しております。
※参考サイト
https://took.jp/window-onload/
※アドバイス頂いたもの
submit_button_validationだけを使って
innerHTML="残り<span>"+v+"</span>文字入力できます。";
の時と、
innerHTML="span>"+v+"</span>文字超過しています。";
の時を、ifで制御すればOK
※考えたコード
<div class="title-partial parts"> <!-- title-partial + parts -->
<h2>名前(name)<span class="required">※必須</span></h2>
<div class=parts>
<input class=submit_button type="text" type="text" name="name1" id="name" data-length=32 placeholder="未入力の場合は、匿名で表示されます" value="<?php echo $namae; ?>">
<div class="submit_button_validation submit_button_validation"></div>
</div>
<div class="body-partial parts"><!-- body-partial + parts -->
<h2>コメント(comment)<span class="required">※必須</span></h2>
<div class=parts>
<input class=submit_button type="text" name="name2" id="message" data-length=40 placeholder="荒らし行為や誹謗中傷や著作権の侵害はご遠慮ください"><?php echo $message; ?>
<div class="submit_button_validation submit_button_validation"></div>
</div>
<script>
function validation_submit(f) {
const submit = document.getElementById("submit_button");
/* 判定は逆なので、逆に渡す */
/*JavaScriptの要素を活性または非活性にする */
submit.disabled = f?false:true;
};
function validation_text(parts) {
/* このpartsグループの、input=textを抽出 */
/* HTML要素を取得 */
let text=parts.getElementsByClassName('submit_button')[0];
/* バリデーション警告パーツを抽出 */
let validation=parts.getElementsByClassName('submit_button_validation')[0];
validation.style.display = 'none';
/* 例えばのチェック */
/* window.onload = function() {} を window.addEventListener('DOMContentLoaded', function() {} に変更 */
window.addEventListener('DOMContentLoaded', function() {
let wao = document.getElementsByClassName('submit_button_validation');
const left = text.dataset.length-text.value.length;
if (left >= 0) {
/* ひとまずclassは複数配置できる形式なので、見つかった最初の1個目にアタッチ */
wao[0].innerHTML="残り<span>"+v+"</span>文字入力できます。";
text.value.length === 0;
} else {
/* そのまま、2個目にアタッチ */
wao[1].innerHTML="<span>"+v+"</span>文字超過しています。";
}
})
};
/* バリデーション条件判断部分 */
function validation() {
let parts = document.getElementsByClassName('parts');
let submit=true;
for (let i=0;i<parts.length;i++) {
if (validation_text(parts[i])!=true) {
submit=false;
}
}
validation_submit(submit);
};
/* DOM構築が終わってから呼び出される初期化関数 */
function init() {
// let text = document.getElementById('submit_button');
// text.oninput = e_text;
/* ↑これを、idじゃなくてclass対応に変更↓ */
/* class=parts内の class=submit_buttonに対して設定 */
let parts = document.getElementsByClassName('parts');
for (let i=0;i<parts.length;i++) {
parts[i].getElementsByClassName('submit_button')[0].oninput = validation;
}
validation();
};
window.onload = init;
</script>
No.2ベストアンサー
- 回答日時:
No1です。
>function() {} でコードをまとめるよりも教えて頂いたように >document.addEventListener を使い、下記のコードを修正した
>ほうが良いのでしょうか?
documentでイベント処理をするのは、必ずしも効率が良くはありません。
(不要なイベントも拾ってしまうので)
No1の回答は、ご提示のHTMLの文書構造を理解できずわからなかったため、やむを得ず(確実な)documentに設定してあります。
(ですので、注書きしてあります。)
一方で、要素にイベント処理をバインドする場合は、当然ながら、対象要素が解釈された後でないと設定できません。
そのためには、onloadイベントを利用するなり、スクリプトの記述方法で対応するなどの方法をとる必要があります。(記述位置やdefer属性など)
https://developer.mozilla.org/ja/docs/Web/HTML/E …
「お礼」にご提示のスクリプトの場合は、イベント設定以前に要素を取得していますので、そのままの内容であれば、HTML解釈後に実行することが必要になります。
また、複数の要素に同じ処理を何度も設定するよりも、直近の包含要素に1回だけ設定しておくことで、後から要素を追加したりするような場合にも対応できるようにすることが可能です。
(そのようなことを行うのか/行わないのかは知りませんけれど・・)
ただし、この方法はバブリングするイベントでしか使えません。
A.アドバイスありがとうございます、なるほどdocumentでイベント処理した方が適切な場合とそうでない場合があるのですね。
対象要素が解釈された後に設定することを考えてwindow.addEventListener("load", init);を使い、
function init() {} 内に/* カメラ画像をファイルアップロード時に非表示にする */コードをまとめるように考えてみたのですが、
条件にあわせて送信ボタンの使用権限を操作する機能をどのように付け加えるべきか悩んでおります。
内部的に初期のDOM構築の時の値と後から書き換えた値の2つが存在するためテキスト解析させるよりもJS内変数でどのように格納した方が良いと指摘頂いており、
どのように対策すべきか分からず… アドバイスお願い致します。
※修正前のコード
https://wandbox.org/permlink/bEQJfRDHSjkJIwKT
function init() {
/* カメラ画像をファイルアップロード時に非表示にする */
省略
/* 文字数表示 */
document.addEventListener('input', e => {
if (!['name', 'message'].includes(e.target.id)) return;
const
t = e.target,
m = t.nextElementSibling,
n = t.value.length - (t.dataset.length | 0),
c = document.createElement('span');
c.append(Math.abs(n));
m.style.color = n > 0 ? 'red' : 'black';
m.replaceChildren(n > 0 ? '' : '残り', c,
`文字${n > 0 ? '超過してい' : '入力でき'}ます。`);
});
};
window.addEventListener("load", init);
No.1
- 回答日時:
こんばんは
なんだか複雑に考えすぎていませんか?
多分、これ(↓)と同じなのだと思いますけれど・・・
https://oshiete.goo.ne.jp/qa/13580015.html
原因となっている「innerHTML」を使用するのをやめれば済むだけのように思われます。
No2様の回答にもあるように内部的にエスケープしてくれる処理を用いれば簡単になります。
(一番気にすべきなのは、クライアント側のスクリプト処理ではなく、サーバー側での受信処理だと思いますけれど・・・)
※ 以下では、処理に直接必要のないクラス等はHTMLから一旦削除してあります。
※ ご提示のHTMLでは、開始-閉じタグの関係がおかしいので、文書構成がよくわからないため、documentにイベントを設定してあります。
(本来なら、直近の包含要素に設定するのが良いでしょう。)
※ また、type属性がダブって設定されていたりもするようです。
<!DOCTYPE HTML>
<html lang="ja">
<head><title>Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
document.addEventListener('input', e => {
if( !['name', 'message'].includes(e.target.id) ) return;
const
t = e.target, m = t.nextElementSibling,
n = t.value.length - (t.dataset.length | 0),
c = document.createElement('span');
c.append(Math.abs(n));
m.style.color = n>0?'red':'black';
m.replaceChildren(n>0?'':'残り', c,
`文字${n>0?'超過してい':'入力でき'}ます。`);
});
</script>
</head>
<body>
<div>
<h2>名前(name)<span>※必須</span></h2>
<input type="text" name="name1" id="name" data-length="32" placeholder="未入力の場合は、匿名で表示されます" value="">
<div></div>
</div>
<div>
<h2>コメント(comment)<span class="required">※必須</span></h2>
<input type="text" name="name2" id="message" data-length="40" placeholder="荒らし行為や誹謗中傷や著作権の侵害はご遠慮ください">
<div></div>
</div>
</body>
</html>
アドバイスありがとうございます、お聞きしたいことがあるのですが実は続きのコードにも問題がありまして、画面表示前にカメラ画像をファイルアップロード時に非表示にするコードが呼ばれると大変なことになるとのアドバイスを頂いているため、DOMツリー構築完了時にしか呼ばないようにしたいと考えて、window.onload = function() {} を使うように考えておりました。
問題の対策としてカメラ画像をファイルアップロード時に非表示にするコードをonloadリスナーにまとめるかonloadの後ろに挿入する必要があるのですが、window.onload = function() {} でコードをまとめるよりも教えて頂いたように document.addEventListener を使い、下記のコードを修正したほうが良いのでしょうか?解決策が分からずアドバイスお願い致します。
/* カメラ画像をファイルアップロード時に非表示にする */
const attach = document.querySelectorAll('.attach');
const del = document.querySelectorAll('.attachdel');
const clear = document.querySelectorAll('.attachclear');
const viewer = document.querySelectorAll('.viewer');
const changeImg = document.querySelectorAll('.changeImg'); // 入力されたら消す画像
for (let i = 0; i < attach.length; i++) {
attach[i].addEventListener('change', () => {
if (attach[i].files[0].size > 15 * 1024 * 1024) {
alert('ファイルサイズが 15MBバイトを超えています');
return;
}
del[i].value = "";
viewer[i].innerHTML = "";
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript 付属の写真のようにエラーが出るようにしたいです。 提示したコードだけでは、エラーメッセージ文字が上の 1 2021/11/23 08:27
- JavaScript javascriptとPHPで入力フォームのコードを書いているのですが、 流れとしては、①入力フォー 2 2021/12/02 09:18
- JavaScript JavascriptでXSSの脆弱性への対策を行いたい 2 2023/08/31 22:28
- JavaScript jqueryを使ったスムーススクロールのコードを書いたのですが、HTMLコード内にある、a butt 2 2022/04/14 10:59
- JavaScript 入力フォームの javascript で メールアドレスの正規チェックをを行い、ボタンをクリックして 2 2022/04/27 16:06
- JavaScript Javascriptが機能せず原因が分からないので教えて頂きたいです 3 2023/06/04 14:50
- HTML・CSS ボタンをクリックした時に、入力フォームのすぐ下部に、「入力欄が空白です」というテキストメッセージが表 1 2022/04/27 16:25
- AJAX jQueryを使いformでsubmitした時の位置を保持する方法について 4 2021/12/23 16:23
- JavaScript フォームが空欄の時にフォームの外をクリックすると、エラーが出るコードを調べています。 1 2023/06/25 11:51
- JavaScript ①入力フォーム→②確認表示画面→③送信完了画面のコードを書いているのです、 入力フォームから受け取っ 2 2022/05/10 16:45
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CSSでreadonlyの機能はあり...
-
【Javascript】ボタンクリック...
-
jQuery クリックした後の動き
-
javascriptで複数の表示・非表...
-
確認ダイアログを次からは表示...
-
「ご処理進めて頂きますようお...
-
エクセルで、日付を入力すると...
-
Excelシート上のマクロを登録し...
-
VBA エンターキーでイベントに...
-
VBAでループ内で使う変数名を可...
-
CloseとDisposeの違い
-
EXCEL VBA マクロ 実行する度に...
-
「PC Helpsoft Driver Updated...
-
エクセルVBAで、MsgBox やInput...
-
エクセルの画面にユーザーフォ...
-
UPS警告音を止めたい
-
UMLでの例外処理
-
switch の範囲指定
-
DoEventsがやはり分からない
-
EXCELの塗りつぶしのボタ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
確認ダイアログを次からは表示...
-
CSSでreadonlyの機能はあり...
-
折りたたみを全て開いて別ペー...
-
formのsubmitを押すとモーダル...
-
webサイトに動画をはりつけ、ク...
-
特定の条件のHTML要素を一括で...
-
javascriptで複数の表示・非表...
-
SITEINFOの書き方について
-
動画の上に広告をオーバーレイ...
-
3重のクォーテーション
-
iframe内のスクリプトを親から3...
-
javascriptのエラーで質問です。
-
(Mootools)スライドインするパ...
-
時間帯によって背景を切り替え...
-
jQueryを使用してのメガメニュ...
-
GoogleストリートビューAPIでイ...
-
Q&A掲示板の入力フォームに文字...
-
macかwinか判別しスタイルシー...
-
2回目以降のページロード時には...
-
JavascriptのHTMLクラス表示に...
おすすめ情報