Q&A
実現したいこと
HTMLの「form」タグのエリア内だけカートボタン「 id=cart-k」を追従させたい
前提
Bcartというカートシステムを使い、干渉できないHTMLのページをカスタマイズしています。
知識のない状態から独学で行っている状況です。
今回、HTMLに「hidden」が入っているため、cssの「position: sticky」が使えず、JavaScriptにて指定エリア内での追従を機能させたいと考えています。
内容
あるサイト様のヒントをいただき、当方のサイトに置き換えた状態で起動してみたのですが、「ReferenceError」(初期化前に「areaFixedFunk」にアクセスできません)が出てしまったため、関数<areaFixedFunk>に渡す値(#cart-k , .c-form)を先に宣言しました。
※Googlechromeのデベロッパーツール
そうしたところ、今度は「Uncaught TypeError」(null のプロパティを読み取れません ('id' を読み取っています))が出てしまいました。
正しく宣言ができていないと思い、チェックのためにコンソールにて「getElementById」と「getElementsByClassName」を使い確認したところ、「Uncaught SyntaxError」(識別子 '要素' は既に宣言されています)というエラーがでてきました。
頭がパンクしております。
どうすれば正しく機能するのでしょうか?
私の知識と理解不足であることは承知しているのですが、どうか、お力を貸していただけますでしょうか。
何卒、よろしくお願いいたします。
発生している問題・エラーメッセージ
●はじめ Uncaught ReferenceError: Cannot access 'areaFixedFunk' before initialization (Uncaught ReferenceError: 初期化前に「areaFixedFunk」にアクセスできません) ●2番目 Uncaught TypeError: Cannot read properties of null (reading 'id') (Uncaught TypeError: null のプロパティを読み取れません ('id' を読み取っています)) ●3番目 Uncaught SyntaxError: Identifier 'element' has already been declared (キャッチされていない SyntaxError: 識別子 '要素' は既に宣言されています)
該当のソースコード
■HTML
html
1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4省略 5</head> 6<body class=" body-product-detail __is-guest "> 7省略(sectionが6個程あります。) 8 9<form method="POST" action="URL" accept-charset="UTF-8" name="setForm" class="c-form"><input name="_token" type="hidden" value="JGbYwuFrw3G2z01SpA5x40TevLik5gu3gvoA84Gp"> 10<section class="__set p-product-set"> 11 <table> 12 <thead> 13 <tr> 14 <th class="__description">内訳</th> 15 <th class="__price"> 16 <div class="__total">販売価格</div> 17 <div class="__detail">(単価 × 入数)</div> 18 </th> 19 <th class="__order">注文数</th> 20 </tr> 21 </thead> 22 <tbody> 23 <tr class="__item __item--1 "> 24 <td class="__description"> 25 <h2 class="__name"> 26 ABS_BK_D00200-1000 / ABS 黒 φ10×L1000 27 </h2> 28 <div class="__spec"> 29 </div> 30 </td> 31 <td class="__price"> 32 <div class="__heading"> 33 <div class="__total">販売価格</div> 34 <div class="__detail">(単価 × 入数)</div> 35 </div> 36 <div class="__body"> 37 <div class="__total"><span class="c-tax-price __tax-price __is-none">1,100,000円</span></div> 38 <div class="__detail"> 39 (<span class="__unit-price"><span class="c-tax-price __tax-price __is-none">1,100,000円</span></span> × <span class="__quantity">1</span><span class="__unit"></span>) 40 </div> 41 </div> 42 </td> 43 <td class="__order"> 44 <div class="__error c-alert c-alert--danger __js-add-cart-error" style="display: none;"></div> 45 <div class="__heading">注文数</div> 46 <div class="__body"> 47 <div class="__input"> 48 <input placeholder="0" class="__js-order-count __js-disabled-enter-key" name="p[1]" type="number"><span class="__spin p-spin"><span class="__minus __js-spin"></span><span class="__plus __js-spin"></span></span> 49 </div> 50 <dl class="__cart-count __js-cart-count" style="display: none;" > 51 <dt>追加済</dt> 52 <dd>0</dd> 53 </dl> 54 <div class="__notice"> 55 <dl class="__min-max-order"> 56 <dt>注文可能数</dt> 57 <dd class="__min"> 58 <span class="__title">最小</span> 59 <span class="__count">1</span> 60 </dd> 61 </dl> 62 </div> 63 </div> 64 </td> 65 </tr> 66 <tr class="__item __item--2 "> 67 (省略※item30個ほど続きます。) 68 </tbody> 69 </table> 70</section> 71<section class="__add-cart"> 72 <input type="hidden" name="act" value="insert"> 73 <button type="button" class="__submit c-button-submit __js-add-cart">カートに入れる</button> 74</section> 75</form>
■ JavaScript
Java
1 //商品ページのカートにスクロールを実装する 2 //関数呼び出し(追従要素,追従エリア) 3 areaFixedFunk('#cart-k', '.c-form'); 4 //指定エリア内に要素を追従させる関数(追従要素,追従エリア) 5 const areaFixedFunk = (fixedElm,fixedArea) => { 6 //エリアチェック 7 const areas = document.querySelectorAll(fixedArea); 8 if(areas.length === 0) { 9 return; 10 } 11 //追従チェック関数 12 const checkFixed = (target,area) => { 13 //要素の位置と高さを取得 14 const startPosi = area.getBoundingClientRect().top; 15 const targetHeight = target.clientHeight; 16 const areaHeight = area.clientHeight; 17 const endPosi = startPosi + areaHeight; 18 19 //エリア内の処理 20 if(0 > startPosi && targetHeight < endPosi) { 21 target.classList.add('is-fixed'); 22 target.style.top = ''; 23 24 //エリアより上の処理 25 } else if(0 <= startPosi) { 26 target.classList.remove('is-fixed'); 27 target.style.top = ''; 28 29 //エリアより下の処理 30 } else { 31 target.classList.remove('is-fixed'); 32 //停止位置を設定 33 target.style.top = (areaHeight - targetHeight) + 'px'; 34 } 35 } 36 //エリア毎に処理 37 areas.forEach((area) => { 38 //エリア内に追従要素が存在する場合のみ処理する 39 const target = area.querySelector(fixedElm); 40 if(target) { 41 checkFixed(target,area); 42 window.addEventListener('resize', ()=> { 43 checkFixed(target,area); 44 }); 45 window.addEventListener('scroll', ()=> { 46 checkFixed(target,area); 47 }, {passive: true}); 48 } 49 }); 50 }
試したこと
JavaScriptのはじまり
java
1//関数呼び出し(追従要素,追従エリア) 2areaFixedFunk('#cart-k', '.c-form');
の前に
java
1//追従要素,追従エリアを宣言する 2const element = document.getElementById('cart-k'); 3console.log(element.id); 4 5const fruitsElem = document.getElementsByClassName("c-form"); 6console.log(fruitsElem);
を記載し、追従要素である「#cart-k」と「c-form」を宣言した
回答1件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2023/03/06 00:21