你可以使用jQuery通过点击卡片内的按钮来切换内部 div 的隐藏类。

huangapple go评论88阅读模式
英文:

How can I toggle the hidden class on an inner div by clicking a button inside a card using jQuery?

问题

Here's the translated part of your code:

  1. function handleMoreInfo() {
  2. // 1) 找到coin-card元素
  3. $(".coin-card").on("click", async function(e) {
  4. // a) 停止事件传播
  5. e.stopImmediatePropagation();
  6. // b) 找到coin的ID
  7. const coinID = ($(this).find('.coin-name').text()).toLowerCase();
  8. // c) 获取有关coin的更多信息
  9. const data = await fetchMoreInfo(coinID);
  10. // d) 可选:隐藏所有面板
  11. // if(nodeList) hideAllPanels();
  12. // e) 显示所选的更多信息面板
  13. if (data) showMoreInfo(data, $(this));
  14. });
  15. }
  16. const showMoreInfo = (data, thatCoin) => {
  17. // 1) 找到所有more-info-panel的类,然后查看hidden类是否存在
  18. // 2) 在显示和隐藏之间切换more-info-panel
  19. nodeList[0].forEach(div => {
  20. const coinNameFromArr = $(div).find('.coin-name').text();
  21. if (coinNameFromArr.toLowerCase() === data.id ) {
  22. console.log('Match');
  23. const panel = $(div).find('.more-info-panel').attr("class");
  24. const panelClassesArr = panel.split(' ');
  25. if(panelClassesArr.length === 1) $(div).find('.more-info-panel').addClass("hidden");
  26. if(panelClassesArr.length === 2) $(div).find('.more-info-panel').removeClass("hidden");
  27. }
  28. })
  29. // 3) 在面板内设置新数据
  30. thatCoin.find('.more-info-image').prop("src", data?.image?.large);
  31. thatCoin.find('.usd').text(`USD: $${data?.market_data?.current_price?.usd}`);
  32. thatCoin.find('.eur').text(`EUR: €${data?.market_data?.current_price?.eur}`);
  33. thatCoin.find('.ils').text(`ILS: ₪${data?.market_data?.current_price?.ils}`);
  34. }
  35. const hideAllPanels = () => {
  36. // 1) 循环遍历body-container的节点列表,看看是否有面板是打开的
  37. console.log(nodeList);
  38. nodeList[0].forEach(div => {
  39. const panel = $(div).find('.more-info-panel').attr("class");
  40. const panelClassesArr = panel.split(' ');
  41. // 2) 如果元素只有一个类,那么面板是显示的,我们需要隐藏它
  42. if(panelClassesArr.length === 1) $(div).find('.more-info-panel').addClass("hidden");
  43. });
  44. }

I've translated the JavaScript part of your code.

英文:

How to create functionality in jQuery that will toggle hidden class on inner div by clicking on a button inside a card?

I tried to create a container div that have some cards in it.the problem is when i click the button
it only opens the panel but doesn't close the panel if i click it again.
however it being closed if i open a new panel(that is somthing i want to happen)

another thing is that hideAllPanels and showMoreInfo works when only one is active.

  1. function handleMoreInfo() {
  2. // 1) Find the coin-card element
  3. $(".coin-card").on("click",async function(e) {
  4. // a) stop bubbling
  5. e.stopImmediatePropagation();
  6. // b) Find coin id
  7. const coinID = ($(this).find('.coin-name').text()).toLowerCase();
  8. // c) Get more info about the coin
  9. const data = await fetchMoreInfo(coinID);
  10. // d) Optional: hide all panels
  11. // if(nodeList) hideAllPanels();
  12. // e) display the chosen more info panel
  13. if (data) showMoreInfo(data,$(this));
  14. });
  15. }
  16. const showMoreInfo = (data,thatCoin) => {
  17. // 1) Find all classes on more-info-panel and then find out if class hidden exists
  18. // 2) Toggle more-info-panel between displayed and hidden
  19. nodeList[0].forEach(div => {
  20. const coinNameFromArr = $(div).find('.coin-name').text();
  21. if (coinNameFromArr.toLowerCase() === data.id ) {
  22. console.log('Match');
  23. const panel = $(div).find('.more-info-panel').attr("class");
  24. const panelClassesArr = panel.split(' ');
  25. if(panelClassesArr.length === 1) $(div).find('.more-info-panel').addClass("hidden");
  26. if(panelClassesArr.length === 2) $(div).find('.more-info-panel').removeClass("hidden");
  27. }
  28. })
  29. // 3) Set new data inside panel
  30. thatCoin.find('.more-info-image').prop("src",data?.image?.large);
  31. thatCoin.find('.usd').text(`USD: $${data?.market_data?.current_price?.usd}`);
  32. thatCoin.find('.eur').text(`EUR: €${data?.market_data?.current_price?.eur}`);
  33. thatCoin.find('.ils').text(`ILS: ₪${data?.market_data?.current_price?.ils}`);
  34. }
  35. const hideAllPanels = () => {
  36. // 1) Loop over node list of the body-container to see if some panels are open
  37. console.log(nodeList);
  38. nodeList[0].forEach(div => {
  39. const panel = $(div).find('.more-info-panel').attr("class");
  40. const panelClassesArr = panel.split(' ');
  41. // 2) If element have only one class it means that panel is displayed add we need to hide it
  42. if(panelClassesArr.length === 1) $(div).find('.more-info-panel').addClass("hidden");
  43. });
  44. }

