изменить тип поля ввода с помощью jQuery - PullRequest
199 голосов
/ 09 октября 2009
$(document).ready(function() {
    // #login-box password field
    $('#password').attr('type', 'text');
    $('#password').val('Password');
});

Предполагается, что поле ввода #passwordid="password"), которое имеет значение type password, должно измениться на обычное текстовое поле, а затем заполнить текст «Пароль».

Хотя это не работает. Почему?

Вот форма:

<form enctype="application/x-www-form-urlencoded" method="post" action="/auth/sign-in">
  <ol>
    <li>
      <div class="element">
        <input type="text" name="username" id="username" value="Prihlasovacie meno" class="input-text" />
      </div>
    </li>
    <li>
      <div class="element">
        <input type="password" name="password" id="password" value="" class="input-text" />
      </div>
    </li>
    <li class="button">
      <div class="button">
        <input type="submit" name="sign_in" id="sign_in" value="Prihlásiť" class="input-submit" />
      </div>
    </li>
  </ol>
</form>

Ответы [ 28 ]

254 голосов
/ 09 октября 2009

Весьма вероятно, что это действие предотвращено как часть модели безопасности браузера.

Редактировать: действительно, тестируя прямо сейчас в Safari, я получаю ошибку type property cannot be changed.

Edit 2: это похоже на ошибку прямо из jQuery. Использование следующего прямого кода DOM прекрасно работает:

var pass = document.createElement('input');
pass.type = 'password';
document.body.appendChild(pass);
pass.type = 'text';
pass.value = 'Password';

Редактировать 3: Прямо из источника jQuery, это, похоже, связано с IE (и может быть ошибкой или частью их модели безопасности, но jQuery не конкретен):

// We can't allow the type property to be changed (since it causes problems in IE)
if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
    throw "type property can't be changed";
76 голосов
/ 21 февраля 2010

Еще проще ... нет необходимости создавать все динамические элементы. Просто создайте два отдельных поля, сделав одно поле «реальным» паролем (type = "password") и одно - полем "fake" password (type = "text"), установив для текста в поле fake светло-серый цвет и установка начального значения на «Пароль». Затем добавьте несколько строк Javascript с помощью jQuery, как показано ниже:

    <script type="text/javascript">

        function pwdFocus() {
            $('#fakepassword').hide();
            $('#password').show();
            $('#password').focus();
        }

        function pwdBlur() {
            if ($('#password').attr('value') == '') {
                $('#password').hide();
                $('#fakepassword').show();
            }
        }
    </script>

    <input style="color: #ccc" type="text" name="fakepassword" id="fakepassword" value="Password" onfocus="pwdFocus()" />
    <input style="display: none" type="password" name="password" id="password" value="" onblur="pwdBlur()" />

Таким образом, когда пользователь вводит поле «фальшивого» пароля, оно будет скрыто, будет показано реальное поле, и фокус переместится на реальное поле. Они никогда не смогут вводить текст в поддельное поле.

Когда пользователь покидает поле с реальным паролем, скрипт увидит, пусто ли оно, и если это так, скроет реальное поле и покажет поддельное.

Будьте осторожны, чтобы не оставить пробел между двумя элементами ввода, потому что IE будет располагать один немного за другим (рендеринг пробела) и поле будет двигаться, когда пользователь входит / выходит из него.

72 голосов
/ 03 октября 2011

Одношаговое решение

$('#password').get(0).type = 'text';
38 голосов
/ 16 февраля 2013

В настоящее время вы можете просто использовать

$("#password").prop("type", "text");

Но, конечно, вы должны просто сделать это

<input type="password" placeholder="Password" />

во всех кроме IE. Существуют заполнители, имитирующие эту функциональность и в IE.

14 голосов
/ 03 октября 2011

Более кросс-браузерное решение ... Надеюсь, суть этого кому-то там поможет.

Это решение пытается установить атрибут type, а в случае неудачи просто создает новый элемент <input>, сохраняя атрибуты элемента и обработчики событий.

changeTypeAttr.js ( GitHub Gist ):

