David
David

Reputation: 409

Modal Box won't open on click

I wrote a script that opens up an enlarged image in a modal box when you click on the smaller one but for some reason when I try to click on the small image the modal box does not open. My website uses bootstrap but I have written my own CSS to create the modal as the bootstrap is not providing me with what I want.

I opened my inspector in Chrome and I got an error with my JavaScript

Uncaught TypeError: Cannot read property 'addEventListener' of null

This is on line 1 of the javascript

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';
});

Upvotes: 1

Views: 159

Answers (3)

biberman
biberman

Reputation: 5767

In your linked HTML-output there are multiple elements with the ID big. This is not valid and therefor you get the error. You should make sure that you have only unique IDs, then your code will work.

Furthermore: Please check double definitions like display and if it's really necessary to use so many !important statements.


If you have multiple elements like this you have to loop over the #big... images. To select all elements with an ID that begins with big you can use the attribute selector:

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

To style the associated div.bgmd you could select the previous element of the clicked anchor:

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

For closing via .xbutton you also have to loop over all of these buttons and style its grandparent (which is the associated div.bgmd):

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

Working example: (minified for demonstration, with some dummy data and without !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>

Upvotes: 0

user16257394
user16257394

Reputation:

You have the display property twice affecting the same element which is conflicting, you should only have display: none; without the !important rule. Also you have an excessive amount of !important rules, they're only necessary when you want to override other styles (typically ones that can't be directly edited)

Upvotes: 2

matt
matt

Reputation: 71

You set

.bgmd {
  display: none !important;
}

which overrides setting the style of the modal to display: flex.

Upvotes: 1

Related Questions