Search code examples
javascriptgetelementbyid

What should i Use instead of document.getElementById for this to work


Hello I have a problem with my javascript. Somebody already informed me to not use document.getElementById in my code but what should i use instead so it works and should i change something else too in my code?

I'm making a website where users can upload posts to the website.

            echo '<a class="annons-tb">
              <div style="background-image: url(img/gallery/'.$row["imgFullNameGallery"].');"></div>
              <h3>'.$row["titleGallery"].'</h3>
              <p>'.$row["descGallery"].'</p>
                <input type="button" class="button1" name="id" value="Visa Mer Info" onclick="on()"></a>
              <div id="overlay" onclick="off()">
              <div id="text">
              <img src="data:img/gallery/jpeg;base64,'.base64_encode($row["imgFullNameGallery"]).'" width="250" height="250">
              <h3>'.$row["titleGallery"].'</h3>
              <p1>Beskrivning: '.$row["descGallery"].'</p1>
              <div id=p-delen">
              <br />
              <p>Pris: '.$row["prisGallery"].'</p>
              <p>Namn: '.$row["namnGallery"].'</p>
              <p>Mail: '.$row["emailGallery"].'</p>
              <p>TelefonNummer: '.$row["nummerGallery"].'</p>
              </div>
              </div></div><script>
                function on() {
                  document.getElementById("overlay").style.display = "block";
                }

                function off() {
                  document.getElementById("overlay").style.display = "none";
                }
                </script>';

        }
    }
    ?>
      </div>

I have already made an overlay effect so when you click on a button you can view more info about the post, but now when you press the button it always shows the extra info for the first post.


