Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   подгрузить файл скрипта на событие (https://javascript.ru/forum/events/3373-podgruzit-fajjl-skripta-na-sobytie.html)

LamerNo1 13.04.2009 16:20

подгрузить файл скрипта на событие
 
подскажите пож-та реально ли подгрузить файл скрипта на событие, т.е. например:

<input type="button" onclick="hello()">

<script>
function hello() {
<script src="blabla.js" type="text/javascript"></script>;
}
</script>


т.е. понятно что такое работать не будет, а как сделать чтоб работало

Kolyaj 13.04.2009 16:22

var s = document.createElement('script');
s.src = 'blabla.js';
document.body.appendChild(s);

LamerNo1 13.04.2009 16:23

Блин тут все гении сидят...
Я почувствовал себя младенцем :(

Kolyaj 13.04.2009 16:25

Цитата:

Сообщение от LamerNo1
LamerNo1

Как корабль назовешь :)

LamerNo1 13.04.2009 16:37

в моем случае надувной матрас... но он растет :)

LamerNo1 13.04.2009 16:59

Цитата:

Сообщение от Kolyaj (Сообщение 16545)
var s = document.createElement('script');
s.src = 'blabla.js';
document.body.appendChild(s);

не работает :(

я правильно понял?

<input type="button" onclick="loadscrcou();">

<script>
function loadscrcou() {
var loadscript = document.createElement('script');
loadscript.src = '../new/js/couscr/Spaot.js';
document.body.appendChild(loadscript);
}
</script>

LamerNo1 13.04.2009 17:08

Вернее в мозилле не работает, а в ИЕ ок

Kolyaj 13.04.2009 17:14

var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'blabla.js';
document.body.appendChild(s);
А так?

LamerNo1 13.04.2009 17:24

Цитата:

Сообщение от Kolyaj (Сообщение 16554)
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'blabla.js';
document.body.appendChild(s);
А так?

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

Kolyaj 13.04.2009 17:26

Странно конечно
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'blabla.js?' + Math.random();
document.body.appendChild(s);

Gvozd 13.04.2009 17:44

подозреваю, что более кросбраузерно будет атачить к head-у
вот код из статьи
function attachScript(id, src){
var element = dojo.doc.createElement("script")
element.type = "text/javascript"
element.src = src
element.id = id
document.getElementsByTagName("head")[0].appendChild(element)
}

Kolyaj 13.04.2009 17:47

Цитата:

Сообщение от Gvozd
подозреваю, что более кросбраузерно будет атачить к head-у

Без разницы.

LamerNo1 13.04.2009 17:47

не грузит :(
и ИЕ через раз
буду стучать бубном...

LamerNo1 13.04.2009 18:19

Цитата:

Сообщение от Gvozd (Сообщение 16557)
подозреваю, что более кросбраузерно будет атачить к head-у
вот код из статьи
function attachScript(id, src){
var element = dojo.doc.createElement("script")
element.type = "text/javascript"
element.src = src
element.id = id
document.getElementsByTagName("head")[0].appendChild(element)
}

а что это за dojo???

Gvozd 14.04.2009 00:34

я упо скопипастил код из статьи.
это часть фреймворка, и dojo.doc Это наврено обертка над document
в лданном случае можно спокойно писать document.createElement("script")

LamerNo1 14.04.2009 13:51

Цитата:

Сообщение от Gvozd (Сообщение 16583)
я упо скопипастил код из статьи.
это часть фреймворка, и dojo.doc Это наврено обертка над document
в лданном случае можно спокойно писать document.createElement("script")

Всем спасибо за подсказки... с кнопкой работает..
в идеале нужно чтоб работало на window.onload
дело в том что изначально срабатывает php script который определяет isset или !isset переменная, и если определена выводит documen.onload, который в свою очередь подгружает файл скрипта

работает:
<input type="button" onclick="loadscr1()">
<script>
function loadscr1() {
var scri = document.createElement('script');
scri.setAttribute('type', 'text/javascript');
scri.src = 'new/js/couscr/Script.js';
document.getElementsByTagName('head')[0].appendChild(scri);
}
</script>


не работает:
<script>
window.onload = function () {
loadscr1();
}
</script>
<script>
function loadscr1() {
var scri = document.createElement('script');
scri.setAttribute('type', 'text/javascript');
scri.src = 'new/js/couscr/Script.js';
document.getElementsByTagName('head')[0].appendChild(scri);
}
</script>


и через jquery пытался сделать не получилось..
так: <body onload="loadscr1()"> тоже не хотелось бы

Gvozd 14.04.2009 17:30

во втором варианте либо поменяй местами теги script, либо объедени их в один(тогда местами можно не менять)
рпоблема в том, что в момент, когда ты пытаешся повесить событие, функция loadscr1() еще не определена
Ее надо либо определить в более раннем блоке script
либо просто поместить в тот же блок(в таком случае она будет видна, даже если будет написана позже.но только если ее определять как ты написал)
<script>
function loadscr1() {
var scri = document.createElement('script');
scri.setAttribute('type', 'text/javascript');
scri.src = 'new/js/couscr/Script.js';
document.getElementsByTagName('head')[0].appendChild(scri);
}
window.onload = function () {
loadscr1();
}
</script>

LamerNo1 14.04.2009 19:42

пробовал поменять, ща еще попробую

x-yuri 15.04.2009 17:33

первый вариант, предложенный Kolyaj, у меня работает:
window.onload = function() {
	var s = document.createElement('script');
	s.src = '1.js';
	document.body.appendChild(s);
}

1.js:
alert(2);

проверял в ie 7, ff 3, opera 9. Либо у тебя более старые версии, либо специфический скрипт

LamerNo1 15.04.2009 20:21

Цитата:

Сообщение от x-yuri (Сообщение 16689)
первый вариант, предложенный Kolyaj, у меня работает:
window.onload = function() {
	var s = document.createElement('script');
	s.src = '1.js';
	document.body.appendChild(s);
}

1.js:
alert(2);

проверял в ie 7, ff 3, opera 9. Либо у тебя более старые версии, либо специфический скрипт

Так работает, но в файле скрипта обязательно должна быть прописана функция... тамскрипт не просто алерт :)
может попробовать таймаут выставить... секнду-две

Kolyaj 15.04.2009 20:44

Цитата:

Сообщение от LamerNo1
в файле скрипта обязательно должна быть прописана функция... тамскрипт не просто алерт
может попробовать таймаут выставить... секнду-две

Че?

x-yuri 15.04.2009 23:22

LamerNo1 в любом случае надо выяснить причину, т.е. постепенно сокращать скрипт, пока он не станет запускаться. Например, в конце скрипта можно вставить тот же alert. При это появление диалогового окна будет означать, что скрипт запустился

azgard 03.05.2009 02:12

Так получилось сделать?

Pattern 29.05.2009 00:31

test.js
var AnyElem={
	param1: 'val1',
	param2: 2,
	setParam: function(p,v){
		if(this[p]&&v){
			this[p]=(typeof this[p]==='string')?v.length>0?v:'':parseInt(v);
		}
	}
};

index.html
<html>
<head>
<script language="javascript">
function loadSrc(p){
	if(p&&p.length>0){
		var s=document.createElement('script');
		with(s){
			setAttribute('type', 'text/javascript');
			setAttribute('language', 'javascript');
			src=p;
		}
//		document.getElementsByTagName('head')[0].appendChild(s);
		document.body.appendChild(s);
	}
}
var init=function(){
	loadSrc('test.js');
	console.log(AnyElem);
}
</script>
</head>
<body onload="init()">
</body>
</html>

Лог консоли FF3
Цитата:

AnyElem is not defined
init()()index.html (line 18)
onload(load )5R3LNk3t...zow%3D%3D (line 2)
[Break on this error] console.log(AnyElem);
Ничего не понял, у кого и что работает? :blink:

x-yuri 29.05.2009 00:55

jquery, например, так не делает, она создает элемент, в который вставляет скрипт, а потом этот элемент вставляет в документ. Примерно так:
var script = document.createElement("script"),
id = "script" + (new Date).getTime();
	script.type = "text/javascript";
	try {
		script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
	} catch(e){}

	root.insertBefore( script, root.firstChild );
	
	// Make sure that the execution of code works by injecting a script
	// tag with appendChild/createTextNode
	// (IE doesn't support this, fails, and uses .text instead)
	if ( window[ id ] ) {
		jQuery.support.scriptEval = true;
		delete window[ id ];
	}

	root.removeChild( script );


	// Evalulates a script in a global context
	globalEval: function( data ) {
		if ( data && /\S/.test(data) ) {
			// Inspired by code by Andrea Giammarchi
			// [url]http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html[/url]
			var head = document.getElementsByTagName("head")[0] || document.documentElement,
				script = document.createElement("script");

			script.type = "text/javascript";
			if ( jQuery.support.scriptEval )
				script.appendChild( document.createTextNode( data ) );
			else
				script.text = data;

			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
			// This arises when a base node is used (#2709).
			head.insertBefore( script, head.firstChild );
			head.removeChild( script );
		}
	},

p.s. по-моему ничего важного не пропустил

Kolyaj 29.05.2009 09:04

. .

Pattern 29.05.2009 10:15

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

x-yuri 29.05.2009 10:37

да уж, сообщение: "Подгружаются все скрипты, приходите завтра!" :)
p.s. я и не говорил, что нужно этим повсеместно пользоваться

