单页应用程序 div 未按预期显示

Single Page Application div not displaying as expected

我的目标是了解为什么在加载页面时没有显示带有产品 ID 的 div。

我希望产品 div 默认显示为网格,因为这是它在样式表中的设置。实际上,产品 div 直到附加到搜索字段的提交事件被触发后才会显示。

我无法理解为什么 product 在 productUpdate() 函数底部的 javascript 中被引用,即使它实际上从未定义为 const 或 var。

if(!flag_error){
                product.style.display = "grid";
                hint.style.display = "none";
                forwardBtn.style.display = "inline";
                backBtn.style.display = "inline";

我已进行了大量尝试,以准确了解哪一段代码可以打开和关闭产品 div。代码在下面,我也上传到http://va.ogs17.brighton.domains/.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>V&A online item search</title>
    <link rel="stylesheet" type="text/css" href="index.css">
    <script src="index.js"></script>
</head>
<body>
    <div class="main-container">
        <div class="welcome-container">
            <h1>Search the V&A Online</h1>
            <h2>Start searching now by entering in a keyword in the searchbar below</h2>
        </div>
        
        <div id="search-container">
            <form>
                <fieldset>
                    <legend><strong>Search for an item here:</strong></legend>
                    <p>The V&A Museum is the world's leading museum of of art, design and performance, housing a permanent collection of over 2.27 million objects. You can search for them here.</p>
                    <img class="info-icon" src="info-icon2.png">
                    <p class="search-hint"> Stuck for ideas? Try searching for an object like a throne or vase. You could try a person or a place. Is there certain techniques or materials you are loooking for? Any keyword will work, even dragons!</p>
                    <label for="search-bar"></label>
                    <input id="search-bar" type="search">
                    <input type="submit" value="Search" href="#product-top">
                    <div class="nav-btn-container">
                        <a href="" type="button" class="back-button">Previous Item</a>
                        <a href="" type="button" class="forward-button">Next Item</a>
                        <span id="hint">This is the last item in the list.</span>
                    </div>
                </fieldset>
            </form>
        </div>

        <div id="loading">
            <img class="loading-img" src="Bean Eater-1s-200px.gif">     
        </div>

        <div id="product">
            <a id="product-top"></a>
            <div class="title">
                <h2 class="">No title found</h2>
            </div>
            <div class="photo-container"><img class="photo" src="image-not-found.png"></div>
            <div class="information">
                <p class="artist">Artist: Unknown</p>
                <p class="object">Object: Unkown</p>
                <p class="date_text">Date: Unkown</p>
                <p class="place">Place: Unkown</p>
                <p class="location">Location: Unknown</p>
                <p class="object_number">Object Number: Unkown</p>
                <p class="museum_number">Museum Number Token: Unkown</p>
            </div>
        </div>

        

        <div id="success">
            <p>Success!</p>
            <!-- Link back to empty form -->
        </div>

        <div id="error">
            <p>error...</p>
            <!-- Link back to empty form -->
        </div>
    </div>
</body>
</html>

CSS

body {
    font-family:'Roboto',sans-serif;
    padding: 32px;
    margin: 0;
    background-image: url("vanda-front.jpg");
    background-size: 100%;
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-position: center;
}

img {
    width: 100%;
}

.welcome-container {
    color:honeydew;
    text-shadow: black;
    margin-top: 2rem;
    margin-left: 3rem;
    margin-bottom: 18rem;
}

.welcome-container h1 {
    font-size: 3.5rem;
}

fieldset {
    padding: 20px;
    width: 60%;
    margin: auto;
    background-color: black;
    opacity: 0.9;
    border-style: none;
}

fieldset label, p, legend {
    color: blanchedalmond;
}

fieldset img{
    max-width: 1rem;
}

/* Button style partly by Frederico Dossena fdossena.com/?p=html5cool/buttons/i.frag */
.nav-btn-container a, input[type=submit] {
    padding:0.35em 1.2em;
    border:0.1em solid #FFFFFF;
    margin:0 0.3em 0.3em 0;
    border-radius:0.12em;
    box-sizing: border-box;
    background-color: black;
    text-decoration:none;
    font-weight:300;
    color:#FFFFFF;
    text-align:center;
    transition: all 0.2s;
    cursor: pointer;
    
}

input[type=submit] {
    font-size: 1.5rem;
}

input[type=search] {
    /* padding:0.35em 1.2em; */
    border:0.1em solid #FFFFFF;
    margin:0 0.3em 0.3em 0;
    border-radius:0.12em;
    box-sizing: border-box;
    text-decoration:none;
    /* min-height: 2.5rem; */
    font-size: 3rem;
}

.nav-btn-container a:hover, input[type=submit]:hover {
    color:#000000;
    background-color:#FFFFFF;
}

.nav-btn-container {
    margin-top: 1.2rem;
}

.search-hint{
    display: none;
}

#product {
    display: grid;
    grid-template-columns: repeat(9, 1fr);
    grid-template-rows: 10rem 1fr;
    gap: 0.2rem;
    padding: 10px;
    box-sizing: border-box;
    /* in the internal divs use grid-column-start and grid-row-end: ;
    basic vid here - https://www.youtube.com/watch?v=Y9rHsdCxU8Q */

}

