繁体   English   中英

如何从setTimeout中获取另一个作用域中的变量集?

[英]How do I get a variable set in another scope from within a setTimeout?

我有一个计时器功能,我离开了这个网站,并尝试对其进行一些修改以满足我的需要。 在大多数情况下,它可以按我的意愿工作,但是我无法将参数传递给JavaScript函数。

我想使用select来更改id值,然后将该值传递到JQuery加载函数中。 有人可以告诉我该怎么做吗?

值得一提的是,当计时器刷新时,选择值需要“固定”,不能重置。

这是我到目前为止的内容:

function RecurringTimer(callback, delay) {
  var timerId, start, remaining = delay;

  this.pause = function() {
    window.clearTimeout(timerId);
    remaining -= new Date() - start;
  };

  var resume = function() {
    start = new Date();
    timerId = window.setTimeout(function() {
      remaining = delay;
      resume();
      callback();
    },remaining);
  };

  this.resume = resume;
  this.resume();
}

var timer = new RecurringTimer(function() {
  $('#id').load('load.asp?id=1'); // The "id" should be "newVal" from JQuery below.
}, 5000);


$(document).ready(function(){
  $('#appList').live('change',function(){
    var select = $(this);
    var newVal = select.val();

    if(newVal != ''){

      // This is where the var newVal needs to be passed into the JavaScript.

    }
  });
});

我已经在某种程度上推测了您的工作状况,因此我做了一些更改以适应尝试使其工作的需要。 因此,如果您对我为什么要做的事情有任何疑问,请告诉我。

这是我的模拟元素,试图匹配代码中的内容:

<div id="selector">
    <select id="appList">
        <option value="1">Application List - App 1</option>
        <option value="2">Application List - App 2</option>
        <option value="3">Application List - App 3</option>
        <option value="4">Application List - App 4</option>
    </select>
</div>
<div id="id"></div>

请注意, #id并不是元素的良好标识符; 我几乎几次将其重命名为#loader 您可以考虑使此元素的id属性更具描述性。

我确实将$.live更改为$.on ; 如果您实际上使用的元素是select或发生真正change事件的东西,请坚持使用$.on而不是$.live $.live已被弃用,在完全删除之前可能不会有太多版本。

我也将$.load换成$.get这样我就可以使用callback jsFiddle并没有真正让我选择使用$.load并返回任何东西。 因此,我使用$.get代替了一条log语句。

好的,所以您将看到包装的jQuery(); 围绕所有RecurringTimer()函数以及callbacktimer$.on 这样做是创建一个“关闭范围”(想像它包含了其中包含的代码),所以我不再处于window范围或全局范围内。 我可以访问window通过调用window ,但是this将属于jQuery.ready()这意味着document

在顶部,您将看到:

jQuery(function run($){
    var $id = $('#id'),
        $applist = $('#appList'),
        timerId,
        start,
        remaining = 0,
        newval,
        select;

这些都是私有变量,将保留在该作用域的函数和属于该作用域的回调中。 因此,如果我在“最私密的”范围内拥有它们,我们可以共享它们。 如果在此范围内的其他函数内部使用var调用它们,则它们将仅属于该范围。 就像var select = $(this); 只能在该$.on处理程序中访问。

因此,我想要var newval; 在最私人的范围内,因此我们可以轻松共享它。 当然,您必须要小心,因为有时您不想将其全部推到那个范围内(例如var select )。

其余部分可能是不言自明的。 您不需要window.setTimeout ,只需要setTimeout 大多数window范围的属性和方法不需要您在window 但是,您可能需要这样做以消除local和global / window属性的歧义,例如,如果您具有local var location = 'http://...'; 在适用范围。 在这种情况下,您需要window.location来实现。

如果您有任何疑问,请告诉我。

jQuery(function run($){
    var $id = $('#id'),
        $applist = $('#appList'),
        timerId,
        start,
        remaining = 0,
        newval,
        select;

    $applist.on('change', function(){
        var select = $(this);

        $id.prepend('<p>App List change event fired</p>');

        newval = select.val();

        if (newval != '') {
            var timer = new RecurringTimer(function() {
                $.get('/echo/html/?id=' + newval, callback); 
            }, 5000);
        }

        function callback(msg, status){
            var report = '<p>Callback returned ' + status + 
                         ' for '  + this.url +  '.</p>';

            $id.prepend(report);
        }
    });

    function RecurringTimer(callback, delay) {
        remaining = delay;

        $id.prepend('<p>RecurringTimer initialized.</p>');

        this.pause = function() {
            clearTimeout(timerId);

            remaining -= new Date() - start;
        };

        var resume = function() {
            start = new Date();

            timerId = setTimeout(function() {
                remaining = delay;
                resume();
                callback();
            }, remaining);
        };

        this.resume = resume;

        this.resume();
    }
});

http://jsfiddle.net/userdude/zU5b3/

也有一些CSS,但是我认为它不相关,因此我将其省略。

好吧,你可以这样做:

if(newVal != ''){
    window.newVal = newVal;
}

并在需要的地方使用window.newVal

$('#id').load('load.asp?id=' + window.newVal);

尝试这个

function RecurringTimer(callback, delay) {
 var timerId, start, remaining = delay;
 var newValue;
  .....
  .....
  .....

然后在你的jQuery中

if(newVal != ''){

     newValue = newVal;

}

然后您可以在计时器中引用它

    var timer = new RecurringTimer(function() {

        $('#id').load('load.asp?id='+newValue); // The "id" should be "newVal" from JQuery below.
}, 5000);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM