トップ・ページの表示 注意書きの表示 掲示板に書き込む前に必ず この ”注意書き”を お読み下さい.

"沙羅"

★この掲示板は書き込みを停止いたしました 。
記事の書き込みはリンク・ページの表示 http://ashtarte.hotcom-web.com/utf8/smt.cgi?r+rpr/ を ご利用 下さい。

   
   

ページの表示順:{ 新しい順/ 古い順}.
初期・ページの表示・位置:{ 先頭ページ/ 末尾ページ}.
1ページ内のスレッド表示数:







<Number>: [00000398]  <Date>: 2024/02/01 15:20:49
<Title>: プログラミング言語人気ランキング
<Name>: amanojaku@管理人

現在 バックエンドにおいて素のPHPの案件は減少傾向にあるらしいですが、PHP系フレームワークの「CakePHP」は人気があるらしいです(「CakePHP」は「Ruby on Rails」の概念を取り入れているらしいので、それが人気の秘訣だと思われる)。
なお WordPressで当然 PHPを使いますが、これはフロントエンドの話です。

参考

CakePHPとは?基礎知識とできることをわかりやすく解説
https://hnavi.co.jp/knowledge/blog/cakephp/

>PHPのプログラム言語で使用するフレームワークは、機能の拡張性に優れるLaravel(ララベル)や、処理速度の速さに定評のあるCodeigniter(コードイグナイター)など、バリエーションに富んだフレームワークが数多く存在します。令和の現代においては、Laravelがシェアを伸ばしつつありますが、国内人気や汎用性の高さに関しては、CakePHPが依然として人気を集めています。

ネットでは「Laravel」が1番 人気があるなどと書かれていますが、それはアマチュアの世界の話しで、Web系(のプロの世界)では「CakePHP」が1番 人気が有るようです。
なお「CakePHP」だけでは不安なら「Laravel」も勉強すると良いでしょう。


Web系は即戦力が求められます。
(Web系は即戦力が求められるので)Web系では資格は意味無いらしいです(他のIT系では資格が評価される場合も有るようですが)。
Web系はフリーランスが基本で、奇跡でも起こらない限り就職は無理と思って下さい。


3DゲームにおいてはUnity(3Dゲームエンジン)がメジャーです。
Unityはプログラミング言語ではなく、ザックリと言うとライブラリです。
ゲームに必要な当たり判定や衝突した場合の反射などの処理が簡単にできるらしいです。
Unity用の開発言語はC#らしいので、Unityを使いたいならC#が必須になります。


プログラミング言語利用実態調査2023
https://xtech.nikkei.com/atcl/nxt/column/18/02670/112900001/
プログラミング言語利用実態調査2022
https://xtech.nikkei.com/atcl/nxt/column/18/02246/110200002/


(本来 PythonはAI専用言語ではありませんが)Pythonの主な案件はWebスクレイピングなので、AIの知識は必要ですし、CSSセレクタに関する深い知識も必要のようです(「Webスクレイピング」はググって下さい)。
Webスクレイピング以外でも大半はAI系(画像認識も含む)だと思われるので、PythonはAIの知識は必須だと思って下さい
Web系はフリーランスが基本です。
つまりAIに興味がないなら(AIを勉強する気がないなら)Pythonを勉強する必要はないでしょう。
Python本体の機能は貧弱らしいですが、ライブラリーで補強できるので問題ないと思われます(AIライブラリだけでなく数学ライブラリも豊富らしいです)。
下記はWebスクレイピングを勉強している人からの質問です。
(最低限)当方のCSSセレクタに関する回答やクイズが理解できるレベルが推奨されます。

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13260657988

もっと具体的に言うなら下記の高度なCSSが自分で組めるレベルが推奨されます。

CSSデモ集(-)
http:../utf8/smt.cgi?r+twilight/&bid+0000025C&tsn+0000025C&bts+2021/12/01%2006%3A41%3A07&

つまりAIの場合は、AI自体の勉強と、その分野の勉強も必要になります。
例えばAIで"経済"を予測するなら"経済"の勉強も必要になると言う事です。


JavaはWeb系ではイマイチ人気は無いような感じです(皆無と言う事ではありませんが)、基幹系ベンダーならJavaを使うと思いますが、(Web系に比べ)基幹系ベンダーは可成り数が少ないと思われるので、就職の難易度は高いと思われます(絶対に不可能と言うことでは無いのでトライしてみるのも良いでしょう)。
Androidなら需要はあるようです(Android系はフリーランスが基本で、奇跡でも起こらない限り就職は無理と思って下さい)、ただしKotlin(コトリン)は日本のプロの世界ではイマイチ人気が無いので推奨しません。
基礎なら素のJavaで勉強しても良いですが、素のJavaとAndroid JavaはGUI APIは別物ですし、またAppletをメッチャ高度化したようなActivityと言うライフ・サイクルの理解も必要になります(なおActivityのstaticフィールドは意図せず初期化されることが有るので要注意)。
機種によって解像度が違うので特定の解像度に依存しないプログラミングが必要とか、機種によって挙動が違うとか、それなりのスキルが要求されます、3Dのスキルがあると更に良いでしょう。
なおAndroidエミュレータでは無く、実機デバッグを強く推奨します。


「Android端末を購入する場合の注意点」
勉強する場合は、意図的に解像度が全く違う機種を2台用意してみると良いでしょう、中古なら1万円前後で買えます、(見た目のグレードはB以上を推奨)。
プロも出来るだけシェアを大きく取りたいので「Android OS 4.4=API Level 19」以降対応とかで作ることも有るので、最新の端末である必要は有りません。
とりあえず「Android OS 6系=API Level 23」以降で良いです(6以降でパーミッション係が大幅に変更されているので)。
ただしAndroid OS 6系端末はメモリーをガバガバ喰うクソ端末なのでストレージは32GByte以上が必須、Android OS 7以降の端末ならストレージは16GByte以上あれば良いですが、Android OS 7系端末は発売当初バグが頻発した(一部の端末でハードウエアを破壊するような深刻なバグも発生した)ために非常に評判が悪かったです。
最新のパッチ済みOSがインストールされていれば問題ないですが、最新のパッチ済みOSの配布サービスが終了している場合はOSをアップデートできないので注意が必要です。
とりあえずAndroid OS 8以降の端末にすると良いでしょう。
Android OS 6未満の端末も勉強したいなら、とりあえずAndroid OS 4系のAndroid OS 4.4以降を1台買っておくと良いでしょう。
Android OS 5系だとOSが6系にアップデートされている危険が有るので注意が必要です、稀にAndroid OS 4系でもOSが6系にアップデートされている可能性も有り得るので、買う前にとりあえずWikipediaで対象の端末の最大バージョンを確認しておきましょう(Wikipediaが不正確な場合も有りますが)。
中華端末はバックドアが仕込まれている可能性があるので要注意です、表面的に中華端末で無くても新品で格安端末なら ほぼ中華製と考えて良いでしょう。
例えばSHARPは中華系に買収されたので、SHARP端末も要注意です。


超ザックリと言うと「C、C++」は高級アセンブラのようなモノなので、それが「C、C++」が難しいと言われる ゆえんです。


C#は内部的にJavaだと揶揄されており、「C、C++」より習得が容易だとされています(Javaレベルの難易度だと言われている)。
C#は内部的にJavaなので、当然パフォーマンス的には「C、C++」より劣ります。


Rust(ラスト)言語はメモリーセーフで、(メモリーアンセーフな)「C、C++」に代わる言語として非常に有望視されています(ただし日本ではまだまだマイナー)。

プログラミング言語 栄枯盛衰?
http:../utf8/smt.cgi?r+twilight/&bid+000001B1&tsn+000001B1&bts+2021/08/09%2005%3A27%3A39&


(バックエンド)「Ruby on Rails」(フリーランス)の案件は「Ruby on Rails」の実務経験が2~3年以上必要なので、基本的に無理と思って下さい。
なお(正社員として)就職できた場合は「Ruby on Rails」をやる可能性は有るようですが。


SQL(データベース言語)は「バックエント、基幹系」を目指すなら必須です。


参考

勉強のために「訓練校、大学」などに行っても良いですが、「訓練校、大学」などに行く前に授業に付いていけるレべルまで独学が必要です(教科書を全て消化できないと先生の評価は下がるので、生徒が理解できるかよりも教科書を全て消化することが優先されますから、授業に付いて行けない人は普通に居ますのでね)。
なおスクールは生徒のことなど、カモネギぐらいにしか思って無いので推奨しません。
教本がシッカリしているなら、それは生徒側の気分の問題ですが。

「バックエンド、基幹系」などを目指すなら、「HTML、CSS」の基礎は常識レベルです、「正規表現、SQL、JavaScript(Ajaxも組める程度)」程度の知識は必要になると思われます(基幹系は高度なCSSの知識も必要だと思われます)。
現在、世界的にjQueryは着実にシェアを減らしており、もうオワコンでしょ、などと囁かれているので、基本的にVanilla JSで良いでしょう。
(Androidなど)動きのあるゲームでは「スレッド、排他制御、最適化の抑制」の知識は必要になります。
(データベースは別として)現在 データ書式として世界的にJSON書式がデファクトスタンダードになっているので、「JSON書式 入門」でググってみると良いでしょう。
アルゴリズム本を1冊買っておくと良いでしょう、ただし特定のアルゴリズムに特化しているので、アルゴリズム本で勉強しても応用は効かないと思われるので、アルゴリズム本は辞書的に使うだけにすると良いでしょう。

外資系企業だと「オブジェクト指向プログラミング、総称型(Generics)」ぐらい出来ないと無能と評価されます。
日本企業(大企業)も外資に買収されている場合が有るので要注意です(役員に外国人が入っていれば確定的)。
面接で「オブジェクト指向プログラミングは分かりますか?」と聞かれる場合が有るようです(多態性(ポリモーフィズム)がオブジェクト指向プログラミングの肝なので、多態性(ポリモーフィズム)が分からない場合は「分かりません」と回答しないと、あとで「オブジェクト指向プログラミングが分かってないだろ」と文句を言われるでしょう)。
そのような企業は選らばないと言うのも1つの手です。

参考

Javaデモ:オブジェクト指向プログラミング
http:../utf8/smt.cgi?r+rpr/&bid+00000007&tsn+00000007&bts+2023/02/09%2022%3A47%3A18&


チャットなどでは参加者数が多くなると、サーバーに負荷が掛かると言う問題がありましたが、Comet(+Ajax)で処理を軽くできるらしいです。
プロを目指すなら、Comet(+Ajax)処理のチャットを実際に作ってみると良いでしょう。
例えば クライアント-サーバー間のデータ書式としてJSON書式を使ってみるのも良いでしょう。

参考

第2回 Comet---プッシュ型のWebアプリケーションを作る
https://xtech.nikkei.com/it/article/COLUMN/20080220/294242/

CometとAjaxを利用したチャットサーバの実装
https://codezine.jp/article/detail/733

リアルタイムなwebアプリを実現する方法(ポーリング、Comet、Server Sent Events、WebSocket)
https://www.kimullaa.com/entry/2016/01/17/231359

EventSource
https://developer.mozilla.org/ja/docs/Web/API/EventSource

Webブラウザの画面にページが表示(レンダリング)される前にJavaScriptを実行したい - DOMContentLoaded イベントの利用 (JavaScript プログラミング)
https://www.ipentec.com/document/javascript-using-dom-content-loaded


Androidアプリのポートフォリオは、2D系ゲーム、タイマー、アラーム、リマインダーなのどポートフォリオを作ってみると良いでしょう、できれば3D系ゲームも。
ゲーム系なら画面をカラフルにしても良いです。

下記は当方が作成したAndroidテトリスのキャプチャ動画です。
https://youtu.be/Mf49zmHEaI0
↑これは2D系ゲームの範疇になります。


(バックエンド系の)ポートフォリオの注意点
例えばスクールの卒業生は面接にECサイトのポートフォリオを持って来るので、そのレベルの難易度が推奨されます(つまりECサイトを作れるレベルがプロの最低ラインと思って良いです)が、テックキャンプの卒業生の粗製乱造により、ECサイトを作るとテックキャンプのヤッツケ課題だと勘違いされるのでヤメたほうが良いと言われているようです。
なおスパゲティーだと、当然 評価は下がるので、コードは1度書いたら終わりでは無く、どうしたら読みやすいコードになるか、何度も見直すと良いでしょう

(プロを目指すなら)とりあえずベンダーに自分の実力をアピールすることが重要なので 、ポートフォリオをいくつか作ってみると良いでしょう。

「HTML、CSS」のレベルはデザインセンスは必要ないですが、デバッグで確認しやすいように配慮する。
高度なレイアウトはフロントエンドの担当なので、通常はバックエンドは高度なレイアウトは必要ないでしょう。
「HTML、CSS」は基本的にform、input、textarea、select、button、submit、div、span、table、tableセルの縦・横の結合、全要素指定"*"、border、インラインブロック、フレックスボックス、width、height、min-width、min-height、autoぐらい分かってれば良いでしょう。
それぐらいの基本的な「HTML、CSS」ならググればなんとかなります。
borderを指定すれば目視で要素サイズを確認できるので、レイアウトが思うように組めない場合は、borderを指定してみると良いでしょう(一時的にborderを全要素指定"*"してみるのも良いでしょう)。

業務の場合は基本的なレイアウトの仕様は決まっていると思われますが、仕様書に要素のサイズが明記されて無い場合は、基本的には内因性サイジングを意図しているので、基本的には要素のサイズは指定しなくて良いですが、明らかにレイアウトが変なら要素のサイズを指定すれば良いでしょう。
ブロックレベル要素は横幅が100%に広がるので、もし横幅も内因性サイジングにしたい場合は、インライン要素では無くインラインブロック要素がオススメです(インライン要素だとCSSの設定が効かない場合がある)。
なお画像などはサイズの指定が必要になると思われます。


(バックエンド系の場合)難易度としてはECサイト・レベルを想定するとなるとTwitterとか良いかもしれません。
以前のTwitterは本質的にはチャットであり、リアルタイム的に記事が更新されていました(現在はリアルタイム的に記事が更新されませんが)。
以前のTwitter仕様で作成したいならチャットを作れば良いでしょう(Ajax(JavaScript)が必用)。
プログラムに「SQL、正規表現、JSON書式」を組み込んで、「それらの知識は有りますよ」とアピールすると良いでしょう(もしそれらが使われて無いと、それらの知識が無いと判断されますので)。

Twitterの主な機能は下記のようになります。
一気に全部 作る必要は無いです、1つ1つ徐々に機能を追加して行くと良いでしょう(自分で優先順位を付けて下さい)。

機能
・「記事+メディア系(画像、音声、動画)」を投稿できる
・「記事の削除」が可能
・「@~」でユーザーの全記事を検索できる
・「#~」でキーワードを検索できる
・「@~#~」で特定のユーザーのキーワードを検索できる
・「通常のワード検索」
・「記事にコメント」が付けられる
・「コメントの削除」が可能
・「フォロー」
・「リツイート」

なおポートフォリオとして提出しないにしても、ECサイトを作ってみるのは勉強になるでしょう。
上記のような感じでECサイトもAmazonなどを参考に実際にどのような機能(売る側に必要な機能、買う側に必要な機能)が必要か考察してみて下さい。
チャットなどでは参加者数が多くなると、サーバーに負荷が掛かると言う問題がありましたが、Comet(+Ajax)で処理を軽くできるらしいので、その普通のTwitterができたらComet(+Ajax)にも挑戦してみると良いでしょう。

>Ajax(JavaScript)が必用

現在、世界的にjQueryは着実にシェアを減らしており、もうオワコンでしょ、などと囁かれており、通常はVanilla JSにしておけば良いでしょう。

参考

JavaScriptフレームワーク
http:../utf8/smt.cgi?r+sara/&bid+00000325&tsn+00000325&bts+2020/05/25%2017%3A50%3A20&

参考
※下記でチャットの基本概念が分かるでしょう。
その「PHPデモ/チャット、Javaデモ/Servlet:チャット」の「Template.html」のコードは完全に同じだと言うことに注意して下さい。
なお、プロならファイルは使わないでしょうから、ファイル・ロックは そんなことも有るんだな~程度に読み流して良いです。