/* x is the <input/> element
   type is the type you want to change it to.
   jQuery is required and assumed to be the "$" variable */
function changeType(x, type) {
    x = $(x);
    if(x.prop('type') == type)
        return x; //That was easy.
    try {
        return x.prop('type', type); //Stupid IE security will not allow this
    } catch(e) {
        //Try re-creating the element (yep... this sucks)
        //jQuery has no html() method for the element, so we have to put into a div first
        var html = $("<div>").append(x.clone()).html();
        var regex = /type=(\")?([^\"\s]+)(\")?/; //matches type=text or type="text"
        //If no match, we add the type attribute to the end; otherwise, we replace
        var tmp = $(html.match(regex) == null ?
            html.replace(">", ' type="' + type + '">') :
            html.replace(regex, 'type="' + type + '"') );
        //Copy data from old element
        tmp.data('type', x.data('type') );
        var events = x.data('events');
        var cb = function(events) {
            return function() {
                //Bind all prior events
                for(i in events)
                {
                    var y = events[i];
                    for(j in y)
                        tmp.bind(i, y[j].handler);
                }
            }
        }(events);
        x.replaceWith(tmp);
        setTimeout(cb, 10); //Wait a bit to call function
        return tmp;
    }
}
8 голосов
/ 27 июня 2012

Это работает для меня.

$('#password').replaceWith($('#password').clone().attr('type', 'text'));
6 голосов
/ 18 января 2010

Лучший способ использовать jQuery:


Оставить исходное поле ввода скрытым от экрана.

$("#Password").hide(); //Hide it first
var old_id = $("#Password").attr("id"); //Store ID of hidden input for later use
$("#Password").attr("id","Password_hidden"); //Change ID for hidden input

Создание нового поля ввода на лету с помощью JavaScript.

var new_input = document.createElement("input");

Перенос идентификатора и значения из скрытого поля ввода в новое поле ввода.

new_input.setAttribute("id", old_id); //Assign old hidden input ID to new input
new_input.setAttribute("type","text"); //Set proper type
new_input.value = $("#Password_hidden").val(); //Transfer the value to new input
$("#Password_hidden").after(new_input); //Add new input right behind the hidden input

Чтобы обойти ошибку в IE, такую ​​как type property cannot be changed, вы можете найти это полезным, как показано ниже:

Прикрепить событие click / focus / change к новому элементу ввода, чтобы вызвать то же событие на скрытом вводе.

$(new_input).click(function(){$("#Password_hidden").click();});
//Replicate above line for all other events like focus, change and so on...

Старый скрытый элемент ввода все еще находится внутри DOM, поэтому будет реагировать на событие, вызванное новым элементом ввода. При смене идентификатора новый элемент ввода будет действовать как старый и реагировать на любой вызов функции для старого идентификатора скрытого ввода, но будет выглядеть иначе.

Немного сложно, но РАБОТАЕТ !!! ; -)

4 голосов
/ 09 декабря 2010

Я не тестировал в IE (так как мне нужно было это для сайта iPad) - форма, которую я не мог изменить HTML, но я мог добавить JS:

document.getElementById('phonenumber').type = 'tel';

(JS старой школы ужасен рядом со всеми jQuery!)

Но http://bugs.jquery.com/ticket/1957 ссылается на MSDN: «Начиная с Microsoft Internet Explorer 5, свойство type доступно только для чтения / записи, но только когда элемент ввода создается с помощью метода createElement и до его добавления к документу. " так что, возможно, вы могли бы продублировать элемент, изменить тип, добавить в DOM и удалить старый?

4 голосов
/ 15 января 2014

Вы пробовали использовать .prop ()?

$("#password").prop('type','text');

http://api.jquery.com/prop/

3 голосов
/ 09 октября 2009

Просто создайте новое поле, чтобы обойти эту вещь безопасности:

var $oldPassword = $("#password");
var $newPassword = $("<input type='text' />")
                          .val($oldPassword.val())
                          .appendTo($oldPassword.parent());
$oldPassword.remove();
$newPassword.attr('id','password');
...