'this' reference undefined

时间:2018-07-24 10:03:25

标签: jquery

onchange of the select I'm running the get_cities_by_countyID() function. In the function I wrote:

function get_cities_by_countyID(countryID) {
  var element = $(this);     
  alert (element.attr("class"));

  // other logic...

  element.closest('form').find('.cityField').html(html);
}

However the alert() prints undefined. How can I fix this?

<form>  
  <div class="col-md-5">
    <label>country</label>
    <select class="selectpicker" name="attraction[countryCode]" data-live-search="true" onchange="get_cities_by_countyID(this.value)">
      <option value=""></option>
    </select>
  </div>
  <div class="col-md-5">
    <label>city</label>
    <select class="selectpicker cityField" name="attraction[cityID]" data-live-search="true">
      <option value=""></option>
    </select>   
  </div>
</form> 

1 个答案:

答案 0 :(得分:3)

The issue is because when you assign event handler using the on* attributes the function is not called within the scope of the element which raised the event; it's called globally, hence this is the window. This is why you receive undefined.

To fix this, pass the this reference in the event attribute to the function, then retrieve the needed values from there:

function get_cities_by_countyID(el) {
  var $el = $(el);
  var countryId = $el.val();
  console.log($el.prop("class"));
  //element.closest('form').find('.cityField').html(html);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <div class="col-md-5">
    <label>country</label>
    <select class="selectpicker" name="attraction[countryCode]" data-live-search="true" onchange="get_cities_by_countyID(this)">
      <option value="A">A</option>
      <option value="B">B</option>
      <option value="C">C</option>
    </select>
  </div>
  <div class="col-md-5">
    <label>city</label>
    <select class="selectpicker cityField" name="attraction[cityID]" data-live-search="true">
      <option value="A">A</option>
      <option value="B">B</option>
      <option value="C">C</option>
    </select>
  </div>
</form>

However you should note that using the on* event attributes is very outdated and should be avoided where possible. Unobtrusive event handlers are much better practice. They also allow you to use the this keyword within the handler as a reference to the element which raised the event. As you're using jQuery already you can implement them like this:

$(function() {
  $('#country').on('change', function() {
    var $el = $(this);
    var countryId = $el.val();
    console.log($el.prop("class"));
    //element.closest('form').find('.cityField').html(html);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <div class="col-md-5">
    <label>country</label>
    <select class="selectpicker" name="attraction[countryCode]" data-live-search="true" id="country">
      <option value="A">A</option>
      <option value="B">B</option>
      <option value="C">C</option>
    </select>
  </div>
  <div class="col-md-5">
    <label>city</label>
    <select class="selectpicker cityField" name="attraction[cityID]" data-live-search="true">
      <option value="A">A</option>
      <option value="B">B</option>
      <option value="C">C</option>
    </select>
  </div>
</form>