[LWID]Westagramの実施


概要


先週、2週目のセッションと課題のINSTAGRAMクローンを行いました.
これはTIDに入れないので「Last Week I Did」と言います乞食すぎじゃないの??😛
タスクは9種類に分けられ、以下のようになります.
  • ログインページレイアウト
  • id、pw入力時にログインボタン機能
  • をアクティブにする.
  • ホームレイアウト
  • コメントを入力してEnterまたはPublishボタンを押すとコメントを追加できます
    ここまでは私たちの必修科目
  • です.
  • IDとパスワード検証
  • コメント点賛/削除機能
  • アイデンティティ検索機能
  • navプロファイル写真をクリックしてメニューボックス
  • を作成します.
  • 反応式実施
    ここまでが提案課題です.
  • 課題実施履歴


    レイアウトはhtmlとcsなのでスキップしてJSに関する内容だけ整理します.

    id,pw入力時にログインボタンをアクティブにする


    この課題は,inputにid,pwが1文字を超えると登録ボタンの色が変わる形式の課題である.
    次のID/パスワード検証タスクは、次のコードに示すように、既存のコンテンツを消去します.
    const validateInputLength = (name, e) => {
      name === 'id' ? (idValue = e.target.value) : (passwordValue = e.target.value);
      if (idValue && passwordValue) {
        loginButton.classList.add('active');
        loginButton.removeAttribute('disabled');
      } else {
        loginButton.classList.remove('active');
        loginButton.setAttribute('disabled', 'disabled');
      }
    };
    1つの関数として、上記の関数を用いた入力がidであるかpasswordであるかをnameで識別し、関数を実行する.

    コメント内容を入力し、EnterまたはPublishボタンを押してコメントを追加


    JSの勉強を始めたばかりの頃はinnerHTMLの使用に関する文章が多く見られたので、これを実現するにはinnerHTMLではなくテキストの内容が主に使われていました.
    const addCommentHandler = (e) => {
      comment = e.target.value;
    
      if (e.key === 'Enter' && comment) {
        displayComment();
      }
    };
    const displayComment = () => {
      if (comment) {
        const commentLiTag = document.createElement('li');
        const commentId = document.createElement('span');
        const commentText = document.createElement('span');
        const commentLike = document.createElement('button');
        const commentRemove = document.createElement('button');
    
        commentId.textContent = 'xoxoxo_S2';
        commentId.classList.add('commentor-id');
        commentText.textContent = comment;
        commentText.classList.add('comment-content');
        commentLike.innerHTML = '<i class="fas fa-heart"></i>';
        commentLike.classList.add('comment-like-button');
        commentLike.addEventListener('click', (e) => changeLikeButtonColor(e));
        commentRemove.textContent = '삭제';
        commentRemove.classList.add('comment-remove-button');
        commentRemove.addEventListener('click', () => removeComment(commentLiTag));
    
        commentLiTag.appendChild(commentId);
        commentLiTag.appendChild(commentText);
        commentLiTag.appendChild(commentLike);
        commentLiTag.appendChild(commentRemove);
        commentList.appendChild(commentLiTag);
    
        comment = '';
        inputComment.value = '';
      }
    };

    fontawesomeを使用している部分だけをinnerHTMLとして処理し、textContentとappendChildを1つずつ使用して処理するのは、内容が長すぎるという欠点があります.
    「いいね」ボタンと「削除」ボタンは、生成時にaddEventListenerに与えられ、イベントがバインド処理される.

    認証とパスワードの検証


    ここからは、追加の実施課題であるため、上の1つの課題に上書きされることがある.
    ここでidには「@」が含まれており、pwはログインボタンをアクティブにするには5文字を超える必要があります.
    const validateInputLength = (name, e) => {
      name === 'id' ? (idValue = e.target.value) : (passwordValue = e.target.value);
      if (idValue && idValue.includes('@') && passwordValue.length >= 5) {
        loginButton.classList.add('active');
        loginButton.removeAttribute('disabled');
      } else {
        loginButton.classList.remove('active');
        loginButton.setAttribute('disabled', 'disabled');
      }
    };
    既に条件文が作成されているので、IDはif文のincludesメソッドを使用して@を含むか否かを決定し、PWは最も簡単なlengthを使用して処理する.

    コメント作成/削除機能

    const changeLikeButtonColor = (e) => {
      !e.target.className.includes('active')
        ? e.target.classList.add('active')
        : e.target.classList.remove('active');
    };
    DBがなければ色を変えるだけで好きなので、classの追加と削除の切り替えで処理しました.
    // commentRemove.addEventListener('click', () => removeComment(commentLiTag));
    
    const removeComment = (li) => {
      li.remove();
    };
    削除コメントを作成するときに、上記のように処理して、コメントの親要素が何であるかを知るため、removeを使用して直接削除します.

    アイデンティティー検索機能


    const searchID = (value) => {
      const inputValue = searchBar.value;
      return value.id.indexOf(inputValue) !== -1;
    };
    searchBar.addEventListener('input', () => {
      searchResult.innerHTML = '';
      searchResult.style.display = 'none';
      searchResultTriangle.style.display = 'none';
      if (searchBar.value) {
        const filterdId = personalInfo.filter((value) => searchID(value));
        if (filterdId) {
          filterdId.forEach((value) => {
            displaySearchResults(value);
          });
        }
      }
    });
    今回の課題の中で最も悩んでいる部分です.
    最初はindexOfを思い浮かべ,それを利用して考え続け,上のコードで与えられたfilterを混合して実現した.

    navプロファイル写真をクリックするとメニューボックスが作成されます



    この実現自体は難しくありません.ここでの具体的な任務は、そのエリアの外をクリックすると、メニューが消えるはずですが、思い出せません.targetのparentNodeをクリックすると、消えてしまい、指導者にヒントを使ってouter clickというキーワードを獲得し、対応するアクティビティを実現します.
    const displayPersonalMenu = (e) => {
      const personalMenu = document.querySelector('.personal-menu');
      const personalMenuTriangle = document.querySelector('.personal-menu-triangle');
    
      if (e.target.className !== 'nav-button-profile') {
        personalMenuTriangle.style.display = 'none';
        personalMenu.style.display = 'none';
      } else {
        personalMenuTriangle.style.display = 'block';
        personalMenu.style.display = 'flex';
      }
    };
    body.addEventListener('click', displayPersonalMenu);
    以上のようにbodyにアクティビティを与え、profileボタンをクリックすると個人メニューが表示され、それ以外は消えます.

    反応式実施


    反応型はレイアウトと同様html,cssを主とし,単独では記述されない.
    しかしこれを始めたばかりの頃はviewport単位を使いたかったのでvmin,vmaxを使いましたが、概念を間違えたのでブラウザが大きくなるとその単位を使う要素が大きすぎてしまいました.

    私のインスタ状態…?

    感想


    実戦2週間の課題である程度のJavaScriptを学習したが,上記コードでは5日間の課題時間を与えたが,残りの学習時間を1日で終えることが多い1週間であった.
    3週目から反応があったので、彼の文章をもう1編書きます.