Попытка сделать добавление текста буква за буквой

0

Привет, я новичок с JavaScript и JQuery. То, что я пытаюсь сделать здесь, это напечатать текст, переданный в алфавите функции onclick() по алфавиту, используя функцию setTimeout. Я не уверен, что я делаю неправильно. Спасибо за вашу помощь.

HTML

<div>
         <p id='myTxt'></p>
</div>
 <input type='button' value='Submit' onclick="imScrolling('Hello World!!', 500, 0, document.getElementById('myTxt'))">   

Мой файл Script.js

 function imScrolling(scrollTxt, interval, index, target)
    {
        //alert(scrollTxt + " " + interval + " " + scrollTxt.length + " " + index + " " + target.id);
       while(index < scrollTxt.length)
      {
         //alert(scrollTxt[index]);
         setTimeout(function (scrollTxt, interval, index, target)
                {
                   $('#myTxt').append(scrollTxt[index]);
                   }, interval);
         index++;       
       }
    }

Кроме того, я заметил, что если я не передаю параметры setTimeout(), то параметры, такие как индекс, интервал, отображаются как неопределенные в предупреждающем сообщении? Почему это так?

Теги:
settimeout

5 ответов

0
Лучший ответ

Не используйте setTimeout. Вы хотите setInterval.

function imScrolling(scrollTxt, interval, index, target) {
    //alert(scrollTxt + " " + interval + " " + scrollTxt.length + " " + index + " " + target.id);

    var notawhileloop = setInterval(function () {
        //alert(scrollTxt[index]);
        $('#myTxt').append(scrollTxt[index]);
        index++;
        if (index == scrollTxt.length) {
            clearInterval(notawhileloop);
        }
    }, interval);
}

Рабочий jsfiddle с вашим HTML.

Изменить: Ой, забыл остановить цикл. Обновлена скрипка.


Редактировать 2: нашел опрятный трюк, который облегчает это с помощью setTimeout.

function imScrolling(scrollTxt, delay, index, target) {
    while (index < scrollTxt.length) {
        setTimeout(appendLetter, index * delay, scrollTxt, index);
        index++;
    }
}
function appendLetter(scrollTxt, index) {
    $('#myTxt').append(scrollTxt[index]);
}

Смотрите, как он работает в этой скрипке. Трюк умножает delay на index (поэтому первый тайм-аут устанавливается на 0 * 500, второй - на 1 * 500, третий - на 2 * 500 и т.д.). Надеюсь, это также продемонстрирует прохождение параметров.

  • 0
    Спасибо, Джастин, быстрый вопрос. Можете ли вы сказать мне, когда я использовал функцию setTimeout, почему параметры не были доступны внутри функции? Предупреждение бросило уведомление как неопределенное.
  • 0
    @NarenSingh Хорошо, я не уверен, правильно ли я понимаю ваш вопрос, но параметры не должны передаваться анонимной функции, они должны передаваться в setTimeout как setTimeout(func, delay, param1, param2) .
Показать ещё 1 комментарий
1

Проблема заключается в том setTimeout является асинхронным, а ваша функция продолжает работать в while синхронно и так setTimeout в настоящее время немедленно много раз. Вот что я предлагаю:

function imScrolling(scrollTxt, interval, index, target)
{
   setTimeout(function (){
       $('#myTxt').append(scrollTxt[index]);
       if(index < scrollTxt.length){
        imScrolling(scrollTxt, interval, index+1, target);
       }
       }, interval);
}

Таким образом, вы снова установите интервал после первого запуска, а не "в одно и то же время". демонстрация

  • 0
    Спасибо, приятель. Я только что сделал это, но у меня это не получилось. Можете ли вы поделиться ссылкой jsfidle? Например, если я добавлю предупреждение в setTimeout с параметрами, ничего не произойдет.
  • 0
    Извините, я забыл удалить параметры функции внутри «setTimeout». Эта функция не должна иметь параметров. Я отредактировал ответ и вот демо: jsbin.com/ohONuDe/1/edit?html,js,output
0

> Живая демонстрация

function imScrolling(txt, intv, i, elID){

  var $el = $(elID),
      tot = txt.length,
      interv = setInterval(doIt, intv);   

  function doIt(){
    $el.append(txt[i++]);
    if(i==tot) clearInterval(interv);
  }

}

Теперь что-то интересное:

Как это сделать, используя метод анимации jQuery:

Вместо setInterval, если вы хотите контролировать общее время, которое происходит, чтобы сделать анимацию, которую вы можете использовать
.animate() и эта функция step:

> Живая демонстрация (3500 мс)

function imScrolling(txt, time, i, elID){

    $({c:i}).animate(
      {c:txt.length},{
       duration : time,
       easing : 'linear',
       step : function(now){
           d = ~~(now);
           r = ~~(this.c);
           if(d!==r)$(elID).append(txt[r]);
       }
      }
    );     

}
  • 0
    Спасибо, это делает это намного проще!
0

Прежде всего, начните с функции, которую вы вызываете с помощью setTimeout.

function (scrollTxt, interval, index, target) {
  $('#myTxt').append(scrollTxt[index]);
}

Вы определили функцию с 4 параметрами, которые вызываются позднее. Проблема в том, что функция, заданная для setTimeout, не передает никакие параметры при ее вызове, поэтому внутри анонимной функции scrollTxt, интервал, индекс и цель будут неопределенными.

Чтобы преодолеть эту проблему, вы можете использовать закрытие. Внутри анонимной функции вы можете использовать переменные, доступные в области, определяющей анонимную функцию:

 var a = 5;
 function () {
    console.log(a); // 5
 }

Есть еще одна проблема. Используемые переменные являются фактическими переменными, а не копиями. Поэтому, если вы измените переменную снаружи, значение внутри анонимной функции также изменится:

var a = 5;
var f = function () {
  console.log(a);
}
a = 10;
f(); // outputs 10

Переменная, которая изменяется для вас, является индексом. Чтобы справиться с этим, вам нужно создать его копию для каждой итерации. Какой лучший способ сделать это, чем дать его в качестве параметра функции?

for (var i=0; i<10; i++) {
  setTimeout((function(new_i) {
     return function () {
       console.log(new_i);
     };
  })(i),100);
}
// outputs 0,1,2,3,4,5,6,7,8,9

Примените это, и вы можете легко решить свою проблему (и понять, как вы ее решаете).

  • 0
    Спасибо. это очень помогает.
  • 0
    Привет Тобос, не могли бы вы взглянуть на изменения, которые я сделал выше? Код совсем не работал для меня. Еще раз большое спасибо!
0

Не пытайтесь использовать атрибуты событий в HTML.

jQuery помогает вам в этом.

Пытаться:

HTML

<div id="container">
    <p id="myTxt"></p>
    <input type="button" value="Submit" id="your-button" /> 
</div>

JAVASCRIPT

$(function () // jquery dom ready
{
    $("#container")
        .on("click", "#your-button", function ()
        {
            var yourText = "Hello World!!".split('');

            for (var i = 0; i < yourText.length; i++)
            {
                $("#myTxt")
                    .append(yourText[i])
                    .append("<br/>"); // just to line break
            }
        }
});

Рабочая скрипка

  • 0
    Спасибо, приятель. Это еще один отличный вариант!
  • 0
    я надеюсь, что это полезно

Ещё вопросы

Сообщество Overcoder
Наверх
Меню