как отформатировать раскрывающийся список при наведении, чтобы он всегда был верхним слоем? - PullRequest
0 голосов
/ 08 мая 2020

У меня есть выпадающий элемент при наведении курсора и выпадающий элемент при щелчке рядом с друг другом. Я дал обоим "положение: относительное;" атрибут для div с раскрывающимся списком. Однако это вызывает проблемы с визуализацией слоя и наведением курсора. Сначала я попытаюсь описать, а затем предоставлю изображения и ссылку на код.

Проблема 1:
Выпадающий div при наведении курсора выходит за пределы моего on- щелкните элемент раскрывающегося списка, и из-за того, что я считаю, это "position: relative;" атрибут, который я должен предоставить для скрытых раскрывающихся списков, элемент span в элементе по щелчку отображается, как если бы он находился поверх раскрывающегося списка при наведении.
неактивное наведение (для справки)
активное наведение

Проблема 2:
предположим, что проблема 1 не была проблемой, и изображение было в порядке. Если я наведу курсор на раскрывающийся список при наведении курсора и опущу его к последней опции в раскрывающемся div при наведении курсора, курсор будет думать, что он завис над раскрывающимся элементом при щелчке, заставляя браузер полагать, что раскрывающееся меню при наведении больше не что наведено, а затем становится неактивным, ie все параметры div при наведении курсора скрываются. Я не могу показать это из-за характера проблемы.

Проблема 3:
Я считаю, что это проблема, аналогичная проблеме 1, только с другими элементы. Предположим, вы щелкнули раскрывающийся список при щелчке, что позволяет увидеть все его параметры. Затем вы перемещаете курсор так, чтобы он зависал над элементом раскрывающегося списка при наведении курсора, что также позволяет увидеть все эти параметры. Он состоит из нескольких слоев, так что параметры при нажатии отображаются поверх параметров при наведении, тогда как должно быть наоборот.
неактивное наведение (для справки)
active hover

Я понимаю, что могу просто перемещать элементы, чтобы мне вообще не приходилось с этим сталкиваться, но я чувствую, что это скорее временное решение, и я хочу исправление. Опять же, я чувствую, что это связано с обоими элементами, для которых атрибут position установлен как relative, но если я избавлюсь от него, они оба будут go нестабильными по ряду разных причин.

вот кодовая страница, извините, если в css есть что-то, что ссылается на вещи, которых нет в html, я попытался очистить все это как можно лучше, чтобы сделать это как можно меньше код barf по возможности.

Спасибо! Дайте мне знать, если вам понадобятся дополнительные разъяснения.

... и, поскольку он не позволит мне опубликовать код без кода в этом посте, вот код:

for (const dropdown of document.querySelectorAll(".dropSelectWrap")) {
  dropdown.addEventListener('click', function() {
    this.querySelector('.dropSelect').classList.toggle('open');
  })
}

for (const option of document.querySelectorAll(".dropSelectOption")) {
  option.addEventListener('click', function() {
    if (!this.classList.contains('dropSelectChosen')) {
      this.parentNode.querySelector('.dropSelectOption.dropSelectChosen').classList.remove('dropSelectChosen');
      this.classList.add('dropSelectChosen');
      this.closest('.dropSelect').querySelector('.dropSelectTrig span').textContent = this.textContent;
    }
  })
}

window.addEventListener('click', function(e) {
  for (const select of document.querySelectorAll('.dropSelect')) {
    if (!select.contains(e.target)) {
      select.classList.remove('open');
    }
  }
});

function selectOption(index) {
  var optionOnIdx = document.querySelector('.dropSelectOption:nth-child(' + index + ')');
  var optionSelected = document.querySelector('.dropSelectOption.dropSelectChosen');
  if (optionOnIdx !== optionSelected) {
    optionSelected.parentNode.querySelector('.dropSelectOption.dropSelectChosen').classList.remove('dropSelectChosen');
    optionOnIdx.classList.add('dropSelectChosen');
    optionOnIdx.closest('.dropSelect').querySelector('.dropSelectTrig span').textContent = optionOnIdx.textContent;
  }
}
:root {
  font-size: 62.5%;
}

body {
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
}


/* anything smaller */