B~Vladi 02.06.2009 10:56

Я делал немного проще...

var head=document.documentElement.firstChild; // Есть и другие варианты получить head. Кому как удобнее.

// Подключаем скрип
var js=document.createElement('script');
js.type='text/javascript';
js.src='script.js';
head.appendChild(js);

//Подключаем стили (так... до кучи...)
var css=document.createElement('link');
css.href='style.css';
css.media='screen'; //all, print ect.
css.rel='stylesheet';
css.type='text/css';
head.appendChild(css);


Работает везде, где нада (не придерацца к мелочам!!).
Проверить загрузился ли скрипт нужно вариантом с callback имхо.

Более точно проверять можно при использовании аякс. Получили в xml, распарсили, вставили(как вариант).

Kolyaj 02.06.2009 12:09

B~Vladi,
для общего развития. Попробуйте запустить ваш код в ИЕ6 в контексте такой вот страницы.
<html>
<head>
    <base href="/" />
    <script type="text/javascript">
        var head=document.documentElement.firstChild; // Есть и другие варианты получить head. Кому как удобнее.
        var js=document.createElement('script');
        js.type='text/javascript';
        js.src='script.js';
        head.appendChild(js);
    </script>
</head>
<body>
</body>
</html>

B~Vladi 02.06.2009 12:15

