Принудительно показывать div внутри навигации по вкладке поверх всего остального содержимого страницы - PullRequest
0 голосов
/ 13 апреля 2020

Я работаю с шаблонами, поэтому могу редактировать только большую часть окружения. У меня настроена навигация с вкладками. На одной из вкладок у меня есть div, который я хочу иметь фиксированную позицию, которая находится вне / поверх всего остального на странице.

Это не тот код, с которым я работаю, но это достаточно похоже, что я могу использовать его в качестве примера. Div "outsidediv" находится в "London" div. Но я хочу сделать так, чтобы вы увидели outsidediv, даже если вы нажмете на вкладки Париж или Токио.

Я пытался использовать z-index и все виды свойств позиции, которые я могу придумать, чтобы заставить это работать , Я не могу переместить посторонний из того места, где он находится.

.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
  font-size: 17px;
}

.tab button:hover {
  background-color: #ddd;
}


.tab button.active {
  background-color: #ccc;
}


.tabcontent {
  display: none;
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}

#outsidediv {
  position: fixed;
  top: 80px;
  right: 50px;
  background: pink;
  }
<div class="tab">
  <button class="tablinks" onclick="openCity(event, 'London')">London</button>
  <button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
  <button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>

<div id="London" class="tabcontent">
  <h3>London</h3>
  <p>London is the capital city of England.</p>
  <div id="outsidediv">This div should appear no matter which tab is selected.</div>
</div>

<div id="Paris" class="tabcontent">
  <h3>Paris</h3>
  <p>Paris is the capital of France.</p> 
</div>

<div id="Tokyo" class="tabcontent">
  <h3>Tokyo</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>

<script>
function openCity(evt, cityName) {
  var i, tabcontent, tablinks;
  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }
  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }
  document.getElementById(cityName).style.display = "block";
  evt.currentTarget.className += " active";
}
</script>

Ответы [ 3 ]

1 голос
/ 13 апреля 2020

Вы можете сделать дополнительную функцию для добавления outsidediv. Перед добавлением элемента сначала проверьте, существует ли он на странице, и, если это так, удалите его, а затем добавьте его в текущий активный элемент вкладки.

Проверьте ниже:

function openCity(evt, cityName) {
  var i, tabcontent, tablinks;
  var div = document.getElementById("outsidediv");
  if(div !== null) { // if outsidediv exists on the page, remove it
    div.remove();
  }
  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }
  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }
  let cityDiv = document.getElementById(cityName);  // made cityDiv variable
  cityDiv.style.display = "block";
  evt.currentTarget.className += " active";
  cityDiv.append( makeOutsideDiv() );  // add the outsidediv to the active element
}

function makeOutsideDiv() {
  let div = document.createElement("div");
  div.innerHTML = "This div should appear no matter which tab is selected.";
  div.id = "outsidediv";
  return div;
}
.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
  font-size: 17px;
}

.tab button:hover {
  background-color: #ddd;
}


.tab button.active {
  background-color: #ccc;
}


.tabcontent {
  display: none;
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}

#outsidediv {
  position: fixed;
  top: 80px;
  right: 50px;
  background: pink;
  }
<div class="tab">
  <button class="tablinks" onclick="openCity(event, 'London')">London</button>
  <button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
  <button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>

<div id="London" class="tabcontent">
  <h3>London</h3>
  <p>London is the capital city of England.</p>
  <div id="outsidediv">This div should appear no matter which tab is selected.</div>
</div>

<div id="Paris" class="tabcontent">
  <h3>Paris</h3>
  <p>Paris is the capital of France.</p> 
</div>

<div id="Tokyo" class="tabcontent">
  <h3>Tokyo</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>
1 голос
/ 13 апреля 2020

Я не знаю, что есть другой способ сделать это, кроме как переместить div так, чтобы он находился вне вкладки, и присвоить ему очень высокое значение z-index, потому что, как только вы скрываете вкладку с помощью display:none вся вкладка (и ее потомки) не будут отображены.

Если вы не можете изменить структуру шаблона HTML, вы можете использовать JavaScript, чтобы переместить ее с этим строка:

document.body.appendChild(document.getElementById("outsidediv"));