PHPデモ/「チャット:SPA(Single Page Application)」:「ファイル・ロック、AJAX、タイマー」(Ver.3)
http:../utf8/smt.cgi?r+sara/&bid+00000743&tsn+00000747&bts+2023/07/12%2001%3A32%3A02&
Javaデモ/Servlet「チャット:SPA(Single Page Application)」:「ファイル入出力、ファイル・ロック、AJAX、タイマー」:「RandomAccessFile、FileChannel、Charset、ByteBuffer」(Ver.2)
http:../utf8/smt.cgi?r+sara/&bid+00000746&tsn+00000748&bts+2023/07/13%2019%3A40%3A08&


担当者は大量のポートフォリオをチェックしているので、目にチカチカするようなカラフルな画面だと、ゲンナリします。
変にカラーを使うよりは(グレー系で)質素な雰囲気の方が良いでしょう。
モチロン目に優しければグレー系でなくても良いですが、グレー系が一番簡単です、とにかく目に優しい質素な雰囲気を目指して下さい。
つまりオリジナルの配色に囚われる必要は無いです。


バックエンドにおいての「HTML、CSS」のレベルは下記の2つの画像(恐らく中学生の課題だと思われますが)ぐらいできれば余裕だと思われます。
実務では、サイズの指定はほぼ無いと思われますが、腕試しとして(サイズを指定して)トライしてみると良いでしょう。
下記の課題はdiv、span、table、tableセルの縦・横の結合、全要素指定"*"、border、インラインブロック、フレックスボックス、width、height、min-width、min-height、auto、position、static、relative、absolute、top、bottom、left、right、ぐらい分かってれば良いでしょう。
それぐらいの基本的な「HTML、CSS」ならググればなんとかなります。

下記の注意点としては、positionは使わずに、「table、フレックスボックス」などで作成してみて下さい(その程度のレイアウトでpositionを使ってるようでは、いくらなんでもスキルが低すぎますので)。
tableのみ、フレックスボックスのみの2パターン作ってみるのも良いでしょう。

https://drive.google.com/file/d/1fUHVK3iy2w3Vtmo2CiMGkSTANFXJTst5/view?usp=sharing

下記の注意点としては、positionもバリバリ使って良いです。
濃い緑の枠はtableにすると良いでしょう。
黄色で囲われいる部分は中央配置です。
赤で囲われいる部分はギャップは明記されてませんが等間隔と考えて下さい。
等間隔ならフレックスボックスを使いますが、フレックスボックスは幅は100%に広げずに、赤で囲っているように内部の要素にピッタリ合わせるようにして下さい。

https://drive.google.com/file/d/17nqdLovxu8k5wJZumYsE6TgVIrW7tk9z/view?usp=sharing


(フリーランスの)案件によっては「フロント」が表記されている場合がありますが、「フロント」が表記されている場合は、ガチのフロントエンドのスキルが要求される可能性があるのでご注意下さい。
ガチのフロントエンドはマジに難易度が高いので、そう言う案件はヤメておいたほうが無難です。

Block( Address 000007A1 Identity 00000398 )


<Number>: [000005C1]  <Date>: 2024/01/22 16:55:47
<Title>: SEO(Search Engine Optimization:検索エンジン最適化)
<Name>: amanojaku@管理人

まず、SEOの基本のキ(常識レベル)として「description」の設定をして下さい(下記参照)。
なお SEO業者が「keywords」を乱用し、「keywords」がスパム化してしまったので、現在はGoogleは「keywords」を評価してないので、「keywords」の指定は不要です。

検索結果に表示!HTMLでmetaタグを使う方法【初心者向け】
https://techacademy.jp/magazine/12701

必須レベル(最重要ファクター):「記事の質(端的に言うとアクセス数)、特定の解像度に依存しないユーザー・フレンドリーなページ」の2本柱。
※この"必須レベル(最重要ファクター)"が最高の優先順位だと言うことに注意して下さい(SEOは王道で勝負が基本です)。
つまり いくら他を頑張っても、この"必須レベル(最重要ファクター)"がグダグダだったらダメダメと言う事になりかねないです。
「特定の解像度に依存しないユーザー・フレンドリーなページ」であるかどうかをチェックしたい場合は、とりあえずChromeモバイル・エミュレーターで一般的には約「300px~3000px」解像度ぐらいをチェックしてみると良いでしょう。

強く推奨レベル:「クロス・ブラウザ、(ペライチでない場合)パン屑リスト(nav要素)、ハンバーガー・メニュー系(nav要素)、レスポンシブ・デザイン、ロボッツ・テキスト(robots.txt)の設置、サイトマップ(sitemap.xml)の設置」。
※パン屑リストはページのヘッダーと、ハンバーガー・メニュー内の両方に設置すると更に良いかもしれません(両方が面倒な場合は、ハンバーガー・メニュー内に設置すれば良いでしょう)。
※「パン屑リスト」の「パン屑」とは、童話のヘンゼルとグレーテルに由来があります。
ヘンゼルとグレーテルが、森の中で道に迷わないように、パン屑をちぎって置いていったエピソードが名前の由来です。
ザックリと言うと自分が観覧した(過去の)ページのリンク・リストです(つまり「パン屑リスト」で いつでも自分が観覧したページに戻れる)。

推奨レベル:「description」。

注意点としては「記事の質(端的に言うとアクセス数)」は当然として、「特定の解像度に依存しないユーザー・フレンドリーなページ」に対応できてないと、SEO的にはマイナスになります。
具体的には(pxなどの)絶対単位を使っていると「特定の解像度に依存する」ので、SEO的にはマイナスになります。

クロス・ブラウザ対応に関しては下記の「クロス・ブラウザ対応法」を参照して下さい。

備忘録【入門】:VisualStudio Code/フロントエンド開発環境の構築
http:../utf8/smt.cgi?r+sara/&bid+000002AB&tsn+000002AB&bts+2019/11/17%2010%3A34%3A59&

表示が重いとSEO的にはマイナスになります。
例えばモバイル端末は必ずしも「4G、5G」通信している保障は無く、電波状況が悪い場合は3G通信になったりするので、ページの全ファイルの合計サイズが肥大化すると、表示が非常に重くなる場合も有り得るので注意が必要です(格安SIMの場合は大量にパケットが消費されるのは非常に迷惑になります)。

ページの「画像、テキスト」ファイルの合計サイズが大きくて表示が重くなると予想される場合はSEO的にはマイナスになります。
なお画像ファイルは遅延ロード(lazy)にすれば画像が重くてもSEO的にはマイナスにならないとされていますが、画像が重すぎてユーザーがブラウザ・バックしてしまえば、実質的にSEO的にはマイナスになりますし、格安SIM回線も考慮して画像ファイルのサイズはダイエットすることが強く推奨されます。
遅延ロード(lazy)はIEは非対応なので、IEにも対応させたい場合はPolyfill(ポリフィル)を使って下さい。
ただし、ページの上の方で直ぐに表示される画像は遅延ロード(lazy)は指定せずにpreloadを指定した方が良いでしょう。

参考

HTMLで画像の遅延ロード処理を行う方法
https://www.design-memo.com/coding/html-loading-lazy

rel=”preload” を使った Core Web Vitals や サイト高速化の改善
https://www.gaji.jp/blog/2021/04/28/7185/


1ページの全てのファイル・サイズの全合計が1.6MB程度が推奨されているようです(「音声、動画」などは計算に含めなくても良いです)。
「CSS、JavaScript、jQueryなど」外部ファイル、「画像」ファイル、「iframe参照など」Webファイル(当然 その中の外部ファイル、「画像」ファイルも全て合計する)などの全てのファイル・サイズの合計が1.6MB程度が推奨されるようです(当然 それ以下でも おk)。
なお、画像にlazy(遅延ロード)が指定されている場合は、その計算に含めなくておkです。

Googleの推奨は1.6MB。7,866のウェブサイトの平均は 2.43MB。あなたのトップページは?
https://webtan.impress.co.jp/u/2018/08/20/30244

テキスト量の注意点。
大量にテキストを書かない、記事を大量に書きたい場合は記事を複数ページに分割して下さい。
1ページあたりの最大・文字数は おおよそ20,000文字ぐらいを目安にして下さい、あくまでも目安なので厳密に考えなくて良いです(最大・文字数が20,000文字を超えたら絶対ダメとか、そう言うことではありません、あくまでも参考程度に考えて下さい)。

画像サイズの注意点。
(画像のファイル・サイズが肥大化すると、画像の表示が重くなるので)画像のファイル・サイズは出来るだけ小さくした方が良いのですが、画面の解像度に合わせて拡大することも考慮しなければなりません。
通常、「PC用、モバイル端末用」の2つを用意します(PC用は大きめに、モバイル端末用は小さめに)。
画像の最適サイズを計算するにはパーセントの概念を理解できる必要がありますが、パーセントの計算は単なる四則演算(+、-、×、÷)なので特に難しいことはありません。
分かりやすく言うと消費税の「税抜き価格→税込み価格」、「税込み価格→税抜き価格」の計算ができれば良いだけなので、中学レベルの学力で全然おkです(二次方程式の解法なんぞと比べれば全然 簡単です)。
YouTube(つまりGoogle推奨と同義)の個人用チャンネルのバナーの横幅は2560pxが推奨されています(モバイル端末用の小さい画像(横幅が1060px)は自動的に作られるようです)。
ですので画像の拡大時も画像の画質を綺麗に表示させたい場合は、PC用なら横幅は2560pxクオリティー、モバイル端末用(縦画面)なら横幅は1060pxクオリティーで作っておけば良いと思われます。
つまり、PC用なら2560pxの解像度で計算し、モバイル端末用なら1060pxの解像度で計算すれば良いでしょう、(ウインドウの横幅を基準とした場合)ウインドウの50%の画像サイズにしたいなら、PC用なら2560*0.5=1280px、モバイル端末用なら1060*0.5=530pxになります。
(2560pxクオリティーの1,5倍の)4K画面(横幅3840px)に、2560pxクオリティーで表示しても、(見た目的に)2560pxクオリティーの解像度とまでは言えないでしょうが、(見た目的に)フルHD(1920px)クオリティー以上の解像度には見えそうな気はします。
なお、モバイル端末は必ずしも4G通信している保障はありません、電波状況が悪い場合は3G通信になるので、画像のファイル・サイズが肥大化すると、画像の表示が重くなるので注意が必要です。
拡大時の画像の画質を"犠牲"にしても良いなら、画像をモバイル・クオリティーで作成しておけば容量も軽くなり、「PC、モバイル端末」両対応になって非常にラクになります。

画像が大量にある場合はlazy(遅延ロード)を考慮してみると良いでしょう。

HTMLで画像の遅延ロード処理を行う方法
https://www.design-memo.com/coding/html-loading-lazy

lazy(遅延ロード)はIEは非対応なので、IEにも対応させたい場合はPolyfill(ポリフィル)を使って下さい。

ただしページの先頭の方に有る(直ぐに表示される)画像にはlazy(遅延ロード)は使わないでpreloadを指定して下さい。
また「外部CSSファイル、外部JSファイル」などにもpreloadを指定して下さい。

rel=”preload” を使った Core Web Vitals や サイト高速化の改善
https://blog.gaji.jp/2021/04/28/7185/

Chromeのデベロッパー・ツールにはモバイル端末をエミュレートできるモバイル・エミュレーターが搭載されていますが、あくまでもエミュレーターなので画像の拡大時に実際に どれだけ画像が劣化してるかをチェックしたい場合は本物の4k画面でチェックして下さい。

4kモニターを購入する場合の注意点
http:../utf8/smt.cgi?r+twilight/&bid+00000041&tsn+00000258&bts+2021/03/26%2020%3A00%3A27&

サイトのタイトルは「ユニーク」で「覚えやすい」タイトルが強く推奨されます。
下記でチェックしてみると良いでしょう。

Free Keyword Generator Tool: Find 100+ Keyword Ideas in Seconds
https://ahrefs.com/ja/keyword-generator

「検索エンジン:Google、国:日本」に設定、「キーワードを探す」をクリック、ロボットでないをチェックする。
「ボリューム」はキーワードの月間平均検索数(推定値)です。
「ボリューム」値が1000前後なら充分にユニークですが、あくまでも推定値なので あまり厳密に考えなくても良いです(「ボリューム」値が2000前後だとダメとか、3000前後だとダメとか、そう言うことではありません、あくまでも参考程度に考えて下さい)。

Block( Address 000007A0 Identity 000005C1 )


<Number>: [00000325]  <Date>: 2024/01/18 20:35:06
<Title>: JavaScriptフレームワーク
<Name>: amanojaku@管理人

JavaScript世界3大フレームワーク「React、 Vue.js、Angular」の内の「React、 Vue.js」の2つは日本でも人気です。

Google Trendsは、あくまでもキーワードの人気度であり、本体の人気度ではありませんが、人々の関心度と考えて良いでしょう。

「jQuery、React、Vue、Angular」のキーワードの人気度。
https://trends.google.co.jp/trends/explore?date=2013-06-01%202022-06-01&q=jQuery,React,Vue,Angular

jQueryは綺麗に下降してますね、Vue.jsが2020年2月頃から激減しているのは3.0で全く別物になったからだと思われます。

jQueryのデメリット。
jQueryはDOM(Document Object Model)の変更が素のJavaScriptよりも面倒になると言う問題がありました。
また現在、世界的にjQueryは着実にシェアを減らしており、もうオワコンでしょ、などと囁かれています。
なおポートフォリオにjQueryを使うとマイナス評価になるらしいです。
このままjQueryのシェアが順調に低下して行けば、いずれ本当にオワコンになると予想されます(プロの場合、現状では現場によっては まだjQueryが使われる場合もあるようですが)。

Angularのデメリット。
Angularは学習コストが高い(難しい)ので日本では人気は有りません。
昔はソースが巨大で読み込みが重かったので、その昔の悪いイメージも人気の無い要因になっているかもしれません、なお 最近はmin版も出ているようです。

Vue.jsのデメリット。
開発規模が肥大化するにつれデバッグが困難になりがちだそうです。
Vue.jsは3.0で全く別物になったようです、Vue.jsはメジャー・バージョンアップ(1.x→2.x→3.x)で全く別物になっているらしく、メジャー・バージョンアップ「3.x→4.x→5.x→…」するたびに全く別物になる可能性があり、そのたびに勉強しなおさなければならないかもしれません。
3.0へのバージョンアップに懲りてVue.jsからReactに乗り換える人も居たようです。

Reactのデメリット。
ReactはJSXの導入が必須レベルで推奨されます、JSXを導入するにはコンパイラ(トランスパイラ)が必要です(いっそのことTypeScriptも導入しても良いかもしれません)。
ReactはVue.jsより少々 学習コストが高そう(下記参照)だと言うデメリットが有ります。
(日本の)プロの世界では、以前は Vue.jsの方が人気が有ったような感じでしたが、現在はReactの方が人気が有るような感じ。

あらためてReactとVueを比較してみる〔2020年最新版〕
https://freelance-jak.com/technology/react/2472/

また、状態管理は別途 他のライブラリの導入が推奨されており「Redux、Redux+Redux Toolkit、unstated、typeless」などなどカオス状態になっています。
(良く分かりませんが)Reactに追加された新機能「Hooks」が状態管理にも使えるらしいです。

React Hooksを試してみよう!(useStateとuseEffect編)
https://casualdevelopers.com/tech-tips/getting-started-with-usestate-and-useeffect-in-react-hooks/

「Redux、Redux Toolkit(+Redux)、unstated、typeless、React Context(React Context API)」のキーワードの人気度。
https://trends.google.co.jp/trends/explore?q=Redux,Redux%20Toolkit,unstated,typeless,React%20Context

Reduxの一強ですね、Redux用の補助ライブラリであるRedux Toolkitですら ほぼゼロです、React標準のReact Context(React Context API)ですら足元にも及ばないとは少々 甘く考えていました。
と言うことで状態管理はReduxがデファクト・スタンダードなので「Redux+Hooks」が推奨されると思われます。

(TypeScriptは大規模開発に向いているので)大規模開発が想定される場合は「JavaScript+TypeScript」と言う選択肢も考慮してみると良いでしょう(小規模開発なら素のJavaScriptでおk)。
(TypeScriptは難易度が高いので)とりあえずVanilla JS(素のJavaScript)を勉強してみると良いでしょう。

