I am working on a new version of the same project. Posted Here
An html page that will read and display places and routes from a kml file using Google Maps API. The earlier version used Leaflet's API. The Leaflet version had over a dozen files: html, js and css. It was always an effort to find the code that supported a feature. Perhaps there is an IDE that supports that. I use a fancy editor but its not really integrated.
So for my new version I was thinking of another approach: Putting all the code for the feature in one js file.
Similar to this: <See DebugControl.js below> which contains js code to build html and set style plus having any needed functions.

I'm looking for comments or recommendations for an approach to allow me to add features to the project without having so many different files or having a lot of none related code in the same file.

function addText(text, nl) {
//      if(++debugCnt > MaxDebugOutput)   return;       // no more output now
   var dboDiv = document.getElementById('debugOutput');
   dboDiv.appendChild(document.createTextNode(text));
   for(i=0;i < nl;i++)
      dboDiv.appendChild(document.createElement('BR'));  // to new line
}

/*  Add new div to body to hold debug output */
const logDiv = document.createElement('div');

logDiv.id="debugOutput";

// Style it
logDiv.style.position = 'absolute';     // or 'fixed' if you want it to stay on screen
logDiv.style.top = '40px';              //  below filename
logDiv.style.left = '20px';
logDiv.style.width = '400px';
logDiv.style.maxHeight = '90vh';        // max height = 90% of viewport height
logDiv.style.backgroundColor = 'pink';
logDiv.style.border = '1px solid #ccc';
logDiv.style.padding = '10px';
logDiv.style.overflowY = 'auto';        // vertical scroll when content exceeds max-height
logDiv.style.zIndex = '1000';

// add to body
document.body.appendChild(logDiv);

//----------------------------------------------------
//  Add a new div to contextMenu div - handle toggle of showing log
const parentDiv = document.getElementById('contextMenu');
const newDiv = document.createElement('div');
newDiv.id = "cm-showLog";
newDiv.textContent = "Hide log";
parentDiv.appendChild(newDiv);

const showBtn = document.getElementById("cm-showLog");
var showingLog = true;
showBtn.addEventListener("click", () => {
  if(showingLog) {
     showBtn.textContent = "Show log";
     logDiv.style.display = "none"; 
  }else {
     showBtn.textContent = "Hide log";
     logDiv.style.display = "block"; 
  }
  showingLog = !showingLog;  //  toggle
});





/*  Trap console.log to our function */
console.log = function(msg) {
  addText(msg, 1);
}
etgcalculator commented: Thanks for sharing this meaningful information. +0

Recommended Answers

All 14 Replies

I think it's just like any project, really. Break code up into classes, functions, and different files.

However, why are you using javascript to add CSS to debugOutput instead of:

#debugOutput {
    position: absolute;
    padding: 10px;
    ...
}

I would strongly avoid doing that if you could at all avoid it.

How do I add css code to a javascript file that is to contain all the components needed for a specific feature? I would like not to have to change other files when fixing or enhancing a feature. That was the problem with my first attempt. The html, js and css were spread over too many files. Updating a feature often required changing more than one file. The main html file has a basic structure. Each feature adds what it needs to the body or a div in that file. This is a small project and will not have more than a dozen features.

How do I add css code to a javascript file that is to contain all the components needed for a specific feature?

You don't. CSS is not meant to be contained in Javascript. Doing it the way you are slows down the page loading and takes up extra CPU cycles on the end-user's web browser.

I'm confused by what you're trying to accomplish. On one hand I hear you saying you're looking for recommendations for structuring a web project, and are complaining about having a lot of non-related code in the same file. On the other hand, you're saying that you want to optimize for having everything contained in one javascript file (at the cost of performance, scalability, flexibility, etc. and pretty much everything that goes into good web architecture).

Websites are created with HTML, CSS, and Javascript. Sure, you can do the crazy thing you're doing and forego a CSS stylesheet by dynamically setting the styles via JS. But you could also take it a step further and have Javascript inject the entire HTML contents into the DOM as well. That would be double crazy, I suppose.

Sorry, I just absolutely cannot get behind wanting to condense a web app into as few files as possible. That completely goes against absolutely everything that makes a well-structured website and is considered good website architecture.

I'm not a Java person, but what would your reaction be if I were to say I wanted to create a Java app where the entire app was contained in the constructor function of one class because I found it too annoying to work with multiple methods and classes?

