Remember place scrolling on each page using jquery - javascript

I have 3 files besides the main HTML: test.html, test2.html and test3.html.
When you press one of the buttons a page is loaded. So I want the scroll position to be saved between page loads. Example: you load page test and then scroll to the middle, load page test2, scroll to the end, load back page test and it should be in the middle.
How could I archive this ?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery load() Demo</title>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#button1").click(function() {
$("#box").load("test.html");
});
$("#button2").click(function() {
$("#box").load("test2.html");
});
$("#button3").click(function() {
$("#box").load("test3.html");
});
});
</script>
</head>
<body>
<div style="position: fixed;"><button id="button1">test</button> <button id="button2">test2</button> <button id="button3">test3</button> </div>
<br><br>
<div id="box">
<h2>Click button to load new content inside DIV box</h2>
</div>
</body>
</html>

This is onde of many ways to do what you want
function currPos() { // crossbrowser get actual scroll position
return window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
}
function loadAndSavePosition(button) {
var pos = currPos(); // obtain current position
if (page) // if there is a loaded page, save the position of the actual page
scrollData[page] = pos;
page = button.target.innerText;
// simulates page load
h2.innerHTML = (button.target.innerText + ' ').repeat(10000);
if (scrollData[page]) { //if there is an already save value ...
window.scrollTo(0, scrollData[page]); // ...move to that position...
} else { // ... or to the top if there isn't.
scrollData[page] = 0;
window.scrollTo(0, 0);
}
}
var h2 = document.getElementById('h2');
var button1 = document.getElementById('button1');
var button2 = document.getElementById('button2');
var button3 = document.getElementById('button3');
var page = ''; // loaded page
var scrollData = {}; // object for saving the page scroll positions
// associate onclick event to the loadAndSavePosition function
[].slice.call(document.getElementsByTagName('button')).forEach(
button => button.onclick = loadAndSavePosition);
<div style="position: fixed;">
<button id="button1">test</button>
<button id="button2">test2</button>
<button id="button3">test3</button>
</div>
<br>
<br>
<div id="box">
<h2 id='h2'>Click button to load new content inside DIV box</h2>
</div>
JSFiddle: https://jsfiddle.net/s5dkL5nn/7/

To remember scroll of all pages use this code
$(document).ready(function (e) {
let UrlsObj = localStorage.getItem('rememberScroll');
let ParseUrlsObj = JSON.parse(UrlsObj);
let windowUrl = window.location.href;
if (ParseUrlsObj == null) {
return false;
}
ParseUrlsObj.forEach(function (el) {
if (el.url === windowUrl) {
let getPos = el.scroll;
$(window).scrollTop(getPos);
}
});
});
function RememberScrollPage(scrollPos) {
let UrlsObj = localStorage.getItem('rememberScroll');
let urlsArr = JSON.parse(UrlsObj);
if (urlsArr == null) {
urlsArr = [];
}
if (urlsArr.length == 0) {
urlsArr = [];
}
let urlWindow = window.location.href;
let urlScroll = scrollPos;
let urlObj = {url: urlWindow, scroll: scrollPos};
let matchedUrl = false;
let matchedIndex = 0;
if (urlsArr.length != 0) {
urlsArr.forEach(function (el, index) {
if (el.url === urlWindow) {
matchedUrl = true;
matchedIndex = index;
}
});
if (matchedUrl === true) {
urlsArr[matchedIndex].scroll = urlScroll;
} else {
urlsArr.push(urlObj);
}
} else {
urlsArr.push(urlObj);
}
localStorage.setItem('rememberScroll', JSON.stringify(urlsArr));
}
$(window).scroll(function (event) {
let topScroll = $(window).scrollTop();
console.log('Scrolling', topScroll);
RememberScrollPage(topScroll);
});

