مشكله في الكود بإظهار وإخفاء الصور بالجافاسكربت

السلام عليكم لو سمحتم عملت prompt فيه قيم وعملت table وداخل td صور وعملتها مخفيه ولما اختار قيمه من القيم اللي في prompt بتظهر صور الاختيار اللي اخترته وبعد اختيار صورة من الصور
ازاي اعمل اخفاء لباقيه الصور مره تانيه ؟

3 Likes

وعليكم السلام ورحمة الله

هاتي الكود نشوفة عشان إقتراح الحل يتماشى مع الذي أنجزتية :grin:

3 Likes
<button onclick="myFunction()" type="submit"> your order</button>
  <table>
  <tr>
    <th>donuts</th>
    <td><img src="448009.svg"width="50"id="image1"></td>
      <td><img src="1041345.svg"width="50"id="image1"></td>
    <td><img src="2164099.svg" width="50"id="image1"></td>
  
  </tr>
  <tr>
<th>drinks</th>
 
    <td><img src="1219491.svg"width="50"id="image2"></td>
      <td><img src="920533.svg"width="50"id="image2"></td>
    <td><img src="9210542.svg" width="50"id="image2"></td>
  
  </tr>
  <tr>
       <th>chocolate</th>
   
    <td><img src="1837203.svg"width="50" id="image3"></td>
      <td><img src="1837283.svg"width="50"id="image3"></td>
    <td><img src="chocolate-stylized-vector-illustration-your-260nw-585933908.jpg" width="50"id="image3"></td>
 
  </tr>
</table>
      
<script> 
    const image=document.getElementById("image1");
        const image2=document.getElementById("image2");
        const image3=document.getElementById("image3");
  
function myFunction() {
  var order = prompt("Please enter your order","donuts");
  switch(order) {
    case "donuts":
        
      image.style='display:block';
          break;
    case "chocolate":
          image3.style.display="block"
      break;
    case "drinks":
          image2.style.display="block"
      break;
  }

  
}
}

هو دا بس مش التصميم بتاعي الرئيسي انا كتبته بسرعه عشان اعرف الحل واوصلك الفكره :relaxed:

2 Likes

@YaserAlnajjar لو سمحت يبشمهندس انا هنا استخدمت if conditions اني لما اضغط ع صوره تتختفي باقيه الصور بس اختفو كل الصور حتي اللي ضعطت عليها ممكن حل :relaxed:

2 Likes

راح اطلع على الكود واقول لي ايش تعملي اليوم المساء :grin:

2 Likes

ماشي تمام شكرا :star_struck:

2 Likes

اللي فهمته هو انك عايزة تكتبي donuts وتظهر الصور الي في ذاك الصف ولما تكتبي chocolate تظهر الصور الي في الصف الخاص بها وتختفي صور الـ donuts. لذا راح اكتب لك احد الطرق الي بتقدري تحققي ذلك من خلالها فإذا فهمت قصدك غلط قولي لي :grimacing:

في البدأية ركزي أنك كررتي نفس الـ id أكثر من مرة لأكثر من عنصر وهذا الشئ غير مسموح مثلاُ هنا جبتي للصور الـ id بإسم image1

<td><img src="448009.svg"width="50"id="image1"></td>
<td><img src="1041345.svg"width="50"id="image1"></td>
<td><img src="1041345.svg" width="50"id="image1"></td>

لذا راح نشيلهم ولكن قبل ذلك خلينا نفكر بخطة العمل وكيف احل المشكلة الي عندنا:

المشكلة:

  • عايزين تكون كل الصور مخفية بشكل مبدأياً.
  • عايزين المستخدم لما يكتب إسم صف معين نظهر الصور الي بذاك الصف فقط.
  • في حال ما إن كان في صور ظاهرة مسبقاً عايزين نخفيها ونظهر الصور الجديدة لما المستخدم يدخل إسم جديد.

الحل:

الفكرة الي معاي هي بالإستفادة من الكلاسات class بحيث إني في البدأية أخفي كل الصور وبعدين لما المستخدم يكتب إسم صف معين أضيف كلاس لذلك الصف فقط، هذا الكلاس يقوم بإظهار الصور الي بالصف دون غيرة.