Block( Address 0000079F Identity 00000325 )


<Number>: [00000231]  <Date>: 2024/01/09 14:32:35
<Title>: Webページにおける基本的な留意点:レベル1
<Name>: amanojaku@管理人

近年 Webページ作成のハードルは上がっています、下記はプロの基礎レベルに相当します(ただし、プロとアマチュアでは方向性が違いますが)。
プロではピクセル・パーフェクトを希求しますが、アマチュアはユーザー・フレンドリーを希求します。
(プロとアマチュアでは方向性が違うので)プロを目指すならピクセル・パーフェクトを希求して下さい(アマチュアの勉強用なら1pxぐらいズレても、全然 気にしなくて良いです)。

ユーザー・フレンドリーは(ビューポートではなく)ディスプレイ画面の解像度を基準とし、テキストはデフォルト・フォント・サイズを基準とします。
現在のピクセル・パーフェクトはビューポートの横幅に比例して伸縮します。
(メディアクエリは除き)Web系においての静的Webページではpxなどの絶対単位を使う古いピクセル・パーフェクトは無くなりました(ただし基幹系においての静的Webページでも昔ながらのpxなどの絶対単位の古いピクセル・パーフェクトを使っているかもしれませんが)。
企業のWebページでは動的Webページになっている場合も有り、クライアントのモニター解像度を取得し、(サーバー側で計算して)動的に絶対単位(px)で生成している場合も有るようです、その場合はレスポンシブ・デザインになって無いと思われるので、(コードを読んだり、写経しても)「レスポンシブ・デザイン」などの勉強は出来ないと言う事になります。
つまり、(Web系においての静的Webページでは)現在のピクセル・パーフェクトは、別物になったと言うことです、(完全な別物なので)それをピクセル・パーフェクトと呼んで良いのかと言う議論は有るでしょうが。
分かりやすく言うと、肉眼で見たイメージとしてのピクセル・パーフェクトなので、脳内で便宜的に「イメージ・パーフェクト(仮)」とでも読み替えれば良いでしょう。
なお 人がピクセル・パーフェクトと言った時に、古いpx単位のピクセル・パーフェクトを言っているのか、「イメージ・パーフェクト(仮)」を言って居るのか、文脈から判断する必要があります。

本当に自分の作りたいサイトを(勉強のために)実用的なWebページで作ってネットで公開してみると良いでしょう(本当に自分の作りたいサイトならモチベーションも上がるでしょうから)。
逆に言うと、自分が本気でネットで公開したいサイトでないと、それだけの学習コスト(学習の労力)を掛けて勉強するのは難しいかもしれません、(もちろん 不可能と言うことでは無いですが)自分が本気でネットで公開したい、と言うモチベーションが有った方が学習に圧倒的に有利です。
自分が本当にネットで公開したいコンテンツが有るか、どうかも重要な要素になるでしょう。
無料レンタルWebサーバーは基本的に広告が入るので、広告がウザくない所を探して下さい。

Webページは基本的にローカルで表示して下さい。
ネット上のページをチェックする場合は、ブラウザのキャッシュが効く(古い状態のページが表示される)ので注意が必要です。
とりあえず「スーパー・リロード」(下記参照)を試してみて、それで最新の状態が反映されない場合は、ブラウザのキャッシュをクリアして下さい。
普段 使ってるブラウザのキャッシュをクリアすると、ログインが面倒になるので、普段 使わないブラウザでチェックしてみると良いでしょう。
なお スマホ用ブラウザ(Chrome)ではスーパー・リロードは存在しないのですが、シークレット・モードのリロードがスーパー・リロードになるらしいです。

各ブラウザでの強制リロード(スーパー・リロード)まとめ
https://ao-system.net/note/69

ブラウザのキャッシュクリア方法
https://nestle.jp/gamebox/info.html


コンテンツの作成時に背景が白のコンテンツを長時間 集中して凝視していると目に良くないので、とりあえず背景は目に優しい色にすることをオススメします。

Webページにおける基本的な留意点:レベル0(ベタ記事レベル)
http:../utf8/smt.cgi?r+sara/&bid+00000231&tsn+0000040B&bts+2019/08/12%2011%3A02%3A18&


pタグを改行と勘違いしている人がいますが、あくまでもParagraph(段落)であって、改行では有りません、改行は<br>。

<p>|正しい段落の使い方・記述方法
https://www.webnoiroha.net/html-p/

>pタグとは?
>段落は英語で“Paragraph”といい、この頭文字の’P’がタグの名称となっています。
>pタグは決して“改行をするためのタグ”ではない

pタグでdivタグは囲えないので注意して下さい。

pタグとは?意味と使い方について
https://sem-journal.com/design/p/#p-5

pタグの中にdivタグは入れられない
http://cly7796.net/wp/css/div-can-not-be-put-in-p/

html5のタグの入れ子ルール(全部 覚えなくても良いです)
https://webaby.site/job/190908/

HTML5 コンテンツモデル ガイド | HTML5 Content Models Guide
https://webgoto.net/html5/
↑その『HTML5 コンテンツモデル ガイド』は数学で言うところの"集合"になっているので見かたにコツが要ります。
例えばabbrは「フレージング、フロー」、canvasは「エンベデッド、フレージング、フロー」、audioは「インタラクティブ、エンベデッド、フレージング、フロー」、aは「インタラクティブ、フレージング、フロー」、linkは「メタデータ、フレージング、フロー」などのようになります。

HTML5の要素による構成例
https://web-svr.com/HTML5%E7%B7%A8/21.php
※↑これは あくまでも基本の例であって、絶対ではありません。
※「header要素、footer要素、nav要素、main要素、aside要素、section要素」などのリンク先のページを参照することを強く推奨します。
それらの解説が良く分からない場合は(タグを間違って使うよりは)divタグで代替すれば良いでしょう。


レイアウトをイメージどおり配置できない場合は、positionをチャント理解できて無い可能性が有ります。
下記に書いてある事を字面を読むだけでなく、様々なパターンを実際にコーディングしてみると良いでしょう。
正常な例だけで無く、ダメな例も実際にコーディングしてみて、そのダメな例がどうなるかも検証してみると良いでしょう。

CSS - position
https://www.tohoho-web.com/css/prop/position.htm

後は「CSS Flexbox 」、「CSS Grid」ぐらいをググっておくと良いでしょう、それらをマスターできればレイアウトを崩れなくすることができるでしょう。


JavaScriptにおけるセキュリティー上の留意点。
「eval()」はセキュルティー・ホールになる可能性が有るので、セキュリティー上の理由から「eval()」は使わずに、「Function()」を使うことが強く推奨されています(「Function()」と「function」は別物だと言うことに注意して下さい)。
どうしても「eval()」を使いたい場合は、外部からのコマンドが実行されないように厳重に注意する必要が有ります(できれば(複数人で)「ダブル・チェック、トリプル・チェック」したほうが良いでしょう)。

eval() - JavaScript | MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/eval

参考

  a = 3;
  formula = "a*5";
  result = window.Function('return ' + formula)();
  // newを指定すればFunctionコンストラクターとしても定義可能。
  console.log(result);


SEO(Search Engine Optimization:検索エンジン最適化)に関する留意点。

SEO(Search Engine Optimization:検索エンジン最適化)
http:../utf8/smt.cgi?r+sara/&bid+000005C1&tsn+000005C1&bts+2022/03/04%2023%3A56%3A24&


クロス・ブラウザが推奨されます、「Chrome、Safari、Edge、Firefox」あたりをチェックすれば良いでしょう(プロの場合は、当然もっと多種のブラウザをチェックすると思いますが)。
なお古いスマホ(PC用Internet Explorer 11も)に対応(クロス・ブラウザ)する場合には、ベンダー・プレフィックスが必要になる場合があります(恐らくCSS3を使ってる場合はベンダー・プレフィックスが必要になると思われます)。
CSSプロパティのvalue名が違う場合も有るので、人力では無理なので、ベンダー・プレフィックス用のツールが必須になります。
また古いスマホでは高度なCSSが効かない場合があるので注意が必用です。
JavaScriptもES6コードで記述している場合に、古いスマホ(PC用Internet Explorer 11も)に対応(クロス・ブラウザ)させるには、BabelなどでES5コードでコンパイル(トランスパイル)しなければなりません。
つまり JavaScriptもES5コードで書けるなら、初めからES5コードで書いた方が良いでしょう。
※ガッツリとスマホ(Android端末)対応したいなら、低いバージョンのスマホ(Android端末)を購入して実際にチェックしてみると良いでしょう、(中古なら1万円前後で買えます)、Androidバージョン4あたりで良いと思います、それ以下だと流石に古すぎます。
※中華端末はバックドアが仕込まれている可能性があるので要注意です、表面的に中華端末で無くても新品で格安端末なら ほぼ中華製と考えて良いでしょう。

クロスブラウザ
https://www.weblio.jp/content/%E3%82%AF%E3%83%AD%E3%82%B9%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6

クロス・ブラウザ対処法に関しては下記に記載してあります。
「Visual Studio Code」を使う場合、下記に記載されているプラグインを全て導入することを推奨します。
基本的にsettings.jsonで なんらかの設定をすることが強く推奨されます、設定しないと「Color Highlight」がウザイので、設定しないなら「Color Highlight」は導入しない方が良いでしょう。

Visual Studio Codeでフロントエンド開発環境を構築する
http:../utf8/smt.cgi?r+sara/&bid+000002AB&tsn+000002AB&bts+2019/11/17%2010%3A34%3A59&


「PC、タブレット、スマホ」などで解像度は機種ごとに違うので、特定の解像度に依存しないユーザー・フレンドリー(PCフレンドリー、タブレット・フレンドリー、スマホ・フレンドリー)なページが推奨されます。
Chromeのモバイル・エミュレーターで「PC、タブレット、スマホ」の各解像度をチェックしてみればユーザー・フレンドリーが如何に重要か解るでしょう。
(各解像度のチェック自体は それほど難しく無いので)現在 Webページを作成しているなら、実際にChromeのデベロッパー・ツールのモバイル・エミュレーターで「PC、タブレット、スマホ」の各解像度をチェックしてみると良いでしょう。

なお スマホ用ブラウザによっては(metaタグの)viewportが指定されてないと、Webページのフォント・サイズをブラウザが勝手に忖度(そんたく)して変更される場合があるので、レスポンシブ・デザインにする場合は(metaタグの)viewportの指定が必須になります(PC版ブラウザではviewportの設定は無視されるようです)。
実機でチェックする場合にはmetaタグのcharset属性の設定の次あたりに下記を記述して下さい(必須)。

<meta name="viewport" content="width=device-width">

下記は、一般的にネットで推奨されているviewportの例ですが、「initial-scale=1」が指定されていると横幅がハミ出る場合が有るようですので、「initial-scale=1」を削除することを推奨します。

> <meta name="viewport" content="width=device-width,initial-scale=1">


Internet Explorerが互換モードに設定されていると、正常に表示できない場合が有るようです。
下記 metaタグでInternet Explorerの互換モードを回避できるようです。

<meta http-equiv="X-UA-Compatible" content="IE=edge">


画面の解像度に関する注意点。
PCの場合、現在4k画面が普及価格帯で販売されており、また高解像度モニターは(高価ですが)「5k画面、6k画面、8k画面」も販売されています(そのうち量産効果で安くなるか?)。
逆に低解像度モニターは(2020年9月現在、価格.com調べ)横幅が800pxと言う画面もあり、アスペクト比は「4:3、16:9」の2つがあるようです。
なお 1K画面(横幅1024px)だとアスペクト比は大抵は4:3になるでしょう。
「HD画面(横幅1280px)、フルHD画面(横幅1920px)、WQHD 2K画面(横幅2560px)、4K画面(横幅3840px)」だとアスペクト比は16:9になります。

とりあえず一般的には約「300px~3000px」解像度ぐらいをチェックすれば良いでしょう(プロなら6k解像度ぐらいは使ってるかもしれませんので、ポートフォリオを作成するなら約「280px~6000px」解像度ぐらいには対応すると良いでしょう)。
「タブレット、スマホ」は既に登録されているプリセットの解像度でチェックできるようです(「タブレット、スマホ」の解像度のプリセットは[Responsive]コンボボックスで選択可能です)。

「スマホ、タブレット」フレンドリーに関する注意点:「スマホ、タブレット」の場合、端末の物理的な解像度と、ブラウザ上の解像度は違うようで、ブラウザ上の解像度を「CSSピクセル、dp解像度」と言うらしいです。

iOS・Android端末のCSSピクセル・dp解像度一覧(あくまでも主なものだけ)
https://wemo.tech/1496

【2022最新】スマホ・タブレットの解像度一覧表(画面サイズの割合)iPhone・iPad..
https://webdesign-abc.com/tech/resolution-list/

今更「dp」について考える
https://developer.android.com/guide/topics/large-screens/support-different-screen-sizes?hl=ja


Viewport領域。
「vw、dvh(又はvh)」の対象となる領域を「Viewport」と言い、その「Viewport」の全体は「100vw、100dvh(又は100vh)」と成りますが、それは「実際の表示領域+スクロールバー」になると言うことに注意が必要です。
※なお モバイル(スマホ、タブレット)はブラウザの仕様が違うので、スクロールバーの幅はゼロと考えて良いです。
なお (メディアクエリは除き)フロントエンド(プロ)では単位には基本的にvwを使います、「(半透明の要素とかで)Viewportの全面を覆う場合」などは「dvh(又はvh)」などを使います。
ただしdvhは「古いスマホ、Internet Explorer」では使えないので、クロスブラウザに対応する場合は、vhで記述するしかないです。
ただしSafariブラウザと他のブラウザでvhの解釈が微妙に違っているらしく、対応方法としてはSafariブラウザでは「-webkit-fill-available」は「100dvh」と等価になるようなので、それを使って工夫する、ただしネストされた要素では使えないなどの制限が有る(検索する場合は「CSS fill-available」などでググって下さい)。
プロを目指す場合と目指さない場合で当然 勉強法が変わってきます、プロを目指さないなら「%、rem、その他Viewport系単位」なども自由に使っても良いです。
ただしモバイル(スマホ、タブレット)でソフトウェア・キーボードを表示すると、ソフトウェア・キーボードが表示された分、Viewport領域が縮小されレイアウトが崩れる場合があるので注意が必用です。
Viewport領域が縮小されもレイアウトが崩れないなら(プロを目指さないなら)単位に「dvh(dvmin、dvmaxなども)、vh(vmin、vmaxなども)、その他Viewport系単位」を自由に使っても良いです。

要素サイズの注意点。
(メディアクエリは除き)フロントエンド(プロ)はpxなどの絶対単位は使いませんが、下記は説明の分かりやすさのためにpx値を使っています。
bodyタグにデフォルトでmarginが指定されているらしく、ほとんどのPC用ブラウザで8pxがデフォルト値らしい(左右で合計16px?)。
100vwは「bodyタグのデフォルトmargin、スクロールバーの幅」は一切 考慮されてないので、横幅が はみ出ます(つまり「bodyのデフォルトmargin、スクロールバーの幅」のサイズを引いて計算しなければなりません)。
なお縦スクロールバーの有る場合と、縦スクロールバーの無い場合の2通りを考えるのも面倒なので、CSSで縦スクロールバーを強制的に常時表示に設定すると良いでしょう。
なお モバイル(スマホ、タブレット)はブラウザの仕様が違うので、スクロールバーの幅はゼロと考えて良いです。

bodyタグのmarginとスクロールバーの幅を考慮すると、現状では40px程度 小さくしておけば良いと言う事になるのですが、bodyタグのmarginが変更されている場合は40pxではダメですし、将来的に「bodyタグのmargin、スクロールバーの幅」が変更される可能性も有り得ます(いずれにしろ40pxの固定値で決め打ちしないほうが良いでしょう)。

