简体   繁体   中英

Keep getting “cannot read property style of null” error

I am working on my own website and not good with codes yet. When I am scrolling down I want to appear another content of the navbar and when I am on the top, original navbar is appearing. I want this to be done in pure JavaScript with no libraries or framewokrs. Please see codes below and I know that codes are not organised. I will do that later on.


    var nav = document.querySelector("nav");
var hide = document.querySelector(".hide");
var appear = document.querySelector(".appear")

window.onscroll = function(){
    if(document.body.scrollTop > 70){
        hide.style.display = "block";
        appear.style.display = "none"
    } else {
        hide.style.display = "none";
        appear.style.display = "block"
    }
}


    nav{
    list-style-type: none;
    text-align: center;
    background-color: #3FA9A5;
    position: sticky;
    top: 0;
}

.hide{
    font-size: 70px;
    font-family: 'Long Cang', cursive;
    display: block;
}
.appear{
    height: 70px;
    display: none;
}

.appear img{
    width: 210px;

}

ul{
    margin: 0 auto;
    padding: 0;
}

body{
    margin: 0;
}

.container{
    max-width: 1080px;
    width: 95%;
    margin: 10px auto;
    display: grid;
    grid-template-columns: 25% 50% 25%;

}


.text{
    text-align: center;
}


.profile {
    border: 1px solid black;
    padding: 0 10px 20px 10px;

}

#main{
    width: 100%;
}

.post{
    margin-left: 4.165%;
}

#image{
    width: 100%;
}

#post-divide{
    margin-left: 10px;
    margin-right: 10px;
}

.comments{
    width: 100%;
    margin-top: 68.5px;
    padding-bottom: 293.5px;
    border: 1px solid black;
}
 h2{
    text-align: center;
 }

 .center{
    grid-column: 2;
 }



        <link rel="stylesheet" type="text/css" href="test.css">
    <link href="https://fonts.googleapis.com/css?family=Indie+Flower|Long+Cang&display=swap" rel="stylesheet">
    <title>test</title>
</head>
<body>
<nav>
    <ul>
        <li class="hide">Unknown</li>
        <li class="appear"><img src="cat.png"></li>
    </ul>
</nav>

<div class="container">

        <div class="col-1">
            <div class="profile text">
                <img id="main" src="https://data.whicdn.com/images/86629641/superthumb.jpg?t=1384568664">
                <hr>
                <p>12 posts</p>
                <p>instagram</p>
                <button>Subscribe!</button>
            </div>
        </div>

        <div class="col-1">
            <div class="post">
                <h2>TITLE</h2>
                <div>
                    <img id="image" src="https://i.pinimg.com/originals/76/d4/8c/76d48cb2928845dfcfab697ac7cbcf1c.jpg">
                </div>
                <hr id="post-divide">
            </div>
        </div>

        <div class="col-1">
            <div class="comments text"></div>
        </div>

        <div class="col-1 center">
            <div class="post">
                <h2>TITLE</h2>
                <div>
                    <img id="image" src="https://i.pinimg.com/originals/76/d4/8c/76d48cb2928845dfcfab697ac7cbcf1c.jpg">
                </div>
                <hr id="post-divide">
            </div>
        </div>

        <div class="col-1">
            <div class="comments text"></div>
        </div>
</div>

I think I should add something to the JS code but don't know why Would be thankful if you would advise me how could I write HTML/CSS code so I do not have to create 2 navbars if it is possible

The following instruction:

document.querySelector("hide");

Will query for elements like:

<hide></hide>

Since plain selectors without prefix ( div , header , span ) will query for the whole element tags, not for classes or attrbitues.

Maybe you meant to query for the class, using the . :

document.querySelector(".hide");
var hide = document.querySelector(".hide");
var appear = document.querySelector(".appear")

So you should use class selector

You are using "hide" and "appear" as selectors but they do not exist in your HTML.

Use ".hide" and ".appear" in your querySelector instead.

 var hide = document.querySelector(".hide"); 
 var appear = document.querySelector(".appear");

Since both navbars have a static data, I would suggest to keep both of them and follow with answers of guys, that suggested to update querySelector param. Or you can hide/show the data inside of navbar (in your case it's only ul element) and leave the whole navbar always visible. So you can put classes appear/hide on ul element instea of navbar and then in JS get them with document.querySelector('.navbar.hide') and document.querySelector('.navbar.appear') .

Using framework/library will definitely simplify it. However, if you still want to have only one navbar in pure js/html/css (or it's data just dynamic) I would probably do like this:

HTML:

<nav class="navbar">
  <ul>
    <li><img src="cat.png"></li>
  </ul>
</nav>

somewhere in JS:

var navbarUl = document.querySelector('.navbar ul');
window.onscroll = function() {
  if (document.body.scrollTop > 70) {
    navbarUl.innerHtml = '';
    navbarUl.appendChild(getTopNavbarHTML);
  } else {
    navbarUl.innerHtml = '';
    navbarUl.appendChild(getNavbarHTML);
  }
}

getNavbarHTML and getTopNavbarHTML - will return documentFragment with li elements, see for details https://www.w3schools.com/jsref/met_document_createdocumentfragment.asp

But changing DOM during a scroll event can drastically decrease performance of a web app

Thanks for help to all of you. Now everything works and i changed code a little. Now I have other problem that when I go back to the Top, first navbar doesn't shows back and it still stays on second navbar style. Also when I start scrolling down, second navbar style shows up as soon as I scroll down, but I want it to appear when first is totally invisible which height is 70px

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM