首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >切换或显示/隐藏

切换或显示/隐藏
EN

Stack Overflow用户
提问于 2022-03-30 23:16:27
回答 1查看 146关注 0票数 0

我需要帮助切换覆盖与多个div。我不想有一个单独的功能,为每一个(有6个不同的覆盖弹出窗口6)。onclick div将显示覆盖弹出。我们很感激你的帮助!我需要帮助切换覆盖与多个div。我不想有一个单独的功能,为每一个(有6个不同的覆盖弹出窗口6)。onclick div将显示覆盖弹出。我们很感激你的帮助!

代码语言:javascript
复制
        function on() {
          document.getElementById("overlay").style.display = "block";
        }

        function off() {
          document.getElementById("overlay").style.display = "none";
        }
代码语言:javascript
复制
    #overlay {
      position: fixed;
      display: none;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0,0,0,0.8);
      z-index: 2;
      cursor: pointer;
    }

    #text{
      position: absolute;
      top: 50%;
      left: 50%;
      font-size: 1rem;
      color: white;
      transform: translate(-50%,-50%);
      -ms-transform: translate(-50%,-50%);
    }
代码语言:javascript
复制
<!-- //DIV  -->
<div class="row ">
      <div class="col-md-6 col-lg-4 d-flex align-items-stretch" onclick="on()">
          <div class="card mb-3">
                <img src="img/ballet.jpg" class="embed-responsive w-100 classpic" alt="...">

                  <div class="card-body">
                <h5 class="card-title">BALLET</h5>
              </div>
            </div>
      </div>

<!-- //POPUP  -->
              <div id="overlay" onclick="off()">
                <div id="text">
                  <h3>Ballet</h3>
                  <p>Ballet is an artistic dance form performed to music using precise and highly formalized set steps and gestures.
                  Classical ballet, which originated in Renaissance Italy and established its present form during the 19th century,
                  is characterized by light, graceful, fluid movements and the use of pointe shoes.
                  </p>
                  <h4>Shedule:</h4>
                  <p>Ages 4-8: Thursdays • 4PM<br>
                     Ages 9-14: Fridays • 7PM</p>
                </div>
                </div>

EN

回答 1

Stack Overflow用户

发布于 2022-03-31 00:19:12

您的方法存在一个问题,即当元素具有display:none时,它将从html树中删除,无法接收单击事件。另外,没有两个元素可以共享相同的id属性,因此您的函数不能直接引用到id。

我做了一个有用的片段,实现了我认为你想要的目标。毫无疑问,也有其他的工作,但这是相当直截了当的工作。

首先,将您的备选div对(一个隐藏的,一个可见的)安排在父div中,并给它一个类名。这样做的好处是,如果您适当地调整容器div的大小,则当您将隐藏的div替换为visible时,内容不会跳转,反之亦然。接下来,给出类来区分(最初)隐藏的内容和可见的div。然后,您的标记模式将重复以下内容:

代码语言:javascript
复制
    <div class='container'>
      <div class='main'>my first main content</div>
      <div class='hidden'>my first hidden content </div>
    </div>

在样式表中,设置类显示属性:

代码语言:javascript
复制
    .hidden {
      display: none;
    }

    .main {
      display: block;
    }

然后,在javascript中设置一个单击事件侦听器。这将从页面上的任何位置获取一个click事件。

代码语言:javascript
复制
    document.addEventListener('click', event => {

    })

在事件侦听器中,放置一个if块来测试.container类的div中的元素是否接收了单击事件:

代码语言:javascript
复制
if (event.target.parentElement.className=='container') {


}

  • I对此略作修改,请参阅编辑说明和底部。

如果单击事件达到了此程度,则该单击必须由容器内的可见div接收(因为隐藏的div无法接收单击事件,并且它们是当前的唯一两个元素。

因此,您可以继续并交换应用于接收单击的可见div的类:

代码语言:javascript
复制
        event.target.classList.add('hidden');
        event.target.classList.remove('main');

现在,您必须与容器类中的另一个div相反,才能使同级可见。问题是,您不知道隐藏类是容器div的第一个子类还是第二个子类。你确实知道的是,另一个div是你刚刚使之看不见的div的兄弟姐妹。

因此,我们可以使用条件来测试是否存在下一个兄弟姐妹:

代码语言:javascript
复制
    if (event.target.nextElementSibling) {
      event.target.nextElementSibling.classList.add('main');
      event.target.nextElementSibling.classList.remove('hidden');
     } 

如果隐藏的div跟随可见的div,将找到一个nextElementSibling并交换类。如果没有发现nextElementSibling,我们知道另一个div必须在我们已经藏好的那个之前来。

因此,可以添加该if块的一个if扩展来切换previousElementSibling上的类。

代码语言:javascript
复制
 ...} else {
      event.target.previousElementSibling.classList.add('main');
      event.target.previousElementSibling.classList.remove('hidden');
    } // end else;

你就完蛋了!

我想详细解释一下逻辑,以确保你知道发生了什么,但这并不复杂。

这种方法的优点是,单个事件侦听器将处理1、2或1,000对div,除了初始的.main.hidden类之外,不需要任何特殊的is或其他任何东西(并且将它们分组在.container div中)。

