Я создал функцию jQuery, расширяющую собственный объект $. Эта функция переводит элементы, прикрепленные к элементу this:
$.fn.extend({
translate: function(sourceLang, targetLang) {
if ($(this).text().trim().length < 1 || !isNaN(parseInt($(this).text().trim())) || sourceLang == targetLang)
return;
let $function = this;
$($function).each(function() {
let $each = this;
$.ajax({
url: 'https://translate.yandex.net/api/v1.5/tr.json/translate',
method: 'GET',
dataType: 'JSONP',
crossDomain: true,
data: {
key: /* my-secret-key */,
text: $($each).text(),
lang: sourceLang + '-' + targetLang
},
success: function(response) {
try {
if (response.code !== 200)
throw "Response: " + response.code;
$($each).text(response.text[0])
} catch(error) {
console.error('Translation error on element: ', $($function).text());
console.error('Message returned by the server:', error);
}
},
error: function(xhr, status, error) {
console.error('Translation error on element: ', $($function).text());
console.error('Message returned by the server:', xhr.responseText);
}
});
});
}
});
После загрузки кода делаю так:
$(document).ready(function() {
let lang = $('html').attr('lang').split('-')[0];
$('td td:visible').translate(lang, "en");
});
Note: the HTML tag looks like this
<html lang = "es-ES">depending on the logged user language.
У меня проблема заключается в том, что таблица загружается через пару секунд (поскольку мы не в производственной среде, их может быть больше 30). Поэтому предыдущий блок кода бесполезен.
Note: the
<tbody>tag is created when the data is added.
Я пробовал:
1. Создать setInterval() и clearInterval(), когда $('td:visible').length больше 0:
let iv = setInterval(function() {
let lang = $('html').attr('lang').split('-')[0];
let rows = $('tbody td:visible');
if (rows.length > 0) {
rows.translate(lang, "en");
clearInterval(iv);
}
}, 1000);
2. Установите .delay() перед переводом:
let isTranslated = false;
while(!isTranslated) {
let lang = $('html').attr('lang').split('-')[0];
let rows = $('tbody td:visible');
if (rows.length > 0) {
rows.delay(1000).translate(lang, "en");
isTranslated = true;
}
}
Браузер использует память более 200 МБ. Я также пробовал с $('table').on('DOMSubstreeModified', 'tbody', function() {}), но это не сработало.
Итак, какой подход вы бы порекомендовали использовать этот плагин перевода на этой таблице после того, как он загрузит свой tbody?
Изменить 1:
Я изменил свой код, поэтому я выполняю меньше запросов API, благодаря рекомендации @ lucifer63:
let $function = this;
let collection = [];
let translation = '';
$(this).each(function() {
collection.push($(this).text());
});
let text = collection.join('::');
$.ajax({
url: 'https://translate.yandex.net/api/v1.5/tr.json/translate',
method: 'GET',
dataType: 'JSONP',
crossDomain: true,
data: {
key: /* my-secret-key */,
text: text,
lang: sourceLang + '-' + targetLang
},
success: function(response) {
try {
if (response.code !== 200) {
throw "Response: " + response.code;
}
translation = response.text[0].split('::');
$($function).each(function() {
$(this).text(translation.shift());
});
} catch(error) {
console.error('Message returned by the server:', error);
}
},
error: function(xhr, status, error) {
console.error('Message returned by the server:', xhr.responseText);
}
});
Но все же мне нужно выяснить, как печатать после загрузки данных.
Спасибо @ lucifer63 за комментарий. Я не уверен, как вставляется таблица, но я почти уверен, что она загружена с помощью Жидкий шаблонизатор с C#. Также я постараюсь делать меньше запросов.
возможно, вы можете посмотреть ... "когда" метод jQuery .. он ждет, пока один или несколько вызовов ajax будут полностью завершены, прежде чем выполнять действие
@Martin Fernandez, лол, у меня только что был опыт работы с API перевода Яндекса, так что это было немного "прощай" по поводу запросов; конечно это оффтоп. Что касается движка шаблонов Liquid: я полагаю, он работает под какой-то структурой, поэтому вы все равно можете прослушивать некоторые события. Но в любом случае, если вам наплевать, как работает ваш проект, просто используйте тайм-аут, не нужно искать другие двери
@ lucifer63, лол, меня действительно волнует, как работает "мой" проект. Но ... теперь вы «спросили», что я могу исследовать, читать, спрашивать, узнавать, насколько глубоко работает мой проект, но у меня нет на это времени. В любом случае спасибо за беспокойство по поводу этого проекта ...



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Что ж ... Думаю, я нашел ответ, который искал:
$('body').on('DOMNodeInserted', 'table', function() {
$('td:visible').translate('es', 'en');
});
Вроде работает правильно.
Как вставить таблицу в свой документ? Если вы используете для этого какую-то структуру, вы всегда можете использовать какое-то событие, которое вы можете прослушать. Если вы делаете это вручную, просто позвоните в службу переводов после инъекции. И, кстати, вам лучше объединить текст, который требует перевода, в один запрос, а не в несколько; afaik yandex имеет некоторые ограничения запросов