I have two scripts and I need to use script1 function in script2. Whats the best way to do it and Is there any simplification using prototype to access function in more scripts. I am using jquery.
script1
$(function(){
function process(){
// some code
}
})
script2
$(function(){
// I would like to use the process function here
}
Sample.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
</HEAD>
<script type="text/javascript" charset="utf-8" src="Script1.js" ></script>
<script type="text/javascript" charset="utf-8" src="Script2.js" ></script>
<script>
</script>
<BODY onload='calling();'>
</BODY>
</HTML>
Scrip1.jc
function call(){
alert("Hi i am called from script2");
}
Scrip2.js
function calling(){
call();
}
Hope this help you.
You can use javascript functions as variables. So just reread your question about the same stuff about variables - Unable to access variable
So just do so your function will be available from global scope.
Just move the function declaration outside the ready event handler, that will make it globally available.
Another idea: use objects:
var Ob = {
process: function(callback) {
callback();
}
}
script1
$(function(){
Ob.process(function(){
... // code
});
});
script 2 (do same)
$(function(){
Ob.process(function(){
... //another code
});
});
If you are using same process function (means same body content, make same thing in both script) then
var Ob = {
process: function() {
...//put code
}
}
script1
$(function(){
Ob.process();
});
script 2 (do same)
$(function(){
Ob.process();
});
Related
I want to call a function using eel that isn't available before the program runs.
With plain JS it works just fine, I need some workaround or something similar for TS.
Python file
import eel
eel.init('web', allowed_extensions=['.js', '.html'])
#eel.expose
def my_python_function():
print(2)
eel.start('index.html', mode='chrome', cmdline_args=['--kiosk'])
Html
<!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.0">
<title>Document</title>
</head>
<body>
<button id="myButton"></button>
<script type="text/javascript" src="/eel.js"></script>
<script type="module" src="js/index.js"></script>
</body>
</html>
Working JS
let button = document.getElementById("myButton");
button.onclick = buttonClicked;
function buttonClicked()
{
console.log("Clicked");
eel.my_python_function();
}
If I am not using TS in it's intended way I'm sorry, I'm a beginner in web dev.
The following code is what i tried in TS but didn't work
let button : HTMLElement | null= document.getElementById('myButton');
button?.addEventListener("click", buttonClicked)
function buttonClicked()
{
console.log("Clicked");
eel.my_python_function(); // Error here
}
I got it working by ignoring the error.
let button : HTMLElement | null= document.getElementById('myButton');
button?.addEventListener("click", buttonClicked)
function buttonClicked()
{
console.log("Clicked");
// #ts-ignore
eel.my_python_function();
}
I am using modern Javascript MyClass.js
export default class MyClass {
constructor(x) {
this.val=x? x: "Hello!"
console.log("MyClass:",x)
}
}
at my http://localhost/myfolder/mypage.htm, with the source below,
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel='shortcut icon' type='image/x-icon' href='./favicon.ico' />
<script type="module" src="./MyClass.js"></script>
<script>
'use strict';
document.addEventListener('DOMContentLoaded', function(){
alert(123)
let x = new MyClass(11);
}, false); //ONLOAD
</script>
</head>
<body> <p>Hello1!</p> </body>
</html>
Why console say "Uncaught ReferenceError: MyClass is not defined"?
PS: this question is a complement for this other about using ES6+ with browser+NodeJs.
NOTE: using UBUNTU ith Apache's Localhost... Some problem with myfolder a symbolic link to real folder? at /var/www/html I used ln -s /home/user/myRealFolder/site myfolder
you need to import the module before using it
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta charset="utf-8" />
<script type="module" src="./MyClass.js"></script>
<script type="module" id="m1">
// script module is an "island", not need onload.
'use strict';
import MyClass from './MyClass.js';
let x = new MyClass(11); // we can use here...
console.log("debug m1:", x) // working fine!
window.MyClassRef = MyClass; // "globalizing" class
window.xRef = x // "globalizing" instance
</script>
<script> // NON-module global script
document.addEventListener('DOMContentLoaded',function(){
// only works after all modules loaded:
console.log("debug:", window.xRef) // working fine!
let x = new window.MyClassRef(22); // using class also here,
console.log("debug:", x) // working fine!
}, false); //ONLOAD
</script>
</head>
<body> <p>Hello1!</p> </body>
</html>
There are two ways to use an imported class:
at module scope (script m1): you can use new MyClass(), and can "globalize" instances (e.g. xRef) or the costructor's class (MyClassRef).
at global scope: to work together other libraries or with main script, use a global reference, e.g. new window.MyClassRef().
All this solution relies upon "static import"...
Optional dynamic import
You can use also import with ordinary default <script> (no type="module"), and no "onload", using this solution, instead the last script:
<script>
'use strict';
import('./MyClass.js').then(({default: MyClass}) => {
alert(123) // async block
let x = new MyClass(11);
});
</script>
See dynamic import.
I've been having trouble with Firefox not executing JavaScript files that were loaded dynamically via an external script.
Let me explain.
I have the following HTML file:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Restive.JS</title>
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="assets/js/load.js"></script>
</head>
<body>
<h1>Loading JavaScript</h1>
</body>
</html>
Inside my load.js file, I have the following code:
document.addEventListener("DOMContentLoaded", function() {
function loadScript(url) {
var script = document.createElement("script");
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
var list_arr = ['assets/js/test1.js', 'assets/js/test2.js'];
for (var i = 0; i < list_arr.length; i++) {
loadScript(list_arr[i]);
}
});
And inside test1.js and test2.js, I have console.log('test1.js is loaded!'); and console.log('test2.js is loaded!');.
The problem is that test1.js and test2.js are loaded (I can see both files in the <head> via inspection), but they are never executed (because no messages appear in the console log).
However, when I change the format of script reference in my original HTML by inlining the JavaScript i.e. changing from this:
<script type="text/javascript" src="assets/js/load.js"></script>
to this:
<script>
document.addEventListener("DOMContentLoaded", function() {
function loadScript(url) {
var script = document.createElement("script");
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
var list_arr = ['assets/js/test3.js', 'assets/js/test4.js'];
for (var i = 0; i < list_arr.length; i++) {
console.log('i = ' + i);
loadScript(list_arr[i]);
}
});
</script>
Then the scripts are loaded and executed.
I don't see this behaviour in Chrome or Safari, only Firefox. Also, inlining is not an option because this functionality is built-in to a library that users will have to reference via an external link.
Is this a problem that is fixable?
EDIT
I'm on a Mac OSX 10.10.5 using Firefox 46.0.1
I'm building a small application in Play and have an 'outer' template which holds all my CSS and JS imports (jQuery and my main.js file). CSS at the top, JS at the bottom with a body tag in between... pretty basic stuff:
<html>
<head>
<title>test</title>
<link rel="stylesheet" href="#routes.Assets.at("stylesheets/foundation.css")">
<link rel="stylesheet" href="#routes.Assets.at("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="#routes.Assets.at("images/favicon.png")">
</head>
<body>
#content
</body>
<script src='#routes.Assets.at("javascripts/jquery-1.9.0.min.js")' type="text/javascript"></script>
<script src='#routes.Assets.at("javascripts/index.js")' type="text/javascript"> </script>
</html>
Which is fine.
However, I have page specific javascript functions that should run based on what the page is. So if I go to localhost:9000/test, I want a particular set of functions to run.
If I go to localhost:9000/chips, I want another set of functions to run.
I can't see a neat way of doing this, really, except checking the current page url in the script and executing functions based on that... but the routes file is already doing stuff based on the current page url - seems strange to have to do something so similar twice.
One solution is to put all my scripts at the top and then execute inline scripts in the HTML... but I hate doing things like that.
You have very nice and clear sample available in the... documentation.
Scroll to the bottom and check section: moreScripts and moreStyles equivalents, you have there ready to use samples.
I use a ViewModel approach to solve this issue.
The default ViewModel:
class DefaultPage(
implicit val request: RequestHeader,
implicit val lang: Lang) {
var title: String = null
val styles = mutable.LinkedHashMap.empty[String, Int]
val scripts = mutable.LinkedHashMap.empty[String, Int]
def title(title: String) {
this.title = title
}
def style(style: String)(implicit priority: Int = 500) {
styles.put(style, priority)
}
def script(script: String)(implicit priority: Int = 500) {
scripts.put(script.toString, priority)
}
def translate(message: String, objects: Any*) = Messages(message, objects: _*)
}
Then I have two template tags:
styles.scala.html
#(styles: scala.collection.mutable.Map[String, Int])
#for(style <- styles.toList.sortBy(_._2)) {
<link rel="stylesheet" href="#routes.Assets.at(style._1)" />
}
scripts.scala.html
#(scripts: scala.collection.mutable.Map[String, Int])
#for(script <- scripts.toList.sortBy(_._2)) {
<script async="true" src="#routes.Assets.at(script._1)"></script>
}
My main template:
main.scala.html
#(page: util.view.models.DefaultPage)(content: Html)
#import tags.scripts
#import tags.styles
#page.style("css/vendor/normalize.min.css")(1)
#page.style("css/vendor/formalize.min.css")(1)
#page.style("css/sprites.min.css")(1)
#page.style("css/main.min.css")(1)
#page.style("css/quirks.min.css")(1000)
#page.script("js/vendor/jquery-1.9.1.min.js")(1)
#page.script("js/vendor/jquery.formalize.min.js")(1)
#page.script("js/plugins.min.js")(1)
#page.script("js/main.min.js")(1)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>#page.title</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width" />
#styles(page.styles)
<script src="#routes.Assets.at("js/vendor/modernizr-2.6.2.min.js")"></script>
</head>
<body class="#page.lang.code #page.lang.language #page.lang.country">
#content
#scripts(page.scripts)
</body>
And a sub template:
#(page: util.view.models.ContactUsPage)
#page.title(page.translate("contact.us.title"))
#page.style("css/contact-us.min.css")
#page.script("js/vendor/jquery.expandable-1.1.4.js")
#page.script("js/contact-us.min.js")
#main(page) {
}
You can pass your javascript which is specific to a page as template parameter link
I try to use some 'dijit' widget from script, for example to change content or to connect event.
For this purpose I try to use 'data-dojo-id' attribute in html, which (as I understood) creates global object of type 'data-dojo-type' and name 'data-dojo-id'.
But I got errors... What I do wrong?
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Dojo test</title>
</head>
<body>
<div id="myDivId"
data-dojo-type="dijit.layout.ContentPane"
data-dojo-id="myDojoId">
Hello Everyone!
</div>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js" data-dojo-config="async: true, parseOnLoad:true"></script>
<script type="text/javascript">
require(["dijit/dijit", "dijit/layout/ContentPane"], function(){
//myDojoId.setContent("Hello World!"); // error : myDojoId is not defined
// Even this not working:
console.log(dijit.byId("myDivId")); // undefined
console.log(dijit.byId("myDojoId")); // undefined
});
</script>
</body>
</html>
data-dojo-id and jsId (deprecated) attributes create a global object referring to that dijit.
I believe you need to wrap the lookups in a ready() call
<script type="text/javascript">
require(["dojo/ready","dijit/dijit", "dijit/layout/ContentPane"], function(ready,dijit,ContentPane){
//shouldn't be defined yet
console.log(dijit.byId("myDivId")); // undefined
console.log(myDojoId); // undefined
ready(function(){
console.log(dijit.byId("myDivId"));
//note how data-dojo-id doesn't have the lookup
console.log(myDojoId);
});
});
</script>