2012-07-03 4 views
7

Мне нужно вызвать функцию во внешнем файле .js из другого файла .js, не ссылаясь на внешний файл в теге <head>.Вызов функции в одном файле Javascript из другого файла Javascript?

Я знаю, что можно динамически добавить внешний файл «.js» в который позволяет получить доступ к этому файлу, я могу сделать это как так ...

var AppFile = "test/testApp_1.js"; 
var NewScript=document.createElement('script'); 
var headID = document.getElementsByTagName("head")[0]; 
NewScript.src = AppFile; 
headID.appendChild(NewScript); 

Однако ...

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

$(document).ready(function() 
{...} 

так что добавление полного файла динамически имеет нежелательный эффект. Кроме того, я не могу предварительно ссылаться на внешний файл в теге <head>, поскольку он должен быть динамическим. Таким образом, этот внешний файл "test/testApp_1.js" содержит функцию, которая возвращает строку переменной ...

function setAppLogo(){ 

var LogoFile = "test/TestApp_1_Logo.png"; 

return LogoFile; 
}  

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

Этот человек уже несколько часов был у меня в тупике, поэтому любые идеи были бы весьма благодарны.

+0

Почему вы не можете динамически добавлять в ''? domready не будет срабатывать, пока не будут загружены все JS, CSS и HTML ... – Rudie

+0

, потому что, динамически добавляя в голову, я в конечном итоге запускаю код, который здесь не нужен. Мне нужно только одно значение переменной из этого файла, а не весь файл. – user1005240

+0

Вы не можете загрузить часть файла ... Вы можете загрузить его с помощью XHR, а затем 'eval()' результат ... Но вы не должны. – Rudie

ответ

0

Вы хотите загрузить файл после загрузки jQuery с помощью ajax, а затем запустить соответствующий скрипт в успешной функции ajax.

функция getScript знакомства JQuery в: http://api.jquery.com/jQuery.getScript/

$(document).ready(function(){ 
$.getScript("http://domain.com/ajax/test.js", function(data, textStatus, jqxhr) { 
    console.log(data); //data returned 
    console.log(textStatus); //success 
    console.log(jqxhr.status); //200 
    console.log('Load was performed.'); 
    //run your second script executable code here 
}); 
}); 
+2

OP сказал, что «добавление полного файла динамически имеет нежелательный аффект», это точно так же, как добавление скрипта в заголовок. – jbabey

+0

да, этот код запускает полный файл, который имеет нежелательные эффекты здесь, действительно, мне нужно, чтобы он мог окунуться в этот файл и запустить только одну функцию, в которой я нуждаюсь, что-то вроде ... 'myFile.theFunctionINeed();' или получить значение переменной в файле, то есть 'myFile.globalVar_1' – user1005240

0

можно загрузить весь сценарий через XHR (например $.get in jQuery), а затем разобрать его, возможно, с использованием регулярных выражений, чтобы извлечь нужную часть:

$.get('pathtoscript.js', function(scriptBody) { 
    var regex = /function\s+setUpLogo\(\)\s*\{[^}]+}/g; 
    alert(scriptBody.match(regex)[0]); // supposed to output a function called 
             // 'setUpLogo' from the script, if the 
             // function does not have {} blocks inside 
}); 

Тем не менее, следует отметить, что такой подход, скорее всего, вызовет препятствия для обслуживания. Регулярные выражения не являются лучшим инструментом для анализа кода JavaScript; пример выше, например, не будет анализировать функции с вложенными {} блоками, которые вполне могут существовать в рассматриваемом коде.

Может быть рекомендовано найти решение проблемы на стороне сервера, например. добавление необходимого пути сценария или его части до отправки страницы в браузер.

+0

Мне нравится ваша идея! его немного сумасшедший, но я думаю, что это сработает ... я мог бы написать функцию, чтобы взять файл, затем проанализировать его для желаемой функции, ее безумной и, вероятно, плохой идеей, но это «из коробки» мышления это круто, чтобы приблизиться! :) – user1005240

