Keep scroll position and save toggle after page refresh - javascript

A long content sub-page has multiple "read more" buttons done with jquery toggleClass.
When a user click the "read more" button the content is showing and the page gets refreshed. (I need the page-refresh for various reasons).
When the page gets refreshed, of course the content is not unfold anymore.
What I am trying todo is:
Save all unfold / fold toggle content before the page-refresh.
Go to the same scroll position before the page-refresh.
I am not sure what is the best way to keep the information -> Cookies, sessionStorage or localStorage for my case, because the user will usually open more sub-pages with "read more" buttons.
I made a JSFiddle (page refresh is not working on a fiddle).

I'd advise using sessionStorage for this.
First, remove all onclick=refreshPage() from your HTML. You want to keep all JS code inside your JS, and to set all handlers at one place. As a best practice, do not use onclick at all.
Next, create two functions: loadState() and saveState(). You will need to call call loadState() on every page load (refresh), and saveState() everytime a toggle button is clicked.
In your handler for clicks on button, also perform the page refresh.
The entire JS code:
$(window).on('load', function() {
loadState();
});
$('.read-more-toggle').on('click', function() {
$(this).next('.read-more-content').toggleClass('hide');
saveState();
refreshPage();
});
// Fold or unfold each content based on state before refresh
// And go to same scroll position before refresh
function loadState() {
let hidden_states = sessionStorage.getItem('hidden-states');
if (!hidden_states) {
return;
}
hidden_states = hidden_states.split(',');
$('.read-more-content').each(function(i, elem) {
if (hidden_states[i] === 'hide') {
elem.classList.add('hide');
}
else {
elem.classList.remove('hide');
}
});
document.scrollingElement.scrollLeft = sessionStorage.getItem('scroll-x');
document.scrollingElement.scrollTop = sessionStorage.getItem('scroll-y');
}
// Remember fold & unfold states, and scroll positions
function saveState() {
let hidden_states = [];
$('.read-more-content').each(function(i, elem) {
hidden_states.push(elem.classList.contains('hide') ? 'hide' : 'show');
});
sessionStorage.setItem('hidden-states', hidden_states);
sessionStorage.setItem('scroll-x', document.scrollingElement.scrollLeft);
sessionStorage.setItem('scroll-y', document.scrollingElement.scrollTop);
}
function refreshPage() {
window.location.reload();
}
Note: If at all possible, try to avoid a page refresh. Storing view states then recreating them after a refresh feels sub-optimal. In some browsers, it may also result in occasional scroll jump glitches as it repaints the restored states.
Lastly, consider if you really need jQuery for your project. Most functionality can be implemented in vanilla JS.

Related

How do I stop JavaScript timer when out of view?

Have a slider in website header that uses JavaScript and Jquery to change its tabs every 6 seconds or when the user clicks one of its tabs. I use it in my project in Webflow (a page builder) and the problem I face is that whenever slide changes, currently focused form window loses focus.
I'm no programmer even though I'm learning js now, but if after some investigation I think that the .w--current class is used both for slider and form focus in Webflow's master js file.
Here is my live project:
https://bauserwis-com-pl.webflow.io/
I found some solutions that use IntersectionObserver API to tell if the header is in viewport and stop the setInterval timer, but I struggle with integrating it with my code. Or perhaps is there a different solution? I don't mind slides changing in the background, I only want to stop the form from losing focus.
Thanks in advance.
var tabTimeout;
clearTimeout(tabTimeout);
tabLoop();
// Cycle through all tabs.
function tabLoop() {
tabTimeout = setTimeout(function() {
var $next = $('.tabs-menu').children('.w--current:first').next();
if($next.length) {
$next.click(); // user click resets timeout
} else {
$('.standard-tab:first').click();
}
}, 6000); // 6 second tab loop (change this)
}
// Reset loop if a tab is clicked
$('.standard-tab').click(function() {
clearTimeout(tabTimeout);
tabLoop();
});
});

Content hide/show

