I have done back function for ajax search using url hash. It works fine but the problems is with sliders and some other animation, the sliders freezing and I can't move crawlers.
var hashState = false;
var historyState = false;
var historyArr = new Array();
// back content with specific hash
window.onhashchange = function(){
var hash = location.hash;
if( ! hashState && hash && historyArr[hash])
{
$('.diamond-filter').html(historyArr[hash]);
historyState = true;
$('#diamond_search').ajaxForm(diamonds_options);
$('#diamond_search').submit();
}
hashState = false;
return false;
};
function logSearch(hash)
{
historyArr[hash] = $('.diamond-filter').html();
}
I suppose it losing some connection. How to keep it or restore without re-init?
Related
After clicking "Take a break" number of sets should decrement, and clock should start.
During clock working, clicking on any element of site should be cousing any effect.
Instead, the first click and it works properly, but after first clock pass, i can click decrement sets during the clock work and click another breaks.
I want to do this without asynchronous stuff (project's requirement ;/ )
I tried adding a freezing variable but i have problem how properly place the ifs.
Here is fragment which i struggle with:
var freeze = false
$(".start").click(function(){
if(!freeze){
freeze = true;
var num = $(this).attr("id");
var currExcercise = routineSample.excercises[num];
var res = this;
var timer = 0;
var setsTd = "#set"+num;
if(!currExcercise.allSetsDone)
{
timer = currExcercise.breakTime;
currExcercise.sets--;
if(currExcercise.sets <= 0 ){
currExcercise.sets = 0;
currExcercise.allSetsDone = true;
}
$(setsTd).text(currExcercise.sets);
if(!currExcercise.breakPassed){
setInterval(function(){
if(timer>0){
timer--;
$(res).text(timer);
}else{
if(!freeze)
$(res).text("MOVE ON!");
currExcercise.timeLeft = timer;
freeze = false;
//currExcercise.breakPassed = true;
}
}, 1000);
freeze = true;
}
}else{
$(res).text("EXCERCISE DONE");
}
} });
To "freeze" a page use the following CSS:
body { pointer-events: none };
I have a series of divs that when clicked it slides up basically a modal. The modal has a data-attribute that appears in the url. The issue I'm having is when I close the modal, the url still has the data-attribute hash, it doesn't revert back and I need it to.
This is the js:
$('[data-agent]').click(function() {
var element = $(this);
var target = element.data('agent');
$('body').addClass('agentLoaded');
$('[data-agent-target]').not('[data-agent-target="'+target+'"]').removeClass('active');
$('[data-agent-target="'+target+'"]').addClass('active');
window.location.hash = 'agent='+target;
return false;
});
if(document.location.hash){
var hash = document.location.hash.split('#')[1];
hash = hash.replace('agent=', '');
if(hash && $('[data-agent-target="'+hash+'"]').length) {
$('[data-agent="'+hash+'"]').trigger('click');
}
}
$('.close').click(function() {
$('[data-agent-target]').removeClass('active');
$('body').removeClass('agentLoaded');
return false;
});
[edit] Please see the question in the code
$('[data-agent]').click(function() {
var element = $(this);
var target = element.data('agent');
$('body').addClass('agentLoaded');
$('[data-agent-target]').not('[data-agent-target="'+target+'"]').removeClass('active');
$('[data-agent-target="'+target+'"]').addClass('active');
window.location.hash = 'agent='+target;
return false;
});
if(document.location.hash){ /* What is this for ? */
var hash = document.location.hash.split('#')[1];
hash = hash.replace('agent=', '');
if(hash && $('[data-agent-target="'+hash+'"]').length) {
$('[data-agent="'+hash+'"]').trigger('click');
}
}
$('.close').click(function() {
$('[data-agent-target]').removeClass('active');
$('body').removeClass('agentLoaded');
return false;
});
I'm building hybrid app with Intel XDK and I need help with back button and it's function. I have only one index.html file. All "pages" are 's and each one have different id.
I navigate through them using activate_subpage("#uib_page_10");
$(document).on("click", ".firs_div_button", function(evt){
//#uib_page_10 is div with it's content
activate_subpage("#uib_page_10");
var thisPage = 1;
goBackFunction (thisPage); //call function and pass it page number
});
$(document).on("click", ".second_div_button", function(evt){
//#uib_page_20 is div with it's content
activate_subpage("#uib_page_20");
var thisPage = 2;
goBackFunction (thisPage); //call function and pass it page number
});
I have set this EventListener hardware on back button.
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
alert("hello");
navigator.app.backHistory();
}
This is functional but it does not work as it should, in my case and for my app.
When I navigate from one page to another (5 pages / divs) and hit back button, sometimes it does not go back to the first page. It just go "back" to history too deep and close the app, without changing the actual page (view) before closing.
Now, I have an idea, but I need help with this.
I will not use history back, I will use counter and dynamic array for up to 5 elements.
function goBackFunction (getActivePage) {
var active_page = getActivePage;
var counter = 0; // init the counter (max is 5)
var history_list = [counter][active_page]; // empty array
counter = counter + 1;
:
:
:
}
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
//read the array and it's positions then activate:
activate_subpage("#PAGE_FROM_ARRAY");
counter = counter - 1;
if (counter == 0) {
//trigger the app exit when counter get's to 0.
navigator.app.exitApp();
}
}
This is only idea, not tested. I would like to store list of opened pages in Array and when back button is pressed, to activate the pages taken from the Array list, backwards.
I do not know how to do this, I'm not a expert :( There is may be batter way to do this. If someone have any suggestion, I will accept it :D
I save an array in localStorage with all pages navigated and I go back using a pop() on the array. At the moment, it's the best way I got to go back.
This is my code:
// First, create the table "pages"
function init_pages_table()
{
var pages = new localStorageDB("pages", localStorage);
if (!pages.isNew())
{
pages.drop();
pages.commit();
}
var pages = new localStorageDB("pages", localStorage);
pages.createTable("Pages", ["nome"]);
// commit the database to localStorage
// all create/drop/insert/update/delete operations should be committed
pages.commit();
}
// Add a page into the array:
function push_pagename(pagename)
{
var pages = new localStorageDB("pages", localStorage);
if (!pages.tableExists("Pages"))
{
init_pages_table();
pages = new localStorageDB("pages", localStorage);
}
pages.insert("Pages", {nome: pagename});
pages.commit();
}
// Pop a page form the array:
function pop_pagename()
{
var output = '';
var id_page = ''
var pages = new localStorageDB("pages", localStorage);
var last_page = pages.queryAll("Pages", { limit: 1,
sort: [["ID", "DESC"]]
});
$.each(last_page, function(index,value){
output = value.nome;
id_page = value.ID;
return false;
});
var rowdeleted = pages.deleteRows("Pages", {ID: id_page});
pages.commit();
return output;
}
You can also define functions for set, get, read:
function set_backpage(pageurl)
{
push_pagename(pageurl);
}
function get_backpage()
{
return pop_pagename();
}
function read_backpage()
{
var output = '';
var id_page = ''
var pages = new localStorageDB("pages", localStorage);
var last_page = pages.queryAll("Pages", { limit: 1,
sort: [["ID", "DESC"]]
});
$.each(last_page, function(index,value){
output = value.nome;
id_page = value.ID;
return false;
});
return output;
}
I have a long list of links inside a big scrollable div. Each time when a user click on a link then click the back button, it starts at the very top of the div. It is not user friendly to our users. Any ways to let the browser scroll to the previous position when pressing the back button?
Thank you very much!
During page unload, get the scroll position and store it in local storage. Then during page load, check local storage and set that scroll position. Assuming you have a div element with id element. In case it's for the page, please change the selector :)
$(function() {
$(window).unload(function() {
var scrollPosition = $("div#element").scrollTop();
localStorage.setItem("scrollPosition", scrollPosition);
});
if(localStorage.scrollPosition) {
$("div#element").scrollTop(localStorage.getItem("scrollPosition"));
}
});
I think we should save scroll data per page, also we should use session storage instead of local storage since session storge effects only the current tab while local storage shared between all tabs and windows of the same origin
$(function () {
var pathName = document.location.pathname;
window.onbeforeunload = function () {
var scrollPosition = $(document).scrollTop();
sessionStorage.setItem("scrollPosition_" + pathName, scrollPosition.toString());
}
if (sessionStorage["scrollPosition_" + pathName]) {
$(document).scrollTop(sessionStorage.getItem("scrollPosition_" + pathName));
}
});
I had the same problem with a simple user interface consisting of a fixed menu div and a scrolling document div ("pxeMainDiv" in the code example below). The following solution worked for me in Chrome 47.0.2526.106 m and in Firefox 43.0.3. (My application is for use in-house and I did not need to cater for old versions of IE).
$(document).ready(function(){
if (history.state) {
$("#pxeMainDiv").scrollTop(history.state.data);
}
$("#pxeMainDiv").scroll(function() {
var scrollPos = $("#pxeMainDiv").scrollTop();
var stateObj = { data: scrollPos };
history.replaceState(stateObj, "");
});
});
On the div scroll event, the scroll position of the div is stored in the state object inside the browser history object. Following a press of the Back button, on the document ready event, the scroll position of the div is restored to the value retrieved from the history.state object.
This solution should work for the reverse navigation of an arbitrarily long chain of links.
Documentation here: https://developer.mozilla.org/en-US/docs/Web/API/History_API
When using window.history.back(), this is actually default browser functionality as user SD. has pointed out.
On a site I am currently building, I wanted the logo of the company to backlink to the index page. Since jQuery 3, $(window).unload(function() should be rewritten to $(window).on('unload', function(). My code looks like this (using Kirby CMS' php syntax):
<?php if ($page->template() == 'home'): ?>
<script>
$(function() {
$(window).on("unload", function() {
var scrollPosition = $(window).scrollTop();
localStorage.setItem("scrollPosition", scrollPosition);
});
if(localStorage.scrollPosition) {
$(window).scrollTop(localStorage.getItem("scrollPosition"));
}
});
</script>
For anyone coming from react or anything similar to react router, here are two simple functions:
export function saveScrollPosition(context: any) {
let path = context.router.route.location.pathname;
let y = window.scrollY;
sessionStorage.setItem("scrollPosition_" + path, y.toString());
}
export function restoreScrollPosition(context: any) {
let path = context.router.route.location.pathname;
let y = Number(sessionStorage.getItem("scrollPosition_" + path));
window.scrollTo(0, y);
}
If a back button is kind of history back button window.history.back() Then what you are seeking for, is a default browser functionality. So you don't have to worry about it.
If your back button actually point to some URL in your application via link or form, then you have to take care that manually.
For solution you may use cookies to store your page scroll value. Each time user scroll on your page, do save scroll value for that page to cookie. Extra work is applied to manual cookie management.
window.onScroll = function(){
document.cookie="pageid=foo-"+window.scrollY+";";
}
This cookie value can be use to set scroll value of the page on page visit.
window.scroll(0,cookievalue);
With History api you can utilize scrollRestoration and stop browser from resetting scroll position.
Read it here. https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration
/* Use the below code to restore the scroll position of individual items and set focus to the last clicked item. */
(function ($)
{
if (sessionStorage)
$.fn.scrollKeeper = function (options)
{
var defauts =
{
key: 'default'
};
var params = $.extend(defauts, options);
var key = params.key;
var $this = $(this);
if (params.init === true)
{
var savedScroll = sessionStorage.getItem(key);
if (typeof savedScroll != 'undefined')
{
var int_savedScroll = parseInt(savedScroll);
if (int_savedScroll > 0)
$this.scrollTop(int_savedScroll);
setTimeout(function ()
{
var selectorFocus = sessionStorage.getItem(key + "-focus");
if (selectorFocus && selectorFocus != "")
$(document.querySelector(selectorFocus)).focus();
}, 100, key);
}
}
window.addEventListener("beforeunload", function ()
{
sessionStorage.setItem(key, $this.scrollTop());
if (document.activeElement)
{
var selectorFocus = elemToSelector(document.activeElement);
if (selectorFocus)
sessionStorage.setItem(key + "-focus", selectorFocus);
else
sessionStorage.setItem(key + "-focus", "");
}
else
sessionStorage.setItem(key + "-focus", "");
});
};
function elemToSelector(elem) /* written by Kévin Berthommier */
{
const {
tagName,
id,
className,
parentNode
} = elem;
if (tagName === 'HTML') return 'HTML';
let str = tagName;
str += (id !== '') ? `#${id}` : '';
if (className)
{
const classes = className.split(/\s/);
for (let i = 0; i < classes.length; i++)
{
if(typeof classes[i] === 'string' && classes[i].length > 0)
str += `.${classes[i]}`;
}
}
let childIndex = 1;
for (let e = elem; e.previousElementSibling; e = e.previousElementSibling)
{
childIndex += 1;
}
str += `:nth-child(${childIndex})`;
return `${elemToSelector(parentNode)} > ${str}`;
}
})(jQuery);
/*
Usage:
$('#tab1div').scrollKeeper({ key: 'uniq-key1', init: true });
If you don't need to restore the scroll positions (for example for restart), and you need just to save the scroll positions for the next time, use:
$('#tab1div').scrollKeeper({ key: 'uniq-key1', init: false });
*/
I found the following script online that makes your website load content with AJAX.
Everything works fine, but it also reload my music player that has to stay when clicking a link.
// Ajaxify
// v1.0.1 - 30 September, 2012
// https://github.com/browserstate/ajaxify
(function(window,undefined){
// Prepare our Variables
var
History = window.History,
$ = window.jQuery,
document = window.document;
// Check to see if History.js is enabled for our Browser
if ( !History.enabled ) {
return false;
}
// Wait for Document
$(function(){
// Prepare Variables
var
/* Application Specific Variables */
contentSelector = '#content,article:first,.article:first,.post:first',
$content = $(contentSelector).filter(':first'),
contentNode = $content.get(0),
$menu = $('#menu,#nav,nav:first,.nav:first').filter(':first'),
activeClass = 'active selected current youarehere',
activeSelector = '.active,.selected,.current,.youarehere',
menuChildrenSelector = '> li,> ul > li',
completedEventName = 'statechangecomplete',
/* Application Generic Variables */
$window = $(window),
$body = $(document.body),
rootUrl = History.getRootUrl(),
scrollOptions = {
duration: 800,
easing:'swing'
};
// Ensure Content
if ( $content.length === 0 ) {
$content = $body;
}
// Internal Helper
$.expr[':'].internal = function(obj, index, meta, stack){
// Prepare
var
$this = $(obj),
url = $this.attr('href')||'',
isInternalLink;
// Check link
isInternalLink = url.substring(0,rootUrl.length) === rootUrl || url.indexOf(':') === -1;
// Ignore or Keep
return isInternalLink;
};
// HTML Helper
var documentHtml = function(html){
// Prepare
var result = String(html)
.replace(/<\!DOCTYPE[^>]*>/i, '')
.replace(/<(html|head|body|title|meta|script)([\s\>])/gi,'<div class="document-$1"$2')
.replace(/<\/(html|head|body|title|meta|script)\>/gi,'</div>')
;
// Return
return $.trim(result);
};
// Ajaxify Helper
$.fn.ajaxify = function(){
// Prepare
var $this = $(this);
// Ajaxify
$this.find('a:internal:not(.no-ajaxy)').click(function(event){
// Prepare
var
$this = $(this),
url = $this.attr('href'),
title = $this.attr('title')||null;
// Continue as normal for cmd clicks etc
if ( event.which == 2 || event.metaKey ) { return true; }
// Ajaxify this link
History.pushState(null,title,url);
event.preventDefault();
return false;
});
// Chain
return $this;
};
// Ajaxify our Internal Links
$body.ajaxify();
// Hook into State Changes
$window.bind('statechange',function(){
// Prepare Variables
var
State = History.getState(),
url = State.url,
relativeUrl = url.replace(rootUrl,'');
// Set Loading
$body.addClass('loading');
// Start Fade Out
// Animating to opacity to 0 still keeps the element's height intact
// Which prevents that annoying pop bang issue when loading in new content
$content.animate({opacity:0},800);
// Ajax Request the Traditional Page
$.ajax({
url: url,
success: function(data, textStatus, jqXHR){
// Prepare
var
$data = $(documentHtml(data)),
$dataBody = $data.find('.document-body:first'),
$dataContent = $dataBody.find(contentSelector).filter(':first'),
$menuChildren, contentHtml, $scripts;
// Fetch the scripts
$scripts = $dataContent.find('.document-script');
if ( $scripts.length ) {
$scripts.detach();
}
// Fetch the content
contentHtml = $dataContent.html()||$data.html();
if ( !contentHtml ) {
document.location.href = url;
return false;
}
// Update the menu
$menuChildren = $menu.find(menuChildrenSelector);
$menuChildren.filter(activeSelector).removeClass(activeClass);
$menuChildren = $menuChildren.has('a[href^="'+relativeUrl+'"],a[href^="/'+relativeUrl+'"],a[href^="'+url+'"]');
if ( $menuChildren.length === 1 ) { $menuChildren.addClass(activeClass); }
// Update the content
$content.stop(true,true);
$content.html(contentHtml).ajaxify().css('opacity',100).show(); /* you could fade in here if you'd like */
// Update the title
document.title = $data.find('.document-title:first').text();
try {
document.getElementsByTagName('title')[0].innerHTML = document.title.replace('<','<').replace('>','>').replace(' & ',' & ');
}
catch ( Exception ) { }
// Add the scripts
$scripts.each(function(){
var $script = $(this), scriptText = $script.text(), scriptNode = document.createElement('script');
if ( $script.attr('src') ) {
if ( !$script[0].async ) { scriptNode.async = false; }
scriptNode.src = $script.attr('src');
}
scriptNode.appendChild(document.createTextNode(scriptText));
contentNode.appendChild(scriptNode);
});
// Complete the change
if ( $body.ScrollTo||false ) { $body.ScrollTo(scrollOptions); } /* http://balupton.com/projects/jquery-scrollto */
$body.removeClass('loading');
$window.trigger(completedEventName);
// Inform Google Analytics of the change
if ( typeof window._gaq !== 'undefined' ) {
window._gaq.push(['_trackPageview', relativeUrl]);
}
// Inform ReInvigorate of a state change
if ( typeof window.reinvigorate !== 'undefined' && typeof window.reinvigorate.ajax_track !== 'undefined' ) {
reinvigorate.ajax_track(url);
// ^ we use the full url here as that is what reinvigorate supports
}
},
error: function(jqXHR, textStatus, errorThrown){
document.location.href = url;
return false;
}
}); // end ajax
}); // end onStateChange
}); // end onDomLoad
})(window); // end closure
Let me explain it a little bit better.
The website has a music player that plays music while you are visiting the website, so clearly the music is not ment to stop whenever you click on a link.
This script works perfectly but it does refresh the whole page (using ajax) AND it is refreshing the music player.
There also is another script that comes with this one for changing the url and title ...
Thanks in advance, Greets
use the statechangecomplete event.
$(window).on('statechangecomplete', function(e, eventInfo){
//your code
})