Цитата:

Сообщение от Kolyaj
для общего развития. Попробуйте запустить ваш код в ИЕ6 в контексте такой вот страницы.

:lol:
НЕЛЬЗЯ обращацца к элементам из хеда :). В твоём варианте мы можем не получить ссылку на хед, т.к. дом не собран. Зачем извращаться?! парню нада динамично(т.е. по событию) вставить скрипт и этот вариант РАБОТАЕТ в 6-ом ишаке;)

Kolyaj 02.06.2009 12:22

Цитата:

Сообщение от B~Vladi
НЕЛЬЗЯ обращацца к элементам из хеда

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

B~Vladi 02.06.2009 13:58

Kolyaj, я бы не стал пользовацца такими методами... уж больно это ненадёжно... вставлять скриптом другой скрипт в хеде это пооолное извращение. Если необходимо по событию прикрутить скрипт/стиль - мой вариант вполне с этим справляется. Стабильно работает в ие6,7,8, опера,9.2, 9.6, 10, мозилла 2, 3, хром (проверено) - что забыл?! Сафари?! протести еси не лень плз.

Вот небольшая вырезка.

Элемент BASE задает в обязательном атрибуте href базовый URI для данного документа, который используется обозревателем для приведения относительных URI к полным. Подробности см. в Приложении 2.

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

когда документ хранится в нескольких узлах Сети, и мы хотим указать "эталонное" хранилище;
когда URI документа неизвестен (например, при его получении по электронной почте).
Рассмотрим следующий пример:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
  <TITLE>Наша продукция</TITLE>
  <BASE href="http://www.bestseller.com/products/intro.html">
</HEAD>
<BODY>
  <P>Лучшие в мире <A href="images/hornhoof.gif">рога и копыта</A>!
</BODY>
</HTML>

С учетом базового URI ссылка "../images/hornhoof.gif" в этом примере соответствует полному URI "http://www.bestseller.com/images/hornhoof.gif".

Заметь 2 вещи:

1."поэтому на практике элемент BASE употребляется только в двух ситуациях". Скажи мне 3-ю, где нада вставлять этот тег?!

2."<BASE href="http://www.bestseller.com/products/intro.html">". Т.е. ссылка должна указывать на документ а не на дирректорию. Получается в твоём варианте неверно указано значение атрибута.

B~Vladi 02.06.2009 14:04

Я если чесно не тестил, в чём же ошибка и где падает скрипт, но сдаёцца мне, что из-за этого base мы просто не можем найти скрипт вот и всё.

Kolyaj 02.06.2009 14:09

Цитата:

Сообщение от B~Vladi
я бы не стал пользовацца такими методами... уж больно это ненадёжно... вставлять скриптом другой скрипт в хеде это пооолное извращение.

Все надежно, когда знаешь, как что работает. И извращения тут нет никакого. Привыкли все просто к $.ready, вот и разучились своей головой думать :)

Цитата:

Сообщение от B~Vladi
Получается в твоём варианте неверно указано значение атрибута.

Ну укажи правильное, все равно ИЕ рухнет. Не в значении дело.

Дело не в том, нужно ли использовать тег base, бывают ситуации, когда он нужен, а бывают -- когда над HTML-кодом ты не властен, а всякие умники туда хрень всякую вставляют.

Kolyaj 02.06.2009 14:18

Вынес в отдельную тему http://javascript.ru/forum/css-html-...a-podumat.html


Часовой пояс GMT +3, время: 01:22.