JQuery $(this).attr( "id" ) не работает

как говорится в заголовке, я продолжаю получать "undefined", когда пытаюсь получить атрибут id элемента, в основном то, что я хочу сделать, это заменить элемент полем ввода, когда значение "другое".

Вот код:

function showHideOther(obj){ 

    var sel = obj.options[obj.selectedIndex].value;
    var ID = $(this).attr("id");

    alert(ID);


    if(sel=='other'){ 

        $(this).html("<input type='text' name='" + ID + "' id='" + ID + "' />");

    }else{
        $(this).css({'display' : 'none'});
    }
}  

HTML:

          <span class='left'><label for='race'>Race: </label></span>
          <span class='right'><select name='race' id='race' onchange='showHideOther(this);'>
            <option>Select one</option>
            <option>one</option>
            <option>two</option>
            <option>three</option>
            <option value="other">Other</option>
          </select>
          </span>

Возможно, что-то маленькое, что я не замечаю, что я делаю неправильно?

Thanx заранее!

Ответ 1

Из-за того, как вызывается функция (т.е. как простой вызов функциональной переменной), this является глобальным объектом (для которого window является псевдонимом в браузерах). Вместо этого используйте параметр obj.

Кроме того, создание объекта jQuery и использование его метода attr() для получения идентификатора элемента является неэффективным и ненужным. Просто используйте свойство element id, которое работает во всех браузерах.

function showHideOther(obj){ 
    var sel = obj.options[obj.selectedIndex].value;
    var ID = obj.id;

    if (sel == 'other') { 
        $(obj).html("<input type='text' name='" + ID + "' id='" + ID + "' />");
    } else {
        $(obj).css({'display' : 'none'});
    }
}

Ответ 2

Измените

var ID = $(this).attr("id");

к

var ID = $(obj).attr("id");

Также вы можете изменить его для использования обработчика событий jQuery:

$('#race').change(function() {
    var select = $(this);
    var id = select.attr('id');
    if(select.val() == 'other') {
        select.replaceWith("<input type='text' name='" + id + "' id='" + id + "' />");
    } else {
        select.hide();
    }
});

Ответ 3

используя this в функции, когда вы должны использовать параметр.

Вы используете только $(this) в обратных вызовах... из таких параметров, как

$('a').click(function() {
   alert($(this).href);
})

В заключение, правильным способом (с использованием примера кода) было бы сделать это

obj.attr('id');

Ответ 4

Вы также можете написать всю свою функцию как расширение jQuery, чтобы вы могли что-то делать в строках `$ ('# element'). showHideOther();

(function($) {
    $.extend($.fn, {
        showHideOther: function() {
            $.each(this, function() {
                var Id = $(this).attr('id');
                alert(Id);

                ...

                return this;
            });
        }
    });
})(jQuery);

Не то, чтобы он отвечал на ваш вопрос... Просто пища для размышлений.

Ответ 5

Удалите inline event handler и сделайте это полностью ненавязчивым, например

​$('​​​​#race').bind('change', function(){
  var $this = $(this),
      id    = $this[0].id;

  if(/^other$/.test($(this).val())){
      $this.replaceWith($('<input/>', {
          type: 'text',
          name:  id,
          id: id
      }));
  }
});​​​

Ответ 6

Что вы ожидаете от $(this) для ссылки?

Вы имеете в виду sel.attr("id"); возможно?

Ответ 7

В контексте функции "this" он не ссылается на элемент select, а на саму страницу

  • Измените var ID = $(this).attr("id"); до var ID = $(obj).attr("id");

Если obj уже является объектом jQuery, просто удалите вокруг него $().

Ответ 8

Я рекомендую вам больше узнать о это ключевое слово.

Вы не можете ожидать, что "this" будет выбирать тег "select" в этом случае.

В этом случае вы хотите использовать obj.id, чтобы получить идентификатор тега select.

Ответ 9

Вы можете сделать

onchange='showHideOther.call(this);'

вместо

onchange='showHideOther(this);'

Но тогда вам также нужно заменить obj на this в функции.