ID karşılaştırıp Class düzenleme

|-Hakan-|

Hectopat
Katılım
19 Ağustos 2018
Mesajlar
673
Çözümler
4
Birkaç saattir uğraşıyorum lakin bir türlü halledemedim, bir de buraya atayım dedim.
Olayı anlatmam gerekirse şu şekilde:

.menus.list.item.active'in ID'sini .vertical-menu.menu.content'in ID'siyle karşılaştırıp eşleşme durumunda eşleşen .vertical-menu.menu-content'in ID'siyle eşleşen Class'tan .hidden'ı silecek ve öncekine de .hidden ekleyecek.

HTML:
<div class="content contentimg">
 <div class="menus" id="menuContainer">
 <div class="list">
 <div class="item" id="a1">
 <div>FOODS</div>
 <img src="img/3.png">
 </div>
 <div class="item active" id="a2">
 <div>DRINKS</div>
 <img src="img/2.png">
 </div>
 <div class="item" id="a3">
 <div>DESSERTS</div>
 <img src="img/1.png">
 </div>
 </div>
 <div class="arow">
 <button class="prev" id="prev" onclick="toggleHiddenClass();">&lt;</button>
 <button class="next" id="next" onclick="toggleHiddenClass();">&gt;</button>
 </div>
 </div>
 <!-- Your menu content here -->
 <div class="vertical-menu">
 <div class="menu-content hidden" id="a1">
 <!-- Menu 1 items here -->
 <div>Menu 1 Item 1</div>
 <div>Menu 1 Item 2</div>
 <div>Menu 1 Item 3</div>
 </div>
 <div class="menu-content" id="a2">
 <!-- Menu 2 items here -->
 <div>Menu 2 Item 1</div>
 <div>Menu 2 Item 2</div>
 <div>Menu 2 Item 3</div>
 </div>
 <div class="menu-content hidden" id="a3">
 <!-- Menu 3 items here -->
 <div>Menu 3 Item 1</div>
 <div>Menu 3 Item 2</div>
 <div>Menu 3 Item 3</div>
 </div>
 </div>
 </div>

CSS:
:root{
 --width-circle: 150vw;
 --radius: calc(100vw / 6);
}
.contentimg {
 background-color: #141414;
}
.menus{
 width: 100vw;
 height: 88vh;
 overflow: hidden;
 position: relative;
 margin-top: -50px;
}
.menus .list{
 position: relative;
 width: max-content;
 height: 100%;
 display: flex;
 justify-content: start;
 align-items: center;
 transition: transform 0.8s;
 pointer-events:none;
}
.menus .list .item{
 width: calc(var(--radius) * 2);
 text-align: center;
 transform: rotate(45deg);
 transition: transform 1s;
}
.menus .list .item.active{
 transform: rotate(0deg);
}
.menus .list .item img{
 width: 90%;
 filter: drop-shadow(0 0 20px #000);
}
.menus .list .item div{
 font-family: 'Times New Roman', Times, serif;
 font-size: larger;
 opacity: 0;
}
.menus .list .item.item.active div{
 font-family: 'Times New Roman', Times, serif;
 font-size: larger;
 opacity: 1;
 transition: 1.5s ease-out;
}
.menus .content{
 position: relative;
 bottom: 5%;
 left: 50%;
 transform: translateX(-50%);
 text-align: center;
 color: #eee;
 width: max-content;
}
.menus .content div:nth-child(2){
 font-size: 5rem;
 text-transform: uppercase;
 letter-spacing: 10px;
 font-weight: bold;
 position: relative;
}
.menus .content div:nth-child(2)::before{
 position: relative;
 left: 60%;
 bottom: 50%;
 width: 80px;
 height: 80px;
 content: '';
 background-image: url(img/leaves.png);
 background-size: cover;
 background-repeat: no-repeat;
}
.menus .content div:nth-child(1){
 text-align: left;
 text-transform: uppercase;
 transform: translateY(20px);
}
.menus .content button{
 border: 1px solid #eee5;
 background: transparent;
 color: #eee;
 font-family: Poppins;
 letter-spacing: 5px;
 border-radius: 20px;
 padding: 10px 20px;
}
#prev,
#next{
 position: absolute;
 top: 50%;
 transform: translateY(-50%);
 width: 50px;
 height: 50px;
 border-radius: 50%;
 background-color: transparent;
 border: 1px solid #eee9;
 background-color: #eee5;
 color: #eee;
 font-size: x-large;
 font-family: monospace;
 cursor: pointer;
 z-index: 15;
}
#prev{
 left: 50px;
}
#next{
 right: 50px;
}
.hidden {
 display: none;
}

