Issue with styled-components in "custom" single page application - javascript

I'm currently working on an old project, which has its "own way" of doing a single page application (does Ajax calls to an MVC application, gets the view, replaces the view client-side, appends styles and lots of other stuff!!), and although not ideal, currently I'm stuck with it!
I am trying to integrate an existing React application into this site, and what I'm doing is to use create-react-app and then build to create the bundles, and in the application, in the view begin returned from the server for a specific page, I'm putting script and link tags, pointing to my bundle files. It's worth noting that this server view is a partial ASP.NET MVC view, so my script and link tags are somehow part of the body.
I'm also using styled-components in my React application.
Now, here's the problem: when I first load the page I mentioned, my script is loaded, and I can see all my components being styled properly, but when I navigate in the existing custom SPA application, at some point, styles related to styled-components are messed up, and the only way to get them back is to reload the page.
I was inspecting the page, and I saw that styled-components is doing things with a custom link created in the head, and I see data-styled-components attribute being populated with custom class names as my components are loaded, but when the problem arises, in Chrome Developer Tools, I see that the link tag flashes as if it's changed, but it stays the same.
I have attached a GIF of the tag:
- It starts with the initial page load
- I navigate away and come back and I see more classes being appended
- I repeat the step, and I only see that it flashes
I know the post is already long, but any help is deeply appreciated. Is it possible that, with the current infrastructure, it has something to do with the fact that whenever I come back to the page, a script tag is sent from the server pointing to my React bundle?

Thanks to Max Stoiber for answering in this GitHub issue:
The reason for this behavior is exactly what I mentioned at the end of the question: every time the page is loaded, a script tag is sent from the server, containing the bundle, which in turn causes a new instance of styled-components to be created; this is not supported in styled-components, and that was the issue

Related

Vue router- Trigger refresh when changing dynamic route via next/previous post links in blog

I'm relatively new to Vue, and I'm working on a portfolio site that is essentially structured like a blog with single/detail views for each project, i.e. SingleProject.vue and are linked using dynamic routes based on the slug name, i.e. path: "/projects/:project_name_slug". In the template, I'm using Axios to request JSON data from a CMS, and passing the data to a post variable via a fetchPosts() function. I'm then running this.fetchPosts() on the mounted life cycle hook. On this single project view, I also have links to the next and previous projects based on the order defined in the CMS. I'm saving JSON data to respective arrays for nextPost and prevPost and then creating router links using the post slug names as follows:
<router-link
v-if="nextPost"
:to="{path: '/projects/' + nextPost.project_name_slug}"
>Next Project</router-link>
Now to get to my actual question: these links for next/previous posts work fine; but when clicked, the view does not fully refresh/transition, and all the text data—title, sidebar info, etc.— changes rapidly, but the images lag a bit while they're downloaded (see diagram below for a visual.) So, for a moment, one will see an image from the previous project alongside text info for the next one, while the new image loads. This is a bit distracting/off-putting, so I'm trying to find a way to essentially reload the view (as if one were clicking to a different [static] route altogether) when clicking on one of these links to change the dynamic route. I found this helpful SO post, which suggests adding a changing key to <router-view> to trigger a full lifecycle whenever the path changes, i.e.
<router-view :key="$route.fullPath"></router-view>
This approach works, and indeed forces the whole SingleProject view (images and all) to refresh when changing routes via the next/previous links. However, I'm wondering if there is a better/more efficient way to limit this lifecycle refresh to just the dynamic (project view) routes? I realize, as noted in that thread, this approach could impact performance by forcing the recycle on all route changes, not just those related to single project views. Please let me know if this is unclear in any way- and thanks for any insight!
If you want to earn such kind of thing you can do it by putting all needed routes into a variable which is an Object. Then you can define some logics to switch between them and apply to a component and use it globally.
Ah, by the way, You can use a good tool called Vuepress. It has its own Previous and Next link buttons. You can say it is for documentation. No you can make blogs and portfolios too. There are so many projects created with Vuepress on the internet.
And even you can change layouts, styles or create your own theme from zero.
Below you can find link to many different projects and websites.
And most of them are ready themes to use in your projects.
https://github.com/topics/vuepress-theme

Moving an HTML+javascript page to iFrame

