I have the following problem:
A ASP.NET MVC3 application, and in _Layout.cshtml, in header section, I have referenced several javascript scripts, as follows:
<script src="#Url.Content("~/Scripts/app/app.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/app/listEnveloppe.js")" type="text/javascript"></script>
In app.js I have defined App object as follows:
var App = {
init: function () {
if (window.console == undefined) {
window.console = {
log: function () {
var str = '';
for (var i in arguments[0]) {
str += i + ':\t' + arguments[0][i] + '\n';
}
alert(str);
}
};
}
/* ....*/
}
Then App object is referenced in listEnveloppe.js as below
App.listEnveloppe = new Function;
The problem is, this code works on FF and Chrome, but not in IE8
Does anyone knows what can be wrong?
Thank you
Maybe a lack of parenthesis in the Function constructor?
App.listEnveloppe = new Function(); // <----- missing () ?
As that wasn't the case, try declaring (and referring to) App as a property of window. And do it in an agnostic way relative to the order of declaration of the scripts:
// In app.js:
var appInstance = window.App || {};
appInstance.init = function () {
};
// In listEnveloppe.js:
var appInstance = window.App || {};
appInstance.listEnveloppe = new Function();
You have some unclosed parenthesis. Try fixing your javascript:
var App = {
init: function () {
if (window.console == undefined) {
window.console = {
log: function () {
var str = '';
for (var i in arguments[0]) {
str += i + ':\t' + arguments[0][i] + '\n';
}
alert(str);
}
};
}
}
/* ....*/
};
Related
I have created a JavaScript class. I'm getting an error when I try to minify the code using javascript-minifier. Can you help me to fix this issue?
My code:
class Test {
onCompleted = () => {};
onDismissed = () => {};
onError = () => {};
isProgress = false;
popup;
payment;
startPayment(payment) {
this.payment = payment;
this.isProgress = true;
this.popup = window.open('---');
var timer = setInterval(function () {
if (this.Test.popup.closed) {
clearInterval(timer);
if (this.Test.isProgress) {
this.Test.isProgress = false;
this.Test.onDismissed();
}
}
}, 500);
}
}
const Test = new Test();
window.addEventListener('beforeunload', function () {
if (Test.popup != null && !Test.popup.closed) {
Test.popup.close();
}
});
window.Test = Test;
Error message:
// Error : Unexpected token: operator (=)
// Line : 2
// Col : 18
The way you are creating the class seems to be wrong. In classes you can use functions like this: onCompleted() {}; and you can create variables in constructor. I also fixed an issue where you have Test defined twice, one as the class and one as variable. I renamed variable to TestInstance
Here would be a fixed example:
class Test {
constructor() {
this.isProgress = false;
this.popup;
this.payment;
}
onCompleted () {};
onDismissed () {};
onError () {};
startPayment(payment) {
this.payment = payment;
this.isProgress = true;
this.popup = window.open("---");
var timer = setInterval(function () {
if (this.Test.popup.closed) {
clearInterval(timer);
if (this.Test.isProgress) {
this.Test.isProgress = false;
this.Test.onDismissed();
}
}
}, 500);
}
}
const TestInstance = new Test();
window.addEventListener("beforeunload", function () {
if (TestInstance.popup != null && !TestInstance.popup.closed) {
TestInstance.popup.close();
}
});
window.Test = TestInstance;
A minified version:
class Test{constructor(){this.isProgress=!1,this.popup,this.payment}onCompleted(){}onDismissed(){}onError(){}startPayment(s){this.payment=s,this.isProgress=!0,this.popup=window.open("---");var t=setInterval(function(){this.Test.popup.closed&&(clearInterval(t),this.Test.isProgress&&(this.Test.isProgress=!1,this.Test.onDismissed()))},500)}}const TestInstance=new Test;window.addEventListener("beforeunload",function(){null==TestInstance.popup||TestInstance.popup.closed||TestInstance.popup.close()}),window.Test=TestInstance;
I don't know if I'm applying the concept of modular javascript correctly, so I need help!
I separated the js files by responsibilities.
Each file will be assigned to a specific function.
I am uploading these files as follows:
<html>
<head>
</head>
<body>
<div id="app-info">
<span id="app-name">name</span>
</div>
<script src="controllers/controllerExample.js"></script>
<script src="resources/ajaxApp.js"></script>
<script src="models/modelExample.js"></script>
<script src="app.js"></script>
</body>
</html>
I don't want to go to requiresJS.
without first understanding how the modular pattern really works.
Also, I want the return of ajax to be assigned to a global object, can we call it ObjectApplication so that anywhere in the application I can access it?
How can I do this?
So I have some js files.
app.js
controllers / controllerExample.js
models / modelExample.js
resources / ajaxApp.js
app.js
let objectApplication = {};
;(function( window, document, undefined ) {
'use strict';
function app() {
var $private = {};
var $public = {};
$private.privateVar = 'private var';
$public.publicMethod = function() {
return 'Init';
};
$private.privateMethod = function() {
return 'Private method';
};
return $public;
}
window.MyGlobalObject = window.MyGlobalObject || {};
window.MyGlobalObject.app = app();
})( window, document );
MyGlobalObject.controllerExample.publicMethod();
console.log(objectApplication);
controllerExample.js
;(function( window, document, undefined ) {
'use strict';
function controllerExample() {
var $private = {};
var $public = {};
$private.privateVar = 'private var';
$public.publicMethod = function() {
return MyGlobalObject.modelExample.publicMethod();
//return 'Init';
};
$private.privateMethod = function() {
return 'Private method';
};
return $public;
}
window.MyGlobalObject = window.MyGlobalObject || {};
window.MyGlobalObject.controllerExample = controllerExample();
})( window, document );
modelExample.js
;(function( window, document, undefined ) {
'use strict';
function modelExample() {
var $private = {};
var $public = {};
$private.privateVar = 'private var';
$public.publicMethod = function() {
buildAppInfo();
//return 'Init in Model';
};
$private.privateMethod = function() {
return 'Private method';
};
return $public;
}
window.MyGlobalObject = window.MyGlobalObject || {};
window.MyGlobalObject.modelExample = modelExample();
})( window, document );
ajax
let buildAppInfo = () => {
let url = 'app.json';
let xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status = 200)
objectApplication = JSON.parse(xhr.responseText);
console.log(objectApplication);
}
}
xhr.send();
};
I have a very simple html page where I put this script at the end:
<?php echo $this->Html->script(['studiomain.js']); ?>
</html>
The script contains an IIF in JS:
window.studiomain = window.studiomain || (function ($) {
let _dataTable = '';
let _modalTemplates = {};
let _webroot = 'studioasq';
function setDataTable (t, options={}) {
_dataTable = $(t);
if (typeof $(t).DataTable == 'function') {
options.language = {
"url": "/" + _webroot + "/js/datatable/i18n/Italian.json"
}
$(t).DataTable(options);
}
}
function setModal(key='',template='') {
_modalTemplates[key] = template;
}
function renderModal(key,data={}) {
if (_modalTemplates[key] !== undefined) {
let copy = _modalTemplates[key];
Object.keys(data).forEach((key) => {
copy.replace(new RegExp("{{" + value + "}}","g"),data[key]);
})
}
return $('#'+key);
}
return {
setDataTable,
setModal,
renderModal
}
})($);
But when the page finishes loading, I have no studiomain in window:
window.studiomain => undefined.
I think the problem is the renderModal function: If I delete it all is fine.
What am I missing?
**** UPDATE ****
Following suggestions, I think the problem is in the order of loading scripts and passing the reference to JQuery.
I discovered also that passing (jQuery) and NOT ($) to the IIF works.
I guess you are trying to achieve modular pattern.
In your code, you'll need to return every thing inside a function, otherwise every code without return will be in private state.
Fix of your code, you need to return window.studiomain as a parameter, you code will work, $ is not defined therefore it's not storing inside window object
window.studiomain = window.studiomain || (function($) {
let _dataTable = '';
let _modalTemplates = {};
let _webroot = 'studioasq';
function setDataTable(t, options = {}) {
_dataTable = $(t);
if (typeof $(t).DataTable == 'function') {
options.language = {
"url": "/" + _webroot + "/js/datatable/i18n/Italian.json"
}
$(t).DataTable(options);
}
}
function setModal(key = '', template = '') {
_modalTemplates[key] = template;
}
function renderModal(key, data = {}) {
if (_modalTemplates[key] !== undefined) {
let copy = _modalTemplates[key];
Object.keys(data).forEach((key) => {
copy.replace(new RegExp("{{" + value + "}}", "g"), data[key]);
})
}
return $('#' + key);
}
return {
setDataTable,
setModal,
renderModal
}
})(window.studiomain);
console.log(studiomain);
In my main.js, I have:
var example = require('./test');
example.speak('Hello world');
While in my test.js, I have:
module.exports = function() {
this.speak = function(str) {
str += ' < you typed.';
return str;
};
this.listen = function(str) {
return str;
};
};
What exactly am I doing wrong so that I can use browserify correctly with this?
You should either export an object:
module.exports = {
speak: function () {},
// etc
}
or use
var example = new require("./test")();
I'm getting SCRIPT5045: Assignment to read-only properties is not allowed in strict mode in IE 11 (latest Chrome works fine) in reference to the line
A.doc.head = A.doc.getElementsByTagName('HEAD')[0];.
I'm confused on how to fix it. I've included what should be the relevant code below.
(function (win, doc, arg) {
'use strict';
var A = win[arg.prefix] = {
'win': win,
'doc': doc,
'arg': arg,
'stu': {},
'fun': (function () {
return {
init: function () {
var scripts = A.doc.getElementsByTagName('SCRIPT'),
n = scripts.length,
i;
for (i = 0; i < n; i = i + 1) {
if (scripts[i].src.match(A.arg.src)) {
A.arg.script = scripts[i];
A.arg.options = A.fun.options();
break;
}
}
A.doc.head = A.doc.getElementsByTagName('HEAD')[0];
A.fun.structure();
},
// more functions
}())
};
A.fun.init();
}(window, document, {
'prefix': 'accescape_' + new Date().getTime(),
'src': '/widget.js',
'defaults': {
'language': 'en'
}
}));
document.head is a read-only property. If you want to shim it for oldIE, you'd better test for its nonexistence first:
if (!doc.head)
doc.head = doc.getElementsByTagName("head")[0];