JavaScript:
function toggleHiddenClass() {
 var activeMenuItem = document.querySelector('.menus .list .item.active');

 if (activeMenuItem) {
 var activeMenuId = activeMenuItem.getAttribute('id');

 if (activeMenuId) {
 var activeMenuData = document.getElementById(activeMenuId)?.getAttribute('id');
 if (activeMenuData) {
 var verticalMenuContent = document.getElementById(activeMenuData);

 if (verticalMenuContent) {
 var matchedElements = document.querySelectorAll('.' + activeMenuData);
 matchedElements.forEach(function(element) {
 if (element.classList.contains('hidden')) {
 element.classList.remove('hidden');
 } else {
 element.classList.add('hidden');
 }
 });
 } else {
 console.error("Vertical menu content bulunamadı.");
 }
 } else {
 console.error("Active menu id içeriği alınamadı.");
 }
 } else {
 console.error("Active menu item için id bulunamadı.");
 }
 } else {
 console.error(".menus .list .item.active bulunamadı.");
 }
}
toggleHiddenClass();
 
Son düzenleyen: Moderatör:
HTML kodunuzda menüdeki ID'lere menu- ön eki ekledim çünkü ID'lerin özgün olması doğru olur. Tarayıcı uyarıyordu, öyle fark ettim. Siz dilerseniz ön ek ismini değiştirebilirsiniz:

HTML:
<div class="vertical-menu">
  <div class="menu-content" id="menu-a1">
    <!-- Menu 1 items here -->
    <div>Menu 1 Item 1</div>
    <div>Menu 1 Item 2</div>
    <div>Menu 1 Item 3</div>
  </div>
  <div class="menu-content" id="menu-a2">
    <!-- Menu 2 items here -->
    <div>Menu 2 Item 1</div>
    <div>Menu 2 Item 2</div>
    <div>Menu 2 Item 3</div>
  </div>
  <div class="menu-content" id="menu-a3">
    <!-- Menu 3 items here -->
    <div>Menu 3 Item 1</div>
    <div>Menu 3 Item 2</div>
    <div>Menu 3 Item 3</div>
  </div>
</div>

JS kodunuzu biraz düzenledim:

JavaScript:
function toggleHiddenClass() {
  const activeMenuItem = document.querySelector('.menus .list .item.active');

  if (!activeMenuItem) {
    console.error(".menus .list .item.active bulunamadı.");
    return;
  }

  const activeMenuId = activeMenuItem.getAttribute('id');

  if (!activeMenuId) {
    console.error("Active menu item için id bulunamadı.");
    return;
  }

  const verticalMenuContent = document.getElementById(`menu-${activeMenuId}`);

  if (!verticalMenuContent) {
    console.error("Vertical menu content bulunamadı.");
    return;
  }

  const matchedElements = document.querySelectorAll(".vertical-menu .menu-content:not(.hidden)");
  matchedElements.forEach(function(element) {
    element.classList.add('hidden');
  });
  
  verticalMenuContent.classList.remove("hidden");
}
  1. İç içe if bloklarını guard if'lere dönüştürdüm: İstenen şart sağlanmazsa bir şey yapmadan işi sonlandır. Fikrimce kod daha okunaklı oluyor.​
  2. var'ları const'lara dönüştürdüm. Buna alışığım, böyle sunmak istedim.​
  3. activeMenuData'yı kaldırdım. Zaten elimizde activeMenuId var. Bunu kullanabiliriz.​
  4. verticalMenuContent elementini bulmak için menu-${activeMenuId} ID'sine sorgu attım (template string).​
  5. .hidden sınıfına sahip olmayan tüm .vertical-menu .menu-content'leri (birden fazla olabilir veya hiç olmayabilir) bulmak için .vertical-menu .menu-content:not(.hidden) sınıf sorgusunu kullandım. :not buradaki kilit eleman. Yanlış kullanmış olabilirim, çok hakim değilim ama denediğimde çalışıyor.​
  6. Bunların hepsine .hidden ekledim. İnternette araştırdığıma göre .add(), var olan sınıfı eklemeye çalışınca bir şey yapmıyor.​
  7. verticalMenuContent elementinden .hidden sınıfını kaldırdım. .add() gibi, sınıf zaten yoksa .remove() bir şey yapmıyor.​
Bu değişiklikler "önceki"/"sonraki" butonlarının işlevini sağlamıyor, belirteyim. Sadece konuda yazdığınız işlevi sağlattım.
 
HTML kodunuzda menüdeki ID'lere menu- ön eki ekledim çünkü ID'lerin özgün olması doğru olur. Tarayıcı uyarıyordu, öyle fark ettim. Siz dilerseniz ön ek ismini değiştirebilirsiniz:

HTML:
<div class="vertical-menu">
 <div class="menu-content" id="menu-a1">
 <!-- Menu 1 items here -->
 <div>Menu 1 Item 1</div>
 <div>Menu 1 Item 2</div>
 <div>Menu 1 Item 3</div>
 </div>
 <div class="menu-content" id="menu-a2">
 <!-- Menu 2 items here -->
 <div>Menu 2 Item 1</div>
 <div>Menu 2 Item 2</div>
 <div>Menu 2 Item 3</div>
 </div>
 <div class="menu-content" id="menu-a3">
 <!-- Menu 3 items here -->
 <div>Menu 3 Item 1</div>
 <div>Menu 3 Item 2</div>
 <div>Menu 3 Item 3</div>
 </div>
</div>

JS kodunuzu biraz düzenledim:

JavaScript:
function toggleHiddenClass() {
 const activeMenuItem = document.querySelector('.menus .list .item.active');

 if (!activeMenuItem) {
 console.error(".menus .list .item.active bulunamadı.");
 return;
 }

 const activeMenuId = activeMenuItem.getAttribute('id');

 if (!activeMenuId) {
 console.error("Active menu item için id bulunamadı.");
 return;
 }

 const verticalMenuContent = document.getElementById(`menu-${activeMenuId}`);

 if (!verticalMenuContent) {
 console.error("Vertical menu content bulunamadı.");
 return;
 }

 const matchedElements = document.querySelectorAll(".vertical-menu .menu-content:not(.hidden)");
 matchedElements.forEach(function(element) {
 element.classList.add('hidden');
 });

 verticalMenuContent.classList.remove("hidden");
}
  1. iç içe if bloklarını guard if'lere dönüştürdüm: İstenen şart sağlanmazsa bir şey yapmadan işi sonlandır. Fikrimce kod daha okunaklı oluyor.​
  2. var'ları const'lara dönüştürdüm. Buna alışığım, böyle sunmak istedim.​
  3. activeMenuData'yı kaldırdım. Zaten elimizde activeMenuId var. Bunu kullanabiliriz.​
  4. verticalMenuContent elementini bulmak için menu-${activeMenuId} ID'sine sorgu attım (template string).​
  5. .hidden sınıfına sahip olmayan tüm .vertical-menu .menu-content'leri (birden fazla olabilir veya hiç olmayabilir) bulmak için .vertical-menu .menu-content:not(.hidden) sınıf sorgusunu kullandım. :not buradaki kilit eleman. Yanlış kullanmış olabilirim, çok hakim değilim ama denediğimde çalışıyor.​
  6. bunların hepsine .hidden ekledim. İnternette araştırdığıma göre .add(), var olan sınıfı eklemeye çalışınca bir şey yapmıyor.​
  7. verticalMenuContent elementinden .hidden sınıfını kaldırdım. .add() gibi, sınıf zaten yoksa .remove() bir şey yapmıyor.​
