How to find the script path from his own js file - javascript

I want to find the script path of my own js file in itself.
So I want have as a string "C:\files\MyProject\MyScripts\MyJavaScript.js".
How is that possible?

You can try (Jquery):
var myScriptDetails = $('script');
myScriptDetails will contain details regarding the script, including its location.

Try this solution. I think this is exactly what u want :)
Put this code in each of your linked script file
var scriptEls = document.getElementsByTagName( 'script' );
var thisScriptEl = scriptEls[scriptEls.length - 1];
var scriptPath = thisScriptEl.src;
var scriptFolder = scriptPath.substr(0, scriptPath.lastIndexOf( '/' )+1 );
console.log(scriptPath +" "+ scriptFolder );// you can save these in any variable also
I tested it with this HTML code:
<!DOCTYPE html>
<html>
<head>
<title>testing...</title>
<script type="text/javascript" src="test.js"></script>
<script type="text/javascript" src="js/test2.js"></script>
<script type="text/javascript" src="../test3.js"></script>
</head>
<body>
content area
</body>
</html>
And found this Output in console:
file:///D:/workspace/dbshell/www/test.js file:///D:/workspace/dbshell/www/ test.js:6
file:///D:/workspace/dbshell/www/js/test2.js file:///D:/workspace/dbshell/www/js/ test2.js:6
file:///D:/workspace/dbshell/test3.js file:///D:/workspace/dbshell/ test3.js:6
Special thanks to meouw..
Hope this helps..

here is how I made it:
function ScriptPath() {
var scriptPath = '';
try {
//Throw an error to generate a stack trace
throw new Error();
}
catch(e) {
//Split the stack trace into each line
var stackLines = e.stack.split('\n');
var callerIndex = 0;
//Now walk though each line until we find a path reference
for(var i in stackLines){
if(!stackLines[i].match(/http[s]?:\/\//)) continue;
//We skipped all the lines with out an http so we now have a script reference
//This one is the class constructor, the next is the getScriptPath() call
//The one after that is the user code requesting the path info (so offset by 2)
callerIndex = Number(i) + 2;
break;
}
//Now parse the string for each section we want to return
pathParts = stackLines[callerIndex].match(/((http[s]?:\/\/.+\/)([^\/]+\.js)):/);
}
this.fullPath = function() {
return pathParts[1];
};
this.path = function() {
return pathParts[2];
};
this.file = function() {
return pathParts[3];
};
this.fileNoExt = function() {
var parts = this.file().split('.');
parts.length = parts.length != 1 ? parts.length - 1 : 1;
return parts.join('.');
};
}

Client-side you can't access the physical path. You can get the src attribute of the script tag though.
Server-side you can get the physical path. For example (C#):
Path.GetFullPath(path)

For finding full path of URL in JavaScript use this location.href

If you can define absolute path of server as constant variable,
you can do it by casting from window.location.href. remove host prefix window.location.host from window.location.href and prepand with server's absolute path.
Try:
console.log(window.location.href);

Related

How Render Partial view from JS in Layout

Trying to use JS to render a partial view based on the URL... This is almost working but I can't use Razor syntax in the PathRoot Var so I tried escaping it but then it doesn't render... Any Ideas would be greatly appreciated.
<head>
<script>
var SiteUrl = window.location.hostname;
var FloodlightPathRoot = '##Html.Partial("~/Views/shared/FloodlightTags/' ;
var FloodlightEnd = '");';
switch (SiteUrl) {
case "www.website.com":
var FloodlightFilePath = "first.cshtml";
break;
case "www.website2.com":
var FloodlightFilePath = "second.cshtml";
break;
}
var FloodFull = (FloodlightPathRoot + FloodlightFilePath + FloodlightEnd);
$('head').append(FloodFull);
</script>
</head>
It writes the razor syntax to the head but the page has already rendered. Can I render the razor syntax after the head is updated?
<head>
#Html.Partial("~/Views/shared/FloodlightTags/first.cshtml");
</head>
While using your code it can done this way
<head>
<script>
#{
string path = Request.RequestUri.PathAndQuery;
if (path.Contains("www.website.com"))
{
#Html.Partial("~/Views/shared/FloodlightTags/first.cshtml");
}
else if (path.Contains("www.website.com"))
{
#Html.Partial("~/Views/shared/FloodlightTags/second.cshtml");
}
}
</script>
</head>
in addition to Stephen's answer you can do it like this:
#{
var url = new Uri(new Uri(this.Context.Request.Url.GetLeftPart(UriPartial.Authority)), Url.Content("~/")).ToString();
if (url == "http://www.website.com/")
{
#Html.Partial("~/Views/shared/FloodlightTags/first.cshtml");
}
else if (url == "http://www.website2.com/")
{
#Html.Partial("~/Views/shared/FloodlightTags/second.cshtml");
}
}
var url will get the site url and then it will check weather it matches http://www.website.com/ if so it will render first.cshtml else it will check the second condition.

Live reloading iframe script on change

I'm setting up some editors with HTML, CSS and JS code. The code of each of them is reloaded in an iframe when it's change. HTML and CSS code reloads perfectly, bus the JS code that is injected inside of a script in the body of the iframe is not working, possible because it's not rerunning once it's updated, but I don't know how to do it...
Any idea?
Here's an example in Plunker http://plnkr.co/edit/tpl:8rFfZljYNl3z1A4LKSL2?p=preview
HTML
<div class="result">
<!-- RESULT -->
<style id="style"></style>
<script id="script"></script>
<script id="jQ" type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<iframe id="view" class="view"></iframe>
</div>
JS
var app = angular.module('plunker', []);app.controller('MainCtrl', function($scope) {
var style = document.getElementById('style');
var script = document.getElementById('script');
var jQ = document.getElementById('jQ');
var view = document.getElementById('view');
var viewDocument = view.contentDocument || view.contentWindow.document;
var body = viewDocument.getElementsByTagName('body')[0];
var head = viewDocument.getElementsByTagName('head')[0];
var widgets = [];
var loadScript = document.createElement('script');
loadScript.innerHTML = "var $ = parent.$; console.log('loaded');";
$scope.html = '<div id="test">Testing</div>';
$scope.js = 'console.log("More test");';
head.appendChild(jQ);
head.appendChild(loadScript);
head.appendChild(style);
body.appendChild(script);
$scope.$watch('html', function(nv){
body.innerHTML = nv;
body.appendChild(script);
});
$scope.$watch('js', function(nv){
script.innerHTML = nv;
});});
Note: Code seems to run fine when is set by hand
SOLVED:
I found a way around. Here's the code in case someone else need it
setTimeout(updatePreview(codeHTML, codeCSS, codeJS), 300);
function updatePreview(codeHTML, codeCSS, codeJS) {
var view = document.getElementById('view');
var viewDocument = view.contentDocument || view.contentWindow.document;
var codeHTML = (codeHTML === undefined) ? '' : codeHTML;
var codeCSS = (codeCSS === undefined) ? '' : codeCSS;
var codeJS = (codeJS === undefined) ? '' : codeJS;
viewDocument.open();
viewDocument.write('<style type="text/css">' + codeCSS + '</style>');
viewDocument.write('<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>');
viewDocument.write(codeHTML);
viewDocument.write('<script type="text/javascript">' + codeJS + '</script>');
viewDocument.close();
}
This is called in $scope.$watch of de editors passing the updated value.
Weave: http://kodeweave.sourceforge.net/editor/#b6b39c95ec91f42950957a1ac8dc707f
I see you were able to solve your problem however I have a minor suggestion.
If a user uses setTimeout or setInterval like so...
setInterval((function() {
return $('body').css('background', newGradient())
}), 1000)
The problem you have in your code is it will add to the original literation and your setInterval function in this case will be added to the previous one.
Thus a good idea is to create the iframe dynamically and add the code within that. This way you have more control over what's being added to the iFrame and how to handle it.
document.querySelector(".preview").innerHTML = ""
var frame = document.createElement("iframe")
frame.setAttribute("id", "preview")
frame.setAttribute("sandbox", "allow-forms allow-modals allow-pointer-lock allow-popups allow-same-origin allow-scripts")
document.querySelector(".preview").appendChild(frame)

load a page inside <div> or when "?param=" is added on url

i know the basics of loading a page or a file in a container frame via js or jQuery, but via event listener like onClick
JS -
document.getElementById("id").innerHTML = "<object type = 'text/html' data = 'myfile.html'> </data>"
JQUERY -
$("#id").load("myfile.txt");
but what I want to achieve is the same as this but not just being loaded onClick in the container frame, but also add a parameter on the url, for example:
if I click on a button, `webpage.html` will load on `<div>` container frame, and the `url` will change to `http://example.com/?loaded=webpage.html`
I wanted to do this, so I can either change the url string or press an element and load a certain file on the div container frame.
the same principle goes as how facebook manages profile.php
http://facebook.com/profile.php?=mypersonalprofile - load my profile
http://facebook.com/profile.php?=myfriendsprofile - load my friends profile
I hope I managed to deliver it clearly.
I think this would demonstrate what you looking for
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
<button class="loadButton" value="input1.txt">Load file 1</button>
<button class="loadButton" value="input2.txt">Load file 2</button>
<div id="view"></div>
</body>
<script>
$(function(){
// Call loadPage on init
loadPage();
$(".loadButton").on("click", function(){
// Change URL, you can change "/testJS/index.html" to suit your web address
history.pushState({}, "", "/testJS/index.html?loaded=" + $(this).attr("value"));
$("#view").empty();
$("#view").load($(this).attr("value"));
});
});
function loadPage() {
console.log("start");
var href = window.location.href;
var index = href.indexOf("?loaded=");
// Load data if we define the loaded param
if (index > -1) {
data = href.substring(index + 8);
console.log(index + " " + data);
$("#view").empty();
$("#view").load(data);
}
}
</script>
</html>
You need to combine the solutions from Get url parameter jquery Or How to Get Query String Values In js and Modify the URL without reloading the page.
You can set the page with
history.pushState({}, "", "/mainpage.html?loaded=webpage.html");
$("#id").load("webpage.html");
Then, if they change the url some other way (which will require the page to reload), you can get the parameter from the url and load it:
var myfile = getUrlParameter("loaded");
$("#id").load(myfile);
The getUrlParameter function is defined as:
var getUrlParameter = function getUrlParameter(sParam) {
var sPageURL = decodeURIComponent(window.location.search.substring(1)),
sURLVariables = sPageURL.split('&'),
sParameterName,
i;
for (i = 0; i < sURLVariables.length; i++) {
sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] === sParam) {
return sParameterName[1] === undefined ? true : sParameterName[1];
}
}
};

