JavaScript TinyMCE / jQuery - условие гонки на Firefox - PullRequest
7 голосов
/ 07 декабря 2008

У меня есть веб-сайт с формой, которая использует TinyMCE; самостоятельно использую jQuery. Когда я загружаю форму с промежуточного сервера в Firefox 3 (MacOS X, Linux), TinyMCE не заканчивает загрузку. В консоли Firefox произошла ошибка, из-за которой t.getBody() вернул null. t.getBody() Насколько я понимаю из документации TinyMCE, это функция, которая возвращает элемент тела документа для проверки на наличие некоторых функций. Проблема не возникает, когда я использую Safari, и когда я использую Firefox с тем же сайтом, работающим с localhost.

Исходный код ошибки JavaScript выглядел следующим образом:

<script type="text/javascript" src="http://static.alfa.foo.pl/json2.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.ui.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">
  tinyMCE.init({ mode:"specific_textareas", editor_selector:"mce", theme:"simple", language:"pl" });
</script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.jeditable.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.tinymce.js"></script>
<script type="text/javascript" charset="utf-8" src="http://static.alfa.foo.pl/foo.js"></script>
<script type="text/javascript">
  $(document).ready(function(){
    /* jQuery initialization */ });
</script>

Я пытался изменить порядок загрузки скрипта, перемещая тег tinyMCE.init()<code> call to the <code><script/>, содержащий вызов $(document).ready() - до, после и внутри этого вызова. Безрезультатно. Когда обработчик tinyMCE.init()<code> was called from within <code>$(document).ready(), браузер зависал по запросу - похоже, было слишком поздно для вызова функции init.

Затем, немного погуглив об использовании TinyMCE вместе с jQuery, я изменил tinyMCE.init() вызов на:

tinyMCE.init({ mode:"none", theme:"simple", language:"pl" });

и добавил следующий вызов jQuery к обработчику $(document).ready():

$(".mce").each( function(i) { tinyMCE.execCommand("mceAddControl",true,this.id); });

Все та же ошибка. Но именно здесь все начинает выглядеть как настоящее вуду, когда я добавил alert (i); перед вызовом tinyMCE.execCommand () , были выданы предупреждения и текстовые области TinyMCE были правильно инициализированы. Я подумал, что это может быть связано с задержкой, вызванной ожиданием отклонения оповещения пользователем, поэтому я ввел секунду задержки, изменив вызов, все еще находящийся в обработчике $ (document) .ready () , следующим образом:

setTimeout('$(".mce").each( function(i) { tinyMCE.execCommand("mceAddControl",true,this.id); });',1000);
</code>

С тайм-аутом текстовые области TinyMCE инициализируются правильно, но это настоящая проблема. Проблема выглядит как явное состояние гонки (особенно, если учесть, что в том же браузере, но когда сервер находится на локальном хосте, проблема не возникает). Но не является ли выполнение JavaScript однопоточным? Кто-нибудь может, пожалуйста, просветить меня о том, что здесь происходит, где настоящая проблема, и что я могу сделать, чтобы это на самом деле было решено?

Ответы [ 3 ]

5 голосов
/ 07 декабря 2008

Браузер выполняет скрипты в порядке их загрузки, а не написания. Ваши немедленные сценарии - tinyMCE.init(...) и $(document.ready(...)); - могут выполняться до окончания загрузки файлов.

Таким образом, проблема, вероятно, заключается в задержке в сети - особенно с 6 отдельными сценариями (каждый из которых требует отдельного HTTP-диалога между браузером и сервером). Итак, браузер, вероятно, пытается выполнить tinyMCE.init() до того, как tiny_mce.js завершит анализ и tinyMCE будет полностью определен.

Если у вас нет Firebug, получите его . ;)
Он имеет вкладку Net , которая покажет вам, сколько времени занимает загрузка всех ваших скриптов.


Хотя вы можете считать setTimeout клейкой лентой, на самом деле это достойное решение. Единственная проблема, которую я вижу, состоит в том, что предполагается, что 1 секунда будет всегда исправлена. Быстрое соединение, и они могли видеть паузу. Медленное соединение, и оно не ждет достаточно долго - вы все равно получаете сообщение об ошибке.

Кроме того, вы можете использовать window.onload - при условии, что jQuery его еще не использует. (Может кто-нибудь еще проверить?)

window.onload = function () {
    tinyMCE.init(...);

    $(document).ready(...);
};

Кроме того, это была прямая копия?

<script type="text/javascript">
  $(document).ready(function(){
    /* jQuery initialization */ }
</script>

Отсутствует окончание ) ready:

<script type="text/javascript">
  $(document).ready(function(){
    /* jQuery initialization */ })
</script>

Отсутствие знаков препинания может привести к значительным повреждениям. Парсер просто продолжит чтение, пока не найдет его - что-то напутает.

2 голосов
/ 19 февраля 2010

Так как это первая страница, которая появилась в Google, когда я задал себе тот же вопрос, это то, что я нашел об этой проблеме.

источник

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

tinyMCE.init({
   ...
   setup : function(ed) {
      ed.onInit.add(function(ed) {
          console.log('Editor is loaded: ' + ed.id);
      });
   }
});
1 голос
/ 11 июня 2011

Если вы используете jquery.tinymce.js, тогда вам не нужно tiny_mce.js, потому что TinyMCE попытается загрузить его с помощью запроса ajax. Если вы обнаружите, что window.tinymce (или просто tinymce) равно undefined, то это означает, что ajax еще не завершен (что может объяснить, почему использование setTimeout для вас работает). Это типичный порядок событий:

  1. Загрузка jquery.js с тегом скрипта (или загрузка в Google).
  2. Загрузите JQuery-плагин TinyMCE, jquery.tinymce.js, с тегом скрипта.
  3. Документ готов к событиям пожаров; Здесь вы звоните .tinymce(settings) на ваши textarea с. Например. $('textarea').tinymce({ script_url: '/tiny_mce/tiny_mce.js' })

  4. Загрузка tiny_mce.js этот шаг выполняется для вас с помощью плагина TinyMCE jQuery, но это может произойти после того, как сработает событие готовности документа.

Иногда вам действительно может понадобиться доступ к window.tinymce, вот самый безопасный способ сделать это:

$ (Документ) .tinymce ({ 'script_url': '/tiny_mce/tiny_mce.js' 'setup': function () { оповещения (TinyMCE); } }); * * Тысячу тридцать-два

TinyMCE зайдет так далеко, что создаст объект tinymce.Editor и выполнит обратный вызов установки. Ни одно из событий редактора не инициируется, и объект редактора, созданный для документа, не добавляется в tinymce.editors.

Я также обнаружил, что ajax-вызов TinyMCE мешает моим .ajaxStop функциям, поэтому я также использовал setTimeout:

$ (Документ) .tinymce ({ 'script_url': '/tiny_mce/tiny_mce.js' 'setup': function () { setTimeout (function () { $ (document) .ajaxStart (function (e) {/ * stuff /}); $ (document) .ajaxStop (function (e) {/ stuff * /}); }, 0); } }); * * 1 044

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...