Modal opens whenever you click, even if you have the eventListener in an image

0

It's a simple thing that is taking me a lot of time.

I want to open a modal when clicking on any product image:

This is the HTML of the page:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>

    <link rel="icon" th:href="@{/favicon_heladeria.png}" />

    <link rel="stylesheet" th:href="@{/vendor/materialize/css/materialize.css}" />
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
    <link rel="stylesheet" th:href="@{/app.css}" />

    <title>Copito de Nieve | Home</title>
</head>
<body>
    <div class="navbar-fixed">
        <nav>
            <div class="container">
                <a th:href="@{/}" class="brand-logo">Heladeria</a>
                <a href="#" data-activates="mobile-nav" class="button-collapse right"><i class="material-icons">menu</i></a>
                <ul class="right hide-on-med-and-down">
                    <li class="active"><a th:href="@{/}">Home</a></li>
                    <li><a th:href="@{/gustos}">Gustos</a></li>
                    <li><a th:href="@{/ingresar}">Ingresar</a></li>
                </ul>
                <ul id="mobile-nav" class="side-nav">
                    <li class="active"><a th:href="@{/}">Home</a></li>
                    <li><a th:href="@{/gustos}">Gustos</a></li>
                    <li><a th:href="@{/ingresar}">Ingresar</a></li>
                </ul>
            </div>
        </nav>
    </div>
    <div class="search-bar container">
        <div class="row">
            <div class="col s12">
                <form action="#" method="get">
                    <div class="input-field">
                        <input name="q" type="search" placeholder="Buscar todos los helados..." required="required" autocomplete="off"/>
                        <i class="material-icons">search</i>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <div>
        <h2 class="mid-title">Productos</h2>
    </div>
    <div class="helados container">
        <div class="row">
            <div th:each="producto : ${productos}" class="col s12 l4">
                <img id="prod-img" th:src="@{'/images/' + ${producto.nombre} +'.png'}" />
                <p class="product-name" th:text="${producto.nombre}"></p>
                <p class="desc" th:text="${producto.descripcion}"></p>
            </div>
        </div>
    </div>
    <!-- Modal -->
    <div id="prodModal" class="modal">
        <div>
            <div class="modal-content">
                <h4 class="modal-title">Haga su pedido</h4>
                <p class="flavour" th:each="gusto : ${gustos}" th:text="${gusto.nombre}"></p>
            </div>
        </div>
    </div>

<script th:src="@{/vendor/jquery/jquery-1.11.3.js}"></script>
<script th:src="@{/vendor/materialize/js/materialize.js}"></script>
<script th:src="@{/home.js}"></script>
</body>
</html>

Clicking the modal opens with all the ice cream tastes of the database as expected, the problem is that it opens whenever you click anywhere on the page and not when you click on the images that is how it should be opened.

This is my JS:

 var prodImages = document.querySelectorAll('#prod-img');
console.log(prodImages);
prodImages.forEach(elm => {
      addEventListener('click', () => {
      var element = document.querySelector('#prodModal');
      var modal = M.Modal.init(element, {});
      modal.open();
    }, false);
});

I'm using the materialize library and I think the materialize.js is the one doing the mess.

    
asked by Nacho Zve De La Torre 21.11.2018 в 18:35
source

1 answer

2

Here you should not take IDs, if not classes

 var prodImages = document.querySelectorAll('#prod-img');

Finally, following your code, by not putting the listener in the element, by default it takes the window or document, so that was it:

prodImages.forEach(elm => {
      //agregar elm como el listener
      elm.addEventListener('click', (event) => {
      //recuerda detener la propagación si es necesario
      event.stopPropagation();
      var element = document.querySelector('#prodModal');
      var modal = M.Modal.init(element, {});
      modal.open();
    }, false);
});

Update: event.stopPropagation;

Stopping propagation applies when there are nested objects. Suppose we have a <div><img /></div>

And both div e img have events click however if you click inside img , this causes a click on div and may not be what you want.

stopPropagation() helps to prevent that, and to respect only the click in the designated area.

Here other things are involved, such as position, z-index, visibility, etc.

    
answered by 21.11.2018 / 18:45
source