can't parse JSON from javascript - javascript

I'm newbie in javascript and My project can't use AJAX or any Framework . . .
It's simple code but still curious what's wrong with it
<html>
<head>
<script type="text/javascript" src="onejs.js"></script>
<link href="onecss.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="myDiv" class="subMenu" onclick="test(this)">CLICK</div>
</body>
</html>
onejs.js
function test(id) {
var s = document.createElement('script');
s.id = 'dynScript';
s.type='text/javascript';
s.src = "http://echo.jsontest.com/one/111oneoneone/key/value";
var obj = JSON.parse(s);
id.innerHTML = (obj.key);
}
When I click in "CLICK" it doesn't change.

You are trying to load JSON as if it was a JavaScript script. It isn't, so you can't.
Normally you would use the XMLHttpRequest object for this type of job.
However, since you are ruled out Ajax (the process of using JavaScript to make HTTP requests), this isn't an option, so you would have to embed the data into the HTML when it initially loads.

Related

Javascript load external frameworks after onReady

Usually you have all your frameworks (scripts and css) in your head element on your HTML source code and while rendering the page they will be loaded.
E.g. I want to load jQuery and boostrap it would look something like this:
<html>
<head>
<script src="jquery.min.js"></script>
<script src="bootstrap.min.js"></script>
<link href="jquery.min.css"\>
<link href="bootstrap.min.css"\>
</head>
</html>
But imagine a situation where you have only jQuery loaded from the beginning and you want to perform a action like clicking on a button and need some framework functionalities like something that bootstrap offers, they would need to be loaded right after the click.
In my understanding that is not as easy as it sounds since the framework which needs to be loaded after the side was already rendered needs to perform an OnReady call. Is there any simple way to achieve this?
Kind regards,
Marius
"imagine a situation where you have only jQuery loaded from the beginning and you want to perform a action like clicking on a button and need some framework functionalities like something that bootstrap offers, they would need to be loaded right after the click."
What you are describing is lazy loading of dependencies.
RequireJS does this very well.
If you are thinking to do this to speed up the user's page load performance you can simply use the async property of the the tag like so:
<script src="jquery.min.js" async></script>
Read more about async loading at https://css-tricks.com/thinking-async/
If you have other reasons to load js after a certain event then use the following approach:
function loadJavaScript(url)
{
var s = document.createElement('script');
s.setAttribute('src', url);
s.setAttribute('async',true);
document.head.appendChild(s);
}
you can pass the address of the script as loadJavaScript('https://ajax.googleapis.com/ajax/libs/dojo/1.12.2/dojo/dojo.js')
UPDATE
Using the onload handler to call a function when the script loads:
$(document).ready(function() {
$('#test').click(function() {
console.log("oO");
loadCss('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css');
loadJavaScript('https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/bootstrap-select.js',function(){
$('.selectpicker').selectpicker('refresh');
});
});
});
function loadCss(url,fn) {
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
document.getElementsByTagName("head")[0].appendChild(link);
}
function loadJavaScript(url)
{
var s = document.createElement('script');
s.setAttribute('src', url);
s.setAttribute('async',false);
if(typeof(fn) == "function")
{
fn();
}
document.head.appendChild(s);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="test" type="button" class="btn btn-primary">Basic</button>
<select class="selectpicker">
<option>1</option>
</select>

How to use Javascript file as a resources file

I'm trying to make a Javascript a key value object and use it as my Resources for localization
I have made this Jascsript code in a javascript file:
var Values = {
lbl_CustomerName:"Customer name: "
}
now need to use this object in my HTML file:
<title>Title</title>
<script src="../content/JS/Resources/en-us/Resources.js"></script>
</head>
<body>
Values.lbl_CustomerName
</body>
</html>
but it's parsed as a plane text!
I need to call this Object and access the key to show it's value in my HTML file how to do this?
we can truly advice you to use a javascript framework like angular js that embed this kind of behavior inside the framework.
without javascript framework, you will need to modify the DOM by yourself to insert your expected value. If you want to do it in pure javascript function you can write a functio like :
function insertKey(elem,id) {
elem.innerHTML = Values[id];
}
In your case it will look like that :
<title>Title</title>
<script src="../content/JS/Resources/en-us/Resources.js"></script>
<script type="text/javascript">
function insertKey(elem,id) {
elem.innerHTML = Values[id];
}
</script>
</head>
<body>
<div onload="insertKey(this,'lbl_CustomerName')"></div>
</body>
</html>
Whenever you want to parse a JavaScript code, you should wrap it inside a script tag.
<title>Title</title>
<script src="../content/JS/Resources/en-us/Resources.js"></script>
</head>
<body>
<script> document.write(Values.lbl_CustomerName); </script>
</body>
</html>
Browsers have interpreters and virtual machines. Natively, they parse the codes as HTML. if you need to use other syntaxes like CSS and JavaScript, you should tell them hey browser, parse this section as a CSS, JavaScript.
That's why we need and tags
I got the answer, the Javascript file must return an object, so I can use it on my page as follows:
javascript:
function resourcesObject() {
return {
"customerName": "Customer name";
};
}
HTML
<script>
var resources=resourcesObject();
var customerName=resources["customerName"];
</script>

How to load third-party javascript tag asynchronously which has document.write

We give out a piece of javascript tags such as <script src="http://ours.com/some.js"></script> which site owners put on their site like http://example.com and in this javascript tag we want to dynamically include a third-party js such as which can have document.write in it, but of course if we try to include it by conventional method,
var script_tag = document.createElement('script');
script_tag.type = 'text/javascript';
script_tag.src="http://third-party.com/some.js";
document.getElementById('target').appendChild(script_tag);
we get a warning from browser,
Warning: A call to document.write() from an asynchronously-loaded
external script was ignored.
How do we get around this? Keep in mind, we don't really have control over third-party scripts so we can't change the logic in it. We are looking for some solution which can work across all browsers.
The problem with loading a script on a already loaded document (instead of having the browser ignore the document.write()) is that you would delete all existent HTML. See this example so you can understand exactly what's happening, or for more details look at a documentation page for the document.write() method.
While I know this might not be what you're expecting to get as an answer, I believe you are out of luck since rewriting the script is not an option.
This appears to be a similar question with similar replies.
You can support script injection the correct way by intercepting calls to document.write in this way:
document.writeText = document.write;
document.write = function(parameter) {
if (!parameter) return;
var scriptPattern = /<script.*?src=['|"](.*?)['|"]/;
if (scriptPattern.test(parameter)) {
var srcAttribute = scriptPattern.exec(parameter)[1];
var script = document.createElement('script');
script.src = srcAttribute;
document.head.appendChild(script);
}
else {
document.writeText(parameter);
}
};
Obviously this can be condensed down a bit further, but the variable names are included for clarity.
Source
How about instead of loading the script by appending a script element, you load the contents of the script URL with an AJAX call and then use eval() to run it in the global scope? Here's an example and I did test it to verify that it works:
<!DOCTYPE html>
<html>
<head>
<script>
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
window.eval(xmlhttp.responseText); //Indirect call to eval to execute in global scope (http://perfectionkills.com/global-eval-what-are-the-options/)
}
}
xmlhttp.open("GET", "https://third-party.com/test.js", false); //This is synchronous so that any document.write calls don't overwrite the entire page when they get called after the document is finished rendering. For all intents and purposes, this just loads the script like any other script, synchronously.
xmlhttp.send();
</script>
</head>
<body>
<div><h2>Hello World</h2></div>
</body>
</html>
And here are the contents I had in the test.js file:
document.write("This is a test...");
alert("...This is a test alert...");
console.log("...And a console message.");
I made the AJAX request for the script synchronous so that it would be loaded exactly as if it were a regular embedded script tag. If you run it asynchronously, and the script uses document.write after the page has been fully rendered, it clears the DOM and then writes to it... Kind of annoying actually. Lemme know if this works for you. :)
Document.write will not work from async script because document is already loaded when script starts working.
But you can do this:
document.body.innerHTML = document.body.innerHTML + '<h1>Some HTML</h1>';
Another procedure is to change the behavior of document.write() function.
Assume you have the main index.php file:
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
Hello<br>
<div id="target"></div>
<script>
document.write = function(input) {
document.body.innerHTML += input;
}
var doit = function() {
var script_tag = document.createElement('script');
script_tag.type = 'text/javascript';
script_tag.src="http://127.0.0.1:8080/testPlace/jsfile.js";
document.getElementById('target').appendChild(script_tag);
}
</script>
</body>
</html>
and the jsfile.js is like this:
document.write("OK MAN!");
now if you type doit() in the js browser console to execute that function (and the script do what you wrote) then the result would be:
Hello
OK MAN!
In which the html is like this:
<html><head>
<meta charset="utf-8">
</head>
<body>
Hello<br>
<div id="target"><script src="http://127.0.0.1:8080/testPlace/jsfile.js" type="text/javascript"></script></div>
<script>
//That Script which here I removed it to take less space in answer
</script>
OK MAN!</body>
</html>
What is the 3rd party javascript file?
If it's Google Maps JavaScript API v3 then make sure you include "&callback=your_init_funct" in the script URL. Then it will call 'your_init_funct' once the maps library is loaded so that you can begin displaying the map.
Another solution would be bezen.domwrite.js which is available here: http://bezen.org/javascript/index.html
Demo: http://bezen.org/javascript/test/test-domwrite.html
Yes, document.write can't be called from an asynchronously loaded script, because it's detached from the document, so it can't write to it.
You can see the approach used here for the google maps api to get around this problem. So, it is possible some of your 3rd party scripts that you haven't named, could have the similar callback pattern implemented.
https://developers.google.com/maps/documentation/javascript/examples/map-simple?hl=EN
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap"
async defer></script>
</body>
</html>