I have an existing website composed of individual pages (each page is a different tool that requires some user input (ie forms), and each with it's own set of javascript functions to populate dropdown lists, etc on that page). Each of the tools is accessed from the main index.html.
Instead of each tool being its own "stand-alone" page that is invoked from index.html, I'd like each tool to be displayed in an iFrame instead on the main page. This way the main page remains static, while only updating the iframe with whatever tool the user selects. So say on the main index page, I have a 3 tools menu (collect logs, collect KPIs, collect status), along with an iFrame. If the user selects collect logs for example, the menu containing "collect logs" stays there, but the "collect logs" page is displayed in the iFrame.
My problem is that all the HTML content works fine, but none of the javascript code in the selected tool page works (ie none of the drop downs get populated since it's the javascript code in the page that does that by reading a file on the server).
Is there an easy way to port each tool page (html+javascript) to an iFrame without having to re-write tons of code (in my naivety I thought simply invoking the page inside an iFrame using target='' in the href would work)? Or is there a better method of accomplishing what I'm trying to do? Maybe iFrame isn't the solution.
Content in iframes remain autonomous from the wrapper app, so it makes sense that it's not working correctly. Other than building a listener for a click event associated with the div wrapped around the iframe, the iframe document isn't accessible if it points to a different origin. (See [same-origin policy]
(https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy))
To stay with simple html/css/js solution:
You can use a regular div to wrap each 'stand-alone' content and then just use whatever button/navigation target you have display that div and hide the previous by changing their css display style with the onClick event.
More invasive option:
You may want to consider using a more modular JS approach, like React JS, to build components vs pages and utilize React's structure to toggle components.
With react you can render each 'tool' when the user selects it . You would be able to utilize React component state as well to help in storing data and such for the life-cycle of the component.

Safely reset (including running js) complete page to just like blank page

We provide live chat service to our customers. customer just copy some code and put in their footer. then they can have video chat, cobrowsing and many things..
but problem comes when user switch from page to page. so we have resume functionality as well. but thats not robost solution.
So i've come to two solution.
1. Iframe solution
i'll give client a some.html file which he'll need to upload to their root url, then upon video chat and cobrowse we load that page in some.html's iframe and chat appear in some.html
so that work well. chat box apprear seamlessly no page reload effects came in. and as its on same domain i can access all contents of iframe.
2. Another hack solution (not implemented yet, looks good solution)
i was thinking that instead of redirecting user to new page (some.html)
i should clear all contents of current page and load same url in one iframe within the page.
i think that will work well. but i affraid that some client might be using complex js based web app. so if i remove complete body from their page they might have problems.
as much as i know i can remove all dom nodes with their events handlers as well. but is their way to clean js runtime. so all js objects will destroyed and removed from scope so no longer run.
so is there a ways to clear any page completely with all its html and associated java-script as well. means reset page to blank.
Finally i found that there is no way to reset page.. but got another way to make it done.
upon need we can redirect user to same page with query string that identity that its reload for iframe, we put small bit of another code at head which remove all dom before loading dom, css, js.. and create just one iframe of same url.
thus it allows me, have user see no change in url, user browse website as normal without any problem and my chatbox always be there in same state across all pages.
will make it live soon on tagove.com
Why don't you empty the HTML page using empty() function of jquery first,
Then remove/update the link i.e.<script src="...."></script> so that the HTML has no dependency on that javascript and that way it won't be able to Modify the DOM.
And then try to build a javascript program to remove any file in the folder which is isolated(No calling, No dependency, no connection whatsoever)

How to seamlessly change url of website

I know this has been asked several times, but I just can't figure out how to change the url or render a new html and make it seem as if you never leave the site.
I want to do exactly what this site does:
http://uncharted.sunbrella.com/
Does it load all the content and just change the visible objects via javascript? Do they use angular states? I can't figure out how to get that effect of seamless transition between sections of websites.
Based on their page source code, it doesn't look like they're using angular, but you certainly could use it. If you did, I would recommend using ui router with multiple views on the page.
The secret to loading html dynamically is by using ajax to request data on the fly and updating the dom via javascript.
The site you referenced used css to make the page responsive and to prevent you from scrolling until you clicked a link. After clicking it looks like the content loaded outside of the view port so you don't see the data loading until you scroll.
Long story short, to point you in the right direction, I would urge you to learn more about ajax loading and css dom manipulations. If you are familiar with Angular, checkout ui router as it would allow you to easily setup multiple views on a page.

Pagination with special loading function?

I was searching for a script or at least a code snippet but haven't really made any progress. Anyway, I'm looking for a script that works like a simple pagination javascript but it should be accessible by linking from anywhere in the document and by calling it with the URL (e.g. on www.abc.de/default.html#thirddiv the third page of the pagination is displayed). Further, the contents should be loaded upon request (when the user clicks on the link and enters the specific page of the pagination), so that cookies, that have been set or deleted in the same document earlier can be used later without reloading the entire page. Something like that is used on Facebook for calling contents and loading them.
I've found a script on CSS Tricks called BetterBlogroll but I don't really get my mind into this. A pagination script from DynamicDrive is already working very well on the page but my problem is that there should be running three of them on the same page and as I said, the content should be loaded upon the user's request.
The script I'd need does not has to be with loads of CSS, the best way would be plain javascript and only the required CSS and HTML data. Anything else just disturbs. If anyone can help me out here, I'd be very thankful.
Check out Ryan Bates's Railscasts #174 and #175. These two are not rails specific, and explain this well.

Categories

Resources