my goal is to hide the content of my homepage when someone visits. onClick to begin button the content should be shown. Content should stay open when user goes to other page and comes back to homepage. But it will be hidden when user closes the window and opens up the homepage again. To achieve this goal I have put the following code but it keeps the content open even when user closes and opens the window. So please help me out.
if (! localStorage.noFirstVisit) {
// hide the element
$("#content").hide();
// check this flag for escaping this if block next time
localStorage.noFirstVisit = "1";
}
Another issue is when the content shows the design gets little messed up(by widening the divs, bringing horizontal scroll)
$(".roll-button").click(function(){
$("#content").show();
});
I would highly appreciate if you check website, suggest me fix or show me proper way to achieve this goal. url:iamicongroup.com
You can totally use sessionStorage to detect whether it is new tab(window) or not.
When you first visit this page, set sessionStorage.noFirstVisit = "1";.
After you go to another page and back, sessionStorage.noFirstVisit is still "1".
But when you close the tab or browser and open the page newly again, sessionStorage.noFirstVisit will be undefined.
Documentation is here
The documentation also provide the difference between sessionStorage and localStorage.
I would suggest reading this: Detect Close windows event by Jquery
It goes over window unloading (beforeunload), which I believe is what you're after. You can set/unset your localstorage values there based on certain criteria being met; for example:
$(window).on("beforeunload", function() {
if(localStorage.noFirstVisit = "1" {
// do something
localStorage.noFirstVisit = "[someValue]"
}
else {
// do something
localStorage.noFirstVisit = "1"
}
})
Another issue is when the content shows the design gets little messed up(by widening the divs, bringing horizontal scroll)
how about adding something like 'ng-cloak' in angular, to avoid the undesirable flicker effect caused by show/hide.
when clicking the roll-button, it prevents the divs from showing unfinished..

Click on button after page reload

I have some links on the page and when user click on link, page is reloaded.
All links have some ID and all have the one same class.
I need to click on some other link after page is reloaded, but only if user click on some of the link with particular class (not anywhere, like menu link).
How I can do something like this using JS or jQuery?
It sounds like you are attempting to build a single page application, ie the application is mostly run by JavaScript instead of server side rendering. In this case page reloads are you enemy. A page reload is basically a restart of your page, and while you can keep state using cookies or localStorage, this will provide you with a rather poor user experience.
In this case, you would just add event handlers to any actions your user would take, and simply handle them in javascript without reloading the page from the server. If you need to get more data in response to the user's actions, you can use AJAX to pull that data from the server.
If you have to use links with urls (still unclear to me why that would be necessary), I would recommend using hash urls like so '#some-action' which will not reload the page when clicked. You can then attach an event handler to the link, or even listen for the url hash to change using the hashchange event. In this way you can know what link the user pressed.
If you are not trying to build a single page application, you will need to add code on the server to store the information you need in the page.
I did it.
So, I created function:
/**
* Click on delivery link after page reload
*
* #return {boolean} [loacalStorage is available]
*/
$.fn.openDelivery = function(){
if (localStorage) {
var addedToCart = localStorage["addCart"];
if (addedToCart) {
setTimeout(function() {
$('#showRight').trigger('click');
}, 1500);
localStorage.removeItem("addCart");
}
$(this).click(function(e) {
localStorage["addCart"] = true;
});
return true;
}
return false;
};
And then called that function:
$(document).ready(function () {
// Trigger delivery click
$('.class-of-my-link').openDelivery();
});
In my case, page reloads after user add some item in shopping cart. With this function I click on link (with 1.5s delay) that opens cart of the user that is shown on the right side of the screen.

Change page on certain condition (before current page shows up)

I would like to prevent the user to access subpages of my jqm page. To do that I use the pagebeforecreate event to check a certain condition and depending on that, change the page displayed (cancel current pageload and redirect or normally load the current starting/main page). The Problem is, that I still see the page flickering up before the changePage() is executed even when I call the preventDefault() method. I also used a relative URL as the first parameter (to = 'page.php') of the changePage(to, options) and since my #subpage1 lies within the page.php it should open - which it did - but then the transitions are broken because no real refresh was done.
Note that I have a page.php including different #subpage's (such as #subpage1, #subpage2).
jQuery(document).on('pagebeforecreate', '#subpage2', function(event, data) {
if (!isCondition1() && !isCondition2()) {
// stop loading #subpage2
event.preventDefault();
jQuery.mobile.changePage(jQuery('#subpage1'), {
data: 'lang=de&param1=foo&param2=bar',
reloadPage: true,
type: 'get'
});
}
// go on loading #subpage2
});
jQuery(document).one('pageinit', '#subpage2', function() {
// do something
});
Have you tried setting the body style to display:none in the html? And then if the page loads correctly you can set it's display property? That should be a 'workaround' to prevent the flicker of the page?

Cancel Browser Scroll Reset for Inline Onclick

I'm using prototype to construct an ajax request from an inline onclick on a link. The function shows an element on the page and this all works fine, except that the browser scroll bar resets to the top after every click of the link. This is bad b/c sometimes the content that I want to show is partially scrolled down the page and this makes it so the user cannot see it. I realize it's better to not include the onclick inline, but I have a situation where I dynamically create these links and then cache the html so it is faster this way. Is there any way to cancel this browser scroll reset using an inline onclick? This is what my code looks like:
example
function linkAjax(word){
if(!making_ajax_request){
making_ajax_request = true;
new Ajax.Request('/example/test',
{parameters:{data: word},
onLoading: function(){searchLoading();},
onComplete: function(){
making_ajax_request = false;
}
});
} else { }
}
Your onclick needs to return false to stop the browser from reloading the page (resulting in scrolling to the top). Try:
example
Do this:
onclick="linkAjax('example') return false"

Categories

Resources