【问题标题】:Scope of variables in JavascriptJavascript中的变量范围
【发布时间】:2010-10-05 13:33:10
【问题描述】:

在这种情况下,我无法理解“this”的范围。我可以调用这些函数中的每一个,例如: this.startTracking();来自时间跟踪器开关对象。但是,当我尝试执行代码时: Drupal.timeTracker.prototype.stopTracking();它失去了所有变量范围,我的 GET 请求变得未定义。如何在 onbeforeunload 上触发 stopTracking()?

    Drupal.behaviors.dynamicTimeTracker = function (context) {
  $('form.node-time-tracker', context).each(function () {
    new Drupal.timeTracker(this);
  });
};

/**
 * A time tracker switch object
 */
Drupal.timeTracker = function (form) {
  var tracker = this;
  this.form = form;
  this.nid = $('#'+ form.id +' input[name="nid"]').attr('value');
  this.uid = $('#'+ form.id +' input[name="uid"]').attr('value');
  this.button = $('#'+ form.id +' input[type="submit"]');
  this.url = Drupal.settings.time_tracker.url + '/' + this.nid + '/' + this.uid;
  this.counter = $('#'+ form.id +' .counter');

  this.initialize(); // TODO: make sure this function is called regularly to make sure trackers are in synch
  this.startTracking();
  $(window).bind('beforeunload', function() {
    Drupal.timeTracker.prototype.stopTracking(); // need help here
  });
};

/**
 * Initialize the time tracker
 */
Drupal.timeTracker.prototype.initialize = function () {
  var tracker = this;

  $.ajax({
    type: "GET",
    url: tracker.url,
    dataType: 'json',
    success: function (status) {
      $(tracker.counter).countdown({compact:true, since:-status['time']}).countdown('resume');

      if (status['status'] == 'ongoing') {
        $(tracker.button).toggle(
          function() {
            tracker.stopTracking();
            return false;
          },
          function() {
            tracker.startTracking();
            return false;
          }
        );
        $(tracker.counter).countdown('resume');
        $(tracker.button).val(Drupal.t('Stop'));
        $(tracker.form).removeClass('node-time-tracker-start').addClass('node-time-tracker-stop');
      }
      else {
        $(tracker.button).toggle(
          function() {
            tracker.startTracking();
            return false;
          },
          function() {
            tracker.stopTracking();
            return false;
          }
        );
        $(tracker.counter).countdown('pause');
        $(tracker.button).val(Drupal.t('Start'));
        $(tracker.form).removeClass('node-time-tracker-stop').addClass('node-time-tracker-start');
      } 
    },
    error: function (xmlhttp) {
      alert(Drupal.ahahError(xmlhttp, tracker.startURL));
    }
  });
};

/**
 * Starts time tracking
 */
Drupal.timeTracker.prototype.startTracking = function () {
  var tracker = this;

  // Ajax GET request for starting time tracker
  $.ajax({
    type: "GET",
    url: tracker.url + '/start',
    dataType: 'json',
    success: function (status) {
      $(tracker.counter).countdown('change', {since: -status['time']}).countdown('resume');
      $(tracker.button).val(Drupal.t('Stop'));
      $(tracker.form).removeClass('node-time-tracker-start').addClass('node-time-tracker-stop');
    },
    error: function (xmlhttp) {
      alert(Drupal.ahahError(xmlhttp, tracker.startURL));
    }
  });
};

/**
 * Stops time tracking
 */
Drupal.timeTracker.prototype.stopTracking = function () {
  var tracker = this;

  // Ajax GET request for stopping time tracker
  $.ajax({
    type: "GET",
    url: tracker.url + '/stop',
    dataType: 'json',
    success: function (status) {
      $(tracker.counter).countdown('change', {since: -status['time']}).countdown('pause');
      $(tracker.button).val(Drupal.t('Start'));
      $(tracker.form).removeClass('node-time-tracker-stop').addClass('node-time-tracker-start');
    },
    error: function (xmlhttp) {
      alert(Drupal.ahahError(xmlhttp, tracker.startURL));
    }
  });
};

【问题讨论】:

    标签: javascript jquery ajax drupal


    【解决方案1】:

    我就拿出一点sn-p:

    this.startTracking();
    $(window).bind('beforeunload', function() {
      // this is defined by the above function definition
      tracker.stopTracking();
    });
    

    您的问题是,当您在其中创建绑定函数时,this 将引用 $(window),因此您需要创建它的副本,以便能够在此新函数中引用它。

    【讨论】:

      【解决方案2】:

      googletorp 的回答应该可以,但只是一个简短的说明:

      我相信你遇到的问题是因为你试图打电话:

      Drupal.timeTracker.prototype.stopTracking();
      

      相反,我认为应该是:

      Drupal.timeTracker.stopTracking();
      

      我认为您不应该在原型上调用函数,而是在您修改了原型的对象上调用函数。

      【讨论】:

      • 我试过这个,Firebug 告诉我我的函数是未定义的
      • 有趣...我想我还有更多关于 JS 原型的知识。
      • 在实例化对象之前,您不会从原型继承(即,您需要创建Drupal.timeTracker 的实例才能在不通过原型对象的情况下使用stopTracking )
      【解决方案3】:

      当您调用new Drupal.timeTracker(this) 时,它会创建一个新对象。该对象继承自Drupal.timeTracker.prototype。在该对象的方法中,this 被设置为对象本身。 Drupal.timeTracker.prototype 不是对象,而只是一个模板,可以从中形成对象的新实例;像千篇一律的,吃起来不是很好。最重要的是,您的实际计时器的内部状态都不存在于那里。

      当您调用Drupal.timeTracker.prototype.stopTracking 时,它是在模板上调用的,而不是真实对象。如果你打电话给tracker.stopTracking(),你会没事的。你不能调用this.stopTracking(),因为当你想调用stopTracking时,你在onbeforeunload的事件处理程序中,所以你的this将是window对象。

      【讨论】:

        猜你喜欢
        • 2012-05-03
        • 1970-01-01
        • 1970-01-01
        • 2020-02-07
        • 2012-12-23
        • 2011-05-10
        • 2011-07-07
        相关资源
        最近更新 更多