Я также изменил / обновил ваш существующий код JavaScript, чтобы вы не использовали .getElementsByClassName() или с использованием встроенного HTML атрибуты события , что делает код намного более эффективным и более соответствующим современным методологиям разработки. Подробности см. В комментариях к коду.

/* Just add this class when you want to hide something 
   and remove when you want to show */
.hidden { display:none; }

.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
  font-size: 17px;
}

.tab button:hover {
  background-color: #ddd;
}

.tab button.active {
  background-color: #ccc;
}


.tabcontent {
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}

#outsidediv {
  position: fixed;
  z-index:9999;
  top: 80px;
  right: 50px;
  background: pink;
}
<div class="tab">
  <!-- Don't use inline HTML event attributes. Do your JavaScript in JavaScript-->
  <button class="tablinks">London</button>
  <button class="tablinks">Paris</button>
  <button class="tablinks">Tokyo</button>
</div>

<div id="London" class="tabcontent hidden">
  <h3>London</h3>
  <p>London is the capital city of England.</p>
  <div id="outsidediv">This div should appear no matter which tab is selected.</div>
</div>

<div id="Paris" class="tabcontent hidden">
  <h3>Paris</h3>
  <p>Paris is the capital of France.</p> 
</div>

<div id="Tokyo" class="tabcontent hidden">
  <h3>Tokyo</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>

<script>
// Move the div that should stay on top to just after the tab divs
document.body.appendChild(document.getElementById("outsidediv"));

// Just set your event up at the parent of the buttons
// and use event delegation to leverage event bubbling
document.querySelector(".tab").addEventListener("click", openCity);

function openCity(event) {
  // Never, never, never use `getElementsByClassName()`
  // and instead, use `.querySelectorAll()`. You can 
  // then loop through the resulting collection with
  // `.forEach()`, which makes looping without indexes
  // possible
  
  // Hide all the tab conttent
  document.querySelectorAll(".tabcontent").forEach(function(tab){
    // Avoid inline styles when possible and just apply/remove classes
    tab.classList.add("hidden");
  });
  
  // Remove the active tab
  document.querySelectorAll(".tablinks").forEach(function(tabLink){
    tabLink.classList.remove("active");
  });
  
  // Loop over the content again
  document.querySelectorAll(".tabcontent").forEach(function(tab){
    // If the text of the clicked button matches the text of the tab header...
    if(event.target.textContent === tab.querySelector("h3").textContent){
      tab.classList.remove("hidden");      // Unhide the tabcontent
      event.target.classList.add("active"); // Make the tab active
    }
  });
}
</script>
0 голосов
/ 14 апреля 2020

Я использовал visibility вместо display, и для каждой неактивной вкладки я устанавливаю position:fixed и отправляю ее над визуализированной областью страницы (вне поля зрения и вне поля зрения). Затем, когда на вкладку нажимают снова, я устанавливаю ее обратно на position:relative без смещения.

Вот скрипка: https://jsfiddle.net/tm1wyax6/1/

<div class="tab">
  <button class="tablinks" onclick="openCity(event, 'London')">London</button>
  <button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
  <button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>

<div id="London" class="tabcontent">
  <h3>London</h3>
  <p>London is the capital city of England.</p>
  <div id="outsidediv">This div should appear no matter which tab is selected.</div>
</div>

<div id="Paris" class="tabcontent">
  <h3>Paris</h3>
  <p>Paris is the capital of France.</p> 
</div>

<div id="Tokyo" class="tabcontent">
  <h3>Tokyo</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>

<script>
function openCity(evt, cityName) {
  var i, tabcontent, tablinks;
  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.visibility = "hidden";
    tabcontent[i].style.position = "fixed";
    tabcontent[i].style.top = "-1000px";
  }
  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }
  document.getElementById(cityName).style.visibility = "visible";
  document.getElementById(cityName).style.position = "relative";
  document.getElementById(cityName).style.top = "0";
  evt.currentTarget.className += " active";
}
</script>

CSS:

.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
  font-size: 17px;
}

.tab button:hover {
  background-color: #ddd;
}


.tab button.active {
  background-color: #ccc;
}


.tabcontent {
  visibility: hidden;
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}

#outsidediv {
  position: fixed;
  top: 80px;
  right: 50px;
  background: pink;
  visibility: visible;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...