【问题标题】:Modal Box won't open on click模态框不会在点击时打开
【发布时间】:2021-07-03 07:10:35
【问题描述】:

我编写了一个脚本,当您单击较小的图像时,它会在模态框中打开放大的图像,但由于某种原因,当我尝试单击小图像时,模态框没有打开。我的网站使用引导程序,但我已经编写了自己的 CSS 来创建模式,因为引导程序没有为我提供我想要的。

我在 Chrome 中打开了我的检查器,但我的 JavaScript 出错了

未捕获的类型错误:无法读取 null 的属性“addEventListener”

这是在 javascript 的第 1 行

HTML&PHP

<div class="bgmd">
    <div class="ctmod">
        <div class="xbutton">&times</div>
        <?php
            echo "<img src='images/car22.jpg'/>";//Large Image
        ?>
    </div>
</div>
<?php
echo "<a href='#' id='big'><img src='images/car".$id.".jpg' class='img-thumbnail center-block'/></a>";//Smaller Image

CSS

.bgmd{
    width: 100% !important;
    height: 100% !important;
    background-color: rgba(0, 0, 0, 0.7) !important;
    position: absolute !important;
    top: 0 !important;
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    display: none !important;
}
.ctmod{
    width: 500px !important;
    height: 300px !important;
    background-color: white !important;
    border-radius: 4px !important;
    text-align: center !important;
    position: relative !important;
}
.xbutton{
    position: absolute !important;
    top: 0 !important;
    right: 14px !important;
    font-size: 42px !important;
    transform: rotate(45deg) !important;
    cursor: pointer !important;
}

JAVASCRIPT

document.getElementById('big').addEventListener('click', function() {
    document.querySelector('.bgmd').style.display = 'flex';
});

document.querySelector('.xbutton').addEventListener('click', function() {
    document.querySelector('.bgmd').style.display = 'none';
});

【问题讨论】:

  • 似乎document.getElementById('big')document.querySelector('.xbutton')null。可以贴出生成的 HTML 代码吗?
  • 因为错误发生在第 1 行,所以应该是 document.getElementById('big') 为空...

标签: javascript html css


【解决方案1】:

您有两次影响同一元素的 display 属性,这是冲突的,您应该只有 display: none; 而没有 !important 规则。此外,您还有过多的 !important 规则,仅当您想要覆盖其他样式(通常是无法直接编辑的样式)时才需要它们

【讨论】:

    【解决方案2】:

    你设置

    .bgmd {
      display: none !important;
    }
    

    覆盖将模式的样式设置为display: flex

    【讨论】:

    • 如果我把它拿出来,它会在我加载页面时显示为模态
    • 是的,因为你之前也有display: flex !important; 3 行。这也阻碍了 JS 更改样式显示属性。仅设置 display: none 以最初隐藏它 - 不设置 !important
    • 我创建了一个CodePen,它显示了您示例中的基本功能。也许你应该考虑使用一些现有的脚本来提供有用的功能,比如a11y-dialog
    【解决方案3】:

    在您链接的 HTML 输出中,有多个 ID 为 big 的元素。这是无效的,因此您会收到错误消息。您应该确保您只有唯一的 ID,然后您的代码才能正常工作。

    此外:请检查像 display 这样的双重定义,如果真的有必要使用这么多 !important 语句。


    如果您有多个这样的元素,则必须循环遍历 #big... 图像。要选择 ID 以 big 开头的所有元素,您可以使用属性选择器:

    var img_triggers = document.querySelectorAll('a[id^="big"]');
    

    要设置关联div.bgmd 的样式,您可以选择单击锚点的前一个元素:

    this.previousElementSibling.style.display = 'flex';
    

    要通过.xbutton 关闭,您还必须遍历所有这些按钮并为其祖父设置样式(即关联的div.bgmd):

    this.previousElementSibling.style.display = 'flex';
    

    工作示例:为演示而缩小,带有一些虚拟数据,没有!important

    var img_triggers = document.querySelectorAll('a[id^="big"]');
    for (let i = 0; i < img_triggers.length; i++) {
      img_triggers[i].addEventListener('click', function() {
        this.previousElementSibling.style.display = 'flex';
      });
    }
    
    var buttons = document.querySelectorAll('.xbutton');
    for (let i = 0; i < buttons.length; i++) {
      buttons[i].addEventListener('click', function() {
        this.parentElement.parentElement.style.display = 'none';
      });
    }
    .bgmd {
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.7);
      position: absolute;
      top: 0;
      justify-content: center;
      align-items: center;
      display: none;
    }
    
    .ctmod {
      width: 250px;
      height: 150px;
      background-color: white;
      border-radius: 4px;
      text-align: center;
      position: relative;
    }
    
    .xbutton {
      position: absolute;
      top: 0;
      right: 14px;
      font-size: 42px;
      transform: rotate(45deg);
      cursor: pointer;
    }
    <div class="bgmd">
      <div class="ctmod">
        <div class="xbutton">&times</div>
        <img src='https://picsum.photos/id/1/150' />
      </div>
    </div>
    <a href='#' id='big1'>
      <img src='https://picsum.photos/id/1/50' class='img-thumbnail center-block' />
    </a>
    
    <div class="bgmd">
      <div class="ctmod">
        <div class="xbutton">&times</div>
        <img src='https://picsum.photos/id/2/150' />
      </div>
    </div>
    <a href='#' id='big2'>
      <img src='https://picsum.photos/id/2/50' class='img-thumbnail center-block' />
    </a>
    
    <div class="bgmd">
      <div class="ctmod">
        <div class="xbutton">&times</div>
        <img src='https://picsum.photos/id/3/150' />
      </div>
    </div>
    <a href='#' id='big3'>
      <img src='https://picsum.photos/id/3/50' class='img-thumbnail center-block' />
    </a>

    【讨论】:

    • ID为big的多个元素的原因是它是由php循环生成的。它的列表与图片。有没有其他方法可以做到这一点?
    • 您可以将循环计数添加到 ID。例如:'&lt;... id="big' . $i . '" ...&gt;'
    • 我能够使用用于链接部分的$id 变量。我认为这满足了唯一 ID 问题。但是我仍然无法让它工作。 echo "&lt;a href='#' id='big".$id."'&gt;&lt;img src='images/car".$id.".jpg' class='img-thumbnail center-block'/&gt;&lt;/a&gt;";//
    • 小提琴不适用于 php 代码。但它会使用您更新的 php 代码生成的 html...
    • 我最终让它工作了。我认为与某些 javascript 存在某种类型的冲突,导致某些下拉菜单适用于过滤。我重写了那部分,模态框现在很好用。
    猜你喜欢
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多