0

I'm trying to make a function that making the password to be text if I click the eye, if you click again, the eye will close. I may use this function for other input, so I separate the function, so I do not use the way that eye.onclick=function(){...}; Below is my code, but my code only work one time, first time I click it, the eye open, but click again, the eye can not close, is that I need to remove the EventLister?

var password = document.getElementById('passWord');
var eye = document.querySelector('#eye');
var flag = 0;
var eyeOpen = function(obj,eyes,flag){
            if (flag===0){
                eyes.className="eye_open";
                obj.type = 'text';
                flag=1;
            }else{
                eyes.className = "eye_close";
                obj.type = 'password';
                flag = 0; 
            }
        }

eye.addEventListener('click', function () { 
        eyeOpen(password,eye,flag);
    });
Lee Alex
  • 171
  • 2
  • 3
  • 13
  • the scope of the `flag` that you edit isn't actually the flag you imagine, it's the flag that is only in the function.. it only works once because from 0 to 1.. then if u click again, it receives the same 0.. forever and ever – The Bomb Squad Jan 17 '21 at 01:58

2 Answers2

1

Please see the discussion here: Pass variables by reference in JavaScript. The problem is that you're passing 0 around, when what you want to be doing is changing flag directly.

var password = document.getElementById('passWord')
var eye = document.getElementById('eye')
var flag = 0

var eyeOpen = function(obj, eyes) {
  if (flag === 0) {
    eyes.className= 'eye_open'
    obj.type = 'text'
    flag = 1
  } else {
    eyes.className = 'eye_close'
    obj.type = 'password'
    flag = 0
  }
}

eye.addEventListener('click', function () {
  eyeOpen(password, eye)
})

The downside of this is that if you're reusing this code in several places, you could have several flags to keep track of. Rather than doing that, you could check the classList (or the input type), which would mean one less variable to keep track of:

var password = document.getElementById('passWord')
var eye = document.getElementById('eye')

var eyeOpen = function (obj, eyes) {
  var isOpen = eyes.classList.contains('eye_open')
  // This would also work:
  // var isOpen = obj.type === 'text'

  if (isOpen) {
    eyes.className = 'eye_close'
    obj.type = 'password'
  } else {
    eyes.className= 'eye_open'
    obj.type = 'text'
  }
}

eye.addEventListener('click', function () {
  eyeOpen(password, eye)
})
Zac Anger
  • 6,983
  • 2
  • 15
  • 42
  • But I want to use the eyeOpen function for the other eye, so I may have flag_2, so, the put the flag as a parameter in the function. Do I have another way to use flag in eyeOpen()? – Lee Alex Jan 17 '21 at 02:05
  • There is, I just added that in my edit. There's really no need for that variable at all, because you can check the `#eye`'s classList or the input's type. – Zac Anger Jan 17 '21 at 02:06
  • Thanks! I use the similar as yor, that is if eyes.className=="eye_close", than open,else close. – Lee Alex Jan 17 '21 at 02:25
0

var password = document.getElementById('passWord');
var eye = document.querySelector('#eye');
var flags=[0] //index based stuff
//if you have another eye..
//flags.push(0)
function openEye(index,password){
  flags[index]++
  if(flags[index]%2){password.type="text"}
  else{password.type="password"}
}
eye.addEventListener('click',function(){
  openEye(0,password) //for each eye the values can change :|
})
<input id="passWord" type="password"/>
<button id="eye">THE EYE</button>
The Bomb Squad
  • 4,192
  • 1
  • 9
  • 17