Show/hide password onClick of button using Javascript only

You are binding click event every time you click a button. You don't want multiple event handlers. Plus you are redefining var pwShown = 0 on every click so you can never revert input state (pwShown stays the same).

Remove onclick attribute and bind click event with addEventListener:

function show() {
    var p = document.getElementById('pwd');
    p.setAttribute('type', 'text');
}

function hide() {
    var p = document.getElementById('pwd');
    p.setAttribute('type', 'password');
}

var pwShown = 0;

document.getElementById("eye").addEventListener("click", function () {
    if (pwShown == 0) {
        pwShown = 1;
        show();
    } else {
        pwShown = 0;
        hide();
    }
}, false);
<input type="password" placeholder="Password" id="pwd" class="masked" name="password" />
<button type="button" id="eye">
    <img src="https://cdn0.iconfinder.com/data/icons/feather/96/eye-16.png" alt="eye" />
</button>
Ameen Ra'is

The easiest way is using a button with an onclick attribute that toggles the type of the input.

<input type="password" id="password" value="myPassword"/>
<button onclick="if (password.type == 'text') password.type = 'password';
  else password.type = 'text';">toggle</button>

You don't need to maintain one extra "pwShown" variable to decide whether to show text or hide it. All you need to do is to examine "type" attribute of "pwd" element as below :

Working Example

JavaScript :

document.getElementById("eye").addEventListener("click", function(e){
        var pwd = document.getElementById("pwd");
        if(pwd.getAttribute("type")=="password"){
            pwd.setAttribute("type","text");
        } else {
            pwd.setAttribute("type","password");
        }
    });

HTML :

<input type="password" placeholder="Password" id="pwd" class="masked" name="password" />
        <button type="button" id="eye">
            <img src="eye.png" alt="eye"/>
         </button>

Follow these steps: Download the images given below. Make a folder. Add your html file and the images in the same folder. Replace the value of "b.src" in javascript as well as in your html code accordingly.

Images : Images Images

function show() {
  var a = document.getElementById("pwd");
  var b = document.getElementById("EYE");
  if (a.type == "password") {
    a.type = "text";
    b.src = "https://i.stack.imgur.com/waw4z.png";
  } else {
    a.type = "password";
    b.src = "https://i.stack.imgur.com/Oyk1g.png";
  }
}
<input type="password" id="pwd">
<button onclick="show()"><img src="https://i.stack.imgur.com/Oyk1g.png" id="EYE"></button>

Based on what you wrote, you are adding the event both in html and in javascript (inside showHide function). May be you can change your js code from what you have, to:

function showHide()
{
  var input = document.getElementById("pwd");
  if (input.getAttribute("type") === "password") {
    show();
  } else {
    hide();
  }
}

The variable "pwShown" is misspelled (as "pwShow") in the else section of your Javascript code. Therefore, pwShown never gets reset to 0.

This is an improvement upon Tunaki's answer. We don't even care to check which state the form field is in already, because this will be entirely determined by the state of the mouse. This allows the password to be only momentarily viewed (only as long as the mouse button is held down over the button.)

<html>
<head>
    <title>Visible Password Test</title>
</head>

<body>
Password : <input type="password" name="password" id="password" />

<button type="button" id="eye" title="Did you enter your password correctly?" 
    onmousedown="password.type='text';" 
    onmouseup="password.type='password';" 
    onmouseout="password.type='password';">Peek at Password</button>

</body>
</html>

JQuery solution from my code: (just change the IDs).

$(document).ready(function () {
        $("#eye").click(function () {
            if ($("#password").attr("type") === "password") {
                $("#password").attr("type", "text");
            } else {
                $("#password").attr("type", "password");
            }
        });
  });

In your code everytime when you call showHide() function, pwShown variable is set to 0.

You need to declare pwShown variable as global one.

var pwShown = 0;
function showHide()
{
 ...
}
function myFunction() {
    var x = document.getElementById("myInput");
    if (x.type === "password") {
        x.type = "text";
    } else {
        x.type = "password";
    }
} 

see also https://www.w3schools.com/howto/howto_js_toggle_password.asp

Dump the eye image and instead use a button showing "Show" or "Hide" according to its state. Then you just click on the text of the button. You can stylize the button to be borderless and initially with the same background as its surrounds. Highlight the button by setting .show:hover to either brighten the background of the button or else to brighten the color of the Show/Hide text. By putting the input and button into the same span, you will have them both inline ( CSS - span{display: inline-block;} ) and vertically align off the same bottom.

Use an ordinary text input just below the span for space to display the validation error alerts. Make sure its tab index is -1 and its background color & border is the same as its surrounding.

  .
  .
  .

  <span class="pwSpan">
    <input type="password" placeholder="Password" id="pwd"  class="masked"  name="password" onblur="return checkPassword();"/>
    <button type="button" class="show" id="show" value="Show" onclick="showHide()" tabIndex="-1" autocomplete="off" >
    </button>
  </span>
  <input type="text" class="error" name="pwErr" value="" tabIndex="-1" />
  .
  .
  .

function showHide()
{
   const pwField = document.getElementById("pwd");
   const showHideValue = document.getElementById("show").value;

   if(showHideValue.trim() === "Show")
   {
      showHideValue = "Hide";
      pwField.setAttribute('type', 'text');
   }
   else 
   {
      showHideValue = "Show";
      pwField.setAttribute('type', 'password');
   }
}