here's what you need to do, if I understand your problem correctly:
you re gonna save the current position of the page in a variable before loading new one. And set scroll position to the value you saved when you call that page again.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery load() Demo</title>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var pos = {}
var lastLoaded
$('.btn').click(function(e) {
v = e.target.value
pos[lastLoaded] = $('body').scrollTop()
$("#box").load(v);
lastLoaded = v
if(pos[v])
$('body').scrollTop(pos[v])
else
$('body').scrollTop(0)
})
});
</script>
</head>
<body>
<div style="position: fixed;">
<button class="btn" id="button1" value="test1.html">test</button>
<button class="btn" id="button2" value="test2.html">test2</button>
<button class="btn" id="button3" value="test3.html">test3</button>
</div>
<br><br>
<div id="box">
<h2>Click button to load new content inside DIV box</h2>
</div>
</body>
</html>

Related

How to save a list of "divs" to sessionStorage and display them when the user reloads the page?

I have an HTML page as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css" type="text/css">
<title>Test</title>
</head>
<body>
<div>
<p>Hello World!</p>
</div>
</body>
</html>
Then I have a JS file that listens for clicks of the enter key, and if the user clicks enter if adds another div.
//the event handler function
function captureEnterPress(event) {
if (event.key === "Enter" || event.keyCode === 13) {
event.preventDefault();
createNewDiv();
}
}
//creates the div
function createNewDiv() {
var body = document.body;
var div = document.createElement("div");
var p = document.createElement("p");
var labelText = document.createTextNode("Hello World!");
p.appendChild(labelText);
div.appendChile(p);
body.appendChild(div);
}
onload = () => {
document.documentElement.addEventListener("keyup", captureEnterPress);
}
I am trying to have the number of divs saved, so when the user reloads the page it shows the same amount of divs like he had before.
What I tried
I tried saving an array of all the divs to sessionStorage as follows:
var myStorage = window.sessionStorage;
var elementsArray = [];
//the event handler function
function captureEnterPress(event) {
if (event.key === "Enter" || event.keyCode === 13) {
event.preventDefault();
createNewDiv();
}
}
//creates the div
function createNewDiv() {
var body = document.body;
var div = document.createElement("div");
var p = document.createElement("p");
var labelText = document.createTextNode("Hello World!");
p.appendChild(labelText);
div.appendChile(p);
body.appendChild(div);
elementsArray[elementsArray.length] = div;
myStorage.setItem("storedPage", JSON.stringify(elementsArray));
}
onload = () => {
var storedPage = JSON.parse(myStorage.getItem("storedPage"));
if(storedPage){
event.preventDefault();
for(var i = 0; i < storedPage.length; i++){
document.body.appendChild(storedPage[i]);
console.log(storedPage)
}
}
document.documentElement.addEventListener("keyup", captureEnterPress);
}
I just logged it to the console to see what the values are, but they are empty. So I tried storing the div.innerHTML instead, but then if I try to append it to the document I get and error that it's a String and not a node.
I am out of ideas, and I am pretty new to the whole state storing concept in front-end development I would appreciate if somebody could tell me what is the right way to do it.
Thanks!
Not tested, but enough to illustrate
function createNewDiv() {
// create html content
const div = `<div><p>Hello World!</p></div>`;
// concat with body
document.body.innerHTML += div;
// save in array
elementsArray[elementsArray.length] = div;
// save in storage
myStorage.setItem("storedPage", JSON.stringify(elementsArray));
}
onload = () => {
var storedPage = JSON.parse(myStorage.getItem("storedPage"));
if(storedPage){
event.preventDefault();
// get stored content array and join by empty '' and add into body
document.body.innerHTML = storedPage.join('');
}
document.documentElement.addEventListener("keyup", captureEnterPress);
}
The problem I see in this code is that JSON.stringify is not able to convert DOM elements. Article on how to do this.
However, the better way is to save the innerHTML of some container, and then restore it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css" type="text/css">
<title>Test</title>
</head>
<body>
<div id="div-container">
<div>
<p>Hello World!</p>
</div>
</div>
</body>
</html>
JS:
var myStorage = window.sessionStorage;
var elementsArray = [];
//the event handler function
function captureEnterPress(event) {
if (event.key === "Enter" || event.keyCode === 13) {
event.preventDefault();
createNewDiv();
}
}
//creates the div
function createNewDiv() {
var divContainer = document.getElementById("div-container");
const div = "<div><p>Hello World!</p></div>";
divContainer.innerHTML += div;
console.log(divContainer.innerHTML);
myStorage.setItem("storedPage", divContainer.innerHTML);
}
onload = () => {
var storedPage = myStorage.getItem("storedPage");
if(storedPage){
event.preventDefault();
var divContainer = document.getElementById("div-container");
divContainer.innerHTML = storedPage;
}
document.documentElement.addEventListener("keyup", captureEnterPress);
}
JSFiddle: https://jsfiddle.net/wLgh1ef8/1/
Edit:
You always can see the content of sessionStorage using DevTools
F12 -> Application tab -> Session Storage