this is the html of a card example

  1. <div class="coin-card">
  2. <div class="headInfo">
  3. <p class="coin-symbol">btc</p>
  4. <div class="form-check form-switch"><input class="form-check-input" num1="0" type="checkbox" role="switch"
  5. onclick="addCoinsToArray()"><label class="form-check-label" for="flexSwitchCheckChecked"></label></div>
  6. </div>
  7. <p class="coin-name">Bitcoin</p><button class="btn btn-info mybtn" onclick="handleMoreInfo()" data-toggle="collapse"
  8. data-target="info" num="0">More Info</button>
  9. <div class="more-info-panel hidden" symbol="bitcoin"><img class="more-info-image"
  10. src="./src/img/bitcoin-g80ff29158_640.jpg">
  11. <p class="info-title">Coin Prices:</p>
  12. <p class="usd">USD: $30</p>
  13. <p class="eur">EUR: 30</p>
  14. <p class="ils">ILS: 30</p>
  15. </div>
  16. </div>

答案1

得分: 1

I agree, your code is a bit overcomplicated. You are also mixing onclick and jQuery .on('click'), so you're basically adding a new .on('click') handler to coin-card every time you click on the button.

I'd approach it like this:

  1. // you don't need an onclick on the button
  2. $('.coin-card .btn-info').on('click', async function() {
  3. // find the parent .coin-card of the button that was clicked
  4. const $card = $(this).closest('.coin-card');
  5. const $infoPanel = $card.find('.more-info-panel');
  6. // const coinName = $card.find('.coin-name').text().toLowerCase();
  7. // const data = await fetchMoreInfo(coinID);
  8. // set data...
  9. // version 1 allow multiple panels open
  10. //$infoPanel.toggleClass('hidden');
  11. // or version 2 behave like accordion. close all other panels
  12. const isOpen = $infoPanel.hasClass('hidden');
  13. $('.coin-card .more-info-panel').addClass('hidden');
  14. if (isOpen) {
  15. $card.find('.more-info-panel').removeClass('hidden');
  16. }
  17. });
  1. .coin-card {
  2. border: 1px solid;
  3. margin: .5rem;
  4. padding: 1rem;
  5. float: left;
  6. width: 20%;
  7. }
  8. p {
  9. margin: 0;
  10. }
  11. .coin-card .more-info-panel.hidden {
  12. display:none;
  13. }
  1. <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  2. <div class="coin-card">
  3. <div class="headInfo">
  4. <p class="coin-symbol">btc</p>
  5. <div class="form-check form-switch"><input class="form-check-input" num1="0" type="checkbox" role="switch" onclick="addCoinsToArray()"><label class="form-check-label" for="flexSwitchCheckChecked"></label></div>
  6. </div>
  7. <p class="coin-name">Bitcoin</p><button class="btn btn-info mybtn" data-toggle="collapse" data-target="info" num="0">More Info</button>
  8. <div class="more-info-panel hidden" symbol="bitcoin"><img class="more-info-image" src="./src/img/bitcoin-g80ff29158_640.jpg">
  9. <p class="info-title">Coin Prices:</p>
  10. <p class="usd">USD: $30</p>
  11. <p class="eur">EUR: €30</p>
  12. <p class="ils">ILS: ₪30</p>
  13. </div>
  14. </div>
  15. <div class="coin-card">
  16. <div class="headInfo">
  17. <p class="coin-symbol">btc</p>
  18. <div class="form-check form-switch"><input class="form-check-input" num1="0" type="checkbox" role="switch" onclick="addCoinsToArray()"><label class="form-check-label" for="flexSwitchCheckChecked"></label></div>
  19. </div>
  20. <p class="coin-name">Bitcoin</p><button class="btn btn-info mybtn" data-toggle="collapse" data-target="info" num="0">More Info</button>
  21. <div class="more-info-panel hidden" symbol="bitcoin"><img class="more-info-image" src="./src/img/bitcoin-g80ff29158_640.jpg">
  22. <p class="info-title">Coin Prices:</p>
  23. <p class="usd">USD: $30</p>
  24. <p class="eur">EUR: €30</p>
  25. <p class="ils">ILS: ₪30</p>
  26. </div>
  27. </div>
  28. <div class="coin-card">
  29. <div class="headInfo">
  30. <p class="coin-symbol">btc</p>
  31. <div class="form-check form-switch"><input class="form-check-input" num1="0" type="checkbox" role="switch" onclick="addCoinsToArray()"><label class="form-check-label" for="flexSwitchCheckChecked"></label></div>
  32. </div>
  33. <p class="coin-name">Bitcoin</p><button class="btn btn-info mybtn" data-toggle="collapse" data-target="info" num="0">More Info</button>
  34. <div class="more-info-panel hidden" symbol="bitcoin"><img class="more-info-image" src="./src/img/bitcoin-g80ff29158_640.jpg">
  35. <p class="info-title">Coin Prices:</p>
  36. <p class="usd">USD: $30</p>
  37. <p class="eur">EUR: €30</p>
  38. <p class="ils">ILS: ₪30</p>
  39. </div>
  40. </div>