Thanks for the responses.
This is my third project of any size for my client of one. The first one ended up with over a dozen files and has been problematic to update. The code for each feature is spread over several files. That's probably true for many first projects. Perhaps a better naming convention or separate folders to hold the js and css files for different features would have been better. I thought for the current project (a rewrite of the first project using Google Maps vs Leaaflet) I'd try something different - all the code for each feature would be in one file similar to a java class where the variables and methods are often in a single java class file.
I don't know how to isolate html statements into separate files something like the include statement in C provides. My idea was to have a basic html page and then have the js for each feature add what it needed to the html body.
Is there a good editor that allows grouping files for each feature so when updating code for a feature only the code (html, js and css) for that feature is visible for searches?

Another question: about scope - how to have some variables that are accessible by a group of functions without worrying about collisions with names in another scope? Sort of like variables in a java class are only available to methods in that class.

Hello , you mentioned Java many times, but we don't structure things that way in Java either. Writing a monolithic class containing everything would make it unreadable. There are many ways to structure a web app. Here is one of them. In the www/public_html directory, we have folders like js, css, imgs, etc. Let's suppose you're in the section of your web app where a user edits their profile. Normally, you would have an EditProfile JavaScript class for it in your 'js' folder, in its own file: EditProfile.js. In there, you could have private/static methods, properties, a constructor method, whatever you need. Then, you'd have an EditProfile.css file in the 'css' folder, which will contain all the CSS this "module" needs when loaded without any user interaction. This is the critical CSS. And then you could have an EditProfile.nc.css in the same folder for the non-critical CSS (user interaction + anything that is not needed immediately when the view is loaded).

Normally, you could have a main app class object instance initialized that would instantiate whatever events object is needed based on some factors (this could even be a data-field in the body).

You could generate the HTML code inside the EditProfile JS class yourself or by using a vDOM framework (Vue, React, etc.), but my take is that you should have a reason to do so. vDOM frameworks shine if your specifications align with the reasons they were created (chats, frequently changed bulletin boards, etc.), where the client side is the source of truth. If this is not the case in your specifications (as most times), you could have a View Generator class server-side (using any language you like) that will generate the main view for the Edit Profile section.

After those steps comes the bundler, which will take those JS files and bundle them into one, and the CSS bundler. Other plugins can be in other folders and loaded on demand. I've oversimplified many things here, just to give you one of the ways we structure web apps.

There is a reason why online code playgrounds such as JSFiddle give you separate fields for HTML, CSS, and JavaScript even for the purpose of quick testing of code snippets. Even the most absolute basic webpages or fragments of webpages need to separate those three out.

Another question: about scope - how to have some variables that are accessible by a group of functions without worrying about collisions with names in another scope? Sort of like variables in a java class are only available to methods in that class.

The let keyword in Javascript is block-scoped.

Also, Javascript supports classes. The let keyword is block-scoped. The var keyword is function-scoped (or globally-scoped if declared outside of any function), but hoisted, and due to that confusion have fallen out of favor in recent years in favor of let.

Also, and sorry for the quadruple posting, but as always seems to be the case with software architecture, how your structure the app tends to come down to what your priorities are. In web development, performance is almost always paramount. gave one possible way of breaking up files. I think what he failed to expand on is that his recommendation is not necessarily to break up by feature, but to break up by what's required for any given page. This way, every webpage starts off by loading global JS/CSS that is used site-wide, in addition to then only loading the CSS and Javascript files required for the specific page.

what's required for any given page
There is only one page

performance is almost always paramount.
I would think loading many files from a server would cost more than loading fewer files that may require some CPU time to process.

a monolithic class would be that
It would be one class per feature plus one for the basic page. The features for example are: Display current status, Measure distance between points, Measure distance on a path, Remove a Path, About the project

commented: Why not? It's your project so it's you and God will know how it works. +17

Premature optimization is the root of all evil. Don't think, measure.

commented: Recent article on developing: "EVERYTHING MUST BE A FACTORY STRATEGY OBSERVER SINGLETON." +17
commented: I fail to see what this refers to. -3

It refers to:

I would think loading many files from a server would cost more than loading fewer files that may require some CPU time to process. Quote Here

commented: I did not consider that in the design. It was in response to Dani's post. +0
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.