如何在第一次迭代后停止此电传类型动画?

时间:2013-02-13 19:10:58

标签: javascript jquery jquery-plugins

我正在使用jquery进行打字效果,并发现此代码并将其编辑为完全正常工作。

但是,我有一个问题,我无法阻止循环。

我试图检测到最后一段被打印,所以我可以在那之后添加一个没有运气的功能。

您的建议和提示表示赞赏。

代码是:

http://jsbin.com/araget/33/

(function ($) {

  function typeString($target, str, cursor, delay, cb) {
    $target.html(function (_, html) {
      return html + str[cursor];
    });

    if (cursor < str.length - 1) {
      setTimeout(function () {
        typeString($target, str, cursor + 1, delay, cb);
      }, delay);
    }
    else {
      cb();
    }
  }

  function deleteString($target, delay, cb) {
    var length;

    $target.html(function (_, html) {
      length = html.length;
      return html.substr(0, length - 1);
    });

    if (length > 1) {
      setTimeout(function () {
        deleteString($target, delay, cb);
      }, delay);
    }
    else {
      cb();
    }
  }

  // jQuery hook
  $.fn.extend({
    teletype: function (opts) {
      var settings = $.extend({}, $.teletype.defaults, opts);

      return $(this).each(function () {
        (function loop($tar, idx) {
          // type
          typeString($tar, settings.text[idx], 0, settings.delay, function () {
            // delete
            setTimeout(function () {
              deleteString($tar, settings.delay, function () {
                loop($tar, (idx + 1) % settings.text.length);
              });
            }, settings.pause);
          });

        }($(this), 0));
      });
    }
  });

  // plugin defaults  
  $.extend({
    teletype: {
      defaults: {
        delay: 100,
        pause: 5000,
        text: []
      }
    }
  });
}(jQuery));

$('#target').teletype({
  text: [
    'Lorem ipsum dolor sit amet, consetetur sadipscing elitr,',
    'sed diam nonumy eirmod tempor invidunt ut labore et dolore',
    'magna aliquyam erat, sed diam voluptua. At vero eos et'
  ]
});

$('#cursor').teletype({
  text: ['_', ' '],
  delay: 0,
  pause: 500
});

2 个答案:

答案 0 :(得分:0)

您需要从setTimeout()获取处理程序并使用处理程序运行clearTimeout()

var handler = setTimeout(function () {
        typeString($target, str, cursor + 1, delay, cb);
      }, delay);
....
clearTimeout(handler);

编辑:我修改了你的代码来解释你应该把停止例程放在哪里。

点击此链接:http://jsbin.com/enukit/1

你需要更多地清理你的逻辑。光标应该由选项分隔或设置,因为你打算停止循环,用于闪烁光标。

(function ($) {
  // writes the string
  //
  // @param jQuery $target
  // @param String str
  // @param Numeric cursor
  // @param Numeric delay
  // @param Function cb
  // @return void

  var handler1, mycount=0, handler2, handler3;
  function typeString($target, str, cursor, delay, cb) {
    $target.html(function (_, html) {
      return html + str[cursor];
    });
    //alert('cursor:'+cursor);
    //alert('str.length:'+str);
    if (cursor < str.length - 1) {
      handler1 = setTimeout(function () {
        typeString($target, str, cursor + 1, delay, cb);
      }, delay);
    }
    else {
      cb();
    }
  }

  // clears the string
  //
  // @param jQuery $target
  // @param Numeric delay
  // @param Function cb
  // @return void
  function deleteString($target, delay, cb) {
    var length;

    $target.html(function (_, html) {
      length = html.length;
      return html.substr(0, length - 1);
    });

    if (length > 1) {
      handler2 = setTimeout(function () {
        deleteString($target, delay, cb);
      }, delay);
    }
    else {
      cb();
    }
  }

  // jQuery hook
  $.fn.extend({
    teletype: function (opts) {
      var settings = $.extend({}, $.teletype.defaults, opts);
      $(this).each(function () {
mycount=0;
        (function loop($tar, idx) {
        mycount ++;
          // type
          typeString($tar, settings.text[idx], 0, settings.delay, function () {
            // delete
            clearTimeout(handler1);
            handler3 = setTimeout(function () {
              deleteString($tar, settings.delay, function () {
                if (mycount<settings.text.length) {
                  loop($tar, (idx + 1));} else {
clearTimeout(handler3);
                    alert('The end!');
                  }
              });
            }, settings.pause);
          });

        }($(this), 0));
      });

    }
  });

  // plugin defaults  
  $.extend({
    teletype: {
      defaults: {
        delay: 100,
        pause: 5000,
        text: []
      }
    }
  });
}(jQuery));

$('#target').teletype({
  text: [
    'Lorem ipsum dolor sit amet, consetetur sadipscing elitr,',
    'sed diam nonumy eirmod tempor invidunt ut labore et dolore',
    'magna aliquyam erat, sed diam voluptua. At vero eos et'
  ]
});
/*
$('#cursor').teletype({
  text: ['_', ' '],
  delay: 0,
  pause: 500
});
*/

答案 1 :(得分:0)

您可以添加一个参数来停止动画的循环,另一个参数可以设置为在动画结束时调用的回调。我们分别说foreverend

// plugin defaults  
$.extend({
  teletype: {
    defaults: {
      delay: 100,
      pause: 5000,
      text: [],
      forever: true,
      end: $.noop
    }
  }
});

forever设置为true会使动画无限期地继续播放,并在到达最后一个元素后从text的第一个元素重新开始。将forever设置为false将使其在第一次迭代达到后停止。

end设置为回调函数,该函数将在动画的第一次迭代完成时调用。此选项要求forever设置为false,否则永远不会被调用。

使用:

if (settings.forever || (idx + 1 < settings.text.length)) {
  loop($tar, (idx + 1) % settings.text.length);
} else {
  settings.end.call(self);
}

而不是

loop($tar, (idx + 1) % settings.text.length);

应用这些更改后,您可以使用正确的参数调用teletype

$('#target').teletype({
  text: [
    'Lorem ipsum dolor sit amet, consetetur sadipscing elitr,',
    'sed diam nonumy eirmod tempor invidunt ut labore et dolore',
    'magna aliquyam erat, sed diam voluptua. At vero eos et'
  ],
  forever: false,
  end: function(){
    alert("Teletype is done!");
  }
});

You can see it here.