2013-08-01 2 views
0

Когда я делаю вызов AJAX для замены div, ответ содержит тег скрипта, указывающий на внешний .js-файл. Однако я не могу заставить возвращенный JS выполнить. Я попытался оценить() ответ, но это не сработало. Я также попытался вызвать функцию внутри внешнего .js-файла из обратного вызова onComplete, но это также не работает. Не уверен, что еще делать. Я использую ядро ​​MooTools 1.4.5Javascript-файл не выполняется после вызова AJAX

Главная страница в JS

window.addEvent('domready', function(){ 

    function ajaxfunc(i) 
    { 
     return function(e){ 
      e.stop(); 
      var requestData = new Request({ 
       url: 'blah.php?cat=' + i, 
       evalScripts: true, 
       evalResponse: true, 
        onComplete: function(response){ 
         $('rt-main').set('html', response); 
        } 
      }); 
      requestData.send(); 
     }; 
    } 

    var total = $('cat_table').getChildren('div').length; 
    for(var i=1; i<=total; i++) 
    { 
     $('catClick'+i).addEvent('click', ajaxfunc(i)); 
    } 


}); 

Возвращаемый HTML

<script src="listings.js" type="text/javascript"></script> 
...(other markup, etc) 

И внутри этого файла listings.js

window.addEvent('domready', function(){ 

    function gotoItem(i) 
    { 
     return function(e){ 
      e.stop(); 
      var id= i; 
      var requestData = new Request ({ 
      url: 'blah.php?id='+id, 
      onComplete: function(response){ 
       $('rt-main').set('html', response); 
      } 
      }); 
      requestData.send(); 
     }; 
    } 

    $$('.itemBox').each(function(el){ 
     el.getElement('a.itemClick').addEvent('click', gotoItem(el.id)); 
    }); 

}); 

Среда I Работает в Joomla 3.1, если это влияет на что-либо.

+0

Является ли скриптовый файл '.js' новым вызовом ajax? – Sergio

+0

Является ли этот тег сценария визуализированным html? Если вы не можете опубликовать свой 'blah.php', в этой части вы разбираете скрипт. Может быть, это связано с тем, чтобы ускользнуть от тегов. Как выглядит «ответ»? – Sergio

+0

Во втором файле .js это действительно другой вызов AJAX. Я хотел добавить новых слушателей событий, когда вторая страница вызывается через AJAX. Тег скрипта, который вы видите, является частью отображаемого HTML. Тег скрипта из blah.php напрямую жестко закодирован (в MVC я жестко запрограммировал его в представлении). то есть я не использую echo для вывода этого тега скрипта. – ehz350

ответ

2

No domready будет стрелять во второй раз для вас в соответствии с вашими листингами.js, ваш DOM уже готов.

Вы можете вручную сделать window.removeEvents('domready') заранее, затем загрузить через XHR и выполнить window.fireEvent('domready') для его запуска.

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

window.addEvent('domready', function() { 
    var ct = document.id('cat_table'), 
     divs = ct.getChildren('div'), //need a more qualified selector 
     rtMain = document.id('rt-main'); 

    divs.each(function(el, i){ 
     // store the index, if you don't have it as an attribute like id, rel or data-id 
     el.store('index', i); 
    }); 

    ct.addEvent('click:relay(div)', function(e){ // needs more qualified also. 
     e && e.stop(); 

     new Request({ 
      method: 'get', // not post, check - faster 
      url: 'blah.php?cat=' + this.retrieve('index'), 
      evalResponse: true, 
      onComplete: function(){ 
       rtMain.set('html', this.response.text); 
      } 
     }).send(); 
    }); 

    // delegation, assumes .itemBox are children of rtMain - just delegate to other parent otherwise. 
    rtMain.addEvent('click:relay(.itemBox)', function(e){ 
     // reliance on index in collection is bad, try to change response above to contain data-id. 
     e.stop(); 

     new Request({ 
      method: 'get', 
      url: 'blah.php?id=' + this.get('data-id'), 
      onComplete: function(){ 
       rtMain.set('html', this.response.text); 
      } 
     }).send(); 
    }); 
}); 

иметь в виду, вы имели зависимость от индекса элемента в коллекции элементов, которые меньше, чем сейф. используйте идентификатор жесткого db, предоставляемый бэкэнд. это небезопасно, ppl может модифицировать DOM, удалять элементы и получать идентификаторы, которые они не должны видеть. Не то, чтобы они не могли сделать это иначе, но ...

Внесение скриптов через XHR и уклонение откликов является анти-шаблоном и дает вектор атаки на вашу страницу для XSS, не забывайте об этом.

+0

Спасибо за ответ! Как именно вы предоставили сценарию жесткий идентификатор db, не извлекая его из разметки? То, как я это понимаю, единственный способ для любого скрипта получить идентификаторы - это путь: DB> PHP> HTML> JS. Или вы говорите, что лучше иметь идентификатор, который неясен, чтобы избежать атак? – ehz350

0

Похоже, что сценарий в связанном .js завернут в событие «domready», но (я здесь немного здесь), дом уже уволил бы готовое событие. Попробуйте удалить обертку window.addEvent('domready', function(){ ...}.

EDIT, так как вы говорите, что это не так может он работать для вас, если вместо возвращения тега сценария, вы просто вернули сценарий, и приложил его к странице, как это:

onComplete: function (response) { 
    // 
    var script = document.createElement('script'); 
    script.innerHTML = response; 
    document.getElementById('rt-main').appendChild(script); 

} 

EDIT I» я просто играл с этим немного, и, похоже, у меня есть неэлегантное решение fiddle.

+0

Спасибо, что ответили. Я тоже пробовал это, но безрезультатно. Я пробовал просматривать Firebug, чтобы узнать, загружен ли сценарий в DOM. Похоже, что нет. – ehz350

+0

hmm ... могу ли я смело предположить, что вы вызываете функцию, которая возвращается из 'ajaxfunc', то есть: var n = ajaxfunc (event); п(); –

+0

Этот вопрос можно задать двумя способами. 1) Возвращаемое значение ajaxfunc - это еще одна функция. Это делается из-за использования циклов с закрытием. Таким образом, да, эта функция вернулась, действительно вызвана, и это подтверждается действующим вызовом AJAX. 2) Файл .js ответа AJAX не имеет функции для вызова. Вместо этого я хочу, чтобы он автоматически запускал прослушиватели событий. Однако это не работает. Я нажимаю на якорь, и он никуда не годится. – ehz350

Смежные вопросы