لذا انا أولاً راح اشيل كل الـ ids الي حطيتيهم للصور وراح أضيف id للعنصر الأب الخاص بكل صف والي هو العنصر tr بالشكل التالي:

<table>
      <tr id="donuts">
        <th>donuts</th>
        <td><img src="448009.svg" width="50"/></td>
        <td><img src="1041345.svg" width="50"/></td>
        <td><img src="1041345.svg" width="50"/></td>
      </tr>
      <tr id="drinks">
        <th>drinks</th>
        <td><img src="1219491.svg" width="50"/></td>
        <td><img src="920533.svg" width="50"/></td>
        <td><img src="9210542.svg" width="50"/></td>
      </tr>
      <tr id="chocolate">
        <th>chocolate</th>
        <td><img src="1837203.svg" width="50"/></td>
        <td><img src="1837283.svg" width="50"/></td>
        <td><img src="chocolate-stylized-vector-illustration-your-260nw-585933908.jpg" width="50"/></td>
      </tr>
</table>

لاحظي أضفت لكل صف id بنفس الإسم الي المستخدم راح يقوم بإدخالة علشان أستفيد من الي راح يدخلة المستخدم لمعرفة أي صف هو عايز يكشف صورة.

الأن أحنا عايزين مبدأياً ان كل الصور تكون مخفية في الصفحة لذا راح استهدف كل الصور الي جوا الـ tr وأعمل لها إخفاء بالـ css:

tr img{
     visibility: hidden;
}

جميل الأن كل شئ مخفي في الصفحة، بس لما المستخدم يكتب إسم صف عايز اسند لذلك الصف كلاس يخلي الصور تظهر، لذا راح اقوم بتجهيز هذا الكلاس لإستخدامه لاحقاً بالشكل التالي:

tr img{
    visibility: hidden;
}

/*هذا الكلاس راح يظهر الصور بالصف المطلوب*/
.is-visible img{
    visibility: visible;
}

مية مية، الأن الخطوة التالية ابدأ أكتب أكود الـ javascript:

بدلاُ من أن أستخدم الـ switch راح أخلي الموضوع أكثر ديناميكية وأخذ القيمة الي بيدخلها المستخدم للـ prompt وأستخدمها لتحديد الصف الذي يريدة المستخدم (تذكري أن كل صف يحمل id بنفس القيمة الي راح يدخلها المستخدم يعني الصف الخاص بالـdonuts الـ id الخاص به هو donuts وهكذا)

كود الـ js

function myFunction() {
   var order = prompt("Please enter your order", "donuts");
   var element = document.getElementById(order);
}

في الكود أعلاة لما المستخدم يكتب في النافذة المنبثقة donuts راح يقوم السطر الثاني بإستهداف ذلك العنصر من خلال الـ id نفسة donuts

الأن بعد أن قمنا بتحديد أي صف يريد المستخدم إظهار الصور الخاصة به، سنقوم بإسناد الكلاس الذي يقوم بإظهار الصور إلية كالتالي:

function myFunction() {
  var order = prompt("Please enter your order", "donuts");
  var element = document.getElementById(order);
  element.classList.add('is-visible');
}

جربي نسخ الأكود وتجربة الصفحة

image

لكن بتلاحظي لما نكتب drinks راح تظهر الصور الخاصة بالمشروبات بدون أن تختفي صور الـ donuts

image

كيف نحل هذه المشكلة؟

عشان نحل هذه المشكلة لازم نمسك بالصف الي معاك الكلاس المسؤول عن إظهار الصور، صحيح؟

تمام خلينا نعمل هذا الشئ

var visableImages = document.getElementsByClassName('is-visible')[0];

راح نستخدم هذا الكود بحيث بقوم بتخزين بداخل المتغير visableImages العنصر الأول الي عندة الكلاس is-visible.

خلينا نضيف هذا الكود بجوار بقية الاكواد:

function myFunction() {
   var order = prompt("Please enter your order", "donuts");
   var element = document.getElementById(order);
   var visableImages = document.getElementsByClassName('is-visible')[0];
   element.classList.add('is-visible');
}

مية مية، حتى الأن لا يوجد أي أختلاف إحنا فقط مسكنا على العنصر الأول الي عندة هذا الكلاس، الأن خلينا نقوم بإخفاء هذا العنصر من خلال إزالة الكلاس منه

