Можно ли ссылаться на функцию или объект из определенного тега script в HTML файл
Представьте, что в файле HTML есть следующий код:
<script id='tag-1'>
function foo(){
alert("this is foo-1");
}
</script>
<script id='tag-2'>
function foo(){
alert("this is foo-2");
}
</script>
<script id='tag-3'>
function foo(){
alert("this is foo-3");
}
</script>
Можно ли вызвать функцию foo
из тега script с id tag-2
?
Мне просто интересно узнать, есть ли кросс-браузерное решение? Спасибо, ребята.
Хорошо, у нас есть два очень важных предложения - тот, который я обозначил для принятого ответа, и еще один комментарий, стоящий ниже этого сообщения - тот, который предлагает @dfsq. Спасибо всем, ребята!!!
Ответы
Ответ 1
Да, это вполне возможно, но вы должны использовать другой тип, кроме text/javascript.
<script id='tag-1' type="myScriptHolder">
function foo(){
alert("this is foo-1");
}
</script>
<script id='tag-2' type="myScriptHolder">
function foo(){
alert("this is foo-2");
}
</script>
<script id='tag-3' type="myScriptHolder">
function foo(){
alert("this is foo-3");
}
</script>
<script>
$.globalEval($('#tag-1').text();
</script>
Ответ 2
Нет, это невозможно, не прибегая к eval()
.
Как только каждый блок script оценивается браузером, предыдущие версии функции перезаписываются.
Вы можете получить доступ к текстовому контексту каждого тега <script>
, но только в том случае, если он встроен. Для доступа к тегу <script src="...">
требуется AJAX.
Ответ 3
Нет, это невозможно. Все Javascript-коды в одном окне имеют одно и то же пространство имен, поэтому то, что вы делаете в своем примере, просто переопределяет foo
, что означает, что в итоге у вас есть только "foo-3".
iframes имеют собственное пространство имен, но было бы бесполезно использовать iframes для чего-то вроде этого.
Если функции нужны только для их соответствующих скриптов, вы можете обернуть каждый script в функцию самоисполнения, например
(function() {
function foo(){
alert("this is foo-1");
}
})();
Это означало бы, что foo
будет недоступным извне, чем script, который, очевидно, может работать или не работать для вас в зависимости от того, где используется функция.
Единственной альтернативой может быть создание собственных пространств имен для функций, например:
var namespace1 = {};
namespace1.foo = function foo() {...}
Ответ 4
Javascript не имеет функции перегрузки. Каждое следующее объявление с тем же именем (переменная или функция) просто повторно объявляет его с предоставленным новым значением. Таким образом, в вашем случае функция из tag-3 будет всегда выполняться.
Возможное решение того, что вы хотите -
1. Дайте разные имена для каждой функции.
или
2. Если вы ожидаете, что функции будут вызываться по-разному в зависимости от предоставленных аргументов. Вы можете проверить объект неявных аргументов внутри функции и выполнить необходимые операции в зависимости от этого.
Простой пример второго решения можно задать следующим образом.
function foo(bar){
if(typeof bar==="number"){
//Do number specific stuff here
} else if(typeof bar==="string"){
//Do string specific stuff here
} else {
}
}
Ответ 5
Вы можете реализовать технику имен имен javascript, которая довольно распространена. Это создает новый объект javascript, который доступен, и вы можете ссылаться через вызовы CodeGuru.File1.Foo();
var CodeGuru = CodeGuru || {};
var CodeGuru.File1 = CodeGuru.File1 || {};
(function(CodeGuru) {
CodeGuru.File1.Foo = function() {
//insert code
}
})(CodeGuru);
Ответ 6
Как насчет чего-то вроде этого:
if (typeof (GenLib) == "undefined") GenLib = {};
GenLib.Tag1 = {};
GenLib.Tag2 = {};
GenLib.Tag3= {};
GenLib.Tag1.Foo = function () {
alert("this is foo-1");
};
GenLib.Tag2.Foo = function () {
alert("this is foo-2");
};
GenLib.Tag3.Foo = function () {
alert("this is foo-3");
};
var theOneYouWantNow = GenLib.Tag2; // Or Tag1 or Tag3, use if/switch/whatever here.
theOneYouWantNow.Foo();