Bu değişiklikler "önceki"/"sonraki" butonlarının işlevini sağlamıyor, belirteyim. Sadece konuda yazdığınız işlevi sağlattım.

Hocam öncelikle vaktinizi ayırdığınız için teşekkür ederim, lakin hala aynı sorunla karşı karşıyayım. Farklı tarayıcılarda da denememe rağmen Console'dan hata kodu ya da log bilgisi düşmüyor ve JS kodunu çalıştırmıyor. Sebebini anlayabilmiş değilim.

Not: buttonların olduğu konum .content.menus.arow .
HTML:
<div class="arow">
                    <button class="prev" id="prev" onclick="toggleHiddenClass()">&lt;</button>
                    <button class="next" id="next" onclick="toggleHiddenClass()">&gt;</button>
                </div>
            </div>
            <!-- Your menu content here -->
            <div class="vertical-menu">
                <div class="menu-content hidden" id="menu-1">
                  <!-- Menu 1 items here -->
                  <div>Menu 1 Item 1</div>
                  <div>Menu 1 Item 2</div>
                  <div>Menu 1 Item 3</div>
                </div>
                <div class="menu-content" id="menu-2">
                  <!-- Menu 2 items here -->
                  <div>Menu 2 Item 1</div>
                  <div>Menu 2 Item 2</div>
                  <div>Menu 2 Item 3</div>
                </div>
                <div class="menu-content hidden" id="menu-3">
                  <!-- Menu 3 items here -->
                  <div>Menu 3 Item 1</div>
                  <div>Menu 3 Item 2</div>
                  <div>Menu 3 Item 3</div>
                </div>
              </div>
JavaScript:
 let num = 2;

document.addEventListener('DOMContentLoaded', function() {
    toggleHiddenClass(); 

    document.getElementById('prev').addEventListener('click', function() {
        toggleHiddenClass(-1); 
    });

    document.getElementById('next').addEventListener('click', function() {
        toggleHiddenClass(+1); 
    });
});

function toggleHiddenClass(offset) {
    num += offset; 

    if(num < 1){ 
        num = 1;
    } else if(num > 3){ 
        num = 3;
    }
    console.log(num);

    if(num < 1){ 
        num = 1;

    } else if(num > 3){ 
        num = 3;

    }

    const activeMenuItem = document.querySelector('.menus .list .item.active');

    if (!activeMenuItem) {
        console.log(".menus .list .item.active bulunamadı.");
        return;
    }

    const activeMenuId = activeMenuItem.getAttribute('id');

    if (!activeMenuId) {
        console.log("Active menu item için id bulunamadı.");
        return;
    }

    const verticalMenuContent = document.querySelector(`.vertical-menu.menu-content#menu-${activeMenuId}`);
   
    if (!verticalMenuContent) {
        console.log("Vertical menu content bulunamadı.");
        return;
    }

    const matchedElements = document.querySelectorAll(".vertical-menu .menu-content:not(.hidden)");
    matchedElements.forEach(function(element) {
        element.classList.add('hidden');
    });
 
    verticalMenuContent.classList.remove("hidden");
}
Bu şekilde bir kod denemekteyim.

Şu anda Vertical menu content'i bulmuyor ve let num'da log sonucu "NaN" olarak veriyor
 
