Suppose you have some kind of listing and you allow this listing to be rendered via CSS either as a list or as a grid (via a varying CSS class or data attribute). Since this is purely a rendering issue it required not (re)processing by the web server, thus you can also simply implement the switch on the client side via JavaScript.
However, suppose you want to save the client's view mode choice, e.g. in the localStorage. Now when the page is rendered, the appropriate view mode needs to be restored.
But what is the best practice here in order to prevent the switch from the default view to the saved view to be visible when the content is above the fold?
Consider the following crude example: http://jsfiddle.net/yaubvq8d/27/
Here the JavaScript for changing the view mode and also loading the saved view mode from the localStorage is at the end of the body, which is obviously not ideal. To visualize the problem I also integrated an externally loaded JavaScript, that blocks rendering of the page for 2 seconds - so it takes at least 2 seconds, before the JavaScript for managing the view mode is actually executed. During these two seconds you first see the default view (which is the grid view) and then it would switch to whatever view you had previously selected (to test this you obviously have to click on "List" first and then run the fiddle again).
The only obvious solution I can think of is defining the view mode in a parent container (let's say the body) and then execute the JavaScript to load the view mode from the local storage right after the starting tag of the parent container.
But are there any other best practices, that I might miss?
Related
I'm relatively new to React (and Javascript, for that matter) so please bear with me.
To put my question shortly: how do i trigger a resize event on my window/component in React?
Now below is a little more context, which may actually prove that i'm asking a wrong question here.
I'm trying to create a small app with several tabs. The component is taken from BlueprintJS framework. The content of these tabs is loaded using a javascript API, which in turn uses RESTful requests to a remote application. The content that will be rendered in my tabs is some tables and charts.
Here is a caveat. The actual rendering of those tables and charts is performed by the javascript API i have to use, not by my React app. I have to pass an ID of a to the API, and it will render returned content into that .
The problem: Only the content of the default active tab is rendered correctly. If i switch to any other tab of my React application, the content is not rendered. HOWEVER if i resize the window the content is rendered instantly (i believe this is handled by the javascript API i'm using). Also if i update parameters of the currently active tab to make the API load updated content from the remote application, the content is also rendered in the active tab.
So i figured if i can simulate the resize event when switching between tabs i can get my content to render.
I tried setting a conditional class on my as depending on whether the current tab is active or not:
<div className={this.state.SelectedTabId === "tab1" ? "container" : "hidden"}>
where "container" and "hidden" have different width configured in CSS file, but this doesn't help. I also tried to directly manipulate the DOM (at least as a test) but even that didn't make a difference:
let e1 = document.getElementsByClassName('container')[0];
e1.width = e1.scrollWidth - 1;
renderedElement.resize(); //this is an API method which is supposed to re-render the content it returns
We have a parent site that provides the real estate for our applications to be added. The flow is described as below
Parent site has a menu.
One of the "links" on the menu points to our
application
When you click on it, the parent site internally parses
the response from our application (including html and javascript)
and loads it within a container. Sort of a portlet. This parsing is problematic, because once the javascript is loaded, it remains in the head tag.
Thereafter, we can use our code to control the application in a SPI manner.
Problem arises, when the user clicks on the menu again, because steps 1-4 get repeated. Thus we end up reloading javascript, which fails spectacularly. Some of the problems include
Angular is reloaded.
Modules get reloaded.
If I defer the loading of Angular conditionally via document.write, then I have to ensure that angular is loaded before the modules are defined.
If I manually bootstrap the application, then I cannot bootstrap it again and I need flags to maintain.
I was able to write a script to ensure that everything is loaded only once, but now the problem is that the DOM does not get "processed" once the user clicks the link again. It is as if the entire DOM content has refreshed with the angular tags and directives, and the javascript is already loaded, but it does not "process" this new DOM content.
What can I do to ensure that newly added DOM via a third party plugin/script/code is recognized by existing angular code?
I am using Firefox, and I have noticed something interesting while working on my website. One page has a table of information, but also maintains Javascript variables indicating the table's contents so it can look up information more easily.
When I navigate away from the page by typing in a URL, then hit the back button to return, I have noticed that the page seems to retain its state. The table still has the same contents as when I left, and further interactions with the page indicate that the Javascript variables have maintained their values as well.
I had assumed that my $(document).ready(); functions would run again when the back button was hit, but this is clearly not the case as I wrote those functions to ensure the page is its initial state, regardless of the page's current content.
I think it is perfectly acceptable for the page to be restored this way as long as I can depend on the page being restored properly. If instead, the page is restored to its initial state, that would be acceptable as well.
Is it safe to rely on this behavior? Would I be better off using something like onunload to ensure that the page's state is not saved? Should I just assume the browser will do things properly?
I would say that my website's state is defined by the HTML on the page and the contents of Javascript variables. It uses AJAX (or I guess technically AJAJ) to interact with PHP pages, but all interactions are discrete transactions. The only state/session needed by the server are login authentication cookies, which should be unaffected by this.
I'm making a game using JavaScript, currently I'm using window.location = "somepage.html" to perform navigation but I'm not sure if that is the correct way to do it. As I said in the title I've choosed Blank App Template so I do not have any navigator.js or something like.
Can you guys tell me the best way to do it?
Although you can use window.location to perform navigation, I'm sure you've already noticed a few of the downsides:
The transition between pages goes through a black screen, which is an artifact of how the underlying HTML rendering engine works.
You lose your script context between pages, e.g. you don't have any shared variables or namespaces, unless you use HTML5 session storage (or WinRT app data).
It's hard to wire up back buttons, e.g. you have to make sure each destination page knows what page navigated to it, and then maintain a back stack in session storage.
It's for these reasons that WinJS + navigator.js created a way to do "pages" via DOM replacement, which is the same strategy used by "single page web apps." That is, you have a div in default.html within which you load an unload DOM fragments to give the appearance of page navigation, while you don't actually ever leave the original script context of default.html. As a result, all of your in-memory variables persist across all page navigations.
The mechanics work like this: WinJS.Navigation provides an API to manage navigation and a backstack. By itself, however, all it really does is manage a backstack array and fire navigation-related events. To do the DOM replacement, something has to be listening to those events.
Those listeners are what navigator.js implements, so that's a piece of code that you can pull into any project for this purpose. Navigator.js also implements a custom control called the PageControlNavigator (usually Application.PageControlNavigator) is what implements the listeners.
That leave the mechanics of how you define your "pages." This is what the WinJS.UI.Pages API is for, and navigator.js assumes that you've defined your pages in this way. (Technically speaking, you can define your own page mechanisms for this, perhaps using the low-level WinJS.UI.Fragments API or even implementing your own from scratch. But WinJS.UI.Pages came about because everyone who approached this problem basically came up with the same solution, so the WinJS team provided one implementation that everyone can use.)
Put together then:
You define each page as an instance of WinJS.UI.Pages.PageControl, where each page is identified by its HTML file (which can load its own JS and CSS files). The JS file contains implementations of a page's methods like ready, in which you can do initialization work. You can then build out any other object structure you want.
In default.html, define a single div for the "host container" for the page rendering. This is an instance of the PageControlNavigator class that's defined in navigator.js. In its data-win-options you specify "{home: }" for the initial page that's loaded.
Whenever you want to switch to another page, call WinJS.Navigation.navigate with the identifier for the target page (namely the path to its .html file). In response, it will fire some navigating events.
In response, the PageControlNavigator's handlers for those events will load the target page's HTML into the DOM, within its div in default.html. It will then unload the previous page's DOM. When all of this gets rendered, you see a page transition--and a smooth one because we can animate the content in and out rather than go through a black screen.
In this process, the previous page control's unload method is called, and the init/load/processed/ready methods of the new page control are called.
It's not too hard to convert a blank app template into a nav template project--move your default.html/.css/.js content into a page control structure, add navigator.js to default.html (and your project), and put a PageControlNavigator into default.html. I suggest that you create a project from the nav app template for reference. Given the explanation above, you should be able to understand the structure.
For more details, refer to Chapter 3 of my free ebook, Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition, where I talk about app anatomy and page navigation with plenty of code examples.
I have an asp.net-mvc website where there is a top section with a bunch of filter information and the middle section is a reports. I now have a few different report formats and I want to toggle between a few reports. I have it working by making them all partial views and loading them via ajax (to avoid loading the common info over and over again) but one issue i realized is that some of the different reports have different javascript that goes along with them. For now, I am loading up all of the javascript files in the main parent page but I realized that I am wasting a lot of resources by download and wiring up all of the jquery events even if i never actually view a report
Is there anyway I can pass some javascript along with downloading a partial view in asp.net-mvc so I only load this and wire up the events "on demand" as required (instead of always)
Of course you can. Just be aware that the effects of the code will stick around even if you later remove the code itself: any functions you defined will remain defined, any listeners you attached will remain attached (as long as their target elements persist)... so it would be a good idea to make a setup() and teardown() methods for the loading code, that you'd invoke from your controlling code, rather than just drop a bunch of code to execute as it loads.
However, I would say it would need to be a rather unique set of circumstances for me to employ this method; for most part, it would be much easier and efficient to just load all the code you need at once, to benefit from client caching if nothing else. Toggle the behaviour of your code, don't toggle the code.