.photo-container {
    opacity: 1;
}

/* text-overflow code by Jokesterfr whosebug.com/questions/7711490/prevent-text-from-overflowing-a-padded-container-in-html */
.title {
    background-color: black;
    opacity: 0.9;
    border-style: none;
    color: blanchedalmond;
    font-size: 3rem;
    overflow: hidden;
    border-left:1em solid transparent;
    border-right:1em solid transparent;
    text-overflow: ellipsis;
}

.information {
    background-color: black;
    opacity: 0.9;
    border-style: none;
    color: blanchedalmond;
}

.back-button, .forward-button {
    display: none;
}

.forward-button{
    float: right;
}

.title {
    grid-column-start: 1;
    grid-column-end: 10;
    grid-row-start: 1;
    grid-row-end: 1;
}

.photo-container {
    grid-column-start: 1;
    grid-column-end: 6;
    grid-row-start: 2;
    grid-row-end: 3;
}

.information{
    grid-column-start:6;
    grid-column-end: 10;
    grid-row-start: 2;
    grid-row-end: 3;
}

input {
    display: block;
    Margin: 5px;
    width: 100%;
}



#hint {
    color:red;
    display: none;
}

#success, #error, #product {
    text-align: center;
    display: none;
}

.loading-img{
    display: none;
}

/* Android A70 */
/* @media(min-width: 751px) and (max-width: 1080px) {
    body{background-color: red;}
} */

/* iPhone 6 */
@media(max-width: 750px) {
    /* body{
        background-color: orangered;
        background-image: none;
    } */

    .welcome-container {
        margin-bottom: 12rem;
    }

    .title {
        grid-column-start: 1;
        grid-column-end: 10;
        grid-row-start: 1;
        grid-row-end: 1;
    }
    
    .photo-container {
        grid-column-start: 1;
        grid-column-end: 10;
        grid-row-start: 2;
        grid-row-end: 3;
    }
    
    .information{
        grid-column-start:1;
        grid-column-end: 10;
        grid-row-start: 3;
        grid-row-end: 4;
    }

}

JavaScript

window.addEventListener('load', function() {
    //global varaibles

    var searchHint = document.querySelector('.search-hint');
    //by defualt, the first item is always shown. Position is incremented using next and previous buttons to show new items.
    var position = 0;
    var maxCap = 45;
    //code by Ry whosebug.com/questions/21147832/convert-camel-case-to-human-readable-string
    function toCapitalizedWords(name) {
        var words = name.match(/[A-Za-z][a-z]*/g) || [];
    
        return words.map(capitalize).join(" ");
    }
    
    function capitalize(word) {
        return word.charAt(0).toUpperCase() + word.substring(1);
    }

    function productUpdate(step) {
        if(position + step >= maxCap - 1){
            //show hint
            var hint = document.querySelector("#hint");
            hint.style.display = "inline";
        }
        else {
            // var loading = document.querySelector('#loading');
            
            position += step;
            var flag_error = false;

            // get all form fields
            var search = document.querySelector("#search-bar").value.trim();

            var hint = document.querySelector("#hint");

            var backBtn = document.querySelector(".back-button");
            var forwardBtn = document.querySelector(".forward-button");

            var productTitle = document.querySelector(".title");
            var productPhoto = document.querySelector(".photo");
            var productInformation = document.querySelectorAll(".information");

            var xhrSearch = new XMLHttpRequest();
            xhrSearch.onreadystatechange = function() {
                
                //readystate 4 means oporation is complete developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState
                //status 200 means OK
                if(this.readyState == 4 && this.status == 200) {
                    console.log(search);
                    //TODO
                    //if there is response text, do this, if not, display hint saying product not found
                    const result = JSON.parse(xhrSearch.responseText);
                    productTitle.textContent = result.records[position].fields.title;

                    //js loops god post whosebug.com/questions/3010840/loop-through-an-array-in-javascript

                    for (let item of productInformation[0].children) {
                        console.log(item);
                        itemClass = item.className;
                        item.textContent = toCapitalizedWords(itemClass) + ": " + result.records[position].fields[itemClass];
                    }

                    var xhrFullRecord = new XMLHttpRequest();
                    xhrFullRecord.onreadystatechange = function() {
                        if(this.readyState == 4 && this.status == 200) {
                            const fullRecordResult = JSON.parse(xhrFullRecord.responseText);
                            productPhoto.src = "https://framemark.vam.ac.uk/collections/" + fullRecordResult[0].fields.image_set[0].fields.image_id + "/full/735,/0/default.jpg";
                        }
                    }
                    fullRecordUrl = "https://www.vam.ac.uk/api/json/museumobject/" + result.records[position].fields.object_number;
                    xhrFullRecord.open("GET", fullRecordUrl);
                    xhrFullRecord.send();
                }
            };
            //what happens to URL if £$&^%$£ is put in search?
            url = "https://www.vam.ac.uk/api/json/museumobject/search?q=" + search + "&limit=" + maxCap;
            //do I want any other params here?
            xhrSearch.open("GET", url);
            xhrSearch.send();

            if(!flag_error){
                //setTimeout(loading.style.display = "none", 5000);
                product.style.display = "grid";
                hint.style.display = "none";
                forwardBtn.style.display = "inline";
                backBtn.style.display = "inline";
            }
        }
    }
    
    document.querySelector('#search-container').addEventListener("submit", function(evt){
        // stop page reload default action
        evt.preventDefault();
        position = 0;
        productUpdate(0);
    })

    document.querySelector('.info-icon').addEventListener("click", function(evt){
        // stop page reload default action
        // evt.preventDefault();
        if(searchHint.style.display == "inline"){
            searchHint.style.display = "none";
        } else {
            searchHint.style.display = "inline";
        }
    })

    document.querySelector('.back-button').addEventListener("click", function(evt){
        // stop page reload default action
        evt.preventDefault();
        productUpdate(-1);
    })

    document.querySelector('.forward-button').addEventListener("click", function(evt){
        // stop page reload default action
        evt.preventDefault();
        productUpdate(1);
    })

    function displayLoading(){
        var loadIcon = document.querySelector(".loadingImg");
        product.style.display = "none";
        loadIcon.style.display = "inline";

    }

});

你有 onload 事件但是 onload 没有调用 productUpdate()

window.addEventListener('load', function() {
     ........
     ........
    // append this line before closing
    productUpdate(0);
})