Son düzenleme:
Kodunuzun yeni hâlinin hepsini paylaşmadığınız için bazı kısımlarda tahminlerim üzerinden gideceğim:
  • ID'leri menu-a1 yerine menu-1 şeklinde yazmışsınız. Diğer ID'ler a1 şeklinde kaldıysa #menu-${activeMenuId} ifadesi #menu-a1 tarzında olacaktır ve bu yüzden verticalMenuContent bulunamayacaktır çünkü gerçek ID'si menu-1.
  • Baştaki toggleHiddenClass() çağrısında offset === undefined olur, num += offset'te de bir sayıya undefined eklemenin sonucu NaN olduğu için -şimdi kontrol ettim- num artık NaN diye kalacaktır. Bunun önüne geçmek için fonksiyonu çağırırken offset'e değer vermeniz gerek: toggleHiddenClass() yerine toggleHiddenClass(0).
    • Boş çağırabilmek ve yine doğru çalışmasını sağlamak isterseniz fonksiyon tanımında argümana bir varsayılan değer atayın: function toggleHiddenClass(offset = 0){...}.
  • Butonlardan HTML'deki onclick'leri kaldırın. JS'te zaten event listener'ları ayarlıyorsunuz. Denemedim ama onları kaldırmamak tahminimce hata sebebi.
Hâlâ beklendik sonuçlar elde edemezseniz tekrar danışabilirsiniz.
 
JavaScript:
let num = 2;

document.addEventListener('DOMContentLoaded', function() {
 toggleHiddenClass();

 document.getElementById('prev').addEventListener('click', function() {
 toggleHiddenClass(-1);
 });

 document.getElementById('next').addEventListener('click', function() {
 toggleHiddenClass(+1);
 });
});

function toggleHiddenClass(offset=0) {
 num += offset;
 console.log(num);
 if(num < 1){
 num = 1;
 } else if(num > 3){
 num = 3;
 }

 if(num < 1){
 num = 1;

 } else if(num > 3){
 num = 3;

 }

 const activeMenuItem = document.querySelector('.menus .list .item.active');

 if (!activeMenuItem) {
 console.log(".menus .list .item.active bulunamadı.");
 return;
 }

 const activeMenuId = activeMenuItem.getAttribute('id');
 console.log(activeMenuId);
 if (!activeMenuId) {
 console.log("Active menu item için id bulunamadı.");
 return;
 }

 const verticalMenuContent = document.querySelector(`.menu-content#${activeMenuId}`);
 console.log(verticalMenuContent);
 if (!verticalMenuContent) {
 console.log("Vertical menu content bulunamadı.");
 return;
 }

 const matchedElements = document.querySelectorAll(".vertical-menu .menu-content:not(.hidden)");
 matchedElements.forEach(function(element) {
 element.classList.add('hidden');
 });

 verticalMenuContent.classList.remove("hidden");
}

Hocam sorunu çözdüm, yardımın için teşekkür ederim. verticalMenuContent'in console.log'unu kontrol ettiğimde Null sonucunu veriyordu ve bunun sebebine bakarken activeMenuId'nin içerisindeki veriyi merak edip Konsol'dan log olarak çıktı aldığımda" menu-1 "olarak çıktı sağlıyordu, bizde kodda querySelector yaparken "#menu-" diye bir ibare eklemiştik, bunu sildiğimde ve sadece ulaşmak istediğim verinin class ismini yazdığımda Sorun'u çözdüm.
 
Son düzenleme:
Rica ederim.

Sistemin bahsettiğiniz ve gösterdiğiniz şekilde çalışabilmesi için listedeki elementlerle menüdeki elementlere menu-[numara] biçiminde aynı ID'leri atamış olmalısınız yanılmıyorsam. İlk mesajımda belirttiğim üzere, ID'lerin özgün olması daha doğru olur.
 

Yeni konular

Geri
Yukarı