skip to Main Content

I’d like to change the following code to javascript only:

$(document).ready(function() {
    $('.fa-eye, .fa-eye-slash').click(function() {
        $(this).toggleClass('fa-eye fa-eye-slash');

        var input=$(this).parent().find('input');

        if(input.attr('type')=='password') {
            input.attr('type', 'text');
        }else input.attr('type', 'password');
    });
});

What is does is when you click in an "eye icon" it changes that icon to "eye-slash icon" and changes the password field within the same div to text, so basically toggle password/text.

Since this is currently the only javascript I’m using, I thought it would be overkill to include jQuery or ZeptoJS only for this and this can probably be done with a few lines of javascript.

Please notice: this needs to be applied to multiple fields, that is why I opted not to use ID.

2

Answers


  1. You can do it with normal vanilla JS means, see this snippet:

    function load() {
        for (let fa of document.querySelectorAll('.fa-eye, .fa-eye-slash')) {
            fa.addEventListener('click', function(e) {
                e.target.classList.toggle('fa-eye');
                e.target.classList.toggle('fa-eye-slash');
    
                let input = e.target.parentNode.querySelectorAll('input');
    
                for (let item of input) {
                    if (item.type === 'password') item.type = 'text';
                    else item.type = 'password';
                }
            });
        }
    }
    
    window.addEventListener('load', load);
    <div>
        <input type="password" value="foo">
        <input type="test" value="bar">
        <div class='fa-eye' style="background-color: green;">CLICK ME</div>
    </div>

    Note that jQuery is also Javascript, albeit, Javascript is not necessarily jQuery.

    Login or Signup to reply.
  2. These are the corrections made to make it work with no jQuery and just relying on vanilla JS and Web API (https://developer.mozilla.org/en-US/):

    • .addEventListener() to add bubbling event handlers to the elements
    • DOMContentLoaded event instead of $(document).ready()
    • .querySelectorAll() and .querySelector() to select elements instead of using the $ function
    • .classList.toggle() instead of .toggleClass()
    • event.target instead of $(this)
    • .getAttribute() and .setAttribute() instead of attr()
    • .forEach() to iterate over the array of returned elements
    document.addEventListener('DOMContentLoaded', ()=>{
      document.querySelectorAll('.fa-eye, .fa-eye-slash')    
        .forEach( el => {
          el.addEventListener('click', event =>{        
            const trigger = event.target;        
            trigger.classList.toggle('fa-eye');
            trigger.classList.toggle('fa-eye-slash');
            
            const input = trigger.parentNode.querySelector('input');         
            if (input.getAttribute('type') == 'password')
              input.setAttribute('type', 'text');
            else
              input.setAttribute('type', 'password');    
          });
        });
    });
    i{
      cursor: pointer;
    }
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    
    <div>
      <input type="password">
      <i class="fa-solid fa-eye"></i>
    </div>
    
    <hr>
    
    <div>
      <input type="password">
      <i class="fa-solid fa-eye"></i>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search