0

Я не уверен, что это хорошая идея, но вы можете создать iframe и eval файл внутри его объекта «window», чтобы избежать большинства нежелательных побочных эффектов (при условии, что он не пытается получить доступ к его родительскому элементу). Затем вы можете получить доступ к любой функции/переменной, которую вы хотите, через объект окна iframe.

Пример:

function loadSomeJsInAFrame(url,cb) { 
     jQuery.get(url,function(res) { 
      iframe = jQuery('<iframe></iframe>').hide().appendTo(document.body); 
      iframe[0].contentWindow.eval(res); 
     if(cb) cb(iframe[0].contentWindow); 
    },'text'); 
} 

loadSomeJsInAFrame('test/testApp_1.js',function(frameWindow) { 
    console.log(frameWindow.setAppLogo()); 
    jQuery(frameWindow.frameElement).remove(); 
}); 

Это не гарантирует, что sript в файле не могут испортить с документом, но вряд ли, если она исходит от доверенного источника.

Кроме того, не забудьте удалить свой iframe после того, как получите от него то, что вам нужно.

1

Возможно, вам будет полезен файл app.js, содержащий глобальные переменные/значения, которые вы хотите использовать из большого количества мест. Вы должны включить этот файл .js на каждую страницу (и, возможно, его минимизировать/объединить с другими js, если вы хотите быть умным и повысить производительность). Как правило, эти глобальные привязки должны быть привязаны к некоторому объекту, который вы создаете, например, var APPNAME = { }; с переменными/функциями на нем, которые будут использоваться из многих мест.

После этого внешний файл '.js', который вы хотите загрузить, и тот, который вы сейчас используете, могут обращаться к глобальной переменной APPNAME и ко всем ее атрибутам/функциям и использовать их по желанию. Это может быть лучшим подходом для того, чтобы сделать ваш javascript более модульным и разделяемым. Надеюсь это поможет.

0

Хорошо, спасибо всем за вход, но я думаю, что то, что я пытаюсь сделать, в настоящее время невозможно, то есть получить доступ к функции из другого файла без загрузки этого файла. Я, однако, нашел решение моей проблемы. Теперь я запрашиваю у своего сервера список доступных приложений, затем я использую этот список для динамического создания приложений в пользовательском интерфейсе. при выборе приложения затем я могу вызвать этот файл и функции внутри. Его немного сложнее, но его динамичность, хорошая производительность, и она работает. Еще раз спасибо за мозговой штурм! ;)

0

Это может быть возможно с помощью Web Workers. Вы могли бы запустить свой скрипт, который вы хотели бы ввести в отдельную среду, поэтому он не испортит вашу текущую страницу.

Как вы сказали, возможно, что setAppLogo будет глобальным в пределах "test/testApp_1.js", поэтому я буду полагаться на это утверждение.

В оригинальном сценарии вы должны создать рабочую, какие ссылки на файл рабочего сценария + прослушать сообщения, которые будут исходить от работника:

var worker = new Worker('worker.js'); 
worker.onmessage = function (e) { 
    // .... 
}; 

Затем в рабочем (worker.js), вы могли бы используйте специальную функцию importScripts (docs), которая позволяет загружать внешние скрипты в рабочий, рабочий также может видеть глобальные переменные этих скриптов. Также есть функция postMessage, доступная в рабочем состоянии для отправки пользовательских сообщений обратно в исходный скрипт, который, в свою очередь, прослушивает эти сообщения (worker.onmessage). Код для worker.js:

importScripts('test/testApp_1.js'); 

// "setAppLogo" is now available to worker as it is global in 'test/testApp_1.js' 

// use Worker API to send message back to original script 
postMessage(setAppLogo()); 

Когда он вызывает, вы получите результат setAppLogo в вас слушателю:

worker.onmessage = function (e) { 
    console.log(e.data); // "test/TestApp_1_Logo.png" 
}; 

Этот пример очень простой, хотя, вы должны прочитать больше о Web Workers API и возможно подводные камни.

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