visableImages.classList.remove('is-visible');

راح احط الكود بجوار الأكواد الأخرى بحيث يكون قبل كود إظهار الصور الجديدة

function myFunction() {
   /*تحديد الصف الذي يريد المستخدم إظهار صورة*/
   var order = prompt("Please enter your order", "donuts");
   var element = document.getElementById(order);

   /*إخفاء الصور التي أظهرناها مسبقاً*/
   var visableImages = document.getElementsByClassName('is-visible')[0];
   visableImages.classList.remove('is-visible');
   
   /*إظهار الصور الجديدة*/
   element.classList.add('is-visible');
}

إنسخي الاكواد وجربي.

في عندنا مشكلة!

لاحظي انه في عندنا مشكلة مش راضي أي شئ يظهر، خلينا نفتح الـ console ونشوف اين المشكلة:
image

يقول لنا

Cannot read property 'classList' of undefined

أي انه مش قادر يجيب الخاصية classList لمتغير غير معرف والي هو المتغير visableImages ، أيش معنا هذا الشئ؟

لاحظي انه قمنا بتخزين بداخل هذا المتغير العنصر الذي عندة الكلاس is-visible ولكن عندما نقوم بفتح الصفحة او تحديثها مابيكون عندنا أي عنصر عندة هذا الكلاس فكل الصور بتكون مخفية، لذا الجافاسكربت مش لاقية أي عنصر عندة هذا الكلاس وبالرغم من ذلك فإحنا بنطلب منه يقوم بمسح هذا الكلاس من العنصر الذي يملكة!

أي مشكلتنا هنا:

visableImages.classList.remove('is-visible');

كأن الجافاسكربت تقول: كيف أقوم بإزالة الكلاس is-visible من عنصر وانا أصلاً مش ملاقي عنصر يحمل هذا الكلاس :exploding_head:

لذا عشان مانزعلها راح نعمل شرط if ونقول لها اذا في عنصر عندة هذا الكلاس، قومي بإزالته منه ويا دار ما دخلك شر:

if (visableImages){
    visableImages.classList.remove('is-visible');
}

خلينا نعيد ترتيب كود الـ js كاملاً:

function myFunction() {
   /*تحديد الصف الذي يريد المستخدم إظهار صورة*/
   var order = prompt("Please enter your order", "donuts");
   var element = document.getElementById(order);

   /*إخفاء الصور التي أظهرناها مسبقاً إذا وجد ذلك*/
   var visableImages = document.getElementsByClassName('is-visible')[0];
   if (visableImages){
       visableImages.classList.remove('is-visible');
    }
   
   /*إظهار الصور الجديدة*/
   element.classList.add('is-visible');
}

النتيجة النهائية: :partying_face:

الكود كاملاً
<button onclick="myFunction()" type="submit">your order</button>
    <table>
      <tr id="donuts">
        <th>donuts</th>
        <td><img src="https://source.unsplash.com/collection/190757/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190797/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190727/100x100" width="50"/></td>
      </tr>
      <tr id="drinks">
        <th>drinks</th>
        <td><img src="https://source.unsplash.com/collection/190726/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190797/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190737/100x100" width="50"/></td>
      </tr>
      <tr id="chocolate">
        <th>chocolate</th>
        <td><img src="https://source.unsplash.com/collection/190717/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190747/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190737/100x100" width="50"/></td>
      </tr>
    </table>

    <script>

      function myFunction() {
        var order = prompt("Please enter your order", "donuts");
        var element = document.getElementById(order);
        var visableImages = document.getElementsByClassName('is-visible')[0];
        
        if (visableImages){
          visableImages.classList.remove('is-visible');
        }
        element.classList.add('is-visible');
      }

    </script>

يتبقى تغطية الإحتمالات الأخرى كالتأكد من إذا ما كان المستخدم أدخل نفس إسم الصف مرتين فلا داعي لإخفاء الصور ومن ثم إظهارها بل تظل ظاهرة، أيضاً ما العمل عندما يقوم المستخدم بإدخال إسم غير متوقع او ليس له صور … الخ

3 Likes

