2012-01-30 1 views
1

. Функция, приведенная ниже, предназначена для захвата/обработки HTML либо селектора jQuery, либо URL-адреса. Если URL-адрес передан, он генерирует iframe и после загрузки iframe захватывает HTML-код iframe. (. Примечание: Я не использую внешние URL-адреса, только другие страницы на том же сайте)Получение содержимого iframe вызывает TypeError: «undefined» не является объектом

Функция бросает TypeError: 'undefined' is not an object (evaluating 'myHTML.find') всякий раз, когда я прохожу в URL. Я не понимаю, почему. Здесь что-то выделяется?

1 mynamespace.html: function (source) { 
2 // Grabs and processes the HTML of a jQuery selector or URL. 
3  
4  var myHTML; 
5 
6   if ($(source).is('iframe')) { 
7   // if it's an iframe, use .contents() 
8   myHTML = $(source).contents().find('html').clone(); 
9 
10  } else if (source.indexOf('http://') === 0) { 
11   // if it's a URL, load an iframe 
12   $(document.body).append('<iframe id="printiframe" src="'+source+'"></iframe>'); 
13   $('#printiframe').load(function() { 
14    // once loaded, send it back into this function, 
15    // where it can then be processed as an iframe 
16    return mynamespace.html ('#printiframe'); 
17   }); 
18 
19  } else { 
20   myHTML = $(source).clone(); 
21  } 
22  
23  // Do stuff to the HTML here, such as myHTML.find('bla')... 
24 
25  return myHTML.html(); 
26 } 
+0

ли ваша страница и IFrame сидеть тот же домен? – Hadas

+0

Да, iframe src и все остальное находятся в моем единственном домене. – supertrue

+0

Надеюсь, вы не возражаете против редактирования, но я помещаю номера строк, чтобы ответы могли легко ссылаться на части вашего кода. – nnnnnn

ответ

2

Я надеюсь, вы не против, но я редактировал свой вопрос, чтобы добавить номера строк кода для удобства, а не повторять весь код здесь.

Во всяком случае, я считаю, что проблема с else if ветви, начиная с линией 10. Последовательность выполнения будет:

  • Line 12 - добавьте IFRAME
  • Line 13 - сделать запрос Ajax .load()
  • линии 18/19 - конец ветви
  • линии 22-24 - где у вас есть свой комментарий о делать вещи, в какой момент myHTML не было присвоено значение (отсюда ошибки вы получаете)
  • Line 25 - возврат из функции

Затем, после асинхронных Ajax возвращается запрос:

  • Линия 16 - тело функции обратного вызова вы предусмотрели.

Это то, как работает асинхронный код - независимо от того, насколько быстро выполняется запрос, обратный вызов не будет вызываться до тех пор, пока не завершится выполнение другого кода. Оператор return в строке 16 не возвращается с вашей функции mynamespace.html(), он возвращается из этого обратного вызова (и ничто не обращает на это внимание).

Вы могли бы попытаться перестроить свой код немного использовать синхронный запрос АЯКСА, в этом случае выполнения будет паузой в строке 13, пока ответ не возвращается, но это дает плохой опыт для пользователя, потому что браузер будет не реагирует в среднем.

Лучше реструктурировать, чтобы придерживаться стандартного aysnc Ajax и разрешить порядок выполнения, описанный выше. Не зная, как называется ваш mynamespace.html(), я не уверен, что смогу это посоветовать.

Я считаю, что вы зашли на мель в "Same Origin Policy", также иногда называемый «политикой безопасности кросс-домена» или другими вариантами этой темы.

Вы не указываете, какие типы URL вы вводите, но в общем смысле JavaScript, работающий в одном кадре, не может получить доступ к содержимому другого фрейма, если источник из другого домена.

(Есть некоторые обходные пути, чтобы получить кадры междоменных общаться друг с другом, но только если оба сотрудничают. - которое не было бы дела здесь)

+0

Да, я знаю об этих проблемах - я на самом деле просто использую один домен, тот же домен, что и скрипт. – supertrue

+0

О, извините. Позвольте мне изменить ... – nnnnnn

+0

Спасибо, это действительно информативно. Функция просто вызвана событием клика. Как я мог бы реструктурировать учетный порядок выполнения? Я предполагаю, что одним из способов было бы отделить HTML «получение» от обработки HTML, например my.HTMLget() и my.HTMLprocess(), и сделать my.HTMLprocess() функцию обратного вызова в вызове iframe .load(). – supertrue