ちなみにフロントエンド(プロ)の場合はbodyのデフォルトmarginをゼロに設定するようです、その場合はスクロールバーの幅のサイズだけを引いて計算すれば良いです。
(フロントエンド(プロ)などで)スクロールバーの幅を(vwで)自分でカスタマイズすれば、実際の表示領域を算出できるでしょう、又はJavaScriptで算出するかですが、フロントエンド(プロ)を目指す場合は、こんなことぐらいでJavaScriptは使わないで下さい(こんなことぐらいでJavaScriptを使ってるようでは、ベンダーに基本が出来て無いスキルの低い人だと評価されますので)。

(bodyのデフォルトmarginをゼロに設定した場合)例えば下記のデモではスクロールバーの幅を1.06vwにカスタマイズしているので、実際の表示領域の幅は98.94vwになります、なのでその98.94vwの表示領域に(数学的な意味の)100%を表示できるように換算する必要があります。
ただしFirefox系はスクロールバーの幅をvwに設定できないので工夫が必要になります。
下記のスクロールバーのカスタマイズはアマチュアによるものです、なのでFirefox系のスクロールバー対応の工夫もアマチュアによるものなので、実際にフロントエンド(プロ)がどのようにFirefox系に対応しているのかは分かりません。

CSSデモ/カスタム・スクロールバー
http:../utf8/smt.cgi?r+twilight/&bid+0000023F&tsn+0000023F&bts+2021/11/17%2011%3A51%3A35&

ただしプロの作品を見てみると、稀に右端の(ハンバーガー・メニューなどの)UI(User Interface)の上にスクロールバーが思いっきり被っていたりする場合も有るので、スクロールバーのことは考慮せずに100vwで計算しても良いのかもしれません(プロの話しなので、当然bodyのデフォルトmarginはゼロとする)、もしbodyのmarginを設定したいなら その分(左右両方のmargin)を引いて計算すれば良いでしょう。
とは言え現在は右端にピッタリ合わせる場合は、スクロールバーが被らないように配置するのが主流のようですが。
100vwで計算するとして右端にピッタリ合わせたいなら、配置の基準にする親要素に「position: relative;」を指定、子要素に「position: absolute; right: ~;」などを指定すれば良いと言う事になりますが、コーダーの勝手な判断でやらないほうが良いでしょう(恐らくWebデザイナーさんからスクロールバーが被らないように右端にピッタリ配置するなどのような指示が有ると思われる)。
(スクロールバーを考慮せずに100vwで計算した場合)右端の「UI(User Interface)、文字」などの上にスクロールバーが被ってしまうような場合は、とりあえずベンダーに それで良いのか確認してみると良いでしょう。

(アマチュアの場合で)単位に「vw」を使って(特定の解像度に依存せずに)はみ出ないように拘りたい場合は横に並んでいる各「要素、マージン、パディング、ボーダー」の合計は それら(bodyタグの左右margin+クロールバーの幅)のサイズが考慮された値でなければなりません(なお、アマチュアの場合は要素に「box-sizing:border-box」を指定してやれば計算は簡単になる)。
各「要素、マージン、パディング、ボーダー」などのサイズは相対指定が必須になるので、当然 bodyタグのデフォルトmarginも相対指定に変更する(アマチュアの場合はケースバイケースですがbodyタグの右側のmarginを0pxにしたほうが良い場合も有ります)。
要素がウインドウの横幅(ビューポートの横幅)から はみ出ても良いとか、要素が改行しても良いとかなら、そこまで拘る必要は無いです。

なお 折り返ししない状態のCSS Flexboxの場合、(pxだろうと、vwだろうと)その子要素の横サイズの合計が(スクロールバーを含まない)表面的な表示領域(viewportの事では無い)の横サイズから(計算的に)ハミ出るような場合には、それらの子要素の横サイズは割合と解釈され(スクロールバーを含まない)表面的な表示領域からハミ出ないように補正されるヘンテコな仕様になっているので要注意です。
ただし「min-width、max-width」には そのルールは適応されないので、勝手に補正されたく無い場合は「min-width、max-width」の両方でサイズを指定すれば良いでしょう。
また CSS Gridレイアウトでは割合を表すフレキシブル・サイジング(fr単位)が指定できます。
以前は「grid-template-columns」の「repeat()」関数内で「フレキシブル・サイジング(fr単位)、内因性サイジング」を使うと正常に横方向に並ばずに、縦方向に並んでしまう問題が有りましたが、現在は正常に表示できてるようです(仕様が変更されたのか?)。
なおCSS Gridは難しいので手抜きして勉強する事を推奨します(100%勉強しなくても良い)、repeat()関数も難しいですが、必須なのでrepeat()関数は手抜きしせずに勉強して下さい。

デスクトップブラウザのスクロールバーの幅
http://xn--lcki7of.jp/1541/

(スクロールバーが表示されている場合)CSS/jQueryでのブラウザのスクロールバーの幅を取得する
http://ithat.me/2016/11/28/css-jquery-get-scrollbar-width

>calc(100vw - 100%)

↑この式がwidthに記述されている場合、親要素のmarginの横方向の合計は引かれないので、(親要素がbodyの場合)正確なスクロールバーの幅は算出できません(親要素がbody以外では使わないで下さい)。
とは言え、こんなに単純で全く予想だにしないモノを見るのは勉強になります。
注.スクロールバーが表示されている時しか使えないので、この式を使いたいならスクロールバーを常時表示にしなければなりません。
(JavaScript)スクロールバーを常時 表示しておけば、window.innerWidthからdocument.documentElement(ルート要素)のclientWidthを引けば、スクロールバーの幅を算出できます。

CSSでスクロールバーを常に表示しておく方法
https://uxmilk.jp/15040

PCとスマホを同一のファイルにする手法はレスポンシブ・デザインと言われており、推奨されています。
レスポンシブ・デザインにする場合、スマホでは高度なCSSが効かない場合があるので、一般的にはモバイル・ファーストで作成する事が推奨されます(折角PC用にCSSで高度な装飾を作っても、後で全面的に修正になる可能性があります)。
PC用を先に作る場合は、PC用を少し作ったら、(高度なCSSの場合は)スマホでも こまめにチェックする必要が有ります、その場合は(モバイル・エミュレーターでは無く)スマホの実機でチェックする必要が有ります。
とりあえずチェックするだけなので、必要最小限の修正で良いですし、PC用のコードのままチェックできるなら修正しなくても良いです。
なので、高度なCSSに限っては最初にスマホ用のコードを作っても良いでしょう(そのコードでPCでもチェックできると尚いいですが)、なお CSSで高度な装飾を使わないならPC用が先でも全然 良いです。
また 絶えずレイアウト構成をスマホの「縦、横」画面、タブレットの「縦、横」画面、PCの画面(アスペクト比「4:3、16:9」)で表示可能か考慮しながら作る必要があります、そうしないと後で全面的に修正しなければならなくなります。

レスポンシブとは? Web用語集
https://web.landgarage.co.jp/2018/04/05/responsive/

もう逃げない。HTMLのviewportをちゃんと理解する
https://qiita.com/ryounagaoka/items/045b2808a5ed43f96607

><meta name="viewport" content="width=device-width">と指定した場合はviewportの幅は端末やブラウザアプリ毎によって異なる。重要なのはここでも実際の液晶の解像度ではなく360とか580などのスマホらしい小さい値が使われるということだ。

注意点として、(metaタグの)viewportのwidthを固定値にすると横画面の横幅も(metaタグの)viewportで設定したwidthの値になるようです。
つまり、例えば(metaタグの)viewportのwidthが480pxと設定されていると、横画面での横幅も480px(高さは「480/16*9=270px」)になるようです(そのために縦画面より横画面のほうが「853.333/480=約1.778倍」拡大して表示されます)。

CSSメディアクエリ(@media)の設定方法。

[CSS]iPad、iPhone 5 向けレスポンシブWEBデザインに必要な Media Queries のまとめ
https://www.webantena.net/css/css3-media-queries/

レスポンシブ CSSメディアクエリ(@media)ブレイクポイントまとめ
https://www.seojuku.com/blog/responsive-mediaquery.html

メディアクエリ
http://www.isolaboratory.com/webstudies/css/media_queries.html

例えばプロにおけるメディアクエリのブレイク・ポイントは、一般的には「1280px以上」、「1280px未満~992px以上」、「992px未満~768px以上」、「768px未満~576px以上」、「576px未満」に分割する5パターンのレイアウト構成が推奨されているようです。
また、もうチョイ細かく分けたい場合は(Bootstrap5のブレイク・ポイントを踏襲し)、「992px以上」のレンジを「1400px以上」、「1400px未満~1200px以上」、「1200px未満~992px以上」に分割する(全部で)6パターンのレイアウト構成が推奨されているようです(Bootstrap5のブレイク・ポイントを踏襲しているだけであって、プロはBootstrapなんぞは使わない)。
※なお「1280px未満」は「1279px以下」と、「992px未満」は「991px以下」と、「768px未満」は「767px以下」と、「576px未満」は「575px以下」と、「1400px未満」は「1399px以下」と、「1200px未満」は「1199px以下」と等価です。
※Bootstrap4のブレイク・ポイント:「xl:特大(Extra large):1200px以上」、「lg:大(Large):1200px未満~992px以上」、「md:中(Medium):992px未満~768px以上」、「sm:小(Small):768px未満~576px以上」、「xs:極小(Extra small):576px未満」。
※Bootstrap5のブレイク・ポイント:「xxl:超特大(Extra extra large):1400px以上」、「xl:特大(Extra large):1400px未満~1200px以上」、「lg:大(Large):1200px未満~992px以上」、「md:中(Medium):992px未満~768px以上」、「sm:小(Small):768px未満~576px以上」、「なし:極小(Extra small):576px未満」。

(当然、アマチュアが そこまで細かく分ける必要があるのかと言う事はあるので)アマチュアにおけるメディアクエリのブレイク・ポイントは、「1312px以上」、「1312px未満~992px以上」、「992px未満~688px以上」、「688px未満」に分割する4パターンのレイアウト構成が推奨されているようです。
※なお「1312px未満」は「1311px以下」と、「992px未満」は「991px以下」と、「688px未満」は「687px以下」と等価です。

なお、「Chrome系、Firefox系」ならメディアクエリのブレイク・ポイントに小数点を指定しても有効に機能するようなので、アマチュアなら小数点の指定も良いでしょう。

もちろん、ページのレイアウト構成によっては、それ以下のパターン数でも作成可能な場合もあります。
※注意点としては、ユーザーが意地悪くPC用ブラウザの横幅を小さくすると、PC用ブラウザで(レスポンシブ用などの)メディアクエリが効いてしまいます(プロの場合はピクセル・パーフェクトか希求されるので、その挙動が正解になりますが)。
メディアクエリを効かせたく無い部分はJavaScriptで記述する必要があります。
※「スマホ、タブレット、PC」の画面の解像度は多少かさなっているので、メディアクエリでは、それらを完全に分けることはできません。

参考

2020年版 見直すサイトコーディング 第1回 環境とブレークポイントを見直す
https://sys-guard.com/post-18463/

完全に「PC、タブレット、スマホ」を分けたい場合はJavaScriptで判定する必要があります。

JavaScript - モバイル判定(スマホ・タブレット・PC)
https://infoteck-life.com/a0368-js-mobile-judge/

↑下記が簡単ですのでオススメです。

function get_device() {
  var ua = navigator.userAgent;
  if (ua.match(/(iPhone|iPod|Android.*Mobile)/i)) {
    return 'sp';
  } else if (ua.match(/iPad|Android|Silk|Kindle/i)) {
    return 'tab';
  } else {
    return 'pc';
  }
}


(Webページ作成の基本のキとして)ブレイク・ポイントを念頭に置き、必ずワイヤー・フレームを作成して下さい、手書きでも良いですし単純なレイアウトなら脳内だけでも おkです。
※横サイズを注釈として書いておくのも良いかもしれません(プロの場合は縦サイズも必須でしょうが)。
初心者の場合はアプリでカッチリ作ったほうが そのサイズが明確になるので分かりやすいかもしれません、いっそのこと WYSIWYGエディタでpxでモックアップを作るのも良いでしょう、それを「vw」に換算する。

WYSIWYGエディタでモックアップを作る場合は、ワイヤー・フレームは手書きで おkです。
フリーのWYSIWYGエディタの有名どころとしては「BlueGriffon」が筆頭のようですが操作は分かりづらいです、なお マイナーかもしれませんが「NVU」は「BlueGriffon」よりは使いやすそうです(アンチMicrosoft派にはオススメか?)。
「Microsoft Expression Web 4」が無料化したらしいです、ただし古い重いなどデメリットは有るようですが、「BlueGriffon、NVU」よりは使いやすそうです(「Microsoft Expression Web 4」:Windows「XP(SP3)、Vista、7、8、10」対応)。

Microsoft Expression Web 4
https://www.wanichan.com/web/expression/web4/

NVU
http://www.nvu.com/


下記はワイヤー・フレームの一例です。
※プロなら4パターン、5パターンのレイアウト構成も普通に有るようです。
※絵だけでなく「ほにゃららの画像」、「ほにゃららの文章」などのように注釈を付ければ更に分かりやすくなるでしょう。
※なおモックアップを作る場合は、ワイヤー・フレームは個々の要素などのサイズ値まで考えなくても良いです。
プロを目指す場合は、(ワイヤー・フレーム、又はモックアップの)個々の要素などのサイズ値はpxで作って下さい(そのpxを自分でvwに換算しないとプロのための勉強にならないので)。
もし基礎ができて無い場合は、(せっかくコーディングの練習ができるのですから)モックアップの作成にはWYSIWYGエディタは使わなほうが良いでしょう。

https://images.app.goo.gl/1yeuxuNJTDNyZE4B7
※後で自分が見て分かりやすく書いてあれば、本当に このような手書きでも おkです。

https://images.app.goo.gl/MEnTjT7LKe1vhacn7
※3パターンの場合

https://images.app.goo.gl/c6DPhnTj5Xrw1GcQ7
※3パターンの場合

https://images.app.goo.gl/Wu8gBmoLJiyRK8Qn6
※3パターンの場合


Chromeのデベロッパー・ツールにはスマホをエミュレートできるモバイル・エミュレーターが搭載されており、このモバイル・エミュレーターは仮想的に解像度も変更できるようです。

Chromeモバイル・エミュレーターの操作法
http:../utf8/smt.cgi?r+sara/&bid+0000052B&tsn+0000052B&bts+2021/11/29%2015%3A52%3A51&

ユーザー・フレンドリーの場合は解像度を変更してフォント・サイズが合わなくなったら、見やすいサイズにブラウザでフォント・サイズを設定して下さい。
また ユーザー・フレンドリーの場合は各解像度で複数のフォント・サイズを検証しなけらばならないので、何度も解像度をチェックするとなると、ブラウザによるフォント・サイズの調整(複数のフォント・サイズを検証)も、かなり面倒になります。
下記にフォント・サイズ自動調整用の「CSS、JavaScript」を記載してあるので、それを使うと便利でしょう。

モバイル・エミュレーター用のフォント・サイズ自動調整用「CSS、JavaScript」
http:../utf8/smt.cgi?r+sara/&bid+0000052B&tsn+0000052E&bts+2021/11/29%2015%3A52%3A51&


<Number>: [0000040B]  <Date>: 2023/04/04 14:56:25
<Title>: Webページにおける基本的な留意点:レベル0(ベタ記事レベル)
<Name>: amanojaku@管理人