بجد طريقه حلوه اوي وسهلة جدا وفهمتها بسرعة :star_struck:
تعبتك معايا جدا لانك كتبت كتير شكرا ي بشمهندس انت واللي زيك اللي بيخلينا نحب البرمجة :heart_eyes: ونتعلم اكتر :star_struck:
بس انت مش قولت لي لما اختار صورة تتحذف باقية الصور ازاي :thinking:

3 Likes

بجد طريقه حلوه اوي وسهلة جدا وفهمتها بسرعة :star_struck:
تعبتك معايا جدا لانك كتبت كتير شكرا ي بشمهندس انت واللي زيك اللي بيخلينا نحب البرمجة :heart_eyes: ونتعلم اكتر :star_struck:

مايهمك هذا واجبنا هنا :relieved:

بس انت مش قولت لي لما اختار صورة تتحذف باقية الصور ازاي :thinking:

تتكلمي عن حذف صورة واحدة بوجة الخصوص ام الثلاث الصور الي بالصف ؟

3 Likes

يعني مثلا لو 10 صور لل donuts واختارت واحد منهم تتختفي 9 صور
انا عملت div من تحت تنزل فيه الصورة اللي اختارتها

2 Likes

شيء مثل هذا؟

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style>
      tr img{
        visibility: hidden;
      }
      .is-visible img{
        visibility: visible;
      }
      img.is-chosen{
        visibility: hidden;
      }
      .chosen-img{
        margin-right: 5px;
      }
    </style>
  </head>
  <body>

    <button onclick="myFunction()" type="submit">your order</button>
    <table id="table">
      <tr id="donuts">
        <th>donuts</th>
        <td><img src="https://source.unsplash.com/collection/190757/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190797/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190727/100x100" width="50"/></td>
      </tr>
      <tr id="drinks">
        <th>drinks</th>
        <td><img src="https://source.unsplash.com/collection/190726/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190797/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190737/100x100" width="50"/></td>
      </tr>
      <tr id="chocolate">
        <th>chocolate</th>
        <td><img src="https://source.unsplash.com/collection/190717/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190747/100x100" width="50"/></td>
        <td><img src="https://source.unsplash.com/collection/190737/100x100" width="50"/></td>
      </tr>
    </table>

    <div id="images">

    </div>

    <script>

      let table = document.getElementById('table');
      table.addEventListener('click', function (e){
        e.target.classList.add('is-chosen');
        var imagesContainer = document.getElementById('images');
        if(e.target.src){
          var image = createImage(e.target.src);
          imagesContainer.innerHTML += image;
        }
      })

      function createImage(src){
        return '<img src="'+src+'" width="50" class="chosen-img" />';
      }

      function myFunction() {
        var order = prompt("Please enter your order", "donuts");
        var element = document.getElementById(order);
        var visableImages = document.getElementsByClassName('is-visible')[0];
        if (visableImages && visableImages != element){
          visableImages.classList.remove('is-visible');
        }
        element.classList.add('is-visible');
      }

    </script>
  </body>
</html>

1 Like

طبعاً الصور تتغير بشكل عشوائي لما تضيفيها لتحت قد تلاقيها تغيرت لشئ أخر فلا تهتمي بهذا الشئ، أشرحي لي كيف بالضبط بيشتغل برنامجك علشان نعمل كود نظيف ومرتب لأنه قد تتغير أشياء كثيرة حسب المنطق والفكرة الي عندك

2 Likes

الكود اللي انت عملته هو اللي كنت بفكر فية :star_struck:انا عملته بس معقد عن اللي انت عملته :joy: انت بتكتبة مختصر وبسيط :star_struck:
البرنامج بتاعي هو عبارة عن فكرة سوبر ماركت حبيت اطبق فيها اللي اتعلمته :face_with_hand_over_mouth:

2 Likes

جميل عرفت خطتك من هذه الحركة :joy:، بيكون موقع تفاعلي لطيف وبانتظار تشاركينا النتيجة

2 Likes

اكيد هشارك النتيجه هنا :star_struck:
لسه معايا مشاكل كتير فيه واسئله كتير هسال عن حلها هنا :relaxed:
ان شاء الله ما تزهق من اسئلتي ي بشمهندس :grin::joy:

2 Likes

مايهمك اي وقت

2 Likes

ربنا يخليك ويزيدك علم يارب :star_struck:

2 Likes