简体   繁体   中英

How can you swap an input text field to a password area on focus in JQuery?

I would like to display "password" as text in the password area, and when focused the box should become empty and allow normal password (starred out) input from the user.

Currently I use the following method. Initially I display a text field showing password, when focused it is removed and replaced with a password field. Here is the jQuery:

$(document).ready(function() {
    $("#password").focus( function() {
        $("#pwd").html('<input type="password" id="password" name="password" value="" />');
        $("#password").focus();
    });
});

This works on Firefox and Chrome but fails in IE 8 (and presumably other IE's) as the focus call fails for some reason (maybe the DOM isn't ready?).

A demo is available on jsbin .

Any ideas?

You could try the watermarker plugin. I don't know if it works in IE8.

After realizing my original solution wouldn't work, I spent a while trying to come up with a working solution just out of curiosity. I'd still recommend using the jQuery plugin eKek0 recommended, since it degrades better, though.

The following example is fairly flexible. Rather than hard-coding the replacement <input /> tags as strings, the replacement tags are derived from the original tags. This helps if the <input /> tag attributes are altered, since you won't lose any styling or other attributes given to the tags.

The following solution has been tested in Chrome, Firefox, IE8, and IE8 in IE7 compatibility mode.

$(document).ready(function() { 

    var focusEvent = function() { 
        if(this.type == 'text') {
            var html = $(this).clone().wrap('<span></span>').parent().html();
            html = html.replace(/type=("|')?text("|')?/, 'type="password"');
            var $newPwdBx = $(html);      

            $(this).replaceWith($newPwdBx);
            $newPwdBx.removeClass('readOnly');
            $newPwdBx.val('');
            $newPwdBx.focus();
            $newPwdBx.blur(blurEvent);
        }
    };

    var blurEvent = function() { 
        if(this.value == '') { 
            var html = $(this).clone().wrap('<span></span>').parent().html();
            html = html.replace(/type=("|')?password("|')?/, 'type="text"');
            var $newTxtBx = $(html);            

            $(this).replaceWith($newTxtBx);
            $newTxtBx.addClass('readOnly');
            $newTxtBx.val('password');
            $newTxtBx.focus(focusEvent);
        } 
    };

    $("#password").focus(focusEvent); 
});

This code replaces the <input /> with the appropriate type on blur and focus. It also adds/removes a class for styling the "password" placeholder text so it is more usable, since the placeholder "password" text is not the default black color, which could potentially be misleading to a user.

You can see it working here: http://jsbin.com/azugu

I have done something similar to this. If you are set on using javascript, this is one way of doing it:

  • Have two input fields, a normal one and a password one
  • The password is hidden with css
  • When normal input gets focus
    • Hide the normal input
    • Show the password input
    • Give focus to the password input

This approach has some problems to consider. If someone has javascript disabled, or is using the NoScript extension for Firefox, they may not be able to submit the form. If someone starts typing before javascript is loaded, there may be unexpected results.

Another approach is to use css and have javascript as a backup (for IE6). Create an image that has text "Password". Have that image be the background image for the password field. You can use pseudo classes in the css to change the background of the password field for hover and. This way, if a person has javascript disabled, the form still works. It also works as soon as the css is loaded.

The CSS might look something like this:

.pass { 
    background-image: url(/path/to/img.png);
}
.pass:hover {
    background: white;
}

Using jquery the javascript might look something like this:

 $( ".pass" ).hover( function() {
     $( this ).css( "background", "white" );
  };

The most common way to achieve this is to set a background image to the password field with the text "password" and remove the background image when it gets the focus.

Why not just change the attribute and wipe out the value?

$("#password").focus( function() {
    $(this).attr('type','password');
    $(this).attr('value','');        
});

Try this, experimentally if you will:

$(document).ready(function() {
    $(".pass").focus(function() {
        $pwInput = $('<input type="password" class="pass" name="password" value="" />');
        $(this).remove();
        $("#someDiv").append($pwInput);
    }).focus();
});

Why don't you just put a div over the top?

var $pwd = $("#passwordBox"),
    pos = $pwd.position()
;
$pwd
    .after(  // add the div
        $('<div></div>')
            .html("Password")
            .css({
                position : "absolute",    // place it over this
                top : pos.top + "px",  // adjust as necessary
                left : pos.top + "px"
            })
    )
    .next() // select the new div
    .andSelf()
    .one('click focus', function() {
        $pwd.next().remove()    // remove the div
            .end().focus() // focus the input box
        ;
    })
;

This works in FF & IE:

$(document).ready(function() {
    $("#password").focus( function() {
        $(this)
          .after('<input type="password" id="password" name="password" value="" />')
          .remove();
        $("#password").focus();
    });
});

There is also this txReplaceFormPassword plugin made by Simone Lippolis.

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