JavaScript范围 - 为onClick in循环获取对象的正确实例

时间:2017-05-01 20:42:37

标签: javascript jquery

对于糟糕的标题感到抱歉,很难在没有显示代码的情况下解释这一点。

我有一个名为Coupon的javaScript类,它有一个基本上打开fancyBox的函数,并显示该优惠券对象的内容(动态)。

喜欢这样

function CouponPopup( id, title, barcodeUrl, expirationDate, description ) {
  this.coupondId = id;
  this.couponContainer = document.createElement('div');
  this.couponTitle = document.createElement('h2');
  this.couponPrizeName = document.createElement('h3');  
  var self = this;
  // More vars, etc. . . 

  // assemble the coupon
 this.couponContainer.appendChild(this.couponTitle);
 this.couponContainer.appendChild(this.couponPrizeName);
 this.couponContainer.appendChild(this.couponRevealDetails);
 this.couponContainer.appendChild(this.couponBarcode);
 this.couponContainer.appendChild(this.couponExpirationText);
 this.couponContainer.appendChild(this.couponPrintButton);

 this.show = function ( event ) {
     $.fancybox(self.couponContainer);
  }
};  // end class CouponPopup

现在,在调用此代码的代码中,我正在尝试创建一个链接 - 单击该链接时,将调用右侧CouponPopup实例上的 show 函数。

for (var i = 0; i < dataLength; i++) {
   if (data.type === "coupon") {
       var couponId = "coupon_" + i;
       // right now, my coupon will be on global scope.
       myCoupon =  new CouponPopup( couponId,
           data.rewards[i].prize_name,
           data.rewards[i].url,
           data.rewards[i].expirationdate);

       rewardInfo = '<a id="' + couponId + '" onclick="myCoupon.show( event )">View Coupon</a>'; 

   }
}

rewardInfo最终被附加到页面 - 看起来很好。

然而,当我点击它时,由于 myCoupon 在globalScope上 - 显示的fancyBox始终是最后创建的优惠券。

如果我尝试将myCoupon放在本地范围内(添加var关键字),我会收到一条JS错误,说明myCoupon在添加到链接的onClick处理程序时未定义。

我想要做的是让 myCoupon 成为一个本地变量并仍然有这项工作 - 所以链接的onClick事件与 myCoupon <的特定实例相关联/ p>

最好的方法是什么?我有一个黑客工作,但它是一个黑客,我真的不喜欢在我的代码中使用全局变量,如果我能帮助它。

对这个人进行大脑放屁,所以对任何帮助表示赞赏!

寻找老式的ES5解决方案。

3 个答案:

答案 0 :(得分:2)

您可以尝试执行以下操作:

for (var i = 0; i < dataLength; i++) {


    if (data.type === "coupon") {
       var couponId = "coupon_" + i;
       // right now, my coupon will be on global scope.
       myCoupon =  new CouponPopup( couponId,
           data.rewards[i].prize_name,
           data.rewards[i].url,
           data.rewards[i].expirationdate);

       rewardInfo = '<a id="' + couponId + '" onclick="showCoupon('+ couponId +')">View Coupon</a>'; 

     }
}

然后像这样创建一个showCoupon函数:

  function showCoupon (couponId) {
    try {
      var index = parseInt(couponId.replace('coupon_', ''));

      new CouponPopup( couponId,
           data.rewards[index].prize_name,
           data.rewards[index].url,
           data.rewards[index].expirationdate).show();
    } catch(err) { console.log("wrong coupon id ", err);}


  }

答案 1 :(得分:1)

您应该创建一个DOM元素而不是html作为文本,并将其放在一个单独的范围内。

我没有测试过这段代码:

for (var i = 0; i < dataLength; i++) {
   if (data.type === "coupon") {
       // separate scope
      (function(i, data) {
       var couponId = "coupon_" + i;
       // local scope
       var myCoupon =  new CouponPopup( couponId,
           data.rewards[i].prize_name,
           data.rewards[i].url,
           data.rewards[i].expirationdate);
       // create a DOM element
       var link = document.createElement('a');
       link.id = couponId;
       link.onclick = function(event) { myCoupon.show(event); };
       link.innerHTML = 'View Coupon';
       // append your link somewhere
      })(i, data);
   }
}

Imo CouponPopup函数最后应该return this;,但我可能错了。

答案 2 :(得分:0)

好的,我明白了 - 非常接近@DimitriL的成功 - 这里是最终的代码:

if (data.type === "coupon") { {
   var link = ( function( i, data  )
   {
      var couponId = "coupon_" + i;
      var myCoupon = new CouponPopup(couponId,
                  data.rewards[i].prize_name,
                  data.rewards[i].url,
                  data.rewards[i].expirationdate);

      var link = document.createElement('a');
      link.id = couponId;
      clickMe = function (event) {
                  console.log("in clickme");
                  myCoupon.show(event);
                };
      link.onclick = this.clickMe;
      link.innerHTML = "View Coupon";
      return link;
   })( i, data );

 $(reward).append(link);

}

感谢大家的帮助 - 关闭和范围问题有时会很痛苦!