-1

I am novice in this web development field. That's why I am working with some online tutorial. Right now I'm working with a responsive navigation bar of w3 school. They have used inline JavaScript javascript:void(0) and onclick="myFunction()". But I want them all inside the external JavaScript file. How can I achieve this? Can any JavaScript expert please help me? Thanks in advance. I include all the codes that I fragment from that tutorial.

I have made the top responsive Navbar fixed with position property, width: 100%; and top: 0;

Here is the screen shot of problem that I want to get rid of

HTML LANGUAGE AS AN EXTERNAL FILE NAMED index.html

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Home Page</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="static/css/style-main.css">
</head>
<body>
</body>
<div class="topnav" id="myTopnav">
  <a href="#home" class="active">Home</a>
  <a href="#news">News</a>
  <a href="#contact">Contact</a>
  <div class="dropdown">
    <button class="dropbtn">Dropdown 
      <i class="fa fa-caret-down"></i>
    </button>
    <div class="dropdown-content">
      <a href="#">Link 1</a>
      <a href="#">Link 2</a>
      <a href="#">Link 3</a>
    </div>
  </div> 
  <a href="#about">About</a>
  <a href="javascript:void(0);" style="font-size:15px;" class="icon" onclick="myFunction()">&#9776;</a>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav with Dropdown</h2>
  <p>Resize the browser window to see how it works.</p>
  <p>Hover over the dropdown button to open the dropdown menu.</p>
</div>
<script src="static/js/main.js"></script>
</body>

</html>

I HAVE ALSO MADE AN EXTERNAL CSS FILE AND CONNECTED IT WITH MAIN HTML FILE.

body {
  margin:0;
  font-family:Arial;
}

.topnav {
  overflow: hidden;
  background-color: #333;
  position: fixed;
  width: 100%;
  top: 0;
}

.topnav a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 17px;
}

.active {
  background-color: #4CAF50;
  color: white;
}

.topnav .icon {
  display: none;
}

.dropdown {
  float: left;
  overflow: hidden;
}

.dropdown .dropbtn {
  font-size: 17px;    
  border: none;
  outline: none;
  color: white;
  padding: 14px 16px;
  background-color: inherit;
  font-family: inherit;
  margin: 0;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  z-index: 1;
}

.dropdown-content a {
  float: none;
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
  text-align: left;
}

.topnav a:hover, .dropdown:hover .dropbtn {
  background-color: #555;
  color: white;
}

.dropdown-content a:hover {
  background-color: #ddd;
  color: black;
}

.dropdown:hover .dropdown-content {
  display: block;
}

@media screen and (max-width: 600px) {
  .topnav a:not(:first-child), .dropdown .dropbtn {
    display: none;
  }
  .topnav a.icon {
    float: right;
    display: block;
  }
}

@media screen and (max-width: 600px) {
  .topnav.responsive {position: relative;}
  .topnav.responsive .icon {
    position: absolute;
    right: 0;
    top: 0;
  }
  .topnav.responsive a {
    float: none;
    display: block;
    text-align: left;
  }
  .topnav.responsive .dropdown {float: none;}
  .topnav.responsive .dropdown-content {position: relative;}
  .topnav.responsive .dropdown .dropbtn {
    display: block;
    width: 100%;
    text-align: left;
  }
}

I HAVE ALSO CREATED AN EXTERNAL FILE FOR JAVASCRIPT AND CONNECTED IT WITH MAIN HTML JUST ABOVE THE LAST BODY TAG BUT CAN'T GET RID OF INLINE JAVASCRIPT THOSE ARE javascript:void(0); onclick="myFunction()"

CAN I REWRITE THAT LINE (INSIDE HTML) IN THE EXTERNAL JAVASCRIPT FILE?

function myFunction() {
  var x = document.getElementById("myTopnav");
  if (x.className === "topnav") {
    x.className += " responsive";
  } else {
    x.className = "topnav";
  }
}

I expect that JavaScript file should be fully external. I don't want to use any inline JavaScript as per experts opinion. Besides I want to start with mobile first approach if possible. Thanks in advance.

Coduser
  • 301
  • 1
  • 2
  • 13

2 Answers2

3

You'd usually assign event listeners in javascript. Don't ever use inline javascript.

