-1

Есть такой код:

<div id='chatbox-list'></div>
<script>
function Test() {
 
 $.ajax({
 type: 'post',
 url: '/blabla'
 }).done(function (data) {
 if (data.length > 0) {
 $('#chatbox-list').append(data);
 }
 });
 
 }
 
setInterval(Test, 2000);
</script>

data это:

<div id='test'> </div>
Какой-то HTML код
<script>
function Name(){
 $.ajax()
.....
 $('#test').append('blabla');
.....
}
setInterval(Name,1000);
</script>

Внимание вопрос знатокам:)

После добавления HTML и Javascript в , как сделать так, чтобы выполнялся setInterval(Name,1000) и соответственно function Name() ? Может есть какое-то другое решение, которое позволит выполнять через определенный промежуток времени динамически добавляемую функцию?

задан 3 апр. 2020 в 17:32
4
  • 1
    Стоп... а ничего, что у вас раз в 2 секунды начнет добавляться новый интервал и через пару минут их будет сотни? Может в data нужен setTimeout ? Commented 3 апр. 2020 в 22:08
  • Вместо интервалов вызовите name() сразу, так вы сделаете первую отправку ajax, потом при приходе ответа (в done у вас) сделайте таймер (не интервал) в котором новый вызов name(). Так вы избавитесь от накопления запросов-без-ответов и от прихода второго ответа раньше первого (сервер не обязан отвечать второй ответ раньше первого, он может выполнять первй долго, а второй моментально). Commented 4 апр. 2020 в 0:47
  • Я пишу чат переписку между пользователями. Каждые 2 сек. будет проверяться есть ли новые запросы на переписку. Если есть, то подгружается кусок HTML с формой и JS для отправки/получения новых сообщений. Вообщем решил сделать загрузку JS на eval() и отдельно HTML через append. В JS тоже должен быть свой setInteval который проверяет есть ли новые сообщения. Commented 4 апр. 2020 в 6:49
  • Спасибо за идею о том, что не накапливать запрос-ответ! Commented 4 апр. 2020 в 8:26

2 ответа 2

1

Вставленный в виде строки скрипт не будет работать. Есть два варианта его обработать:

  1. eval()
  2. createElement("script")

let data = 'name(); function name() { console.log("Name!!!"); }';
eval(data);
/***/
let script = document.createElement('script');
script.innerHTML = data;
document.head.appendChild(script);

Но так добавлять скрипты, тем более раз в 2 секунды - плохая идея, как минимум потому что может возникнуть конфликт имен переменных.

И еще, что будет, если ответы начнут задерживаться, а запросы так и будут отправляться раз в 2 секунды? Поэтому можно отправлять следующий запрос только после получения предыдущего, зациклив их через setTimeout.

А вместо вставки целого скрипта, можно завернуть data в JSON, который будет хранить все необходимые данные для обработки, около того:

/* data = {
 * "html": "<div>bubu...</div>",
 * "scriptData": {
 * "text": "example.com",
 * "timeout": 1000,
 "appendTo": "#test"
 * }
 * }
 */
let STOP_AJAX = false;
ajaxLoop();
function ajaxLoop() {
 $.ajax({
 // ляляля
 }).done(function (data) {
 handleAjaxData(data);
 if ( STOP_AJAX ) return;
 // Чтобы можно было остановить запросы в случае чего.
 setTimeout(ajaxLoop, 2000); // Функция вызывает саму себя
 });
}
function handleAjaxData(data) {
 if( !data.length ) return;
 data = JSON.parse(data);
 if( data.html ) $('#chatbox-list').append(data.html);
 if( data.scriptData ) {
 // вместо вашей функции Name
 let elem = data.scriptData.appendTo;
 let text = data.scriptData.text;
 let tick = data.scriptData.timeOut;
 setTimeout(function(){
 $(elem).append(text);
 // Или например, еще один запрос, если по другому никак.
 }, tick);
 }
}
ответ дан 4 апр. 2020 в 1:04
4
  • Спасибо за ответ! Commented 4 апр. 2020 в 6:34
  • Я пишу чат переписку между пользователями. Каждые 2 сек. будет проверяться есть ли новые запросы на переписку. Если есть, то подгружается кусок HTML с формой и JS для отправки/получения новых сообщений. Вообщем решил сделать загрузку JS на eval() и отдельно HTML через append. В JS тоже должен быть свой setInteval который проверяет есть ли новые сообщения.Протестил вроде работает. Commented 4 апр. 2020 в 6:43
  • @plavv тогда можно еще завести какую-нибудь внешнюю переменную, чтобы после получения запроса, стереть предыдущий интервал... let interval = null; - - прилетел ответ -- .done( clearInterval(interval); eval(data); ) — при этом интервал из дата будет такой interval = setInterval(ляляля) чтобы запомнить номер текущего интервала для следующего удаления. Commented 4 апр. 2020 в 11:58
  • Спасибо за помощь! Commented 7 апр. 2020 в 15:28
0

Не совсем понял, но потести это:

<script>
(()=>{
 const Name=()=>{
 // $.ajax();
 $('#test').append('blabla');
 };
 setInterval(Name, 1000);
})();
</script>
ответ дан 3 апр. 2020 в 22:40

Ваш ответ

Черновик сохранён
Черновик удалён

Зарегистрируйтесь или войдите

Регистрация через Google
Регистрация через почту

Отправить без регистрации

Необходима, но никому не показывается

Отправить без регистрации

Необходима, но никому не показывается

Нажимая «Отправить ответ», вы соглашаетесь с условиями пользования и подтверждаете, что прочитали политику конфиденциальности.

Начните задавать вопросы и получать на них ответы

Найдите ответ на свой вопрос, задав его.

Задать вопрос

Изучите связанные вопросы

Посмотрите похожие вопросы с этими метками.