Implemeting Create and Delete function properly using javascript

I am able to create a div using javascript. However, not able to remove that div that I created previously. Only after post-back, I can remove that div. Actually after creating div, script cannot find that div because page did not loaded again.
What I want to do is to create a page that I am able to add an item and remove that item.
Add script works fine.
Remover script:
<script type="text/javascript">
$(function () {
$('.remove ,.shop-button-large, .shop-button-add').click(function () {
var itemToDelete = $(this).attr("data-id");
if (itemToDelete != '') {
$.post("/ShoppingBox/RemoveFromBox", { "id": itemToDelete },
function (data) {
$("#boxItem-" + itemToDelete + "-" + data.ItemCount).fadeOut(300);
});
}
});
});
</script>
The click handler for the remove was done before the DOM node was rendered. It needs to be insider the $(function() { ... }
http://plnkr.co/edit/IhtyH6ampodXICPBv6Fq?p=preview
<!DOCTYPE html>
<html>
<head>
<script data-require="jquery#2.1.3" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script>
$(function() {
$("#create").click(function() {
var createDiv = document.createElement("div");
createDiv.id = "myDiv";
createDiv.style.margin = "0 auto";
createDiv.style.width = "600px";
createDiv.style.height = "600px";
createDiv.style.backgroundColor = "red";
document.getElementById("myBody").appendChild(createDiv);
});
$("#remove").click(function() {
console.log('remove', $("#myDiv"));
$("#myDiv").fadeOut(300);
});
});
</script>
</head>
<body id="myBody">
Create
Remove
</body>
</html>
In order to clarify, I have prepared a simple code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="js/jquery-2.1.3.intellisense.js"></script>
<script src="js/jquery-2.1.3.min.js"></script>
<script src="js/jquery-2.1.3.js"></script>
<script src="js/jquery-ui.js"></script>
<script>
$(function () {
$("#create").click(function () {
var createDiv = document.createElement("div");
createDiv.id ="myDiv";
createDiv.style.margin = "0 auto";
createDiv.style.width = "600px";
createDiv.style.height = "600px";
createDiv.style.backgroundColor = "red";
document.getElementById("myBody").appendChild(createDiv);
});
});
$("#remove").click(function () {
$("#myDiv").fadeOut(300);
});
</script>
<title></title>
</head>
<body id="myBody">
Create
Remove
</body>
</html>

Javascript: How to get a list of all open windows

Suppose you open a handful of windows with:
window.open(url1,'win1');
window.open(url2,'win2');
window.open(url3,'win3');
(each window has a unique name)
And then you refresh the page.
The 3 popup windows are still open. Is there a way to list the names of all of the open windows and close them?
This is not a duplicate question.
In this question the browser is being refreshed, so you cannot simply use a global array to keep track of child windows.
This is not a duplicate question.
So the questions is closed, I'll post an answer based on the comments and research.
Firstly, to all who commented, thank you for helping.
Answer:
There is not a built-in object which tracks opened windows and persists from page load to page load.
As Felix Kling pointed out, using localStorage is a possible work-around.
Try postMessage to communicate between existing windows within the same domain. That's how i'm going to try and solve the same problem. See: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
index.htm
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>pop</title>
</head>
<body>
<script>
var pops = [];
window.onmessage = function(e)
{
// todo: check domain
// if( e.origin )
var data;
try
{
data = JSON.parse(e.data);
}
catch(e)
{
// fail silent...?
return;
}
switch(data.event)
{
case "RestoreOpenWindow":
onClosePopup(e.source.name);
case "QueryOpenWindows":
pops.push(e.source);
updateLabel();
break;
}
};
window.onload = function()
{
window.onClosePopup = onClosePopup;
updateLabel();
};
window.onbeforeunload = function()
{
for(var i = 0; i < pops.length; i++) pops[i].queryOpenPopups();
};
function onClosePopup(name)
{
for(var i = pops.length - 1; i >= 0; i--)
if(pops[i].name === name)
{ pops.splice(i, 1); break; }
updateLabel();
};
function openPopup()
{
pops.push(window.open("pop/popup.htm", "pop" + pops.length, ' '));
updateLabel();
setTimeout(function(){
alert('Click ok to refresh...');
location.href = location.href;
}, 5000);
}
function updateLabel()
{
document.getElementById("total").innerHTML = pops.length;
var html = [];
for(var i = 0; i < pops.length; i++)
html.push(pops[i].name);
document.getElementById("names").innerHTML = html.join("<br"+"/"+">");
}
</script>
<button onclick="openPopup()">open popup and refresh after 5 seconds (...allow em popups...)</button></br>
<span>total: </span><span id="total"></span></br>
<span id="names"></span></br>
</body>
</html>
popup.htm
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>pop</title>
</head>
<body>
<script>
window.queryOpenPopups = function()
{
var count = 0;
var hInterval = setInterval(function () {
try
{
if(window.opener)
{
window.opener.postMessage(JSON.stringify({"event": "QueryOpenWindows", "name": window.name}), "*");
clearInterval(hInterval);
} else count++;
}
catch(e)
{
count++;
}
if(count > 50)window.close();
}, 100);
};
window.onbeforeunload = function(){
window.opener.onClosePopup(window.name);
};
// restore link with opener on refresh
window.opener.postMessage(JSON.stringify({"event": "RestoreOpenWindow", "name": window.name}), "*");
window.onload=function(){ document.getElementById("name").innerHTML = window.name; };
</script>
<span id="name"></span>
</body>
</html>

Control multiple html5 audio tracks using a single controller

I am trying to implement a very minimal audio player for a web site.
The interface is rather simple. It has a play/pause button, and a mute/unmute button.
The problem I have is implementing multiple instances of the same player for different tracks.
The javascript for the player is:
jQuery(function() {
var myAudio = document.getElementById("myAudio");
var btnPlayPause = document.getElementById("btnPlayPause");
var btnMute = document.getElementById("btnMute");
btnPlayPause.addEventListener("click", function() {
if (myAudio.paused || myAudio.ended) {
myAudio.play();
btnPlayPause.innerHTML = "<span aria-hidden=\"true\" data-icon=\"\"></span><span class=\"screen-reader-text\">Play</span>";
}
else {
myAudio.pause();
btnPlayPause.innerHTML = "<span aria-hidden=\"true\" data-icon=\"\"></span><span class=\"screen-reader-text\">Pause</span>";
}
});
btnMute.addEventListener("click", function() {
if (myAudio.muted) {
myAudio.muted = false;
btnMute.innerHTML = "<span aria-hidden=\"true\" data-icon=\"\"></span><span class=\"screen-reader-text\">Mute</span>";
}
else {
myAudio.muted = true;
btnMute.innerHTML = "<span aria-hidden=\"true\" data-icon=\"\"></span><span class=\"screen-reader-text\">Unmute</span>";
}
});
});
This works fine for a single track. But if I have multiple tracks on the same page, this becomes a problem.
I am guessing that I need some modification to the syntax where I define the myAudio variable:
var myAudio = document.getElementById("myAudio");
However, I am not sure how to change that so the same script can control multiple audio tracks.
If possible, I also would like to be able to ensure that if the user clicks the play button on a different track, the track that is currently playing "stops" or is "paused" and the new track starts (so 2 tracks are not playing on top of each other).
This is jQuery based solution. To make HTML5 audio work also in IE8/7 use some additional flash fallback.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> - jsFiddle demo</title>
<script type='text/javascript' src='//code.jquery.com/jquery-1.10.1.js'></script>
<style type='text/css'>
.mp3Player {
padding:8px;
margin:8px;
background-color:#ddf;
}
</style>
<script type='text/javascript'>//<![CDATA[
jQuery(function (){
var myAudio = document.getElementById("myAudio");
var current = null;
var playingString = "<span aria-hidden=\"true\" data-icon=\"\"></span><span class=\"screen-reader-text\">Pause</span>";
var pausedString = "<span aria-hidden=\"true\" data-icon=\"\"></span><span class=\"screen-reader-text\">Play</span>";
$(document.body).on('click', '.btnPlayPause',function(e){
var target = this;
//console.log(target, current); //return;
if (current == target) {
target.innerHTML = pausedString;
target.parentNode.setAttribute('data-pos', myAudio.currentTime); //start from paused
myAudio.pause();
current = null;
} else { // current!=target
if (current != null) {
current.innerHTML = pausedString;
current.parentNode.setAttribute('data-pos', '0'); //reset position
target.parentNode.setAttribute('data-pos', myAudio.currentTime); //start from paused
}
current = target;
target.innerHTML = playingString;
if(myAudio.canPlayType && myAudio.canPlayType("audio/mpeg") != "") { // MP3
myAudio.src = target.parentNode.getAttribute('data-src');
} else if(myAudio.canPlayType && myAudio.canPlayType("audio/ogg") != "") { // OGG
myAudio.src = target.parentNode.getAttribute('data-src2');
} else {
return; // no audio support
}
myAudio.play();
myAudio.onloadeddata = function () {
myAudio.currentTime = parseFloat(target.parentNode.getAttribute('data-pos'));
};
}
});
$(document.body).on('click', '.btnMute',function(e){
myAudio.muted = !myAudio.muted;
$('.btnMute').each(function(){
if (myAudio.muted) {
this.innerHTML = "<span aria-hidden=\"true\" data-icon=\"\"></span><span class=\"screen-reader-text\">Muted</span>";
} else {
this.innerHTML = "<span aria-hidden=\"true\" data-icon=\"\"></span><span class=\"screen-reader-text\">Audible</span>";
}
});
});
});
//]]>
</script>
</head>
<body>
<audio id="myAudio"></audio>
<div class="mp3Player" data-src="a.mp3" data-src2="a.ogg" data-pos="0">
<button class="btnPlayPause button">►||</button>
<button class="btnMute button">MUTE</button>
<span class="infoLabel">Audio #1</span>
</div>
<div class="mp3Player" data-src="b.mp3" data-src2="b.ogg" data-pos="0">
<button class="btnPlayPause button">►||</button>
<button class="btnMute button">MUTE</button>
<span class="infoLabel">Audio #2</span>
</div>
</body>
</html>
jQuery code + result page.
javascript code + result page.
Both scripts need additional existing .mp3 files to play the sound

touchenter event not being called

Can anyone tell me why the touchenter event is not working in this code. The mouseenter works fine on a desktop. Should be so simple, I'm missing something though.
Example here - http://jsfiddle.net/gCEqH/6/
Full code below:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<img id="myImg" src="http://jackiehutchings.com/wp-content/uploads/2011/09/g-plus-icon-96x96.png" />
<script>
$(window).load(function() {
$('#myImg').on("touchenter mouseenter", function(event){
alert('entered!');
});
});
</script>
</body>
</html>
Maybe something like this would work?
var elementIdTouching = "";
$('body').on("touchmove", function(e){
var tList = e.touches; // get list of all touches
for (var i = 0; i < tList.length; i++) {
var thisTouch = tList[i]; // not 100% sure about this
var elementTouching = document.elementFromPoint(
thisTouch.screenX,
thisTouch.screenY
);
if (elementTouching.id != elementIdTouching) {
elementIdTouching = elementTouching.id;
if (elementTouching.id == "myImg") {
alert("entered!");
}
}
}
}).on("touchend", function(e){
elementIdTouching = "";
});
$('#myImg').on("mouseenter", function(e){
alert('entered!');
});
tList ~ https://developer.mozilla.org/en-US/docs/Web/API/TouchList
Disclaimer: I haven't tested this.

Categories

Resources