Add external file to head - one for Staging and one for Production

I need to add an external javascript file to the <head> section of a website - one file when on the Staging server, and a different one for production.
So far I have this, but I get an error: 'return' outside of function
<script type="text/javascript">
var pathOrigin = window.location.origin;
var headtg = document.getElementsByTagName('head')[0];
if (!headtg) {
return;
}
var linktg = document.createElement('script');
if (pathOrigin.toLowerCase().indexOf("staging.server.com") >= 0) {
linktg.src = '/script-staging.js';
} else {
linktg.src = '/script-production.js';
}
headtg.appendChild(linktg);
</script>
What am I missing?
Thanks.
Return - Specifies the value to be returned by a function.
That means the error you got from the browser is correct. Your returnstatement is not part of a function, but of the global scope. You wil either have to skip using the return statement and use simple variable assingment like in #Azzy's answer, or encapsulate it in a function like so:
function getHead() {
var headtg = document.getElementsByTagName('head')[0];
if (typeof headtg === 'undefined') {
return; // will break the function
} else {
var linktg = document.createElement('script');
if (pathOrigin.toLowerCase().indexOf("staging.server.com") >= 0) {
linktg.src = '/script-staging.js';
} else {
linktg.src = '/script-production.js';
}
headtg.appendChild(linktg);
};
};
getHead(); // don't forget to initialize the function
//or you could do:
element.onload/onclick/on<whatever_event> = getHead();
To me it is also not clear what you want to return, unless you simply want to stop script execution; citing from MDN:
If the expression in return [expression] is omitted, undefined is returned instead.
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return
NB: Check this why it is safer to use the typeofstatement than a simple !mark to check if something exists: Check if object exists in JavaScript.
EDIT: For a very simple use case of the return statement, you can check out this fiddle I made which is basically a counter that will output an error when it reaches 100.
Where place this code? Are you sure that the path is correct?
Another method to add js file into head is this method:
<head>
....
<script type="text/javascript">
var pathOrigin = window.location.origin;
var path = "";
if (pathOrigin.toLowerCase().indexOf("staging.server.com") >= 0) {
path = '/script-staging.js';
} else {
path = '/script-production.js';
}
document.write( '<script type="text/javascript" src="' + path + '"><\/script>' );
</script>
.....
</head>
<html>
<head>
<script type='text/javascript'>
var path = window.location.origin
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
if (path == 'local'){
fileref.setAttribute("src", 'file:///D:/JS/jquery.js')
}
else{
fileref.setAttribute("src", 'file:///D:/JS/jquery.js')
}
document.getElementsByTagName("head")[0].appendChild(fileref)
//list all the js loaded dynamically
var scripts = document.getElementsByTagName('script');
console.log(scripts);
</script>
</head>
<body>
<p>test</p>
</body>
</html>
To load script dynamically, you can try out this..
The javascript error "return statement outside of function" means you've created a code fragment that is not allowed to exist outside of a function definition.