代码语言:javascript
复制
document.addEventListener('click', event => {

  if (event.target.parentElement && event.target.parentElement.className=='container') {
    event.target.classList.add('hidden');
    event.target.classList.remove('main');
    
      if(event.target.nextElementSibling) {
event.target.nextElementSibling.classList.add('main');
event.target.nextElementSibling.classList.remove('hidden');
      } else {
event.target.previousElementSibling.classList.add('main');
event.target.previousElementSibling.classList.remove('hidden');
      } // end else;
   
   } // end parentElement if;

}) // end click listener;
代码语言:javascript
复制
.hidden {
  display: none;
  border: 1px solid red;
  margin: 5px;
}

.main {
  display: block;
  border: 1px solid black;
  margin: 5px;
}
代码语言:javascript
复制
<div class='container'>
  <div class='main'>my first main content</div>
  <div class='hidden'>my first hidden content </div>
</div>

<div class='container'>
  <div class='main'>my second main content</div>
  <div class='hidden'>my second hidden content </div>
</div>

编辑检测单击事件的父元素是否为.container div的条件,以检查事件目标是否有父元素,以及父元素是否为.container div。如果在container div之外的任何地方都收到单击,这将防止错误。

**显示不透明的覆盖以响应单击**

同样,该解决方案允许将功能应用于无限制的div元素,而不需要独立的ids。同样,使用两个类.main.hidden来确定从应用到document而不是多个div的单个事件侦听器中单击了哪个div。

显示然后重新隐藏(最初隐藏的) .overlay div的基本过程非常简单:

代码语言:javascript
复制
   if (element.className == 'main') {
     element.parentElement.getElementsByClassName('overlay')[0].classList.remove('hidden');   
   } 

   if (element.className == 'overlay') {
     element.classList.add('hidden');   
   } 

但是,由于使用类名而不是ids,出现了一个问题。也就是说,当显示覆盖时,没有类名.hidden的子类元素可能会收到对它的单击。为了正常工作,必须给覆盖div的每个子代赋予.hidden类,并在.hidden div中用类交换应用永远的元素。如果div有许多子元素(可能有他们自己的后代),这可能会变得非常复杂。

相反,当接收到单击时,将检查目标元素,以查看它是否有相关的类(main还是隐藏的)。如果是这样的话,脚本就会流向简单的类切换块。但是,如果没有,或者有不同的类名,do-while循环检查单击的父元素,以查看它是否包含在相关的(主类或隐藏类)中。循环继续搜索文档树,直到找到相关的元素,或者没有更多的父元素需要检查。

如果发现父类具有所需的类名,则对元素的引用将传递给类切换块。

代码语言:javascript
复制
  do {

    if (element && (element.className == 'overlay' || element.className == 'main')) {
      // foundElementClassName = element.className;
      break;
    } // end if;
    
    if (element.parentElement) {
      element = element.parentElement;
    } else {
      break;
    } 

  } while (element.className != "overlay" || element.className != "main");

下面的工作片段演示了该功能。在它中,三个div (彩色粉红色)有一个关联的(最初)隐藏的覆盖div,而第四个div没有关联的覆盖,应该忽略点击。

如果单击粉色div,则会出现特定的覆盖。无论该单击是由覆盖div本身接收到,还是由子元素或更深的后代(例如,单击覆盖的文本(在子h2元素中)仍然允许正确的.overlay div切换以再次隐藏它),覆盖上的任何位置都会取消它。

代码语言:javascript
复制
document.addEventListener('click', (event) => {
  let element = event.target;

  do {

    if (element && (element.className == 'overlay' || element.className == 'main')) {
      // foundElementClassName = element.className;
      break;
    } // end if;
    
    if (element.parentElement) {
      element = element.parentElement;
    } else {
      break;
    } 

  } while (element.className != "overlay" || element.className != "main");
  // end do-while loop;


// if a relevant element was found, the element object is stored in element variable;

   if (element.className == 'main') {
     element.parentElement.getElementsByClassName('overlay')[0].classList.remove('hidden');   
   } 

   if (element.className == 'overlay') {
     element.classList.add('hidden');   
   } 

}) // end click event listener;
代码语言:javascript
复制
.main {
  display: block;
  width: 50%;
  margin: 10px;
  border: 1px solid black;
  background: pink;
}


.overlay {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  top: 0px;
  left: 0px;
  width: 100%;
  min-height: 100%;
  bottom: auto;
  z-index: 1;
  background: rgba(255,255,0,0.7);
  padding: 20px;
}

.hidden {
    display: none;
} 

.other {
  display: block;
  width: 50%;
  margin: 10px;
  border: 1px solid black;
  background: yellow;
}
代码语言:javascript
复制
<div class="container">
  <div class="main">Content of div 1. Content of div 1. Content of div 1. Content of div 1. Content of div 1. Content of div 1. Content of div 1. Content of div 1 </div>
  <div class="overlay hidden"><h1>overlay for first pink div</h1> </div>
</div>

<div class="other">
some other content that doesn't have an associated overlay and that should ignore clicks.
</div>


<div class="container">
  <div class="main">Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2.</div>
  <div class="overlay hidden"><h1>overlay for SECOND  pink div</h1> </div>
</div>

<div class="container">
  <div class="main">Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. </div>
<div class="overlay hidden"><h1>overlay for Third pink div</h1> </div>
</div>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71685139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档