【问题标题】:Why does function only run once?Trying to run function multiple times,after previous invokation complete, using an counter function为什么函数只运行一次?尝试多次运行函数,在上一次调用完成后,使用计数器函数
【发布时间】:2015-01-01 11:23:19
【问题描述】:

我目前正在编写一本带有 jQ​​uery 翻页效果的书(无插件)。到目前为止,翻页效果很好,只要您一页一页地点击。但现在我想包含一个下拉选择(即一个选择元素),以便用户可以直接跳转到所选内容。我尝试使用循环和 .each() 方法来完成这项工作,以便重复调用 turnRightPage/turnLeftPage 函数,直到显示包含所选内容的页面。但是经过相当多的反复试验和大量研究后,我认为对于我的 turnRightPage /turnLeftPage() 函数(它们是翻转相应页面的转换函数)来说,循环迭代太快了,因为循环完成了,在功能完成之前。我认为,我需要做的是找到一种方法来暂停循环,直到函数完成执行,然后在下一次迭代中恢复。我认为最有前途的方法是使用带有迭代计数器的函数,就像这里建议的那样: Javascript: wait for function in loop to finish executing before next iteration(此时感谢 jfriend00)我也读过 Invoking a jQuery function after .each() has completedwait for each jQuery 以及其他类似的解决方案。

以下是我如何尝试实现 jfriend00 的回调。一旦翻页次数完成,我添加了一个返回语句来打破那个“回调循环”。

//determine whether to flip pages forward or back - first forward 
if(currentPagePos < foundPagePos){  // => turn right page
      //determine how many times need to turn page
      if (pageDifference > 1 && pageDifference % 2 !=0) {
          var numPageTurns = (pageDifference-1)/2;
          pageForward (numPageTurns);
      } //else if ... rest omitted for brevity
}    

function pageForward (numPageTurns){
      var i = 0;
      function next(){
          i++;
          if (i <= numPageTurns){
            turnRightPage ();
          } else {
              return;
          }
      }
      next();
  };  

完整代码可以看这里:http://jsfiddle.net/snshjyxr/1/

它确实会翻页,但只有一次!我错过了什么?

我对 javascript / jQuery 还是很陌生,所以如果问题看起来太明显了,我深表歉意。任何指针表示赞赏。谢谢!

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    问题是所有的翻页都被触发了,但都是一次性的。您必须等到每个过渡完成才能开始下一个过渡。

    turnRightPageturnLeftPage 函数中使用回调函数。 turnRightPage 的示例:

    function turnRightPage(callback) {
    
        [...]
    
        //change class AFTER transition (frm. treehouse-site)
        $page.on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function () {
            //need to double-set z-index or else secondtime turning page open setting z-index does not work (tried in Chrome 38.0.2125.111 m)
            $page.css("z-index", turnedZindex + 1);
            $(".turned").removeClass("turned");
            $page.addClass("turned");
    
            if(typeof callback == "function") {
                callback();
            }
        });
    };
    

    在你的pageForward 函数中,递归使用turnRightPage

    function pageForward(numPageTurns) {
        console.log("number of FORWARD page turns: " + numPageTurns);
    
        if(numPageTurns > 0) {
            turnRightPage(function(){
                pageForward(numPageTurns - 1);
            });
        }
    };
    

    这是您更新后的jsfiddle。如您所见,当您进行多次页面更改时,仍然存在一个错误,这是由于您在每次翻页时都在过渡端添加侦听器而从未删除它们。所以他们每次都在执行。

    编辑: jsfiddle 再次更新,没有烦人的最后一个错误。如您所见,只需在事件侦听器触发后立即解除绑定即可。

    【讨论】:

    • 太棒了!非常感谢,安托万。尽管我不得不承认,我仍然很难理解这里的回调函数是如何工作的。 if(typeof callback == "function") { callback.call(); 到底是什么? } -bit 在这里做什么?
    • if 部分只是检查变量callback 是否确实是一个函数,因此我们不会尝试调用一个公共变量(这只会引发错误)。 callback.call() 只是调用包含在 callback 变量中的函数。现在我想到了这一点,callback() 也能做到这一点。我将编辑我的答案。
    • 请记住.call() 方法在您想将特定上下文传递给您调用的函数时非常方便(即:如果您希望/需要this 不是@987654337 @ 在你的函数中)
    • 非常感谢,现在清楚一点了。我真的很感谢你的努力。但是为什么 turnRightPage 不不断地重复自己呢?这里的if语句中的条件(typeof callback == "function")永远为真,所以每次turnRightPage结束时都会调用callback。在我的菜鸟头脑中,只要看一下代码,我就希望它会永远运行,一旦你翻页。
    • typeof callback == "function" 仅检查一次,transitionend 事件仅在单个页面上触发一次。这项工作在pageForward 函数内完成,递归使用。这意味着它会调用自己,直到不再需要它为止。这里停止函数调用自身的明显条件是当我们没有更多的页面可以翻页时,这就是为什么每次函数调用自己时,它都会通过减少要翻页的数量来实现。所以最后这个函数是用0页来调用的。这就是检查numPageTurns &gt; 0 禁止进一步调用该函数的地方。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 2016-10-28
    • 1970-01-01
    相关资源
    最近更新 更多