document.getElementById('foo').addEventListener('click', event => {
  // event holds the event's additional data 
  console.log('clicked');
});
<a id="foo">Click</a>
baao
  • 71,625
  • 17
  • 143
  • 203
  • A slight alternative: document.getElementById("foo").addEventListener("click", myFunction); – James P Aug 11 '19 at 20:49
  • Can you please literally rewrite the whole JavaScript? I'm totally confused as I can't understand well your example as I am new comer. Please don't give me example, better rewrite them if you have time. Thanks! – Coduser Aug 11 '19 at 23:08
  • Sure I can @Coduser. Do you want to pay via bitcoin or paypal? – baao Aug 12 '19 at 12:23
  • @chrispbacon I am really sorry sir. I am unable to pay you by any means. But I can be grateful to you for ever. I am just a kid who is learning every thing by overriding pen on every alphabet everyday. Please help me to solve this problem. Thanks! **Here is the image link what I want: https://i.stack.imgur.com/hoSMe.jpg – Coduser Aug 12 '19 at 12:52
0

The problem woth W3Schools is that their examples are often a little out of date. Also note they are not actually associated with W3C. MDN is a much better resource, though the tutorials can be a little more intimidating for the absolute novice.

As Chris mentions in their answer, you should be using event listeners. Also depending on your browser support requirements you should also be looking at other more modern approaches. Instead of manipulating the full class attribute, you should look at using classList, specifically toggle()

document.querySelector("#myTopnav [data-action=toggleMenu]").addEventListener("click", myFunction);

function myFunction() {  
  var nav = document.getElementById("myTopnav");
  console.log(nav);
  nav.classList.toggle("topnav");  
}
body {
  margin:0;
  font-family:Arial;
}

.topnav {
  overflow: hidden;
  background-color: #333;
  position: fixed;
  width: 100%;
  top: 0;
}

.topnav a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 17px;
}

.active {
  background-color: #4CAF50;
  color: white;
}

.topnav .icon {
  display: none;
}

.dropdown {
  float: left;
  overflow: hidden;
}

.dropdown .dropbtn {
  font-size: 17px;    
  border: none;
  outline: none;
  color: white;
  padding: 14px 16px;
  background-color: inherit;
  font-family: inherit;
  margin: 0;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  z-index: 1;
}

.dropdown-content a {
  float: none;
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
  text-align: left;
}

.topnav a:hover, .dropdown:hover .dropbtn {
  background-color: #555;
  color: white;
}

.dropdown-content a:hover {
  background-color: #ddd;
  color: black;
}

.dropdown:hover .dropdown-content {
  display: block;
}

@media screen and (max-width: 600px) {
  .topnav a:not(:first-child), .dropdown .dropbtn {
    display: none;
  }
  .topnav a.icon {
    /*float: right;*/
    display: block;
  }
}

@media screen and (max-width: 600px) {
  .topnav.responsive {position: relative;}
  .topnav.responsive .icon {
    position: absolute;
    right: 0;
    top: 0;
  }
  .topnav.responsive a {
    float: none;
    display: block;
    text-align: left;
  }
  .topnav.responsive .dropdown {float: none;}
  .topnav.responsive .dropdown-content {position: relative;}
  .topnav.responsive .dropdown .dropbtn {
    display: block;
    width: 100%;
    text-align: left;
  }
}
<div class="topnav" id="myTopnav">
  <a href="#home" class="active">Home</a>
  <a href="#news">News</a>
  <a href="#contact">Contact</a>
  <div class="dropdown">
    <button class="dropbtn">Dropdown 
      <i class="fa fa-caret-down"></i>
    </button>
    <div class="dropdown-content">
      <a href="#">Link 1</a>
      <a href="#">Link 2</a>
      <a href="#">Link 3</a>
    </div>
  </div> 
  <a href="#about">About</a>
  <a href="#" style="font-size:15px;" class="icon" data-action="toggleMenu">&#9776;</a>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav with Dropdown</h2>
  <p>Resize the browser window to see how it works.</p>
  <p>Hover over the dropdown button to open the dropdown menu.</p>
</div>
Jon P
  • 19,442
  • 8
  • 49
  • 72
  • Dear @Jon P I used your code and get this results. 1. On wide screen it looks okay https://cdn1.imggmi.com/uploads/2019/8/12/fb052bde9f888b419cd9b070a5c47d6c-full.png 2. On responsive menu hamburger icon appears adjacent to Home menu. https://cdn1.imggmi.com/uploads/2019/8/12/6752e68c5236bc21556bdc0524c2d758-full.png 3. After clicking the hamburger icon navigation menu breaks. https://cdn1.imggmi.com/uploads/2019/8/12/8d7fd30fb8fffca084fa45a3693ffeae-full.png So now how can I solve this problem? Could you please try a bit more? Thanks again for trying me. – Coduser Aug 12 '19 at 13:32
  • @Codeuser, with the responsive view, I'd commented out `float:right` as it was not playing nice with the internal nav of the StackSnippet. Uncomment that line and the alignment will be fixed. The issue after clicking is a whole different issue and should be addressed in a brand new question. – Jon P Aug 12 '19 at 22:09