How do I refer to the parameter passed to javascript in html?

When I call the script via
<script type="text/javascript"
src="include/javascript/test_something.js?v=1128557"></script>
how do I refer to the variable V passed in the html?
Thanks in Advance!
The most simple way would be to use a server side technology. This is in php.
<?php
$v=1128557;
?>
<script type="text/javascript">
//This will make this value available to javascript too
var val=<?php=$v?>;
</script>
<script type="text/javascript"
src="include/javascript/test_something.js?v=<?php=$v?>"></script>
...
...
...
<div id='baba<?php=$v?>'>
...
...
</div>
This will be translated to the following html
<script type="text/javascript">
//This will make this value available to javascript too
var val=1128557;
</script>
<script type="text/javascript"
src="include/javascript/test_something.js?v=1128557"></script>
...
...
...
<div id='baba1128557'>
...
...
</div>
Get it from the src attribute of the last script element in your page:
var scripts = document.getElementsByTagName("script");
var src = scripts[scripts.length - 1].src;
var v = null;
if (/\?v=(.+)$/.test(src)){
v = RegExp.$1;
}
If it's the first script tag on the page, you can do something like:
var thescripttag = document.getElementsByTagName('script');
var v = thescripttag[0].src.replace(/^[^\?]+\??/,''); //gets everything after the '?'
If it's not the first script tag, you can change [0] to be whichever one it is, or try assigning an id to the script tag (untested).
You can find the appropriate script tag by looking for the desired filename and get the parameters off that .src URL.
function findScriptParams(fname) {
fname = "/" + fname + "?";
var scripts = document.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
var pos = scripts[i].src.indexOf(fname);
if (pos != -1) {
return(scripts[i].src.substr(pos + fname.length));
}
}
}
And then you would invoke it like this:
var params = findScriptParams("test_something.js");
if (params) {
// process the params here
}
Change it to
<script type="text/javascript"
src="include/javascript/test_something.php?v=1128557" />
Then create the script test_something.php to be
<?php
echo "var queryString='" . $_SERVER[`QUERY_STRING] . "'\n;";
?>
... rest of javascript here
You can even perform error checking/parsing of the query string using PHP or just get Javascript to do this.
You should do the following:
var scripts = document.getElementsByTagName('script');
var data = {};
for (var i = 0; i < scripts.length; i ++) {
if (!scripts[i].src) {
continue;
}
var value = scripts[i]..substring(scripts[i].indexOf('?') + 1);
var params = value.split('&');
for (var i = 0; i < params.length; i ++) {
params[i] = params[i].split('=');
data[params[i][0]] = params[i][1];
}
}
EDIT: Just incorporated some of the tips from others, and added them to my own answer.
JavaScript only has access to URL data for the page it's being executed on via window.location. It does not have access to any HTTP request variables passed to the javascript file itself unless the web server explicitly serializes it to JavaScript in the output.
One hack/workaround would be to find the script tag, get the src attribute, parse the URL and extract the GET parameters you need.
function getParamsFor(script) {
var params, anchor, paramArray, keyVal, tag, scripts;
scripts = document.getElementsByTagName("script");
// Make sure [].filter exists beforehand
tag = Array.prototype.filter.call(scripts, function (e) {
return e.src.indexOf(script) > -1;
})[0];
if (tag) {
anchor = document.createElement("a");
anchor.href = tag.src;
paramArray = anchor.search.substring(1).split('&');
params = {};
for(var i = 0; i < paramArray.length; i++) {
keyVal = paramArray[i].split('=');
params[unescape(keyVal[0])] = (typeof keyVal[1] != "undefined") ? unescape(keyVal[1]) : keyVal[1];
}
return params;
}
}
var o = getParamsFor("test_something.js");
o.v; // 112..

Categories

Resources