英文:

I agree, your code is a bit overcomplicated. You are also mixing onclick and jQuery .on(&#39;click&#39;), so you're basically adding a new on(&#39;click&#39;) handler to coin-card everytime you click on the button.

I'd approach it like this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. // you don&#39;t need an onclick on the button
  2. $(&#39;.coin-card .btn-info&#39;).on(&#39;click&#39;, async function() {
  3. // find the parent .coin-card of the button that was clicked
  4. const $card = $(this).closest(&#39;.coin-card&#39;);
  5. const $infoPanel = $card.find(&#39;.more-info-panel&#39;);
  6. // const coinName = $card.find(&#39;.coin-name&#39;).text().toLowerCase();
  7. // const data = await fetchMoreInfo(coinID);
  8. // set data...
  9. // version 1 allow multiple panels open
  10. //$infoPanel.toggleClass(&#39;hidden&#39;);
  11. // or version 2 behave like accordion. close all other panels
  12. const isOpen = $infoPanel.hasClass(&#39;hidden&#39;);
  13. $(&#39;.coin-card .more-info-panel&#39;).addClass(&#39;hidden&#39;);
  14. if (isOpen) {
  15. $card.find(&#39;.more-info-panel&#39;).removeClass(&#39;hidden&#39;);
  16. }
  17. });

<!-- language: lang-css -->

  1. .coin-card {
  2. border: 1px solid;
  3. margin: .5rem;
  4. padding: 1rem;
  5. float: left;
  6. width: 20%;
  7. }
  8. p {
  9. margin: 0;
  10. }
  11. .coin-card .more-info-panel.hidden {
  12. display:none;
  13. }

<!-- language: lang-html -->

  1. &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js&quot;&gt;&lt;/script&gt;
  2. &lt;div class=&quot;coin-card&quot;&gt;
  3. &lt;div class=&quot;headInfo&quot;&gt;
  4. &lt;p class=&quot;coin-symbol&quot;&gt;btc&lt;/p&gt;
  5. &lt;div class=&quot;form-check form-switch&quot;&gt;&lt;input class=&quot;form-check-input&quot; num1=&quot;0&quot; type=&quot;checkbox&quot; role=&quot;switch&quot;
  6. onclick=&quot;addCoinsToArray()&quot;&gt;&lt;label class=&quot;form-check-label&quot; for=&quot;flexSwitchCheckChecked&quot;&gt;&lt;/label&gt;&lt;/div&gt;
  7. &lt;/div&gt;
  8. &lt;p class=&quot;coin-name&quot;&gt;Bitcoin&lt;/p&gt;&lt;button class=&quot;btn btn-info mybtn&quot; data-toggle=&quot;collapse&quot;
  9. data-target=&quot;info&quot; num=&quot;0&quot;&gt;More Info&lt;/button&gt;
  10. &lt;div class=&quot;more-info-panel hidden&quot; symbol=&quot;bitcoin&quot;&gt;&lt;img class=&quot;more-info-image&quot;
  11. src=&quot;./src/img/bitcoin-g80ff29158_640.jpg&quot;&gt;
  12. &lt;p class=&quot;info-title&quot;&gt;Coin Prices:&lt;/p&gt;
  13. &lt;p class=&quot;usd&quot;&gt;USD: $30&lt;/p&gt;
  14. &lt;p class=&quot;eur&quot;&gt;EUR: 30&lt;/p&gt;
  15. &lt;p class=&quot;ils&quot;&gt;ILS: 30&lt;/p&gt;
  16. &lt;/div&gt;
  17. &lt;/div&gt;
  18. &lt;div class=&quot;coin-card&quot;&gt;
  19. &lt;div class=&quot;headInfo&quot;&gt;
  20. &lt;p class=&quot;coin-symbol&quot;&gt;btc&lt;/p&gt;
  21. &lt;div class=&quot;form-check form-switch&quot;&gt;&lt;input class=&quot;form-check-input&quot; num1=&quot;0&quot; type=&quot;checkbox&quot; role=&quot;switch&quot;
  22. onclick=&quot;addCoinsToArray()&quot;&gt;&lt;label class=&quot;form-check-label&quot; for=&quot;flexSwitchCheckChecked&quot;&gt;&lt;/label&gt;&lt;/div&gt;
  23. &lt;/div&gt;
  24. &lt;p class=&quot;coin-name&quot;&gt;Bitcoin&lt;/p&gt;&lt;button class=&quot;btn btn-info mybtn&quot; data-toggle=&quot;collapse&quot;
  25. data-target=&quot;info&quot; num=&quot;0&quot;&gt;More Info&lt;/button&gt;
  26. &lt;div class=&quot;more-info-panel hidden&quot; symbol=&quot;bitcoin&quot;&gt;&lt;img class=&quot;more-info-image&quot;
  27. src=&quot;./src/img/bitcoin-g80ff29158_640.jpg&quot;&gt;
  28. &lt;p class=&quot;info-title&quot;&gt;Coin Prices:&lt;/p&gt;
  29. &lt;p class=&quot;usd&quot;&gt;USD: $30&lt;/p&gt;
  30. &lt;p class=&quot;eur&quot;&gt;EUR: 30&lt;/p&gt;
  31. &lt;p class=&quot;ils&quot;&gt;ILS: 30&lt;/p&gt;
  32. &lt;/div&gt;
  33. &lt;/div&gt;
  34. &lt;div class=&quot;coin-card&quot;&gt;
  35. &lt;div class=&quot;headInfo&quot;&gt;
  36. &lt;p class=&quot;coin-symbol&quot;&gt;btc&lt;/p&gt;
  37. &lt;div class=&quot;form-check form-switch&quot;&gt;&lt;input class=&quot;form-check-input&quot; num1=&quot;0&quot; type=&quot;checkbox&quot; role=&quot;switch&quot;
  38. onclick=&quot;addCoinsToArray()&quot;&gt;&lt;label class=&quot;form-check-label&quot; for=&quot;flexSwitchCheckChecked&quot;&gt;&lt;/label&gt;&lt;/div&gt;
  39. &lt;/div&gt;
  40. &lt;p class=&quot;coin-name&quot;&gt;Bitcoin&lt;/p&gt;&lt;button class=&quot;btn btn-info mybtn&quot; data-toggle=&quot;collapse&quot;
  41. data-target=&quot;info&quot; num=&quot;0&quot;&gt;More Info&lt;/button&gt;
  42. &lt;div class=&quot;more-info-panel hidden&quot; symbol=&quot;bitcoin&quot;&gt;&lt;img class=&quot;more-info-image&quot;
  43. src=&quot;./src/img/bitcoin-g80ff29158_640.jpg&quot;&gt;
  44. &lt;p class=&quot;info-title&quot;&gt;Coin Prices:&lt;/p&gt;
  45. &lt;p class=&quot;usd&quot;&gt;USD: $30&lt;/p&gt;
  46. &lt;p class=&quot;eur&quot;&gt;EUR: 30&lt;/p&gt;
  47. &lt;p class=&quot;ils&quot;&gt;ILS: 30&lt;/p&gt;
  48. &lt;/div&gt;
  49. &lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月5日 04:36:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76402321.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定