自分のサイト内の(リンク可能な)コンテンツは相対アドレスで指定して下さい(当然、ローカルのフル・パス「C:\~」もダメです)。
絶対アドレスで指定すると引越し時に面倒なことになります(基本的に先頭に「 http:// 」が付くのが絶対アドレス、「 http:// 」が付かないのが相対アドレスです)。

現在、キャラクターセット(文字エンコード)は多数ありますが、「UTF-8、Shift_JIS」の2つがインターネットでのデファクトスタンダードです(現在、Shift_JISよりUTF-8の方が推奨されています)。
metaタグのcharset属性で(「UTF-8、Shift_JIS」などの)キャラクターセット(文字エンコード)が設定可能です。
必ず(metaタグの)charset属性に設定されているキャラクターセット(文字エンコード)でセーブして下さい、セーブ時のキャラクターセット(文字エンコード)が違うと全角文字が文字化けするので注意して下さい。

ブラウザのフォント・サイズの初期値は16pxのようです、スマホなどではフォント・サイズは初期値(16px)が推奨されているようです。

インターネットでは「ファイル名、フォルダ名」は(半角)英文字の小文字と大文字が区別されるので注意が必要です。
また、インターネットに公開する場合、「ファイル名、フォルダ名」には使えない文字、使ってはダメな文字があります、半角「英字(大文字・小文字)、数字、アンダースコア、ハイフン」程度にして下さい、当然「ファイル名、フォルダ名」には全角文字も使用しないで下さい。
なお、(実際は何の問題もないのですが)インターネット上の慣習で英大文字は推奨されませんが、それは ただの慣習なのでアマチュアなら それほど気にしなくても良いでしょう(プロを目指すなら英大文字は使わないほうが良いでしょうが)。

【WEB】URLで使用できる文字の規定 RFC3986 Section2.3
https://ses-blog.net/archives/web/983.html

>チルダはユーザディレクトリ、ピリオドはファイルの拡張子で使われるため、実際は以下と考えること。
>・半角大文字アルファベット A~Z
>・半角小文字アルファベット a~z
>・半角数字 0~9
>・ハイフン –
>・アンダースコア _

ASCII あれこれ
http://yytomy.sakura.ne.jp/fundamental/ascii.html

ASCII(規格)だけでは漢字は表現できないので、JIS漢字(規格)が考案されましたが、非常に使いづらかったので、MicrosoftがJIS漢字(規格)を勝手に改変しShift_JIS(規格)が作成されました。
しかし Shift_JIS(規格)は約6,300文字程度しか収録されておらず、規格上からも収録文字数を大幅に増やすことはできませんでした。
そこでユニコードコンソーシアムによってUnicode(規格)が作成されました。
UTF-8(規格)はUnicode系の文字エンコードです。

UTF-8にはBOMを付与できますが、本来 BOM(Byte Order Mark)はエンディアン(ビッグエンディアン、リトルエンディアン)を指定するためのモノなのですが、UTF-8にはエンディアン(ビッグエンディアン、リトルエンディアン)は存在しないので、本来のBOM(Byte Order Mark)と意味で使われている訳ではなく、単にUTF-8エンコードである事を表わしているにすぎません。

BOM(Byte Order Mark)
http://exlight.net/devel/unicode/bom.html


HTML内では特殊文字は「文字実体参照」か「数値文字参照」に変換しなければなりません(クォーテーション、ダブル・クォーテーション」はバッティングする場合だけ変換すれば良い)。
※JavaScriptでは「¥」(半角エンサイン)を使うエスケープ・シーケンスもあるので注意が必要です。

HTMLの記号・特殊文字の文字コード表(文字実体参照、数値文字参照)
https://gray-code.com/html_css/list-of-symbols-and-special-characters/

例えばHTMLでは「<'&"&"&'>」と言うテキスト・データを表したいなら最低限「<」、「>」、「&」を変換する必要がありますが、「クォーテーション、ダブル・クォーテーション」がバッティングする場合は、それらも変換する必要があります。
下記は、その具体例です。
通常のテキストは勿論、URLまで変換しなければならない事に注意して下さい(HTML内のテキストは徹底的に変換しなければならないと認識する必要があります)。
リンク・テキストは「<'&"&"&'>」と表示されているハズです、またリンクをマウスの右ボタンで、「リンクのURLをコピー」をすると「 http://<'&"&"&'> 」となるハズです。
※URLは「href="http://~ "」とダブル・クォーテーションで囲まれており、ダブル・クォーテーションはバッティングするので、ダブル・クォーテーションも変換していることに注意して下さい(クォーテーションを変換したい場合は「&#39;」)。


<html>
    <head>
<!--
metaタグでcharsetをUTF-8に設定しています。
(モチロン他のキャラクターセットに変更しても良いですが)必ずcharsetに設定されているキャラクターセットでセーブして下さい。
-->
        <meta charset="UTF-8">
        <title>test</title>
    </head>
<body>
    <a href="http://&lt;'&amp;&#34;&amp;&#34;&amp;'&gt; " >&lt;'&amp;"&amp;"&amp;'&gt;</a><br>
</body>
</html>

Block( Address 0000079B Identity 00000231 )


<Number>: [0000052B]  <Date>: 2024/01/08 20:37:56
<Title>: Chromeモバイル・エミュレーター操作法
<Name>: amanojaku@管理人

「PC、タブレット、スマホ」などで解像度は機種ごとに違うので、特定の解像度に依存しないユーザー・フレンドリー(PCフレンドリー、タブレット・フレンドリー、スマホ・フレンドリー)なページが推奨されます。
Chromeのモバイル・エミュレーターで「PC、タブレット、スマホ」の各解像度をチェックしてみればユーザー・フレンドリーが如何に重要か解るでしょう。
(各解像度のチェック自体は それほど難しく無いので)現在 Webページを作成しているなら、実際にChromeの開発者ツール(デベロッパー・ツール)のモバイル・エミュレーターで「PC、タブレット、スマホ」の各解像度をチェックしてみると良いでしょう。

Chromeの開発者ツール(デベロッパー・ツール)にはスマホをエミュレートできるモバイル・エミュレーターが搭載されており、このモバイル・エミュレーターは仮想的に解像度も変更できるようです(なお 「Galaxy、Pixel、iPhone、iPad」などの解像度のプリセットも用意されているようです)。
ただし、そのプリセットは解像度を再現するだけであり、(当然 本質はPC用ブラウザなので)「スマホでは余りCSSが効かないとか、バク的な仕様とか」などを再現するわけではないので注意して下さい。

モバイル・エミュレーターは、当然 モバイル(スマホ、タブレット)用のエミュレーターなので(metaタグの)viewport属性で固定値が指定されている場合は、viewportの設定値の解像度が優先されるので注意して下さい(この制限を理解していればPC用としても利用可能です)、つまり PC用ページとしてチェックしたい場合で(metaタグの)viewport属性で固定値が指定されている場合は、その設定をコメントにし、代わりに下記の(metaタグの)viewport属性を設定て下さい。
「<!-- 」、「 -->」で囲うとコメントにできます(例.「<!-- コメント -->」)。
そうしないとスマホ用(metaタグの)viewport属性の固定値が有効になってしまうのでPC用の表示をチェックできません。
(metaタグの)viewport属性の設定が存在しない場合は、(metaタグの)charset属性の設定の次あたりに それを記述して下さい。

<meta name="viewport" content="width=device-width">


なお 下記は、一般的にネットで推奨されているviewportの例ですが、「initial-scale=1」が指定されていると横幅が はみ出る場合が有るようですので、「initial-scale=1」を削除することをオススメします。

> <meta name="viewport" content="width=device-width,initial-scale=1">


モバイル・エミュレーターは あくまでもモバイル用ブラウザのエミュレーターです、PC用ブラウザとはビミョウに仕様が違います(モバイル用ブラウザはスクロールバーの幅はゼロになります)。
PC用として利用したい場合は、その仕様を理解して使って下さい。
つまり(PC用として利用したい場合は)モバイル・エミュレーターはザックリとしたイメージを確認する場合のみにして、本格的にチェックしたい場合は、PCでチェックしたい解像度用の複数のアカウントを作成すると良いでしょう(その場合、PCモニターは4k解像度が推奨される)。

4kモニターを購入する場合の注意点
http:../utf8/smt.cgi?r+twilight/&bid+00000041&tsn+00000258&bts+2021/03/26%2020%3A00%3A27&


【画面の解像度に関して】
PCモニターの場合、現在4k画面(横幅3840px)が普及価格帯で販売されており、「HD画面(横幅1280px)、FHD(Full-HD)画面(横幅1920px)、WQHD(Wide Quad-HD)画面(横幅2560px)」などもあります。
また高解像度モニターは(高価ですが)「5k画面(横幅5120px)、6k画面(横幅6016px)、8k画面(横幅7680px)」も販売されています(そのうち量産効果で安くなるか?)。
逆に低解像度モニターは1K画面(横幅1024px)や(2020年9月現在、価格.com調べ)800px画面(横幅800px)も有るようです。

参考:下記はテレビ画面のHD(ハイビジョン)以降の規格(解像度)です。
今どきの若い人はHD(ハイビジョン)など知らないかもしれませんが、「4k画面、8k画面」ぐらいは聞いたことは有るでしょう。
ただしPCモニターの解像度は、テレビ画面のような正式な規格と言う訳では無いですが。

https://images.app.goo.gl/ZQctd4Rb7AorGsNp6

レスポンシブ・デザインの場合は、とりあえずChromeモバイル・エミュレーターで一般的には約「300px~3000px」解像度ぐらいをチェックすれば良いでしょう(プロなら6k解像度モニターぐらいは使ってるかもしれませんので、ポートフォリオを作成するなら約「280px~6000px」解像度ぐらいには対応すると良いでしょう)。
「タブレット、スマホ」は既に登録されているプリセットの解像度でチェックできるようです(「タブレット、スマホ」の解像度のプリセットは[Responsive]コンボボックスで選択可能です)。


「スマホ、タブレット」の場合は、端末の物理的な解像度とブラウザ上の解像度は違うようで、ブラウザ上の解像度を「CSSピクセル、dp解像度」と言うらしいです。

iOS・Android端末のCSSピクセル・dp解像度一覧
https://wemo.tech/1496

【2022最新】スマホ・タブレットの解像度一覧表(画面サイズの割合)iPhone・iPad..
https://webdesign-abc.com/tech/resolution-list/

今更「dp」について考える
https://developer.android.com/guide/topics/large-screens/support-different-screen-sizes?hl=ja

【実質的な解像度に関する注意点】
Windowsでは表示を拡大するスケーリング機能が有ります。

Windowsの4Kスケーリング環境を検証する
https://pc.watch.impress.co.jp/docs/column/4kshugyousou/732083.html

>視力に基づく見えやすさによって変わってくるが、4Kの場合150%で2,560×1,440ドット相当、200%で1,980×1,020ドット相当になり、この辺りが目安かと思われる。ディスプレイサイズも踏まえるなら、27型なら150%、15.6型なら200%にしておけば、ほとんどの人が見やすい文字サイズになるだろう。

つまり、スケーリングを考慮すると、PCにおいては最低限「約1000px~約2500px」解像度の範囲は対応する必要が有ると言うことになります。

(ここは流して読んでおけば良いです)それとは別に当方もザックリとした試算をしてみる。
PCでは視距離はモニターの横サイズに比例すると考えるようです(テレビでは視距離は画面の縦サイズに比例すると考えるようですが)。
(当方の環境で算出)視距離とモニターの横サイズに比例する(便宜的な)「視距離率」は1.45とする。
1m先の仮想的なドットピッチを(便宜的に)仮想ドットピッチとする。
「15インチ・モニター(アスペクト比 3:4)、解像度 1024x768、横サイズ 約305mm、ドットピッチ 約0.29785mm」⇒「視距離 1.45*305=約442mm、仮想ドットピッチ 0.29785*1000/442=約0.674mm」。
27インチ・モニターはスケーリングを150%と想定する、スケーリングしたドットピッチを(便宜的に)スケーリング・ドットピッチとする。
「27インチ・モニター(アスペクト比 9:16)、解像度 3840x2160、横サイズ 約598mm、ドットピッチ 約0.15573mm」⇒「視距離 1.45*598=約867mm、スケーリング・ドットピッチ 0.15573*1.5=約0.2336mm、仮想ドットピッチ 0.2336*1000/867=約0.269mm」。
15インチ・モニターと比べ27インチ・モニターの仮想ドットピッチは約40%のサイズになる。
つまり、15インチ・モニター「解像度 1024x768」でチェックする場合、「1024px~2560px」をチェックすれば良いと言うことになる。

【実際の操作法】
レスポンシブ・デザインの場合は、とりあえず一般的には約「300px~3000px」解像度ぐらいをチェックすれば良いでしょう(プロなら6k解像度モニターぐらいは使ってるかもしれませんので、ポートフォリオを作成するなら約「280px~6000px」解像度ぐらいには対応すると良いでしょう)。
モバイル・エミュレーターで解像度を変更したら、必ずリロードして下さい、Windowsなら[F5]。
自分のモニター解像度・以上か未満かで、モバイル・エミュレーターの操作法が変わるので注意して下さい。
なので まずは自分のモニター解像度を把握して下さい。

漢字入力はOFFにして下さい。
Windowsなら[F12]で開発者ツール(デベロッパー・ツール)を起動できます(起動に少々時間が かかるかもしれません)。
デフォルトではブラウザの右側に開発者ツール(デベロッパー・ツール)が表示されます。
開発者ツール(デベロッパー・ツール)の右上のスリー・ドットをクリックすると、メニューの先頭に開発者ツール(デベロッパー・ツール)・ドックの位置が指定できます(3番目の画像の赤く囲われた所)、左から順番に「別ウインドウ、左側、下側、右側」(個人的には別ウインドウを推します)。
開発者ツール(デベロッパー・ツール)・ドックを別ウインドウにした場合、Windowsなら下のタスク・バーに、その(開発者ツール(デベロッパー・ツール)・ドック用の)タスク・アイコンが表示されるので、それをクリックすることで表示・非表示を簡単に切り替えられます。
開発者ツール(デベロッパー・ツール)の上部のモバイル・エミュレーター・アイコン(1番目の画像の赤く囲われた所)をクリック。

【PC画面のエミュレイトの場合】
自分のモニター解像度より解像度を小さくする場合は、説明が難しくなるので、(Chromeモバイル・エミュレーターでチェックする場合は)かえって1k解像度モニターのほうが分かりやすいでしょう。
現状で1k解像度モニターが無い場合、(モニターが1600px解像度 以上なら)新規アカウントを作成し解像度を「800px~1280px」程度の解像度に設定すると良いでしょう(アカウント名は「1k」とかにして、そのアカウントは1k解像度専用にする)、1366px解像度 以下なら特に いじらなくても良いです。

PCモニターにおいては大まかなイメージが確認できれば良いだけなので、解像度の値は多少 誤差があっても問題ありません、とりあえず「1k~3k」解像度 程度を目安にしてみて下さい。

自分のモニター解像度より解像度を大きくする場合は、少々コツが要ります。
まず 最初に2番目の画像の赤く囲われたズーム指定(パーセント指定)を一旦 100%に指定、"幅"(左)に自分が指定したい解像度を入力し[Enter]、ビュー・エリアの右下の縁をドラッグし、縦・横を画面幅いっぱいにして下さい(特にビュー・エリアの幅は必ず、画面幅いっぱいにして下さい)。
(自分のモニター解像度より解像度を大きくする場合は)大まかなイメージが確認できれば良いだけなので解像度の値は多少 誤差があっても問題ありません。

なお Chromeモバイル・エミュレーターはモバイル・ブラウザをエミュレートしているので、スクロールバーの幅はゼロになります(通常のスクロールバーは表示されない)。
もし 本格的にチェックしたい場合は4k解像度モニター(+グラボ?)を買って、そのデフォルト解像度を2k~2.5k解像度とした場合には、1k解像度のアカウントを作って「デフォルト解像度と1k解像度」をチェックしてやれば良いでしょう。

4kモニターを購入する場合の注意点
http:../utf8/smt.cgi?r+twilight/&bid+00000041&tsn+00000258&bts+2021/03/26%2020%3A00%3A27&

【モバイル画面のエミュレイトの場合】
モバイルの場合は2番目の画像の赤く囲われたズーム指定(パーセント指定)を とりあえず100%に設定してみて下さい(明らかにサイズ感が違う場合は変更して下さい)。

ブレイク・ポイントをチェックしたい場合は、ビュー・エリアの縁をドラッグし、ブレイク・ポイントあたりで正常にレイアウトが変化するかを注視して下さい。
ビュー・エリアの縁をドラッグする場合、縦画面の最小値は280pxまでで良いです。

「タブレット、スマホ」の解像度のプリセットは(2番目の画像の赤く囲われたプリセット指定の)[サイズ:レスポンシブ]コンボボックスで選択可能です。
プリセットの解像度でチェックする場合はビュー・エリアはマウスで動かさないで下さい。

【解像度の変更時の注意点】
モバイル・エミュレーターで解像度を変更したら、必ずリロードして下さい、Windowsなら[F5]。
単位に「em、ex、ch、rem、lh」を使っている場合、解像度を変更してフォントなどの表示サイズが合わなくなったら、見やすいサイズにブラウザでフォント・サイズを設定して下さい。
《重要》ただし「Chrome」の「最小フォント・サイズ」設定は、「HTML、CSS」の設定を無視して強制的にフォント・サイズを変更してしまうので、本当にユーザー・フレンドリーか どうかをチェックしたいなら、「最小フォント・サイズ」設定は最小にしておかなければなりません。
例えば単位に「vw」などを使っている場合に、モバイル・エミュレーターで解像度を小さくしてもフォントの表示サイズが小さくならない時は「最小フォント・サイズ」設定が最小に設定されてないと思われるので ご注意ください(つまり「最小フォント・サイズ」設定が最小に設定されてないと、正しい表示をチェックできない)。
通常の「フォント・サイズ」設定でフォント・サイズが大きくならない場合は、フォント・サイズがフォント系単位 以外で指定されていると思われます。

【全画面表示でのチェックに関する注意点】
もし モバイル・エミュレーターを全画面表示でチェックしたい場合には、Windowsなら[F11]で全画面表示のON/OFFが可能です、全画面表示で起動中の他のアプリを表示したい場合は[Alt]+[Tab]でタスクマネージャーが起動できます、[Alt]は放さずに[Tab]を複数回 押すことで表示したいアプリを選択できます。

蛇足ですが

(メディアクエリは除き)Web系においての静的Webページでは古いpxなどの絶対単位を使うピクセル・パーフェクトは無くなりました(ただし動的Webページでは動的に絶対単位で生成している場合が多い感じです、また基幹系においての静的Webページでも昔ながらの古いpxなどの絶対単位のピクセル・パーフェクトを使っているかもしれませんが)。
つまり、(Web系においての静的Webページでは)現在の所謂ピクセル・パーフェクトは、別物になったと言うことです、(完全な別物なので)それをピクセル・パーフェクトと呼んで良いのかと言う議論は有るでしょうが。
分かりやすく言うと、肉眼で見たイメージとしてのピクセル・パーフェクトなので、脳内で便宜的に「イメージ・パーフェクト(仮)」とでも読み替えれば良いでしょう。
なお 人がピクセル・パーフェクトと言った時に、古いpx単位のピクセル・パーフェクトを言っているのか、「イメージ・パーフェクト(仮)」を言って居るのか、文脈から判断する必要があります。
なお (メディアクエリは除き)pxなどの絶対単位を使っていると「特定の解像度に依存する」ので、SEO(Search Engine Optimization:検索エンジン最適化)的には当然 マイナスになります。

ユーザー・フレンドリー(所謂 リキッド・レイアウト)はレイアウトが想定の範囲内で崩れるように設計しなければならないので、初心者には難しいです。
所謂ピクセル・パーフェクト(イメージ・パーフェクト(仮))なら、px→vwの換算は単なる四則演算なので特に難しいことはありません(アマチュアの勉強用なら1pxぐらいズレても、全然 気にしなくて良いです)。
いずれにしろ、「@media:メディアクエリ」はプログラムで言うところの条件分岐になるので、初心者には少々 取っつきにくいかもしれません。
プロとアマチュアでは方向性が違います、もし プロを目指すならピクセル・パーフェクトを希求して下さい。

本当に自分の作りたいサイトを(勉強のために)実用的なWebページで作ってネットで公開してみると良いでしょう(本当に自分の作りたいサイトならモチベーションも上がるでしょうから)。
逆に言うと、自分が本気でネットで公開したいサイトでないと、それだけの学習コスト(学習の労力)を掛けて勉強するのは難しいかもしれません、(もちろん 不可能と言うことでは無いですが)自分が本気でネットで公開したい、と言うモチベーションが有った方が学習に圧倒的に有利です。
自分が本当にネットで公開したいコンテンツが有るか、どうかも重要な要素になるでしょう。
無料レンタルWebサーバーは基本的に広告が入るので、広告がウザくない所を探して下さい。

いきなり難しいことから始めずに、初めは簡単なレイアウトから挑戦してみると良いでしょう。


<Number>: [0000052E]  <Date>: 2022/03/27 14:13:45
<Title>: モバイル・エミュレーター用のフォント・サイズ自動調整用「CSS、JavaScript」
<Name>: amanojaku@管理人

下記コードは あくまでもユーザー・フレンドリー用なので、(プロなど)ピクセル・パーフェクトを希求する場合は不要です。

Webページ作成時に何度も解像度をチェックするとなると、ユーザー・フレンドリーの場合は、各解像度で複数のフォント・サイズを検証しなけらばならないので、ブラウザによるフォント・サイズの調整(複数のフォント・サイズを検証)も、かなり面倒になります。
下記にフォント・サイズ自動調整用の「CSS、JavaScript」を記載してあるので、それを使うと便利でしょう、あくまでもモバイル・エミュレーター用の(暫定的なテスト表示用)コードなので、本番用Webページではコメントにするなど無効にして下さい。
※Edgeでは正常に動作しないので、必ずChromeを使って下さい。
モバイル・エミュレーターで解像度を変更したら、必ずリロードして下さい。

フォント・サイズ自動調整用の「CSS、JavaScript」により、下記「チンチロリン」ようにセレクトボックスが表示されます。

チンチロリン
http://xd305417.html.xdomain.jp/responsive/dice000/dice000.htm


【CSS定義(styleタグ内)の先頭に挿入】
※charset定義用metaタグの次にstyleタグを記述。

html {font-size: var(--HTML_FontSize);}

:root {
  /* 0.217 0.18 */
--HTML_SelectOption_MNumber: 1;
--HTML_SelectOption_FontSize: calc(1rem * var(--HTML_SelectOption_MNumber));
}
* {font-size: 1rem;}
select > option {font-size: var(--HTML_SelectOption_FontSize);}


【JavaScript】
※styleタグの次に下記のJavaScriptを記述。
※フォントの大きさを変更したい場合は「vnFontRatio = 6;」の値を変更して下さい。

<script>
  fwHTMLRoot = document.documentElement;
  vnScreenWidth = screen.width;
  vnScreenHeight = screen.height;
  fwHTMLRoot.style.setProperty('--ScreenWidth', vnScreenWidth+'px');
  fwHTMLRoot.style.setProperty('--ScreenHeight', vnScreenHeight+'px');
  console.log('vnScreenWidth:'+vnScreenWidth); 
  console.log('vnScreenHeight:'+vnScreenHeight); 
  oCSSViewport = document.getElementById('idCSSViewport');
  console.log('get_device():'+get_device()); 
  if('sp'==get_device()){
    console.log("if('sp'==get_device())"); 
    // oCSSViewport.setAttribute('content', 'width=480, user-scalable=yes');
  }
  vnDevicePixelRatio = window.devicePixelRatio;
  console.log('vnDevicePixelRatio='+vnDevicePixelRatio);
  vnDScreenWidth = vnScreenWidth*vnDevicePixelRatio;
  vnDScreenHeight = vnScreenHeight*vnDevicePixelRatio;
  fwHTMLRoot.style.setProperty('--DScreenWidth', vnDScreenWidth+'px');
  fwHTMLRoot.style.setProperty('--DScreenHeight', vnDScreenHeight+'px');
  console.log('vnDScreenWidth='+vnDScreenWidth);
  console.log('vnDScreenHeight='+vnDScreenHeight);
  fwHTMLHead = document.head;
  voComputedStyle = window.getComputedStyle(fwHTMLHead, null);
  vnWindow_InnerWidth = window.innerWidth;
  vnWindow_InnerHeight = window.innerHeight;
  vnWindow_InnerMinimum = Math.min(vnWindow_InnerWidth, vnWindow_InnerHeight);
  vnWindow_InnerMaximum = Math.max(vnWindow_InnerWidth, vnWindow_InnerHeight);
  fwHTMLRoot.style.setProperty('--Window_InnerWidth', vnWindow_InnerWidth+'px');
  fwHTMLRoot.style.setProperty('--Window_InnerHeight', vnWindow_InnerHeight+'px');
  fwHTMLRoot.style.setProperty('--Window_InnerMinimum', vnWindow_InnerMinimum+'px');
  fwHTMLRoot.style.setProperty('--Window_InnerMaximum', vnWindow_InnerMaximum+'px');
  console.log('vnWindow_InnerWidth:'+vnWindow_InnerWidth); 
  console.log('vnWindow_InnerHeight:'+vnWindow_InnerHeight); 
  vsDefaultFontSize = voComputedStyle.fontSize;
  console.log('vsDefaultFontSize='+vsDefaultFontSize);
  vnDefaultFontSize = parseFloat(vsDefaultFontSize); 
  console.log('vnDefaultFontSize='+vnDefaultFontSize);
  // JavaScript - モバイル判定(スマホ・タブレット・PC)
  // https://infoteck-life.com/a0368-js-mobile-judge/
  function get_device() {
    var ua = navigator.userAgent;
    if (ua.match(/(iPhone|iPod|Android.*Mobile)/i)) {
      return 'sp';
    } else if (ua.match(/iPad|Android|Silk|Kindle/i)) {
      return 'tab';
    } else {
      return 'pc';
    }
  }
  vnHTMLRoot_ClientWidth = fwHTMLRoot.clientWidth;
  vnHTMLRoot_ClientHeight = fwHTMLRoot.clientHeight;
  console.log('vnHTMLRoot_ClientWidth:'+vnHTMLRoot_ClientWidth); 
  console.log('vnHTMLRoot_ClientHeight:'+vnHTMLRoot_ClientHeight); 
  vnWindow_ScrollbarWidth = vnWindow_InnerWidth-vnHTMLRoot_ClientWidth;
  console.log('vnWindow_ScrollbarWidth:'+vnWindow_ScrollbarWidth); 
  fwHTMLRoot.style.setProperty('--Window_ScrollbarWidth', vnWindow_ScrollbarWidth+'px');
  CSSValue_Window_ScrollbarWidth = getComputedStyle(fwHTMLRoot).getPropertyValue('--Window_ScrollbarWidth');
  console.log('CSSValue_Window_ScrollbarWidth:'+CSSValue_Window_ScrollbarWidth); 
  //
  vnFontRatio = 1.55*(vnDefaultFontSize/5-1);
  vnHTML_FontSize = Math.ceil(vnWindow_InnerMinimum/200*vnFontRatio);
  // ↑ブラウザのフォント設定でフォントを拡大させたい場合。
  // ※当然、ブラウザのフォント設定が必要。
  console.log('vnFontRatio='+vnFontRatio); 
  console.log('vnHTML_FontSize='+vnHTML_FontSize); 
  vnFontRatio = 6;
  vnHTML_FontSize = Math.ceil(vnWindow_InnerMinimum/200*vnFontRatio);
  // ↑※テスト用(ブラウザのフォント設定の手間が無い)。
  console.log('vnFontRatio='+vnFontRatio); 
  console.log('vnHTML_FontSize='+vnHTML_FontSize); 
  fwHTMLRoot.style.setProperty('--HTML_FontSize', vnHTML_FontSize+'px');
  SetFontScale('1');
  function SetFontScale(sFScale){
    vnFontScale = Number(sFScale);
    vnHTML_FontSize = Math.ceil(vnWindow_InnerMinimum/200*vnFontRatio*vnFontScale);
    fwHTMLRoot.style.setProperty('--HTML_FontSize', vnHTML_FontSize+'px');
    console.log('vnHTML_FontSize='+vnHTML_FontSize); 
  }
</script>


【bodyタグの次に挿入】

<br>
<form>
  <select name='nmFontScaleSelect' style='' onchange='FSS=this.form.nmFontScaleSelect; SetFontScale(FSS.options[FSS.selectedIndex].value);'>
    <option value='0.85'>Font:0.85倍</option>
    <option value='1' selected>Font:1倍</option>
    <option value='1.25'>Font:1.25倍</option>
    <option value='1.65'>Font:1.65倍</option>
  </select>
</form>
<script>
  CSSValue_ScreenWidth = getComputedStyle(fwHTMLRoot).getPropertyValue('--ScreenWidth');
  CSSValue_ScreenHeight = getComputedStyle(fwHTMLRoot).getPropertyValue('--ScreenHeight');
  CSSValue_VDScreenWidth = getComputedStyle(fwHTMLRoot).getPropertyValue('--VDScreenWidth');
  CSSValue_VDScreenHeight = getComputedStyle(fwHTMLRoot).getPropertyValue('--VDScreenHeight');
  CSSValue_Window_InnerWidth = getComputedStyle(fwHTMLRoot).getPropertyValue('--Window_InnerWidth');
  CSSValue_Window_InnerHeight = getComputedStyle(fwHTMLRoot).getPropertyValue('--Window_InnerHeight');
  document.write(
  "oCSSViewport.getAttribute('content'):"+oCSSViewport.getAttribute('content')+';<br>'+
  'get_device():'+get_device()+';<br>'+
  'CSSValue_ScreenWidth:'+CSSValue_ScreenWidth+';<br>'+
  'CSSValue_VDScreenWidth:'+CSSValue_VDScreenWidth+';<br>'+
  'CSSValue_Window_InnerWidth:'+CSSValue_Window_InnerWidth+';<br>'+
  '<br>');
</script>

Block( Address 0000079A Identity 0000052B )


<Number>: [0000036D]  <Date>: 2023/12/23 13:31:21
<Title>: フロントエンドエンジニアの必須スキル
<Name>: amanojaku@管理人

コーダーとは?コーダーの業務と求められる能力
https://www.webstaff.jp/guide/jobcategory/coder/%E3%82%B3%E3%83%BC%E3%83%80%E3%83%BC%E3%81%AE%E4%BB%95%E4%BA%8B%E3%81%A8%E3%82%B9%E3%82%AD%E3%83%AB/

Webデザイナーとコーダーの違いとは?Web制作の職種を役割ごとに紹介
https://ktsuyoshi.com/web-design-designer-corder-difference

駆け出しマークアップエンジニアのためのWebサイト制作フロー - Qiita
https://qiita.com/AkiHamano/items/917c5b1ac50425bfcf95
※↑SEO対策も常識ですが、現在のSEO対策は昔とは全く別モノになってます。

フロントエンドエンジニアとは?フロントエンジニアの仕事内容・スキル・将来性
https://www.bigdata-navi.com/aidrops/1692/

Photoshop、Illustrator、XDからのコーディングに慣れよう!
https://note.com/haniwaman/n/nefa48db83682

データベースの基礎知識 WordPressとは
https://wp-exp.com/blog/database-kiso/

フロントエンドエンジニアには「HTML、CSS、レスポンシブ・デザイン、クロスブラウザ、Vanilla JS、jQuery、Vue.js、React、SCSS、 CMS(Contents Management System):「WordPress自体、PHP、SQL(データベース言語)」、Ajax、Next.js(React)、Nuxt.js(Vue.js)、SPA(Single Page Application)、SSR(Server Side Rendering)、サーバ-サイドJavaScript(Node.js、Deno)、TypeScript」あたりの知識が必要になると思われます。
プロは通常はBootstrapなんぞ使いませんが、既にBootstrapで作られているコードの改修なら有るかもしれません。
コーダーの実務経験が無いと、フロントエンドエンジニアには成れ無いので、まずはコーダーからスタートして年季を積んで下さい。

なお、「jQuery、Vue.js、React、Angular」のデメリットについては下記「JavaScriptフレームワーク」参照。

JavaScriptフレームワーク
http://ashtarte.pa.land.to/utf8/smt.cgi?r+sara/&bid+00000325&tsn+00000325&bts+2020/05/25%2017%3A50%3A20&

Block( Address 00000798 Identity 0000036D )


<Number>: [00000747]  <Date>: 2023/12/01 23:35:47
<Title>: PHPデモ/「チャット:SPA(Single Page Application)」:「ファイル・ロック、AJAX、タイマー」(Ver.3)
<Name>: amanojaku@管理人

デモなのでイロイロ手抜きをしています。

ザックリと言うと、サーバー側から(クライアントとの)差分のデータだけを持って来ています。
効率は良いと言うメリットは有りますが、プログラムとしては見通しが悪くなってしまってます(つまり読みづらい)。

レスポンスの遅延を想定して、タイマー処理はsetInterval()では無く、setTimeout()にする、(レスポンスの遅延を想定して)レスポンスが来てからsetTimeout()を設定する。
つまりsetTimeout()を設定する場所はどこでも良いと言う訳では無い。

サーバー・サイドの場合、多数のユーザーが同時にアクセスした場合を考慮する必要があります。
具体的にはサーバー・サイドの場合は、ファイル出力時にファイルをロックしないとデータ破壊される危険性があります。
また ファイルの書き換え(ファイル入力してファイル出力する)は、ファイル入出力を一体としてロックしないとデータ破壊される危険性があります、つまり ファイル入力とファイル出力でファイル・ロックを2つに分けるとファイル・データが破壊される危険性があります。
下記デモでもファイル入力とファイル出力でファイル・ロックは1つだけだと言うことに注意して下さい。

なお (データの削除などで)ファイル・サイズが前より小さくなる場合は「rewind(~)、ftruncate(~,0)」で一旦ファイル・サイズをゼロにする必要があります。


【index.php】

<?php
$fnHTMLSpecialcChars = "htmlspecialchars";
$fnHTMLEntities = "htmlentities";
$fnRawURLEncode = "rawurlencode";
$fnFile_Article = "File_Article";
$fnPrintOut = "PrintOut";

$nDebugSW = 0;
$sEncode = "UTF-8";
$sASC_LF = "\x0A"; // Line Feed.
$sASC_CR = "\x0D"; // Carriage Return.

$sIndention = $sASC_CR;
$sUE_Indention = rawurlencode($sIndention);
$sDelimiter = "<>"; // "\t"; // 
// $Delimiterは実際は"\t"タブ文字などが推奨されますが、
// デバッグ用表示には"<>"の方が分かりやすいでしょう。
$sUE_Delimiter = rawurlencode($sDelimiter);

$sFName_Article = "Article.txt";
$sFName_Template = "Template.html";
$sFFirst_Print = "@Print_";
$sFExt_Print = ".txt";

$nArticleMax = 100;

$Article_Add = false; // true; //
$nLastSerial = -1;

$sPT_Name = "";
if (isset($_POST['Name'])) {
  $sPT_Name = $_POST['Name'];
  // PrintOut("sPT_Name: {$sPT_Name}");
}
$FName_Print = $sFFirst_Print . $sPT_Name . $sFExt_Print;

if ($nDebugSW) {
  touch($FName_Print);
  ($FHW_Print = fopen($FName_Print, "w"))
    || die("die: fopen w: {$FName_Print}.");
  flock($FHW_Print, LOCK_EX); // ファイル排他ロック
  // LOCK_SH : ファイル共有ロック
  // LOCK_EX : ファイル排他ロック
}

$sPT_Submit = "";
if (isset($_POST['Submit'])) {
  $sPT_Submit = $_POST['Submit'];
  PrintOut("sPT_Submit: {$sPT_Submit}");
}

PrintOut("Delimiter: {$sUE_Delimiter}");

$sPT_LineMarker = "";
if (isset($_POST['LineMarker'])) {
  $sPT_LineMarker = $_POST['LineMarker'];
  PrintOut("sPT_LineMarker: {$sPT_LineMarker}");
}
// PrintOut("sPT_LineMarker: {$sPT_LineMarker}");

$sPT_Name = "";
if (isset($_POST['Name'])) {
  $sPT_Name = $_POST['Name'];
  PrintOut("sPT_Name: {$sPT_Name}");
}

$sPT_Comment = "";
if (isset($_POST['Comment'])) {
  $sPT_Comment = $_POST['Comment'];
  PrintOut("sPT_Comment: {$sPT_Comment}");
}

// PrintOut("POST['name']: {$_POST['name']}";
// PrintOut("POST['comment']: {$_POST['comment']}";

$sHE_Name = $sPT_Name;
// $sHE_Name = htmlspecialchars($sPT_Name, ENT_QUOTES);
$sHE_Comment = "";
$Article_Dsp = true; // false; //
if ($sPT_Submit == "AJAX") {
  // $AJAX = true; // false; //
}
if ("" < $sPT_Name && "" < $sPT_Comment) {
  PrintOut("if (sPT_Name && sPT_Comment &&)");
  $Article_Add = true; // false; //
  PrintOut("Article_Add: {$Article_Add}");
} else {
  PrintOut("else (sPT_Name && sPT_Comment &&)");
  // $sHE_Comment = $sPT_Comment;
}

$sResponse = "";
if ($sPT_Submit != "AJAX") {
  $sResponse = File_Template();
}
if ($sPT_Submit == "AJAX") {
  $sResponse = File_Article($sPT_LineMarker);
}

if ($FHW_Print) {
  // ファイルclose // ファイル・ロックも開放
  fclose($FHW_Print)
    || die("die: fclose: {$FName_Print}.");
}

echo $sResponse;

// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =   

function PrintOut($msg)
{
  global $FHW_Print, $FName_Print, $sPT_Submit;
  if ($FHW_Print) {
    $msg = $msg ? $msg : "";
    fwrite($FHW_Print, $msg . PHP_EOL)
      || die("die: fwrite: {$FName_Print}.");
  }
}

function File_Template()
{
  global $sFName_Template, $nDebugSW, $sUE_Delimiter, $sUE_Indention,
    $sIndention, $nArticleMax;

  // touch($sFName_Template);
  ($FHR_Template = fopen($sFName_Template, "r"))
    || die("die: fopen r: {$sFName_Template}.");
  // flock($FHW_Template, LOCK_EX); // ファイル排他ロック
  // LOCK_SH : ファイル共有ロック
  // LOCK_EX : ファイル排他ロック

  // $a1sTemplate = [];
  $sTemplate = "";
  while ($line = fgets($FHR_Template)) {
    $sTemplate .= $line . $sIndention;
  }
  $sTemplate = str_replace('<&$DebugSW>', $nDebugSW, $sTemplate);
  $sTemplate = str_replace('<&$UE_Delimiter>', $sUE_Delimiter, $sTemplate);
  $sTemplate = str_replace('<&$UE_Indention>', $sUE_Indention, $sTemplate);
  $sTemplate = str_replace('<&$ArticleMax>', $nArticleMax, $sTemplate);

  // ファイルclose // ファイル・ロックも開放
  fclose($FHR_Template)
    || die("die: fclose: {$sFName_Template}.");

  return $sTemplate;
}

function File_Article($sMarker)
{
  global $sFName_Article, $sDelimiter, $AJAX,
    $sPT_Name, $sPT_Comment, $Article_Add,
    $nArticleMax, $sIndention;

  $oTimeStamp = new DateTime();
  $sSummary = "";

  touch($sFName_Article);
  ($FHRP_Article = fopen($sFName_Article, "r+"))
    || die("die: fopen r+: {$sFName_Article}.");
  flock($FHRP_Article, LOCK_EX); // ファイル排他ロック
  // LOCK_SH : ファイル共有ロック
  // LOCK_EX : ファイル排他ロック
  $serial = -1;
  $line = null;
  $a1sArticle = [];
  while ($line = fgets($FHRP_Article)) {
    $line = str_replace(PHP_EOL, '', $line);
    $a1sArticle[] = $line;
    $col = explode($sDelimiter, $line);
  }
  if (0 < count($a1sArticle)) {
    $col = explode($sDelimiter, $a1sArticle[0]);
    $serial = (int)$col[0];
  }

  if ($Article_Add) {
    $line = "{$oTimeStamp->format('Y/m/d H:i:s v')}{$sDelimiter}{$sPT_Name}{$sDelimiter}{$sPT_Comment}";
    if ($serial < 0) {
      $serial = 0;
    } else {
      $serial++;
      $serial = $serial & 0xFFFFFFFF;
    }
    $line = $serial . $sDelimiter . $line;
    array_unshift($a1sArticle, $line);
    $a1sArticle = array_slice($a1sArticle, 0, $nArticleMax);
  }
  // $nLastSerial = $serial;
  $iMarker = $sMarker == "" ? -1 : (int)$sMarker;
  PrintOut("sMarker : {$sMarker}; iMarker : {$iMarker}; ");
  $a1sNewArticle = [];
  $summary = true; // false; //
  PrintOut("");
  PrintOut("for (i = 0; i < min(count(a1sArticle), nArticleMax); i++)");
  for ($i = 0; $i < min(count($a1sArticle), $nArticleMax); $i++) {
    $line = $a1sArticle[$i];
    $col = explode($sDelimiter, $line);
    $serial =  (int)$col[0];
    PrintOut("serial : {$serial}, ");
    if ($iMarker == $serial) {
      PrintOut("if (iMarker == serial)");
      $summary = false; // true; //
      break;
    }
    if ($summary) {
      PrintOut("line : {$line}, ");
      $sSummary .= $line . $sIndention;
    }
    $line = ($i != 0 ? $sIndention : "") . $line;
    // $a1sNewArticle[] = $line;
  }

  if ($Article_Add) {
    fseek($FHRP_Article, 0);
    rewind($FHRP_Article)
      || die("die: fseek: {$sFName_Article}.");
    ftruncate($FHRP_Article, 0)
      || die("die: ftruncate: {$sFName_Article}.");
    foreach ($a1sArticle as $key => $line) {
      PrintOut($line);
      fwrite($FHRP_Article, $line . PHP_EOL)
        || die("die: fwrite: {$sFName_Article}.");
    }
  }

  // ファイルclose // ファイル・ロックも開放
  fclose($FHRP_Article)
    || die("die: fclose: {$sFName_Article}.");
  PrintOut($sSummary);

  return $sSummary;
}


【Template.html】

<!DOCTYPE html>
<html>
<head>
  <meta charset='UTF-8'>
</head>
<style>
  p,
  section {
    border: thin solid #000;
    min-height: 1.5em;
  }

  #idDebug,
  #idDebugControl {
    display: none;
  }

</style>
<body>
  <form action="" method="POST">
    <input type="text" id="idName" name="Name" value="" placeholder="Name"><br>
    <input type="text" id="idComment" name="Comment" value="" placeholder="Comment">
    <button type="button" name="Submit" onclick="sSubmit='Article_Add';">Submit</button>
  </form>
  <main id="idMain">
    <div id="idDebugControl">
      <button type="button" onclick="AJAXComm();">AJAXComm</button><br>
    </div>
    <section id="idDebug">
    </section>
    <section id="idMessage">
    </section>
    <section id="idArticle">
    </section>
  </main>
</body>
<script>
  nDebugSW = Number("<&$DebugSW>");
  sIndention = decodeURI("<&$UE_Indention>");
  sDelimiter = decodeURI("<&$UE_Delimiter>");
  nArticleMax = Number("<&$ArticleMax>");
  nTimeout = 500;
  sSubmit = "";
  LineMarker = "";
  wDebug = document.getElementById("idDebug");
  wDebugControl = document.getElementById("idDebugControl");
  wMessage = document.getElementById("idMessage");
  wName = document.getElementById("idName");
  wComment = document.getElementById("idComment");
  wArticle = document.getElementById("idArticle");
  ConsoleOut(`nDebugSW: ${nDebugSW}`);
  ConsoleOut(`sDelimiter: ${sDelimiter}`);
  if (nDebugSW) {
    wDebug.style.display = "block";
    wDebugControl.style.display = "block";
  }

  function AJAXComm() {
    ConsoleOut();
    ConsoleOut("function AJAXComm()");
    var sAJAX_Charset = "UTF-8";
    var sAJAX_Server = "";
    var sQueryParameter = `Submit=AJAX&LineMarker=${LineMarker}&`;
    sQueryParameter += `Name=${encodeURI(wName.value)}&`;
    ConsoleOut(`sSubmit: ${sSubmit}, `);
    var err = false; // true; //
    if (sSubmit == 'Article_Add') {
      ConsoleOut("if (sSubmit == 'Article_Add')");
      sSubmit = "";
      ConsoleOut(`wName.value: ${wName.value}, `);
      ConsoleOut(`wComment.value: ${wComment.value}, `);
      wMessage.innerText = "";
      if (!wName.value) {
        err = true; // false; //
        wMessage.innerText += "★Nameが入力されていません\n";
      }
      if (!wComment.value) {
        err = true; // false; //
        wMessage.innerText += "★Commentが入力されていません\n";
      }
      sQueryParameter += `Comment=${encodeURI(wComment.value)}&`;
      wComment.value = "";
    }
    ConsoleOut(`sQueryParameter: ${sQueryParameter}, `);
    var sAJAX_Parameter = "";
    var oAJAX = new XMLHttpRequest();
    oAJAX.onload = function () {
      ConsoleOut();
      ConsoleOut("oAJAX.onload");
      if (this.readyState === 4 && this.status === 200) {
        ConsoleOut("this.readyState: " + this.readyState);
        ConsoleOut("this.status: " + this.status);
        var res = oAJAX.responseText;
        ConsoleOut(`res: ${res}, `);
        wDebug.innerText = res;
        if (res) {
          var a1sArticle = res.split(sIndention);
          ConsoleOut("a1sArticle");
          ConsoleOut(a1sArticle);
          var col = null;
          for (var i = a1sArticle.length - 1; 0 <= i; i--) {
            var line = a1sArticle[i];
            if (" " <= line) {
              var wP = document.createElement('p');
              wP.innerText = line;
              wArticle.prepend(wP);
              col = line.split(sDelimiter);
            }
          }
          /*
          var wFirst = wArticle.firstElementChild;
          if (wFirst) {
            col = wFirst.innerText.split(sDelimiter);
          }
          */
          if (col) {
            LineMarker = Number(col[0]);
          }
          ConsoleOut(`LineMarker: ${LineMarker}, `);
          while (nArticleMax < wArticle.childElementCount) {
            wArticle.lastElementChild.remove();
          }
        }
      }
      if (!nDebugSW) {
        setTimeout(AJAXComm(), nTimeout);
      }
    }
    // oAJAX.overrideMimeType('text/plain; charset=' + sAJAX_Charset);
    oAJAX.open('POST', sAJAX_Server);
    oAJAX.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    oAJAX.send(sQueryParameter);
    ConsoleOut(`oAJAX.send(sQueryParameter)`);
    ConsoleOut(`sQueryParameter: ${sQueryParameter}, `);
  }

  if (!nDebugSW) {
    setTimeout(AJAXComm(), nTimeout);
  }

  function ConsoleOut(msg) {
    if (nDebugSW) {
      msg = msg ? msg : "";
      console.log(msg);
    }
  }
</script>
</html>

Block( Address 00000796 Identity 00000743 )


<Number>: [00000791]  <Date>: 2023/11/30 19:34:40
<Title>: PHPデモ/「チャット:SPA(Single Page Application)」:「AJAX、タイマー、ファイル・ロック」(Ver.32)
<Name>: amanojaku@管理人

デモなのでイロイロ手抜きをしています。

ザックリと言うと、サーバー側の全データを持って来ています。
効率は悪いですが、プログラムとしては見通しが良くなるメリットが有ります(つまり読みやすい)。

レスポンスの遅延を想定して、タイマー処理はsetInterval()では無く、setTimeout()にする、(レスポンスの遅延を想定して)レスポンスが来てからsetTimeout()を設定する。
つまりsetTimeout()を設定する場所はどこでも良いと言う訳では無い。

サーバー・サイドの場合、多数のユーザーが同時にアクセスした場合を考慮する必要があります。
具体的にはサーバー・サイドの場合は、ファイル出力時にファイルをロックしないとデータ破壊される危険性があります。
また ファイルの書き換え(ファイル入力してファイル出力する)は、ファイル入出力を一体としてロックしないとデータ破壊される危険性があります、つまり ファイル入力とファイル出力でファイル・ロックを2つに分けるとファイル・データが破壊される危険性があります。
下記デモでもファイル入力とファイル出力でファイル・ロックは1つだけだと言うことに注意して下さい。

なお (データの削除などで)ファイル・サイズが前より小さくなる場合は「rewind(~)、ftruncate(~,0)」で一旦ファイル・サイズをゼロにする必要があります。


【index.php】

<?php
$fnHTMLSpecialcChars = "htmlspecialchars";
$fnHTMLEntities = "htmlentities";
$fnRawURLEncode = "rawurlencode";
$fnCount = "count";
$fnPrintOut = "PrintOut";
$fnFile_Article = "File_Article";

// Debug用 Switch : {1, 2}
$nDebugSW = 0;
$sEncode = "UTF-8";
$sASC_LF = "\x0A"; // Line Feed.
$sASC_CR = "\x0D"; // Carriage Return.

$sIndention = $sASC_CR;
$sDelimiter = "<>"; // "\t"; // 
// $Delimiterは実際は"\t"タブ文字などが推奨されますが、
// デバッグ用表示には"<>"の方が分かりやすいでしょう。

$nJS_Timeout = 500;
$sCommMode_Default = "AJAX";
$sCommMode_ArticleAdd = "ArticleAdd";
$Article_Add = false; // true; //
$nArticleMax = 100;
$nSerialSurp = 0x10000000;
/*
// Debug用
$nArticleMax = 3;
$nSerialSurp = 4;
*/

$sUE_Indention = rawurlencode($sIndention);
$sUE_Delimiter = rawurlencode($sDelimiter);

$sFName_Article = "Article.txt";
$sFName_Template = "Template.html";
$sFFirst_Print = "@Print_";
$sFExt_Print = ".txt";
$sClientIP = Get_ClientIP();

$sPT_Name = "";
if (isset($_POST['Name'])) {
  $sPT_Name = $_POST['Name'];
  // PrintOut("sPT_Name: {$sPT_Name}");
}
$sPIdentifi = $sPT_Name;
$FName_Print = $sFFirst_Print . $sPIdentifi . "@0" . $sFExt_Print;
$FName1_Print  = $sFFirst_Print . $sPIdentifi . "@1" . $sFExt_Print;

if ($nDebugSW) {
  if (file_exists($FName_Print)) {
    copy($FName_Print, $FName1_Print);
  }
  touch($FName_Print);
  ($FHW_Print = fopen($FName_Print, "w"))
    || die("die: fopen w: {$FName_Print}.");
  flock($FHW_Print, LOCK_EX); // ファイル排他ロック
  // LOCK_SH : ファイル共有ロック
  // LOCK_EX : ファイル排他ロック
}

$oTimeStamp = new DateTime();
$sTimeStamp = "{$oTimeStamp->format('Y/m/d H:i:s v')}";

PrintOut("sTimeStamp: {$sTimeStamp}");
PrintOut("sPIdentifi: {$sPIdentifi}");

$sPT_SubmitMode = "";
if (isset($_POST['SubmitMode'])) {
  $sPT_SubmitMode = $_POST['SubmitMode'];
  PrintOut("sPT_SubmitMode: {$sPT_SubmitMode}");
}

$sPT_Name = "";
if (isset($_POST['Name'])) {
  $sPT_Name = $_POST['Name'];
  PrintOut("sPT_Name: {$sPT_Name}");
}

$sPT_Comment = "";
if (isset($_POST['Comment'])) {
  $sPT_Comment = $_POST['Comment'];
  PrintOut("sPT_Comment: {$sPT_Comment}");
}

$sPT_LineMarker = "";
if (isset($_POST['LineMarker'])) {
  $sPT_LineMarker = $_POST['LineMarker'];
  PrintOut("sPT_LineMarker: {$sPT_LineMarker}");
}

PrintOut("sPT_Name: {$sPT_Name}");
PrintOut("sPT_Comment: {$sPT_Comment}");
PrintOut("sPT_SubmitMode: {$sPT_SubmitMode}");

$vArticleAdd = false; // true; //
if (
  "" < $sPT_Name && "" < $sPT_Comment
  && $sPT_SubmitMode == $sCommMode_ArticleAdd
) {
  PrintOut("if (sPT_Name && sPT_Comment && ~ArticleAdd)");
  $vArticleAdd = true; // false; //
  PrintOut("vArticleAdd: {$vArticleAdd}");
}

$sResponseMode = "";
if ($sPT_SubmitMode) {
  $vResponseMode = $sCommMode_Default;
}

$sResponse = "";
if (!$sPT_SubmitMode) {
  $sResponse = File_Template();
} else {
  $sResponse = File_Article();
}

if ($FHW_Print) {
  // ファイルclose // ファイル・ロックも開放
  fclose($FHW_Print)
    || die("die: fclose: {$FName_Print}.");
}

echo $sResponse;

// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =   

function PrintOut($msg)
{
  global $FHW_Print, $FName_Print, $sPT_SubmitMode;
  if ($FHW_Print) {
    $msg = $msg ? $msg : "";
    fwrite($FHW_Print, $msg . PHP_EOL)
      || die("die: fwrite: {$FName_Print}.");
  }
}

function File_Template()
{
  global $sFName_Template, $nDebugSW, $sUE_Delimiter, $sUE_Indention,
    $sIndention, $nArticleMax, $sCommMode_Default, $sCommMode_ArticleAdd,
    $nJS_Timeout, $fnCcount;

  // touch($sFName_Template);
  ($FHR_Template = fopen($sFName_Template, "r"))
    || die("die: fopen r: {$sFName_Template}.");
  // flock($FHW_Template, LOCK_EX); // ファイル排他ロック
  // LOCK_SH : ファイル共有ロック
  // LOCK_EX : ファイル排他ロック

  $sTemplate = "";
  while ($line = fgets($FHR_Template)) {
    $sTemplate .= $line . $sIndention;
  }
  $sTemplate = str_replace('<\$DebugSW\>', $nDebugSW, $sTemplate);
  $sTemplate = str_replace('<\$CommMode_Default\>', $sCommMode_Default, $sTemplate);
  $sTemplate = str_replace('<\$CommMode_ArticleAdd\>', $sCommMode_ArticleAdd, $sTemplate);
  $sTemplate = str_replace('<\$UE_Indention\>', $sUE_Indention, $sTemplate);
  $sTemplate = str_replace('<\$UE_Delimiter\>', $sUE_Delimiter, $sTemplate);
  $sTemplate = str_replace('<\$JS_Timeout\>', $nJS_Timeout, $sTemplate);

  // ファイルclose // ファイル・ロックも開放
  fclose($FHR_Template)
    || die("die: fclose: {$sFName_Template}.");

  return $sTemplate;
}

function File_Article()
{
  PrintOut("");
  PrintOut("function File_Article()");
  global $sFName_Article, $sDelimiter, $AJAX,
    $sPT_Name, $sPT_Comment, $fnCcount,
    $nArticleMax, $sIndention, $nSerialSurp, $oTimeStamp,
    $sTimeStamp, $a1sArticle, $vArticleAdd;

  touch($sFName_Article);
  ($FHRP_Article = fopen($sFName_Article, "r+"))
    || die("die: fopen r+: {$sFName_Article}.");
  flock($FHRP_Article, LOCK_EX); // ファイル排他ロック
  // LOCK_SH : ファイル共有ロック
  // LOCK_EX : ファイル排他ロック
  $serial = PHP_INT_MIN;
  $begin = PHP_INT_MIN;
  $line = null;
  if (!$a1sArticle) {
    $a1sArticle = [];
    while ($line = fgets($FHRP_Article)) {
      $line = str_replace(PHP_EOL, '', $line);
      $a1sArticle[] = $line;
      $a1col = explode($sDelimiter, $line);
    }
  }
  if ($a1sArticle) {
    $a1col = explode($sDelimiter, $a1sArticle[0]);
    $serial = (int)$a1col[0];
  }

  if ($vArticleAdd) {
    PrintOut("if (vArticleAdd)");
    PrintOut("sPT_Name: {$sPT_Name}");
    PrintOut("sPT_Comment: {$sPT_Comment}");
    $line = "{$sTimeStamp}{$sDelimiter}{$sPT_Name}{$sDelimiter}{$sPT_Comment}";
    if ($serial < 0) {
      $serial = 0;
    } else {
      $serial++;
      $serial = $serial % $nSerialSurp;
    }
    $line = $serial . $sDelimiter . $line;
    array_unshift($a1sArticle, $line);
    // $a1sArticle = array_slice($a1sArticle, 0, $nArticleMax);
    PrintOut("serial: {$serial}");
    PrintOut("line: {$line}");
    $cnt = count($a1sArticle);
    PrintOut("count(a1sArticle): {$cnt}");
  }

  $a1sNewArticle = [];
  $article = "";
  PrintOut("");
  PrintOut("for (i = 0; i < count(a1sArticle); i++)");
  for ($i = 0; $i < count($a1sArticle); $i++) {
    $line = $a1sArticle[$i];
    PrintOut("if ($i < nArticleMax)");
    PrintOut("if ($i < $nArticleMax)");
    if ($i < $nArticleMax) {
      PrintOut("if ($i < nArticleMax)");
      PrintOut("line : {$line}, ");
      $a1sNewArticle[] = $line;
      $article .= ($i != 0 ? $sIndention : "") . $line;
      $nArticleSize = count($a1sNewArticle);
      PrintOut("article : {$article}, ");
    } else {
      break;
    }
  }

  if ($vArticleAdd) {
    $a1sArticle = $a1sNewArticle;
    fseek($FHRP_Article, 0);
    rewind($FHRP_Article)
      || die("die: fseek: {$sFName_Article}.");
    ftruncate($FHRP_Article, 0)
      || die("die: ftruncate: {$sFName_Article}.");
    foreach ($a1sArticle as $key => $line) {
      PrintOut($line);
      fwrite($FHRP_Article, $line . PHP_EOL)
        || die("die: fwrite: {$sFName_Article}.");
    }
  }

  // ファイルclose // ファイル・ロックも開放
  fclose($FHRP_Article)
    || die("die: fclose: {$sFName_Article}.");
  return $article;
}


function Get_ClientIP()
{
  if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    // HTTP_CLIENT_IPをチェック
    $ip = $_SERVER['HTTP_CLIENT_IP'];
  } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    // HTTP_X_FORWARDED_FORをチェック
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  } else {
    // REMOTE_ADDRをチェック
    $ip = $_SERVER['REMOTE_ADDR'];
  }
  return explode(",", $ip)[0];
}