@media only screen and (min-width: 0px) {
  .top-nav .dropdwn>.spanItem {
    display: none;
  }
}


/* desktop */

@media only screen and (min-width: 1500px) {
  .top-nav .dropdwn>.spanItem {
    display: block;
  }
  .top-nav .dropdwn>.buttItem {
    display: none;
  }
}

#outmostBox {
  width: 80rem;
}

header {
  margin-top: 4rem;
}

.bottomTopLinks .text,
header nav a {
  font-size: 1.45rem;
}


/* #region NAVBAR_HOVER */

#outmostBox {
  margin: 0;
  padding: 0;
  justify-items: center;
  display: grid;
}

header {
  justify-items: center;
  display: grid;
}

.dropNav * {
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
}

nav,
.dropNav {
  width: 100%;
}

.dropNav .top-nav {
  display: flex;
  justify-content: center;
  padding: 0;
  font-size: 0;
  /* eliminates whitespace from inline-block*/
}

.top-nav div {
  display: inline-block;
  /* blocks just line up without floats */
  position: relative;
  /* sets positioning context for 2nd level menu */
  width: inherit;
}

.top-nav button {
  border: none;
}

.top-nav button:focus {
  outline: 0;
}

.top-nav .text,
.top-nav .sub-nav a {
  text-align: center;
  /* centeres the text horizontally */
  display: block;
  /* links now fill the block*/
  padding: 10px 20px;
}

.top-nav .text {
  text-decoration: underline;
}

.top-nav .text:hover,
.top-nav .sub-nav span>a:hover {
  background-color: rgba(228, 228, 228, 0.39);
}

.top-nav .sub-nav {
  /* positions the menu UNDER the list item*/
  position: absolute;
  width: 100%;
  /* hides the menu until needed */
  visibility: hidden;
  padding: 0;
}

.top-nav div:hover .sub-nav {
  /* shows the submenu when the list item is hovered */
  visibility: visible;
  box-shadow: 0 5px 4px rgba(0, 0, 0, 0.2), 0 11px 10px rgba(0, 0, 0, 0.19);
  border-bottom-right-radius: 5px;
  border-bottom-left-radius: 5px;
}

.top-nav .sub-nav div {
  background-color: white;
  width: 100%;
}

.top-nav .bottomItem {
  border-bottom-right-radius: 5px;
  border-bottom-left-radius: 5px;
}


/* #endregion */

#searchAndGenre {
  margin-top: 2rem;
  width: 100%;
  display: flex;
  justify-content: space-around;
}


/* everything below here is for the select drop-down */

.searchBar .searchTerm,
.selectDropCont {
  font-size: 1.45rem;
}

.searchCont,
.selectDropCont,
.selectDropCont .dropSelectWrap {
  width: 20rem;
}

.searchCont,
.selectDropCont,
.selectDropCont .dropSelectWrap,
.selectDropCont .dropSelectWrap .dropSelect span {
  height: 3.5rem;
}


/* #region SELECTDROP-INNARDS */

.selectDropCont *,
.selectDropCont *:after,
.selectDropCont *:before {
  box-sizing: border-box;
}

.selectDropCont,
.selectDropCont .dropSelectWrap {
  display: flex;
  align-items: center;
}

.selectDropCont {
  justify-content: center;
  align-items: center;
  background: rgba(250, 250, 250, 1);
}

.selectDropCont .dropSelectWrap {
  text-align: center;
}

.selectDropCont .dropSelectWrap .selectNameCont .selectName {
  width: 100%;
  height: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  user-select: none;
  border-width: 3px;
  border-color: rgba(151, 151, 151, 1);
  border-style: none solid none none;
}

.selectDropCont .dropSelectWrap .selectNameCont {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 35%;
}

.selectDropCont .dropSelectWrap {
  user-select: none;
}

.selectDropCont .dropSelectWrap .dropSelect {
  display: flex;
  flex-direction: column;
  border-width: 0;
  width: 65%;
}

.selectDropCont .dropSelectWrap>div {
  display: inline-block;
  /* blocks just line up without floats */
  height: 35px;
}

