2016-09-27 44 views
0

这里搜索“某事”是我的代码:不能使用“在”运营商在不确定的

. 
. 
keydown: function(ev) { 

    clearTimeout($(this).data('timer')); 
    if ('abort' in $(this).data('xhr')) $(this).data('xhr').abort();  // error here 
    var xhr, timer = setTimeout(function() { 
     xhr = $.ajax({ 
      url : '/files/tags_autocomplete.php', 
      dataType : 'JSON', 
      success : function (tags) { 
      $("ul").html(tags.output); 
      } 
     }); 
    }, 500); 

    $(this).data({timer : timer, xhr : xhr}); 
} 
. 
. 

正如我评论说,第三行引发此错误:

Uncaught TypeError: Cannot use 'in' operator to search for 'abort' in undefined

哪有我修复它?

+0

[IN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in)是用来寻找一个属性在一个对象或数组中,我不认为'$(this).data(“xhr”)'是 –

+0

@SterlingArcher'$(this).data(“xhr”)'是'xhr'的值变量,它是'$ .ajax'返回的'jqXHR'对象。 – Barmar

+0

拍摄,我认为这是一个数据属性。我的错。 –

回答

2

更改从:

if ('abort' in $(this).data('xhr')) $(this).data('xhr').abort(); 

到:

if ($(this).data('xhr') && $(this).data('xhr').abort) { 
    $(this).data('xhr').abort(); 
} 

问题是简单地检查,如果对象具有xhr元件。默认情况下,它不存在,因此它是undefined,并且您要求JS引擎在undefined信息中找到导致错误的元素。

所以这就是为什么我添加到检查是否有.data('xhr')因为JS undefined被视为false之后,我检查是否有data('xhr')属性abort

通过,如果你想停止计时的方式,当按键被按下它更好地只是明确超时,它将无法运行AJAX调用,因此没有必要把XHR对象元素的数据存储:

if($(this).data('timer')) { 
    clearTimeout($(this).data('timer')); 
} 

var timer = setTimeout(function() { 
    $.ajax({ 
     url : '/files/tags_autocomplete.php', 
     dataType : 'JSON', 
     success : function (tags) { 
      $("ul").html(tags.output); 
     } 
    }); 
}, 500); 

$(this).data('timer', timer); 

或者更简单(没有数据存储):

if(window.autocompleteTimer) { 
    clearTimeout(window.autocompleteTimer); 
} 

window.autocompleteTimer = setTimeout(function() { 
    $.ajax({ 
     url : '/files/tags_autocomplete.php', 
     dataType : 'JSON', 
     success : function (tags) { 
      $("ul").html(tags.output); 
     } 
    }); 
}, 500); 
+3

'$(this).data('xhr')'似乎是一个很好的候选变量。 – 4castle

+0

@ 4castle haha​​(:我刚刚给出了问题的解决方案,但是在数据属性中保留对象和/或函数是不对的 – num8er

2

这里的问题是,undefined值没有任何属性。您需要检查返回值data()以检查它是否未定义。

var xhr = $(this).data('xhr'); 
if(typeof xhr !== 'undefiend' && xhr.abort) { 
    // do your code here 
} 

用上面的4行代码替换您的if语句。

1

问题是,如果用户在500ms过去之前再次键入,$(this).data('xhr')可能是未定义的,因为它尚未设置为ajax请求。

正如我们不能使用in操作上undefined,只有在对象上,正确的解决方案既清除超时并中止任何挂起的请求,是只检查是否$(this).data('xhr')已定,并且是一个对象,之前检查它是否有一个abort属性

keydown: function(ev) { 
    var self = $(this); 

    clearTimeout(self.data('timer')); 

    if (typeof self.data('xhr') === 'object' && 'abort' in self.data('xhr')) { 
    self.data('xhr').abort(); 
    } 

    var timer = setTimeout(function() { 
    self.data('xhr', $.ajax({ 
     url: '/files/tags_autocomplete.php', 
     dataType: 'JSON', 
     success: function(tags) { 
     $("ul").html(tags.output); 
     } 
    })); 
    }, 500); 

    self.data('timer', timer);