【Template.html】

<!DOCTYPE html>
<html>
<head>
  <meta charset='UTF-8'>
</head>
<style>
  p,
  section {
    border: thin solid #000;
    min-height: 1.5em;
  }

  #idDebug,
  #idDebugControl {
    display: none;
  }

</style>
<body>
  <form method="POST" id="idForm" action="">
    <input type="text" id="idName" name="Name" value="" placeholder="Name"><br>
    <input type="text" id="idComment" name="Comment" value="" placeholder="Comment">
    <button type="button" onclick="AJAXComm('<\$CommMode_ArticleAdd\>')">Submit:(Model)</button>
    <input type="hidden" id="idLineMarker" name="LineMarker">
    <input type="hidden" id="idSubmitMode" name="SubmitMode" value="<\$CommMode_Default\>">
  </form>
  <main id="idMain">
    <div id="idDebugControl">
      <button type="button" onclick="AJAXComm();">AJAXComm:(Event)</button><br>
    </div>
    <section id="idDebug">
    </section>
    <section id="idMessage">
    </section>
    <section id="idArticle">
    </section>
  </main>
</body>
<script>
  nDebugSW = Number("<\$DebugSW\>");
  sIndention = decodeURI("<\$UE_Indention\>");
  sDelimiter = decodeURI("<\$UE_Delimiter\>");
  sCommMode_Default = "<\$CommMode_Default\>";
  sCommMode_ArticleAdd = "<\$CommMode_ArticleAdd\>";
  nTimeout = Number("<\$JS_Timeout\>");
  sSubmitModel = "";
  LineMarker = -1;
  wDebug = document.getElementById("idDebug");
  wDebugControl = document.getElementById("idDebugControl");
  wMessage = document.getElementById("idMessage");
  wForm = document.getElementById("idForm");
  wName = document.getElementById("idName");
  wComment = document.getElementById("idComment");
  wSubmitMode = document.getElementById("idSubmitMode");
  wLineMarker = document.getElementById("idLineMarker");
  wArticle = document.getElementById("idArticle");
  ConsoleOut(`nDebugSW: ${nDebugSW}`);
  ConsoleOut(`wForm: ${wForm}`);
  ConsoleOut(wForm);
  if (2 <= nDebugSW) {
    wDebug.style.display = "block";
    wDebugControl.style.display = "block";
  }

  function AJAXComm(submit) {
    ConsoleOut();
    ConsoleOut("function AJAXComm()");

    if (submit) {
      sSubmitModel = submit;
    }

    var sAJAX_Charset = "UTF-8";
    var sAJAX_Server = "";
    var err = false; // true; //
    ConsoleOut(`sSubmitModel: ${sSubmitModel}`);
    ConsoleOut(`wSubmitMode.value: ${wSubmitMode.value}`);
    if (sSubmitModel) {
      ConsoleOut("if (sSubmitModel)");
      wMessage.innerText = "";
      if (!wName.value) {
        err = true; // false; //
        wMessage.innerText += "★Nameが入力されていません\n";
      }
      if (!wComment.value) {
        err = true; // false; //
        wMessage.innerText += "★Commentが入力されていません\n";
      }
      if (!err) {
        wSubmitMode.value = sSubmitModel;
      }
      ConsoleOut(`err: ${err}`);
      ConsoleOut(`wSubmitMode.value: ${wSubmitMode.value}`);
      sSubmitModel = "";
    }

    var oAJAX = new XMLHttpRequest();
    oAJAX.onload = function () {
      ConsoleOut(``);
      ConsoleOut(`oAJAX.onload = function ()`);
      ConsoleOut(`sSubmitModel: ${sSubmitModel}`);
      ConsoleOut(`wSubmitMode.value: ${wSubmitMode.value}`);
      if (wSubmitMode.value == sCommMode_ArticleAdd) {
        wComment.value = "";
        wMessage.innerText = "";
      }
      wSubmitMode.value = sCommMode_Default;
      ConsoleOut();
      ConsoleOut("oAJAX.onload");
      if (this.readyState === 4 && this.status === 200) {
        ConsoleOut("this.readyState: " + this.readyState);
        ConsoleOut("this.status: " + this.status);
        var res = oAJAX.responseText;
        wDebug.innerText = res;
        if (res) {
          var a1sArticle = res.split(sIndention);
          var col = null;
          //wArticle.innerHTML = "";
          var w = null;
          while (w = wArticle.firstChild) {
            wArticle.removeChild(w);
          }
          for (var i = a1sArticle.length - 1; 0 <= i; i--) {
            var wP = document.createElement('p');
            wArticle.prepend(wP);
            // appendChild(element);
            var line = a1sArticle[i];
            wP.innerHTML = KillTag(line);
            a1col = line.split(sDelimiter);
          }
          if (a1col) {
            LineMarker = Number(a1col[0]);
          }
          wLineMarker.value = LineMarker;
          ConsoleOut(`LineMarker: ${LineMarker}, `);
        }
      }
      if (nDebugSW < 2) {
        setTimeout(AJAXComm(), nTimeout);
      }
    }

    ConsoleOut(`wForm: ${wForm}`);
    ConsoleOut(wForm);
    oForm = new FormData(wForm);
    ConsoleOut(`oForm: ${oForm}, `);
    ConsoleOut(oForm);
    for (var d of oForm.entries()) {
      ConsoleOut(`${d[0]}: ${d[1]}`);
    }
    // oAJAX.overrideMimeType('text/plain; charset=' + sAJAX_Charset);
    oAJAX.open('POST', sAJAX_Server);
    // oAJAX.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    oAJAX.send(oForm);
    ConsoleOut(`oAJAX.send(oForm)`);
  }

  if (nDebugSW < 2) {
    setTimeout(AJAXComm(), nTimeout);
  }

  function ConsoleOut(msg) {
    if (nDebugSW) {
      msg = msg ? msg : "";
      console.log(msg);
    }
  }

  function KillTag(txt) {
    return txt
      .replace(/&/gs, '&amp;')
      .replace(/</gs, '&lt;')
      .replace(/>/gs, '&gt;')
      .replace(/"/gs, '&quot;')
      .replace(/'/gs, '&apos;');
  }

</script>
</html>

Block( Address 00000795 Identity 00000791 )






ページの表示順:{ 新しい順/ 古い順}.
初期・ページの表示・位置:{ 先頭ページ/ 末尾ページ}.
1ページ内のスレッド表示数:

   
   

管理者用 Password:

  




SMT Version 8.022(+A) Release M6.
Author : amanojaku.