.selectDropCont .dropSelectWrap .dropSelect {
  position: relative;
  /* sets positioning context for 2nd level menu */
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px;
  height: 35px;
  cursor: pointer;
  border-width: 0;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .centCont {
  width: 100%;
}

.selectDropCont .dropSelectWrap .dropSelectOptions {
  position: absolute;
  display: block;
  top: 100%;
  left: 0;
  right: 0;
  border: none;
  background: white;
  transition: all 0.5s;
  opacity: 0;
  visibility: hidden;
}

.selectDropCont .dropSelectWrap .dropSelect.open .dropSelectOptions {
  opacity: 1;
  visibility: visible;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectOptions .dropSelectOption {
  width: 100%;
  justify-content: center;
  display: inline-flex;
  align-items: center;
  padding: 0 22px 0 22px;
  color: rgba(83, 83, 83, 1);
  line-height: 30px;
  cursor: pointer;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectOptions .dropSelectOption:hover {
  cursor: pointer;
  background-color: rgba(228, 228, 228, 0.39);
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow {
  position: relative;
  height: 10px;
  width: 10px;
  padding: 5px 5px;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow::before,
.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow::after {
  content: "";
  position: absolute;
  bottom: 0px;
  width: 0.15rem;
  height: 100%;
  transition: all 0.5s;
}

.selectDropCont .arrow::before {
  left: -3px;
  transform: rotate(45deg);
  background-color: #394a6d;
}

.selectDropCont .arrow::after {
  left: 3px;
  transform: rotate(-45deg);
  background-color: #394a6d;
}

.selectDropCont .open .arrow::before {
  left: -3px;
  transform: rotate(-45deg);
}

.selectDropCont .open .arrow::after {
  left: 3px;
  transform: rotate(45deg);
}


/* #endregion */
<div id="outmostBox">

  <header>

    <nav class="bottomTopLinks">
      <div class="dropNav">
        <div class="top-nav">

          <div class="dropdwn"><span class="text spanItem">creative</span><button class="text buttItem">creative</button>
            <div class="sub-nav">
              <div><span><a href="?">photos</a></span></div>
              <div class="bottomItem"><span><a class="bottomItem" href="?">music</a></span></div>
            </div>
          </div>

        </div>
      </div>
    </nav>

  </header>
  <!-- new code below this line -->

  <div id="searchAndGenre">

    <div class="selectDropCont">
      <div class="dropSelectWrap">

        <div class="selectNameCont">
          <div class="selectName"><span>type</span></div>
        </div>

        <div class="dropSelect">
          <div class="dropSelectTrig">
            <div class="centCont"><span>all</span></div>
            <div class="arrow"></div>
          </div>
          <div class="dropSelectOptions">
            <span class="dropSelectOption dropSelectChosen" data-value="all">all</span>
            <span class="dropSelectOption" data-value="expository">expository</span>
            <span class="dropSelectOption" data-value="persuasive">persuasive</span>
            <span class="dropSelectOption" data-value="research">research</span>
            <span class="dropSelectOption" data-value="descriptive">descriptive</span>
          </div>
        </div>

      </div>
    </div>

  </div>
  <!-- new code above this line -->


</div>

1 Ответ

0 голосов
/ 09 мая 2020

Хорошо, ребята, похоже, никто не ответит на этот вопрос, так что для всех, кто смотрит на это и задается вопросом, черт возьми, как я, вот мой лучший ответ. Пожалуйста, не стесняйтесь предлагать лучшее альтернативное решение lmao.

Я много играл с кодом, пока не заставил его работать, вот мой код:

for (const dropdown of document.querySelectorAll(".dropSelectWrap")) {
        dropdown.addEventListener('click', function () {
            this.querySelector('.dropSelect').classList.toggle('open');
        })
    }

    for (const option of document.querySelectorAll(".dropSelectOption")) {
        option.addEventListener('click', function () {
            if (!this.classList.contains('dropSelectChosen')) {
                this.parentNode.querySelector('.dropSelectOption.dropSelectChosen').classList.remove('dropSelectChosen');
                this.classList.add('dropSelectChosen');
                this.closest('.dropSelect').querySelector('.dropSelectTrig span').textContent = this.textContent;
            }
        })
    }

    window.addEventListener('click', function (e) {
        for (const select of document.querySelectorAll('.dropSelect')) {
            if (!select.contains(e.target)) {
                select.classList.remove('open');
            }
        }
    });

    function selectOption(index) {
        var optionOnIdx = document.querySelector('.dropSelectOption:nth-child('+index+')');
      var optionSelected = document.querySelector('.dropSelectOption.dropSelectChosen');
      if (optionOnIdx !== optionSelected) {
        optionSelected.parentNode.querySelector('.dropSelectOption.dropSelectChosen').classList.remove('dropSelectChosen');
                optionOnIdx.classList.add('dropSelectChosen');
                optionOnIdx.closest('.dropSelect').querySelector('.dropSelectTrig span').textContent = optionOnIdx.textContent;
            }
    }
:root{ font-size: 62.5%; }

body{
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center; }

/* anything smaller */
@media only screen and (min-width: 0px){
  .top-nav .dropdwn > .spanItem { display: none; }
}

/* desktop */
@media only screen and (min-width: 1500px){
        .top-nav .dropdwn > .spanItem { display: block; }
        .top-nav .dropdwn > .buttItem { display: none; }
}

#outmostBox { width: 80rem; }
  header { margin-top: 4rem; }
  .bottomTopLinks .text, header nav a { font-size: 1.45rem; }


/* #region NAVBAR_HOVER */
#outmostBox {
    margin: 0;
    padding: 0;
    justify-items: center;
    display: grid; }

    header {
        justify-items: center;
        display: grid; }

        .dropNav * { 
            box-sizing: border-box;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box; }

          nav, .dropNav { 
            width: 100%;
            position: relative;
            z-index: 4;}

              .dropNav .top-nav {
                  display: flex;
                  justify-content: center;
                  padding: 0;
                  font-size: 0; /* eliminates whitespace from inline-block*/ }

                  .top-nav div {
                      display: inline-block; /* blocks just line up without floats */
                      position: relative; /* sets positioning context for 2nd level menu */
                      width: inherit; }

                  .top-nav button { border: none; }

                  .top-nav button:focus { outline: 0; }

                      .top-nav .text, .top-nav .sub-nav a {
                          text-align: center; /* centeres the text horizontally */
                          display: block; /* links now fill the block*/
                          padding: 10px 20px; }

                      .top-nav .text { text-decoration: underline; }

                      .top-nav .text:hover,
                      .top-nav .sub-nav span > a:hover { background-color: rgba(228, 228, 228, 0.39); }

                      .top-nav .sub-nav {
                          /* positions the menu UNDER the list item*/
                          position: absolute;
                          width: 100%;
                          /* hides the menu until needed */
                          visibility: hidden; 
                          padding: 0; }

                  .top-nav div:hover .sub-nav{
                      /* shows the submenu when the list item is hovered */
                      visibility: visible; 
                      box-shadow: 0 5px 4px rgba(0, 0, 0, 0.2), 0 11px 10px rgba(0, 0, 0, 0.19);
                      border-bottom-right-radius:5px;
                      border-bottom-left-radius:5px; }

                          .top-nav .sub-nav div {
                              background-color: white; 
                              width: 100%; }

                          .top-nav .bottomItem {
                              border-bottom-right-radius:5px;
                              border-bottom-left-radius:5px; }
/* #endregion */

#searchAndGenre { 
  margin-top: 2rem;
  width: 100%;
  display: flex;
  justify-content: space-around;
}

/* everything below here is for the select drop-down */

.searchBar .searchTerm, .selectDropCont { font-size: 1.45rem; }
.searchCont, 
.selectDropCont, 
.selectDropCont .dropSelectWrap {
  width: 20rem;
}
.searchCont, .selectDropCont, .selectDropCont .dropSelectWrap, .selectDropCont .dropSelectWrap .dropSelect span { height: 3.5rem; }


/* #region SELECTDROP-INNARDS */

.selectDropCont *,
.selectDropCont *:after,
.selectDropCont *:before {
  box-sizing: border-box;
}

.selectDropCont, .selectDropCont .dropSelectWrap {
  display: flex;
  width:200px;
  height: 35px;
}

.selectDropCont {
  position: relative;
  justify-content: center;
  align-items: center;
  background: grey; 
}

.selectDropCont .dropSelectWrap .selectNameCont .selectName {
  width: 100%;
  height: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  user-select: none;
  border-width: 3px;
  border-color: rgba(151, 151, 151, 1);
  border-style: none solid none none;
}

.selectDropCont .dropSelectWrap .selectNameCont {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 35%;
}

.selectDropCont .dropSelectWrap {
  position: relative;
  user-select: none;
  align-items: center;
  text-align: center;
}

.selectDropCont .dropSelectWrap .dropSelect {
  position: relative;
  display: flex;
  flex-direction: column;
  border-width: 0;
  width: 65%;
}

.selectDropCont .dropSelectWrap > div {
  display: inline-block; /* blocks just line up without floats */
  position: relative; /* sets positioning context for 2nd level menu */
  height: 35px;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px;
  height: 35px;
  cursor: pointer;
  border-width: 0;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .centCont { width: 100%; }

.selectDropCont .dropSelectWrap .dropSelectOptions {
  position: absolute;
  display: block;
  top: 100%;
  left: 0;
  right: 0;
  border: none;
  background: white;
  transition: all 0.5s;
  opacity: 0;
  visibility: hidden;
}

.selectDropCont .dropSelectWrap .dropSelect.open .dropSelectOptions {
  opacity: 1;
  visibility: visible;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectOptions .dropSelectOption {
  position: relative;
  display: block;
  padding: 0 22px 0 22px;

  color: rgba(83, 83, 83, 1);
  line-height: 30px;
  cursor: pointer;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectOptions .dropSelectOption:hover {
  cursor: pointer;
  background-color: rgba(228, 228, 228, 0.39);
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow {
  position: relative;
  height: 10px;
  width: 10px;
  padding: 5px 5px;
}

.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow::before,
.selectDropCont .dropSelectWrap .dropSelect .dropSelectTrig .arrow::after {
  content: "";
  position: absolute;
  bottom: 0px;
  width: 0.15rem;
  height: 100%;
  transition: all 0.5s;
}

.selectDropCont .arrow::before {
  left: -3px;
  transform: rotate(45deg);
  background-color: #394a6d;
}

.selectDropCont .arrow::after {
  left: 3px;
  transform: rotate(-45deg);
  background-color: #394a6d;
}

.selectDropCont .open .arrow::before {
  left: -3px;
  transform: rotate(-45deg);
}

.selectDropCont .open .arrow::after {
  left: 3px;
  transform: rotate(45deg);
}

/* #endregion */
  <div id="outmostBox">

    <header>

      <nav class="bottomTopLinks">
        <div class="dropNav">
          <div class="top-nav">

            <div class="dropdwn"><span class="text spanItem">creative</span><button class="text buttItem">creative</button>
               <div class="sub-nav">
                 <div><span><a href="?">photos</a></span></div>
                 <div class="bottomItem"><span><a class="bottomItem" href="?">music</a></span></div>
               </div>
            </div>

          </div>
        </div>
      </nav>

    </header>
    <!-- new code below this line -->

    <div id="searchAndGenre">

      <div class="selectDropCont">
        <div class="dropSelectWrap">

          <div class="selectNameCont">
            <div class="selectName"><span>type</span></div>
          </div>

          <div class="dropSelect">

            <div class="dropSelectTrig"><div class="centCont"><span>all</span></div>
              <div class="arrow"></div>
            </div>

            <div class="dropSelectOptions">
              <span class="dropSelectOption dropSelectChosen" data-value="all">all</span>
              <span class="dropSelectOption" data-value="expository">expository</span>
              <span class="dropSelectOption" data-value="persuasive">persuasive</span>
              <span class="dropSelectOption" data-value="research">research</span>
              <span class="dropSelectOption" data-value="descriptive">descriptive</span>
            </div>

          </div>

        </div>
      </div>

    </div>
    <!-- new code above this line -->

    
  </div>

Честно говоря, не понимаю, что я на самом деле сделал. В конце концов, я думаю, что изменил атрибуты позиции и z-index вверх. Как хорошо, удачи. Я только что узнал о z-index, вот ресурс solid для тех, кому он нужен: freecodecamp.org

...