I want to execute Nav.init(), Nav1.init() both after dom ready so I call DomReady module inside Nav, Nav1 each module before.
Now I try edit the code to call DomReady module before require them both, then just need to write one time but because there is a require parameter I don't know how should I do?
Does it like this define(['require','DomReady!'], function (require, DomReady) { ?
define(['DomReady!'], function (require, DomReady) {
var Nav = require('custom/Nav');
Nav.init();
var Nav1 = require('custom/Nav1');
Nav1.init();
});
Try this
define(['DomReady!'], function (DomReady) {
require(['custom/Nav'], function(Nav){
Nav.init();
});
require(['custom/Nav1'], function(Nav1){
Nav1.init();
});
});
Related
I put all my .js files in one. So one page will use less than 10% of the functions there.
eg, page1.php need only .func1, but now I have func 2, 3, 4...
$(document).on("click", ".func1", function() { /* ... */ });
$(document).on("click", ".func2", function() { /* ... */ });
$(document).on("click", ".func3", function() { /* ... */ });
$(document).on("click", ".func4", function() { /* ... */ });
$(document).click(function(){ /* ... */ });
... fun20, func30.
Is it ok? I need only func1 but all this others listeners are working too. any thing I need or should do?
There's nothing wrong with your code but definitely it can get better.
There are some ways in order to do that :
1. Use a code bundler like webpack
Using webpack would be a good Idea specially for it's new feature Code Splitting that let's you to import different modules dynamically.
2. Using Modular design patterns like Revealing Module Pattern
There are someways to do this and it's so easy. I put some example codes for you down below :
// Self Invoke function
var Module1 = (function(){
// Configurations
var config = {
body : '.body',
header : '.header',
...
}
// Functions
function bodyHandler(){
...
}
function headerHandler(){
...
}
// Bind Events
$(document).on('click', config.body , bodyHandler);
$(document).on('click', config.header , headerHandler);
})()
You can separate your JavaScript code into various modules and use them in different pages.
Also you can config each module dynamically from outside (In html page for instance) like so :
(function(){
var Page = {
// Init the Module with your own configuration
init(conf){
this.config = conf;
this.bindEvents()
},
// Bind Events
bindEvents(){
$(document).on('click', this.config.body , this.bodyHandler);
$(document).on('click', this.config.header , this.headerHandler);
},
bodyHandler(){
...
},
headerHandler(){
...
},
}
// You can Init the module whereever you want
Page.init({
body : '.body',
header : '.header',
// Other options ...
})
})()
I currently have a similar process when it comes to JavaScript. All functions I write go into one large file. I then have a single function that runs when the DOM is ready that binds events onto specific elements.
By doing it that way a) I know where all the event binding is happening and b) Only events that are specific to the content of the page are actually bound
for example....
(function() {
function fnFunctionA() { ... }
function fnFunctionB() { ... }
function fnFunctionC() { ... }
$('.containerA').on('click', '.subElementA', fnFunctionA);
$('.containerB').on('click', '.subElementB', fnFunctionB);
$('.containerC').on('click', '.subElementC', fnFunctionC);
}());
Function A is only ever bound when containerA actually exists on the page and so on and so forth
I'm using requirejs to bundle my files. I've used p5.js for some time, but I need to add p5.dom now. The problem is I don't know how to do it with my requirejs. I couldn't find any information how to do it with bundling.
I have something like this:
require(['lib/p5js/lib/p5'], function (p5) {
var myp5 = new p5(function (_sketch) {
_sketch.setup = function() {
????.createButton('click me'); // I need to access p5.dom here.
}
});
});
EDIT: When I try to use it like a variable I get undefined.
require(['lib/p5js/lib/p5', 'lib/p5js/lib/addons/lib/p5.dom'], function (p5, p5Dom) {
var myp5 = new p5(function (_sketch) {
_sketch.setup = function() {
p5Dom.createButton('click me'); // p5Dom is undefined.
}
});
});
I used shim to ensure that p5.js is loaded before p5.dom is loaded, but it didn't help:
shim: {
'lib/p5js/lib/addons/p5.dom': {
deps: ['lib/p5js/lib/p5']
}
},
I found a solution. Unfortunately I wasn't able to do it with requirejs, but I simply included script tags before requirejs and it solved the problem. So it looks like this:
<script src="~/lib/p5js/lib/p5.js"></script>
<script src="~/lib/p5js/lib/addons/p5.dom.js"></script>
<script src="~/lib/requirejs/require.js" data-main="/js/scripts/tetromino-client/client.js"></script>
I hoped to do this in requirejs, but I don't understand why it didn't work.
Using jQuery as suggested by Wordpress, I have wrapped my code in an anonymous function so that jQuery will not conflict with other javascript libraries:
(function($) {
// Inside of this function, $() will work as an alias for jQuery()
// and other libraries also using $ will not be accessible under this shortcut
})(jQuery);
The problem is that I want to split my code into two files: 1) main.js and 2) utility.js.
How can the main program (main.js) call functions within the other file (utility.js) when both are encapsulated?
utility.js
(function($) {
function doSomething() {
/* code here */
}
})(jQuery);
main.js
(function($) {
$(document).ready(function(){
doSomething();
}
})(jQuery);
Thanks
You can use to return an object out of this utility.js:
(function($, win) {
win.util = function(){
this.doSomething = function() {
$('pre').append('util.js');
}
};
})(jQuery, window);
(function($, $U) { // <----referred it with $U
$(document).ready(function() {
$U.doSomething();
});
})(jQuery, new util()); //<----pass the util object here.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre></pre>
Actually i like the way to use it in OOJS way. Try creating a constructor and pass a new object.
The simplest solution is to assign all functions in utility.js to some global object. Assuming your code works in the browser you could do something like this:
utility.js
(function($, context) {
context.Utility = {
doSomething: function() {
/* code here */
}
};
})(jQuery, window);
main.js
(function($, Utility) {
$(document).ready(function(){
Utility.doSomething();
}
})(jQuery, Utility);
A more general solution would be to use asynchronous module loading (http://requirejs.org/) or a tool like JSPM to manage modules in your application.
I have a panel widget with a button. Clicking the button should execute some global actions related to all such widgets and after that execute some local actions related to this widget instance only. Global actions are binded in a separate javascript file by CSS class like this:
var App = function ()
{
var handleWidgetButton = function ()
{
$('.widgetBtn').on('click', function (e)
{
// do smth global
});
return {
init: function ()
{
handleWidgetButton();
}
};
}
}();
jQuery(document).ready(function()
{
App.init();
});
And in the html file local script is like this:
$("#widgetBtn1234").click(function (e)
{
// do smth local
});
Currently local script is executed first and global only after while I want it to be the opposite. I tried to wrap local one also with document.ready and have it run after global but that doesn't seem to change the execution order. Is there any decent way to arrange global and local jQuery bindings to the same element?
The problem you're having comes from using jQuery's .ready() function to initialize App, while you seem to have no such wrapper in your local code. Try the following instead:
var App = function ()
{
var handleWidgetButton = function ()
{
$('.widgetBtn').on('click', function (e)
{
// do smth global
});
return {
init: function ()
{
handleWidgetButton();
}
};
}
}();
$(function()
{
App.init();
});
Then in your local JS:
$(function() {
$("#widgetBtn1234").click(function (e)
{
// do smth local
});
});
Note that $(function(){}) can be used as shorthand for $(document).ready(function(){});. Also, make sure your JS file is located before your local JS, as javascript runs sequentially.
Alternatively, you can use setTimeout() to ensure everything's loaded properly:
(function executeOnReady() {
setTimeout(function() {
// Set App.isInitialized = true in your App.init() function
if (App.isInitialized) runLocalJs();
// App.init() hasn't been called yet, so re-run this function
else executeOnReady();
}, 500);
})();
function runLocalJs() {
$("#widgetBtn1234").click(function (e)
{
// do smth local
});
};
How about this instead:
var widget = $("#widgetBtn1234").get(0);//get the vanilla dom element
var globalHandler = widget.onclick; //save old click handler
// clobber the old handler with a new handler, that calls the old handler when it's done
widget.onclick = function(e){
//do smth global by calling stored handler
globalHandler(e);
//afterward do smth local
};
There might be a more jqueryish way to write this, but I hope the concept works for you.
-------VVVV----keeping old answer for posterity----VVVV--------
Why not something like this?
var App = function ()
{
var handleWidgetButton = function ()
{
$('.widgetBtn').on('click', function (e)
{
// do smth global
if(this.id === 'widgetBtn1234'){
//do specific things for this one
}
});
return {
init: function ()
{
handleWidgetButton();
}
};
}
}();
Please excuse any syntax errors I might have made as I haven't actually tested this code.
Check out my simple JQ extension I created on jsbin.
http://jsbin.com/telofesevo/edit?js,console,output
It allows to call consequentially all defined personal click handlers after a global one, handle missed handlers case if necessary and easily reset all personal handlers.
I'm having a very strange and frustrating problem with RequireJS. When I call require for a module with a list of dependencies, all dependencies available in the callback reference a single module. This is probably easier to explained with code:
Including require.js script (with no data-main attribute)
<script type="text/javascript" src="/js/common/require.min.js" ></script>
Below that I include require my main.js (used in all pages of the site) which in the callback requires my page specific js.
<script type="text/javascript">
require(['/js/require/main.js'], function () {
require(['page/home_page']);
});
</script>
main.js
requirejs.config({
baseUrl: 'js/require'
});
requirejs(['base'],
function() {
var base = require('base');
base.init();
});
home_page.js
define(['home','searchbar'], function (home,searchbar){
console.log(home.init == searchbar.init); // This is always true !!!
home.init();
searchbar.init();
});
home.js
define(function(){
this.init = function(){
console.log('in home page');
}
return this;
});
searchbar.js
define(function(){
this.init = function(){
console.log('Now in the searchbar init')
}
return this;
});
The issue is in home_page.js both modules home and searchbar reference the same thing. What's strange is that now that I've simplified this example, it seems pretty random which one it chooses. Most times it's searchbar but every few refreshes it will be home.
Anyone have an ideas? Is it something terribly obvious?
EDIT: Simplified example and provided all module source.
You are assigning to this in both modules. This is not a good idea (excuse the pun). this will possibly be the window object in both cases. You could check by adding a
window.init === searchbar.init
test.
Rewrite the modules to return unique objects, like so:
define(function() {
return {
init: function() {
console.log('in home page');
}
};
});
and
define(function() {
return {
init: function() {
console.log('Now in the searchbar init');
}
};
});