ご回答いただけるとありがたいです。よろしくお願いします!
実現したいこと
document.URL.matchを使って、特定のページにだけJSを反映させたい。
現状
Railsを使ってSNSのようなアプリを作っています。そこでプロフィールアイコン機能を実装しています。
アイコンを登録する時に、画像のプレビューを表示させるために、JSを用いています。
※ユーザー登録する時に、nickname, password, password-confirmationが入力されていないと、エラーメッセージが表示され、登録できない設定です。
該当のソースコード
views
1#registrations/new.html.erb 2<div class="account-page"> 3 <div class="account-page-title"> 4 アカウントを作成 5 </div> 6 <%= form_with model: @user, url: user_registration_path, local: true do |f|%> 7 <%= devise_error_messages!%> 8 <div class="account-page-container"> 9 <div class="account-page-wrapper"> 10 <div class="field-input account-page-input-avator"> 11 <label class="account-page-input-avator-btn"> 12 <div id="avator-list"></div> 13 <%= image_tag "human.dummy.png", class: "human-dummy" %> 14 <%= f.file_field :avator, class: 'hidden' %> 15 </label> 16 </div> 17(省略)
js
1#preview.js 2if (document.URL.match( "users/sign_up" )) { 3 document.addEventListener('DOMContentLoaded', function(){ 4 const ImageList = document.getElementById('avator-list'); 5 6 const createImageHTML = (blob) => { 7 const imageElement = document.createElement('div'); 8 9 const blobImage = document.createElement('img'); 10 blobImage.setAttribute('src', blob); 11 12 imageElement.appendChild(blobImage); 13 ImageList.appendChild(imageElement); 14 }; 15 16 document.getElementById('user_avator').addEventListener('change', function(e){ 17 const imageContent = document.querySelector('img'); 18 if (imageContent){ 19 imageContent.remove(); 20 } 21 22 const file = e.target.files[0]; 23 const blob = window.URL.createObjectURL(file); 24 25 createImageHTML(blob); 26 }); 27 }); 28}
以上のコードで、アイコンに指定した画像を表示させることができています。
また、表示されているアイコンをクリックしたら、アイコンを変更することもできます。
###起きていた問題(解決済)
わざと何も入力せずに「(アカウントを)登録する」ボタンをクリック。
エラーメッセージが表示される。
画像を選択し、表示させようと思っても表示されない。
なぜか確認したところ、一度登録に失敗するとURLが
(失敗前)http://localhost:3000/users/sign_up (失敗後)http://localhost:3000/users
になりsign_upがなくなります。
そこでJSのコードを以下のように変えました。
js
1#preview.js 2if (document.URL.match( "users/sign_up" ) || document.URL.match( "users" )) { 3(省略)
これで登録失敗後にも、画像を選択したら表示されるようになりました。
ここからがわからないところです。
###起きている問題
ログイン画面(http://localhost:3000/users/sign_in)でコンソールを確認すると以下のエラー文が表示されます。
Uncaught TypeError: Cannot read property 'addEventListener' of null at HTMLDocument.<anonymous> (avatorPreview.js:18)
原因は先ほど
js
1#preview.js 2if (document.URL.match( "users/sign_up" ) || document.URL.match( "users" )) { 3(省略)
にしたから、usersが含まれるURL全てにjsが適応されているからということは理解しています。
そこでdocument.URL.match( "users" )の部分を変えないといけないと思い、以下などを参考にいろいろ試しました。
URLの指定の仕方
URLで条件分岐(取得とif文の組み方)
###試したこと
document.URL.match.pathname( "users" ) document.path.match( "users" ) window.location.pathname( "users" )
他にも
①"users"の後のパスを読み込まない方法
②document.URL.matchの反対で"users/sign_inを読み込まない方法
などがあるのかと予想して調べてみましたが、そのような方法があることする見つけることができませんでした。
以上になります。ご助言いただけると幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/09 09:42