$.ajax({ url: "plugin.js", dataType: 'script', cache: true, success: function() {
alert('loaded');
}});
1) I can't get the script to load, probably due to incorrect path, but how do I determine the correct path? The above code is in init.js, plugin.js is also in the same folder.
2) Can I load multiple plugins at once with the same request? eg. plugin.js, anotherplugin.js?
root
|
|_ html > page.html
|
|_ static > js > init.js, plugin.js
Thanks for your help
You need to use getScript, not ajax. Ajax is for loading data, not for executing code.
If you need to load multiple files, try something like this:
var scripts = ['plugin.js', 'test.js'];
for(var i = 0; i < scripts.length; i++) {
$.getScript(scripts[i], function() {
alert('script loaded');
});
}
1) The path will be relative to the page it's loaded from (not the path of your init script) since that's the url the browser will be at when it executes the ajax request.
Edit: Based on your edit, the path to load your script from is either /static/js/plugin.js (if it'll be deployed at the root of your domain), or ../static/js/plugin.js to be safe (assuming all pages that it'll be loaded from will be in /html).
2) No. If they're in different files, they'll need to be different requests. You could merge them into one file on the server-side though...
As an update, the better way to do this with jQuery 1.9.x is to use Deferreds-methods (i.e. $.when), such as follows:
$.when(
$.getScript('url/lib.js'),
$.getScript('url/lib2.js')
).done(function() {
console.log('done');
})
The .done() callback function has a number of useful params.
Read the documentation: http://api.jquery.com/jQuery.when/
Check out the jQuery .getScript function, which will load the script and include it in the current document.
1) The path should be /static/js/plugin.js, relative to your document.
2) No. Each file is loaded by a single HTTP request.
I would check Firebug's net tab to see if it was loaded correctly, and the path it is trying to load from.
The path will be from the document where the JavaScript was included.
I also keep a config object like this (PHP in this example)
var config = { basePath: '<?php echo BASE_PATH; ?>' };
Then you could do
var request = config.basePath + 'path/to/whatever.js';
You can use '../' to set the script path as base path. Then add the relative path for the
$.getScript("../plugin.js").done(function(script, textStatus ) {
alert("loaded:" + textStatus);
}).fail(function(script, textStatus ) {
alert("failed: " + textStatus);
});
Related
I've set up a very small browser project using create-js-app. I try to load a file called test.txt located in my src directory.
Following is the content of my main.js:
import * as THREE from 'three';
const loader = new THREE.FileLoader();
loader.load(
"test.txt",
function (data) {
console.log(data);
},
function (xhr) {
console.log(
"Loading file : " +
(xhr.loaded / xhr.total) * 100 +
"% loaded"
);
},
function (err) {
console.error(err);
}
);
When running my site in Chrome, I get the content of my index.html file instead of test.txt. I spent some time trying to understand this with no success.
I get this result no matter which file path I specify as first argument of loader.load(), I can even specify a file that is not existing.
Has anybody already faced this issue?
Thanks a lot.
Edit: I'm using Parcel as the bundler.
This issue comes down to internal details of create-js-app, and different web applications may host static resources (i.e. images and other assets that are not compiled source code) in different ways. But generally speaking, the src/ directory is not hosted/deployed/served on the website. If your application has the structure shown here then you probably want to put the .txt file into the public/ directory instead.
Requesting any file that cannot be found at the given URL might be giving you the index page instead, depending on how your site is set up by create-js-app.
I'm updating the answer above: I'm using Parcel. I fixed my project by adding this line:
url = require('test.txt')
The require function makes the browser import the txt file, and it returns the hashed url of the stored file. All I had to do next was to call
loader.load(url, ... )
My ajax call is working on localhost but not when i upload the files in domain. Using ajax I am searching all jpg/png files in a folder called 'images' and showing them in my webpage. The code is -
<script>
//Use ajax to load all images (jpe?g|png|gif) from a folder to a page called Gallery
//images folder should be in the same folder as the file
var folder = "../images/";
$.ajax({
url : folder,
success: function (data) {
$(data).find("a").attr("href", function (i, val) {
if( val.match(/\.(jpe?g|png|gif)$/) ) {
// create 'img' element using JS and dynamically add image source and class
var imgSrc = document.createElement('img');
imgSrc.src= folder + val;
imgSrc.className = 'imageThumbnails';
$("#spanImage").append(imgSrc);
}
});
}
});
</script>
please change
var folder = "../images/";
to
var folder = "images/";
hope this helps.. cheers
Ok, so as you saw when you tried accessing the folder directly in your browser, your web server does not allow this, which is common on web servers. Very few people actually want visitors to be able to see a list of all files in a folder, for security reasons.
The quick and dirty way to do this would be to allow listing files in that folder, through a htaccess file, using Options +Indexes, but I strongly recommend you do not do that
Instead, I would suggest you place a file inside your images folder called index.php and have that file build you a list of files placed alongside it, in the images folder. That way you have control over which files you show and which ones you don't. The index.php file can return a simple text output, one file name per line or something like that. Then your ajax call should work as it used to.
Hope this helps!
I have some Ajax that makes a Cross Origin Resource call
$("#inductive1").click(function (event) {
$.post(
"https://www.mysite.co.uk/folder/tests/Inductive/Test1/index.phtml",
function (data) {
$('.stage2').html(data);
}
);
});
within the index.phtml file I have some Script that calls exam.xml
Script inside index.phtml
( function($, undefined) {
$(function() {
var test = new Test({
testName: "Inductive Test 1",
dataURL : "/getresultshtml.php",
sendEmailURL: "/sendresultsbyemail.php",
contentFolder : "./",
solutionURL: "../../../content/f/id/10/",
userID: 0,
courseItemID: 25,
XMLFile: "exam.xml",
isStandalone: false
});
test.start();
});
}(jQuery));
However the xml file is trying to be called from the other server,
EG
https://server1.com/exam.xml
it should be
https://myserver.com/exam.xml
I have tried changing the JS to direct path as in
XMLFile: "htttps:/myserver.com/exam.xml"
but it is being read as
https://server1.com/myserver.com/exam.xml
how do I change the javascript so that it changes the root URL to myserver.com and not server1.com
Looks like some plugin you are using is changing document's base URL,
you can try putting this at the beginning of index.phtml
<base href="https://myserver.com">
If that doesn't work you might need to dynamically change the base property through JavaScript just before the ajax call
document.write("<base href='http://myserver.com/'>");
I'm not sure how the Test will use the XMLFile. But per the jquery.ajax documentation, passing the complete url (with the protocol) in the url parameter should be enough.
Maybe the test.start() is doing some manipulation?
The only other possible issue that I found is that you are declaring your protocol with an extra t and a missing /
XMLFile: "htttps:/myserver.com/exam.xml"
Try using
XMLFile: "https://myserver.com/exam.xml"
I have a page1 which has a wrapper with articles.
<div id="wrapper">
<article>...</article>
<article>...</article>
<article>...</article>
<article>...</article>
</div>
I am loading new articles from page2 with Ajax and appending them to the wrapper
$.ajax({
url : page_to_load,
success : function (data) {
$('article',data).appendTo('#wrapper');
}
});
But some of this new articles might need specific scripts that were not loaded in page1 but would be loaded if accessed directly page2.
So the problem is some of the content in new articles breaks as they are missing those scripts.
What is the best solution? I can think of checking the new loaded page scripts and compare them with the already loaded and download the new ones, but I have no idea of how to do this.
EDIT
I noticed if I set the dataType to 'html' I cant search for the scripts, although they are there:
$('script',data)//doesn't match anything
But if I do:
console.log(data);
I can see the whole page with <html> and <script> tags
There is no problem actually, if you append HTML to the Dom then script calls will be interpreted as if the page was loaded directly, just make sure you use the same parameters as the shorthand jquery $.POST method.
I actually do this all the time and the <script src=""> are called and interpreted correctly
Just make sure you're accessing the scripts from the right scope as if the html was hardcoded on page1.
If this doesn't work, then check with the web inspector if the scripts are loaded or not.
Working solution:
$.ajax({
url : page_to_load,
success : function (data) {
// load the scripts
var dom = $(data);
dom.filter('script').each(function(){
var scriptSrc = $(this).attr('src');
if(!$('script[src="'+ scriptSrc +'"]').length && scriptSrc !== undefined) {
var script = $("<script/>");
script.attr('src', scriptSrc);
$("head").append(script);
}
});
// load the articles
$('article',data).appendTo('#wrapper');
}
});
Not sure but maybe you could add a script in the AJAX call - I'm not sure of this because I haven't tried it:
Proxy.Scripts.Add(new ScriptReference(AddVersion("/Pages/Items/SearchList/SearchList.Grid.js" )));
This workflow should work :
After every page request :
Get all the script tags in the loaded page.
Loop over the scripts
If it's not loaded yet , load it.
Here is the code snippet :
$.ajax({
url : 'http://localhost',
success : function (data) {
$('article',data).appendTo('#wrapper');
$.each($.parseHTML(data,null,true),function(){
if($(this)[0].tagName == "SCRIPT"){
var src = $(this).attr('src');
if($('script[src="'+ src +'"]').length){
$.getScript(src);
}
});
}
});
Disable async.
$.ajax({
url : page_to_load,
async: false,
success : function (data) {
$('article',data).appendTo('#wrapper');
}
});
you can use RequireJS or HeadJs library for calling js files.
RequireJS is a JavaScript file and module loader and HeadJS, a small library for Responsive Design, Feature Detections & Resource Loading
HeadJs is great and useful, try it.
I have a bunch of JavaScript files that I would like to include in the page, but I don't want to have to keep writing
<script type="text/javascript" src="js/file.js"></script>
So is there a way to include all files in a directory (unknown size)? Can I do something like...
$.getScript("js/*.js");
... to get all the JavaScript files in the "js" directory? How can I do this using jQuery?
In general, this is probably not a great idea, since your html file should only be loading JS files that they actually make use of. Regardless, this would be trivial to do with any server-side scripting language. Just insert the script tags before serving the pages to the client.
If you want to do it without using server-side scripting, you could drop your JS files into a directory that allows listing the directory contents, and then use XMLHttpRequest to read the contents of the directory, and parse out the file names and load them.
Option #3 is to have a "loader" JS file that uses getScript() to load all of the other files. Put that in a script tag in all of your html files, and then you just need to update the loader file whenever you upload a new script.
What about using a server-side script to generate the script tag lines? Crudely, something like this (PHP) -
$handle = opendir("scripts/");
while (($file = readdir($handle))!== false) {
echo '<script type="text/javascript" src="' . $file . '"></script>';
}
closedir($handle);
Given that you want a 100% client side solution, in theory you could probably do this:
Via XmlHttpRequest, get the directory listing page for that directory (most web servers return a listing of files if there is no index.html file in the directory).
Parse that file with javascript, pulling out all the .js files. This will of course be sensitive to the format of the directory listing on your web server / web host.
Add the script tags dynamically, with something like this:
function loadScript (dir, file) {
var scr = document.createElement("script");
scr.src = dir + file;
document.body.appendChild(scr);
}
It can be done fully client side, but all javascript file names must be specified.
For example, as array items:
function loadScripts(){
var directory = 'script/';
var extension = '.js';
var files = ['model', 'view', 'controller'];
for (var file of files){
var path = directory + file + extension;
var script = document.createElement("script");
script.src = path;
document.body.appendChild(script);
}
}
You can't do that in JavaScript, since JS is executed in the browser, not in the server, so it didn't know anything about directories or other server resources.
The best option is using a server side script like the one posted by jellyfishtree.
#jellyfishtree it would be a better if you create one php file which includes all your js files from the directory and then only include this php file via a script tag. This has a better performance because the browser has to do less requests to the server. See this:
javascripts.php:
<?php
//sets the content type to javascript
header('Content-type: text/javascript');
// includes all js files of the directory
foreach(glob("packages/*.js") as $file) {
readfile($file);
}
?>
index.php:
<script type="text/javascript" src="javascripts.php"></script>
That's it!
Have fun! :)
You could use something like Grunt Include Source. It gives you a nice syntax that preprocesses your HTML, and then includes whatever you want. This also means, if you set up your build tasks correctly, you can have all these includes in dev mode, but not in prod mode, which is pretty cool.
If you aren't using Grunt for your project, there's probably similar tools for Gulp, or other task runners.
You can't do that in Javascript from the browser... If I were you, I would use something like browserify. Write your code using commonjs modules and then compile the javascript file into one.
In your html load the javascript file that you compiled.
I was looking for an answer to this question and had my own problems. I found a couple solutions in various places and put them together into my own preferred answer.
function exploreFolder(folderURL,options){
/* options: type explaination
**REQUIRED** callback: FUNCTION function to be called on each file. passed the complete filepath
then: FUNCTION function to be called after loading all files in folder. passed the number of files loaded
recursive: BOOLEAN specifies wether or not to travel deep into folders
ignore: REGEX file names matching this regular expression will not be operated on
accept: REGEX if this is present it overrides the `ignore` and only accepts files matching the regex
*/
$.ajax({
url: folderURL,
success: function(data){
var filesLoaded = 0,
fileName = '';
$(data).find("td > a").each(function(){
fileName = $(this).attr("href");
if(fileName === '/')
return; //to account for the (go up a level) link
if(/\/\//.test(folderURL + fileName))
return; //if the url has two consecutive slashes '//'
if(options.accept){
if(!options.accept.test(fileName))
//if accept is present and the href fails, dont callback
return;
}else if(options.ignore)
if(options.ignore.test(fileName))
//if ignore is present and the href passes, dont callback
return;
if(fileName.length > 1 && fileName.substr(fileName.length-1) === "/")
if(options.recursive)
//only recurse if we are told to
exploreFolder(folderURL + fileName, options);
else
return;
filesLoaded++;
options.callback(folderURL + fileName);
//pass the full URL into the callback function
});
if(options.then && filesLoaded > 0) options.then(filesLoaded);
}
});
}
Then you can call it like this:
var loadingConfig = {
callback: function(file) { console.log("Loaded file: " + file); },
then: function(numFiles) { console.log("Finished loading " + numFiles + " files"); },
recursive: true,
ignore: /^NOLOAD/,
};
exploreFolder('/someFolderURL/', loadingConfig);
This example will call that callback on every file/folder in the specified folder except for ones that start with NOLOAD. If you want to actually load the file into the page then you can use this other helper function that I developed.
function getFileExtension(fname){
if(fname)
return fname.substr((~-fname.lastIndexOf(".") >>> 0) + 2);
console.warn("No file name provided");
}
var loadFile = (function(filename){
var img = new Image();
return function(){
var fileref,
filename = arguments[0],
filetype = getFileExtension(filename).toLowerCase();
switch (filetype) {
case '':
return;
case 'js':
fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
break;
case "css":
fileref=document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", filename);
break;
case "jpg":
case "jpeg":
case 'png':
case 'gif':
img.src = filename;
break;
default:
console.warn("This file type is not supported: "+filetype);
return;
}
if (typeof fileref !== undefined){
$("head").append(fileref);
console.log('Loaded file: ' + filename);
}
}
})();
This function accepts a JS | CSS | (common image) file and loads it. It will also execute the JS files.
The complete call that needs to be run in your script to load all images and* stylesheets and other scripts could look like this:
loadingConfig = {
callback: loadfile,
then: function(numFiles) { console.log("Finished loading " + numFiles + " files"); },
recursive: true,
ignore: /^NOLOAD/,
};
exploreFolder('/someFolderURL/', loadingConfig);
It works amazingly!
Another option that is pretty short:
<script type="text/javascript">
$.ajax({
url: "/js/partials",
success: function(data){
$(data).find('a:contains(.js)').each(function(){
// will loop through
var partial= $(this).attr("href");
$.getScript( "/js/partials/" + partial, function( data, textStatus, jqxhr ) {});
});
}
});
</script>