Access object from script tag

I'm writing java script code in script tag in head like:
<head>
<script language="javascript">
object o = new object({....});
</script>
</head>
and trying to use object a in body tag
<body>
<script>
alert(o.value);
</script>
</body>
how can i access object from body???
is their any alternatives?
<head>
<script language="javascript">
var o = new Object();
o.value="a"
</script>
</head>
<body>
<script>
$(document).ready(function()
{
alert(o.value)
});
</script>
</body>
In this case var a is accessible in complete application, but one thing you need to make sure if you are using external JS files then it must be loaded when you using the variable. try onload function to assure JS is loaded and ready to use in body:
window.onload = function ()
{
alert(a);
}
Since your variable is declared outside any functions it can be accessed from anywhere in your document from the same script block or from a seperate script block like in your example. it can even be accessed from html event-attributes like this (note that its better to attach events to html elements using using js):
<button onclick="alert(a);">Click this button to open an alert!</button>

jQuery script not working with Ajax

I have an issue:
I am implementing jQuery scroll bar (from here) on my content list that are populating through Ajax. I have two pages. On the first page js/custom_scrollbar.js have main "jp-container" function.
First Page:
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<link rel="stylesheet" type="text/css" href="css/jquery.jscrollpane.codrops2.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<!-- the mousewheel plugin -->
<script type="text/javascript" src="js/jquery.mousewheel.js"></script>
<!-- the jScrollPane script -->
<script type="text/javascript" src="js/jquery.jscrollpane.min.js"></script>
<script type="text/javascript" src="js/scroll-startstop.events.jquery.js"></script>
<script type="text/javascript" src="js/custom_scrollbar.js"></script>
</head>
<body onload='myContactList();'>
<div id="contentListDiv" class="list jp-container"></div>
</body>
</html>
Second Page:
<ul>
<li>
Z
</li>
</ul>
When i receive Ajax response, it populates <li> list and merge contents in <div> on the first page through .innerHTML. I'm simply calling a part of another page and merging its contents into the main page. Following function is getting Ajax response.
function myContentList() {
var http = createRequestObject();
http.open('GET', 'myContentListURL');
document.getElementById("contactListDiv").innerHTML = '<img src="images/loader-small.gif" border="0" />';
http.onreadystatechange = function() {
if (http.readyState == 4 && http.status == 200) {
if (http.getResponseHeader("SessionExpired") == "true")
window.location = "SessionExpiredURL";
var response = http.responseText;
if (response) {
document.getElementById("contactListDiv").innerHTML = response;
eval(document.getElementById('contactsDivScript').innerHTML);
}
}
};
http.send(null);
}
When I place <ul> on first page without calling Ajax or .innerHTML - jQuery works as expected and it displays jQuery scroll bar on contents. But if i follow above code it doesn't call jQuery script.
Thank You!
The flow of your code goes something like this:
1) You load the page and the javascript.
2) jScrollPane is initialized and <div id="contentListDiv" class="list jp-container"></div> is made scrollable.
3) You call ajax and receive response.
4) You overwrite <div id="contentListDiv" class="list jp-container"></div> with your ajax response making it just plain old html (non scrollable).
You see the problem?
Basically what you need to do is call jScrollPane after you got the ajax response and updated <div id="contentListDiv" class="list jp-container"></div>. So the jspane can make it scrollable again. To do this you need to modify your code after ajax response like following:
document.getElementById("contactListDiv").innerHTML = response;
eval(document.getElementById('contactsDivScript').innerHTML); //eval()? seriously?
$('#contentListDiv').jScrollPane();
You can read more about jScrollPane here -> http://jscrollpane.kelvinluck.com/
Also You should get some javascript and jquery knowledge first, no offense.
Actually you don't use the full functionallity of jquery.
The code you post uses al lot of plain Javascript. Not a real problem, but a little bit strange.
so please look at the documentation of jquery and especially at the Ajax docu.
http://api.jquery.com/category/ajax/
But nevertheless:
I will do it like this:
$("#contactListDiv").load("GET", url ,function(){
//add your content here when loading is finished
});
Using the full potential of jQuery could make this as simple as:
$(function(){
$("#contactListDiv").load('myContentListURL', function(){
$(this).jScrollPane();
});
});
Take a look in:
http://api.jquery.com/ready/
and
http://api.jquery.com/load/

Categories