Is there a way to use javascript to modify a script element?
Like for example:
HTML:
<script id="something" src="/js/file.js"></script>
Javascript:
var something = document.getElementById("something");
something.src = "/js/anotherfile.js"
Is it possible? Because I have a bit of code that works like that and it sort of doesn't work
To be specific, here's the code:
<!DOCTYPE html>
<html>
<head>
<title>MyohTheGod's Website</title>
<link rel="icon" type="image/x-icon" href="/supercorn.gif" defer>
</link>
<link id="css" href="/css/dark.css" rel="stylesheet" type="text/css">
</link>
<script src="/js/particles.js" defer></script>
<script src="/js/header.js"></script>
<script src="/js/theme.js"></script>
<script>window.alert("Welcome to the Home of MyohTheGod. You can play games, check out our web proxies, and more. Also, please do check out the About page. Press OK to continue...");</script>
</head>
<body>
-snip-
</body>
<script id="foot" src="/js/footer.js"></script>
</html>
<script>
-snip-
</script>
var css = document.getElementById("css");
var foot = document.getElementById("foot");
function toggleDLmode(m) {
-snip-
if (dlmodebool) {
css.href = "/css/dark.css"
foot.src="/js/dark-footer.js"
} else {
css.href = "/css/index.css"
foot.src="/js/footer.js"
}
}
-snip-
It is working, do you inspect it? It does changed, but maybe you're thinking, "hm why this /js/anotherfile.js is not downloaded?". Well because of the script tag is already rendered and already downloaded, so you can't do that. What you can do though add NEW script tag.
Maybe this will help How to dynamically change the script src?. This links would explain more why your code "does not work".
There certainly is. You can use document.scripts which returns an collection that you can iterate through like an array. You can change the code using the innerHTML property very much like a normal element. See here https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection
Edited to add: If you've got a html page with multiple script tags, the document.script collection has each script in the order they appear. The code below will log out the source (src tag) or the actual javascript for each script element.
You can also 'write' javascript by setting the innerHTML property.
IMHO it's a bit of a solution that's looking for a problem but at least it gives you access to the number of scripts you have.
[...document.scripts].forEach(script => {
if (script.src != '') {
console.log("Script source:" + script.src);
} else {
console.log(script.innerHTML);
}
});
I am trying to add a javascript file that generated via Transcrypt from Python file.
However, when I add that script to my HTML file, there are some errors appeared in Console and I failed.
The Python file that I used: try.py
def greet():
name = document.getElementById("Name").value
if name == "" or name.length == 0 or name == null:
document.getElementById("groet").innerHTML = '<p><font color="#ff0000">Hello Anonymous, may I know yor name? Please insert it below:</font></p>'
else:
document.getElementById("groet").innerHTML = '<p><font color="#00ff00">Hello, '+name+', thank you for introducing you</font></p>'
After that script, I ran the command python3 -m transcrypt -b try.py and a folder called "target" created automatically and it contains a file "try.js".
So, I wrote a HTML file which is a basic sample that shows a greeting message: hello.html
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="__target__/try.js"></script>
</head>
<title>Insert Text</title>
<body onload=try.greet()>
<h2>Hello Demo Name</h2>
<p>
<div id = "groet">...</div>
</p>
<p>Your Name: <input name="name" type="text" maxlength="80" id="Name" value=""/> [Please enter your name]<br><br>
<button onclick=try.greet()>Refresh the greeting!</button>
</p>
</body>
</html>
I am expecting that when I clicked the button or reload the file the greeting message should be placed. However, in console I got two errors:
Uncaught SyntaxError: import declarations may only appear at top level of a module try.js:1:13
Uncaught SyntaxError: missing { before try block hello.html:1:3
So, what is the problem guys?
[EDIT]
After the T.J's answer, I updated the html file as following:
'use strict';import{AssertionError,AttributeError,BaseException,DeprecationWarning,Exception,IndexError,IterableError,KeyError,NotImplementedError,RuntimeWarning,StopIteration,UserWarning,ValueError,Warning,__JsIterator__,__PyIterator__,__Terminal__,__add__,__and__,__call__,__class__,__envir__,__eq__,__floordiv__,__ge__,__get__,__getcm__,__getitem__,__getslice__,__getsm__,__gt__,__i__,__iadd__,__iand__,__idiv__,__ijsmod__,__ilshift__,__imatmul__,__imod__,__imul__,__in__,__init__,__ior__,__ipow__,
__irshift__,__isub__,__ixor__,__jsUsePyNext__,__jsmod__,__k__,__kwargtrans__,__le__,__lshift__,__lt__,__matmul__,__mergefields__,__mergekwargtrans__,__mod__,__mul__,__ne__,__neg__,__nest__,__or__,__pow__,__pragma__,__proxy__,__pyUseJsNext__,__rshift__,__setitem__,__setproperty__,__setslice__,__sort__,__specialattrib__,__sub__,__super__,__t__,__terminal__,__truediv__,__withblock__,__xor__,abs,all,any,assert,bool,bytearray,bytes,callable,chr,copy,deepcopy,delattr,dict,dir,divmod,enumerate,filter,float,
getattr,hasattr,input,int,isinstance,issubclass,len,list,map,max,min,object,ord,pow,print,property,py_TypeError,py_iter,py_metatype,py_next,py_reversed,py_typeof,range,repr,round,set,setattr,sorted,str,sum,tuple,zip}from"./org.transcrypt.__runtime__.js";var __name__="__main__";export var greet=function(){var py_name=document.getElementById("Name").value;if(py_name==""||py_name.length==0||py_name==null)document.getElementById("groet").innerHTML='<p><font color="#ff0000">Hello Anonymous, may I know yor name? Please insert it below:</font></p>';
else document.getElementById("groet").innerHTML='<p><font color="#00ff00">Hello, '+py_name+", thank you for introducing you</font></p>"};
//# sourceMappingURL=hello.map
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="module">
import { greet } from "./hello.js";
document.getElementById("greetButton").onclick=greet();
</script>
</head>
<title>Insert Text</title>
<body>
<h2>Hello Demo Name</h2>
<p>
<div id = "groet">...</div>
</p>
<p>Your Name: <input name="name" type="text" maxlength="80" id="Name" value=""/> [Please enter your name]<br><br>
<button id="greetButton">Refresh the greeting!</button>
</p>
</body>
</html>
import declarations may only appear at top level of a module
is fairly clear: You're not loading the script as a module, so you can't use import. Add type="module" to the script tag. (But be sure that your target browsers support modules -- all modern major ones do, but you don't have to go more than a few versions back in some before module support isn't there.)
missing { before try block
You have
<body onload=try.greet()>
try is a keyword in JavaScript, you can't use it as an identifier. You'll need to use a different name for your try object. (I'll use xtry in the rest of this answer.)
If your code really is a module, you also won't be able to use your xtry as a global, even if it's declared at the top level of your code, because the top level scope of a module isn't global scope. You'll need to import it to use it. That also means you don't need a script tag for try.js since the import will do it. Remove the onload and your current script tag and instead:
<script type="module">
import { xtry } from "__target__/try.js";
xtry.greet();
</script>
That won't run until the HTML has been fully parsed and the DOM has been populated (because of the type="module").
Side note: onload attribute handlers are generally not best practice, for two reasons: 1. They can only use globals, and 2. The load event happens very late in the page load cycle, waiting for all resources (including all images) to load. Sometimes that's what you want, but not often. Instead, use modern event handling (if you really need to hook up a handler on load) and use modern script techniques (type="module", defer, ...).
In addition to #T.J. Crowder's answer, I changed the script in html as:
<script type="module">
import * as hello from "./__target__/hello.js";
window.hello = hello;
</script>
As explained in the tutorial of Transcrypt.
With this way, I can call the Python function on button's click.
I'm looking for a Javascript equivalent of a technique I've been using in PHP. That is, to place even the most basic page setup:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
...in a php file like 'doc_start.php' and then start every page in my site with...
<?php require_once('/path/to/doc_start.php); ?>
Now I need to begin a project that's strictly HTML and JS (no PHP) and want a similar way to avoid duplicating basic, common HTML elements. Obviously, I want to do more than this very basic stuff, like import JQuery in every page, link to a common stylesheet, etc. Again, all easy in PHP, but I'm still kind of a newbie in JS.
I've read about HTML5 includes, but can't seem to find anything that addresses what I want to do
In order to import other pages into your current document, you need to use a link tag.
For example....
<head>
<link rel="import" href="/path/to/imports/stuff.html">
</head>
This will allow you to reference other html, css or javascript documents into your page without copying and pasting the same code within each page.
https://www.w3schools.com/html/html_links.asp
Javascript and PHP are different languages for very different purposes. But assuming you have some element you don't want to repeat some elements one solution is the following:
Save the HTML elements that you don't want to keep repeating as a string. Then use the .innerHTML property to add elements.
The .innerHTML property stores the mark up of an element as a string.
For example, if we have the following <div>:
<div class="example"> <br> Hello there this is a test! </div>
...and we use .innerHTML:
console.log(document.querySelector(".example").innerHTML);
It will output "<br> Hello there this is a test!".
We can add to the .innerHTML using the += operator. So if you want to add something inside the body it's as simple as:
var something = "some HTML";
document.body.innerHTML += something;
Hope this was what you were looking for!
I am working on an app using node_webkit combining HTML, CSS and JS. In one part of my app I want to update the Array.prototype so that I can access the last element of an array easily. The code for that is:
if (!Array.prototype.last){
Array.prototype.last = function(){
return this[this.length - 1];
};
}
If I run only the js-file that works fine and as expected. If I include that js-file into an HTML document it seems that the prototype of the array stays unchanged and I get the error:
data.last is not a function
Do I have to change something so that I can run my code normally from an HTML file or does that not work at all and I have to take the long way around and access each array with array[array.length - 1]?
The HTML code I use to include the script is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../CSS/Cocktails.css">
<title>Cocktails</title>
<script type="text/javascript" src="../JavaScript/Cocktail.js"></script>
</head>
<body>
/* some elements, that don't use the script yet */
</body>
</html>
It sounds like you're not calling the function, you'd want to call it like data.last() where data is some array that you've declared. Here's a JSFiddle of it in action.
In ES5 you need to use defineProperties in order to modify the Array prototype in an enumberable way:
Following should work,
Object.defineProperties(Array.prototype,
{ last: { value: function() { return this[this.length - 1]; } } });
More information at:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties
Is there a way to use jQuery.html() and not loose the scripts and styles? or any other non-jQuery way?
I'm trying to output the full HTML of the page the user is on. Is this even possible?
jQuery.html() removes scripts and styles
That isn't my experience (see below). In practice, you have to be aware that what you get back by querying the DOM for HTML strings is always going to be the interpreted HTML, not the original, and there will be quirks (for instance, on IE all the HTML tag names are IN UPPER CASE). This is because jQuery's html function relies on the browser's innerHTML property, which varies slightly browser to browser. But the demo below includes both style and script tags on Chrome 4, IE7, and Firefox 3.6; I haven't tried others, but I would expect them to be okay.
If you want to get the content of externally-linked pages as well as the inline content, you will naturally have to parse the result and follow the src (on scripts), href (on links that have rel = "stylesheet"), etc...
Demo:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'></script>
<script type='text/javascript'>
(function() {
$(document).ready(pageInit);
function pageInit() {
$('#btnGo').click(go);
}
function go() {
alert($('html').html());
}
})();
</script>
</head>
<body>
<input type='button' id='btnGo' value='Go'>
</body>
</html>
I see 2 scenarios here
you use jQuery.html(yourHTML) to overwrite the entire html of the page, so even the script tags were overwritten...
you use jQuery.html() to retrieve the entire document html. if this is the case you need tu ensure that the element on which .html() function is used, is the entire html... as T.J. Crowder suggested $('html').html()