Solution

  • If you assigned an event listener to both types of elements ( input[type='button'] and div ) but remove the ID attribute- replace with a class of the same value for example then you can easily monitor for events being triggered upon any/all like this.

    <script>
        document.addEventListener('DOMContentLoaded',()=>{
            Array.prototype.slice.call( document.querySelectorAll( 'div.overlay, button.button1' ) ).forEach( function(node){
                node.addEventListener('click', function(e){
                    e.preventDefault();
                    switch( this.tagName ){
                        case 'INPUT':
                            this.style.display='block';
                        break;
                        case 'DIV':
                            this.style.display='none';
                        break;
                    }
                });
            });
        });
    </script>
    

    The above uses the forEach method to iterate through the collection of nodes found using document.querySelectorAll - however some browsers do not support this method being used on a nodelist hence using the Array.prototype.slice.call to convert the nodelist to an array.

    The supporting HTML/PHP ( essentially the same but ID attributes have been changed for classes and it has been indented properly )

        echo '
            <a class="annons-tb">
                <div style="background-image: url(img/gallery/'.$row["imgFullNameGallery"].');"></div>
                <h3>'.$row["titleGallery"].'</h3>
                <p>'.$row["descGallery"].'</p>
                <input type="button" class="button1" name="id" value="Visa Mer Info">
            </a>
            <div class="overlay">
                <div class="text">
                    <img src="data:img/gallery/jpeg;base64,'.base64_encode($row["imgFullNameGallery"]).'" width="250" height="250" />
                    <h3>'.$row["titleGallery"].'</h3>
                    <p1>Beskrivning: '.$row["descGallery"].'</p1>
                    <div class="p-delen">
                        <br />
                        <p>Pris: '.$row["prisGallery"].'</p>
                        <p>Namn: '.$row["namnGallery"].'</p>
                        <p>Mail: '.$row["emailGallery"].'</p>
                        <p>TelefonNummer: '.$row["nummerGallery"].'</p>
                    </div>
                </div>
            </div>';
        }
    }
    ?>
      </div>
    

    I made a couple of corrections to the above ( which was not tested when written - sorry ) and have put together a demo. You'll notice that the javascript appears before the HTML body - the event listeners get registed because of the event listener already assigned to the body which essentially waits for all the DOM elements to be rendered before trying to bind to specific elements. In essence you can do like this or after the repeated content

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset='utf-8' />
            <title>Alternative for document.getElementById</title>
            <script>
                /*
                    I had made a slight error with the selector - it should be input.button1
                    rather than button.button1
    
                    The action invoked by the button also needed to be changed - it now
                    navigates up the DOM tree to it's parent then to the parent's sibling
                */
                document.addEventListener('DOMContentLoaded',()=>{
                    Array.prototype.slice.call( document.querySelectorAll( 'div.overlay, input.button1' ) ).forEach( function(node){
                        node.addEventListener('click', function(e){
                            e.preventDefault();
                            switch( this.tagName ){
                                case 'INPUT':
                                    this.parentNode.nextElementSibling.style.display='block';
                                break;
                                case 'DIV':
                                    this.style.display='none';
                                break;
                            }
                        });
                    });
                });
            </script>
            <style>
                html *{box-sizing:border-box;}
                #wrapper{width:100%;height:100vh;margin:0;padding:0;}
                #wrapper > a.annons-tb{ padding:1rem;height:5rem;width:100%;display:inline-block; }
                #wrapper > div.overlay{ background:whitesmoke;border:1px dotted rgba(100,100,100,0.25);padding:1rem;margin:1rem auto;display:none }
            </style>
        </head>
        <body>
            <div id='wrapper'>
            <?php
                /*
                    To emulate the db call
                    a static array can be used
                */
                $rs=array(
                    array(
                        'titleGallery'=>'Mega Gallery 1',
                        'descGallery'=>'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed orci ipsum, commodo pulvinar rutrum non, congue ut justo. Phasellus nec scelerisque diam, ut cursus felis.',
                        'imgFullNameGallery'=>'Gallery 1',
                        'prisGallery'=>'abc',
                        'namnGallery'=>'bob',
                        'emailGallery'=>'gal1@example.com',
                        'nummerGallery'=>'0141 353 3780'
                    ),
                    array(
                        'titleGallery'=>'Super Gallery 2',
                        'descGallery'=>'urabitur tristique libero non lorem blandit eleifend. Sed gravida ut purus vitae dignissim. Aenean pellentesque, diam ac euismod eleifend, lorem mauris dapibus lorem, id fermentum augue nisi at nisl.',
                        'imgFullNameGallery'=>'Gallery 2',
                        'prisGallery'=>'def',
                        'namnGallery'=>'rita',
                        'emailGallery'=>'gal2@example.com',
                        'nummerGallery'=>'0131 551 7488'
                    ),
                    array(
                        'titleGallery'=>'Awesome Gallery 3',
                        'descGallery'=>'Morbi ultrices nisl elementum augue sagittis porttitor. Nulla posuere molestie quam posuere tempus. Sed convallis metus mi, quis faucibus est lobortis sed.',
                        'imgFullNameGallery'=>'Gallery 3',
                        'prisGallery'=>'ghi',
                        'namnGallery'=>'sue',
                        'emailGallery'=>'gal3@example.com',
                        'nummerGallery'=>'01307 462 059'
                    )
                );
                /*
                    for the static array a foreach rather than while loop
                    but essentially the same...
    
                    I prefer use printf to constantly escaping out from the html to
                    include the variable but again essentially the same as the original
                    except for the lack of ID attributes
                */
                foreach( $rs as $row ){
                    printf('
                        <a class="annons-tb">
                            <div style="background-image: url(img/gallery/%s);"></div>
                            <h3>%s</h3>
                            <p>%s</p>
                            <input type="button" class="button1" name="id" value="Visa Mer Info">
                        </a>
                        <div class="overlay">
                            <div class="text">
                                <img src="data:img/gallery/jpeg;base64,%s" width="250" height="250" />
                                <h3>%s</h3>
                                <p1>Beskrivning: %s</p1>
                                <div class="p-delen">
                                    <br />
                                    <p>Pris: %s</p>
                                    <p>Namn: %s</p>
                                    <p>Mail: %s</p>
                                    <p>TelefonNummer: %s</p>
                                </div>
                            </div>
                        </div>',
    
                        $row['imgFullNameGallery'],
                        $row['titleGallery'],
                        $row['descGallery'],
                        $row['imgFullNameGallery'],
                        $row['titleGallery'],
                        $row['descGallery'],
                        $row['prisGallery'],
                        $row['namnGallery'],
                        $row['emailGallery'],
                        $row['nummerGallery']
                    );
                }
    
            ?>
            </div>
        </body>
    </html>