Collision detection not working (Javascript) - javascript

I'm trying to build a simple game and having hard time with collision detecting. I want the alert to be popped up when the hero hits the virus and below is my js code. I'm not sure if my collision detect logic is wrong too. The viruses are moving randomly and I used CSS transition for them to move gradually.
var henryLocation = {
top: 700,
left: 700
}
document.onkeydown = function (evt) {
// console.log(evt)
if (evt.keyCode === 38 && henryLocation.top > 10) {
henryLocation.top = henryLocation.top - 25
} else if (evt.keyCode === 40 && henryLocation.top < 700) {
henryLocation.top = henryLocation.top + 25
} else if (evt.keyCode === 37 && henryLocation.left > 10) {
henryLocation.left = henryLocation.left - 25
} else if (evt.keyCode === 39 && henryLocation.left < 1360) {
henryLocation.left = henryLocation.left + 25
}
moveHenry()
}
function moveHenry () {
document.getElementById('henry').style.top = henryLocation.top + 'px'
document.getElementById('henry').style.left = henryLocation.left + 'px'
}
const startBtn = document.getElementById('btn-start')
startBtn.addEventListener("click", theGame)
function theGame () {
const startGame = setInterval(moveCorona, 1300)
function moveCorona () {
const theCorona = document.getElementById('corona')
const theCorona1 = document.getElementById('corona1')
const theCorona2 = document.getElementById('corona2')
const w = 1300, h = 600
theCorona.style.top = Math.floor(Math.random() * h) + 'px'
theCorona.style.left = Math.floor(Math.random() * w) + 'px'
theCorona1.style.top = Math.floor(Math.random() * h) + 'px'
theCorona1.style.left = Math.floor(Math.random() * w) + 'px'
theCorona2.style.top = Math.floor(Math.random() * h) + 'px'
theCorona2.style.left = Math.floor(Math.random() * w) + 'px'
function collisionDetect () {
var theHenry = henry.getBoundingClientRect();
var theCorona = corona.getBoundingClientRect();
if ((theCorona.top > theHenry.top && theCorona.top < theHenry.bottom) || (theCorona.bottom > theHenry.top && theCorona.bottom < theHenry.bottom)) {
let verticalCollision = true
} else {
let verticalCollision = false
}
if ((theCorona.right > theHenry.left && theCorona.right < theHenry.right) || (theCorona.left < theHenry.right && theCorona.left > theHenry.left)) {
let horizontalCollision = true
} else {
let horizontalCollision = false
}
if (verticalCollision && horizontalCollision) {
alert('collision detected')
} else {
console.log('Game goes on')
}
}
// collisionDetect()
}
}
function gameLoop () {
setTimeout(gameLoop, 1000)
}
gameLoop()

Related

Custom javascript Video player stops after 11 seconds

I am currently developing a custom javascript videoplayer for my website to be able to show some showreels. It works perfectly fine in firefox but in chrome the demo video stops everytime after 11 seconds but the buffering process has already loaded more than 11s.
Here is the link to the videoplayer: https://www.cankarka.com/en/portfolio
Does anyone have an idea why this is happening? I got no errors in the console.
Thanks in advance :)
This is my HTML:
<div class="custom-video-player">
<video class="video" src="inc/video.mp4" preload="auto"></video>
<div class="video-controls">
<div class="video-bar">
<div id="currentBuffer" class="currentBuffer"></div>
<div id="currentProcess" class="currentProcess"></div>
</div>
<div class="buttons">
<button id="skip-back" class="skipBack" type="button"></button>
<button id="playPause" type="button"></button>
<button id="skip-front" class="skipForward" type="button"></button>
<button id="volumeBtn" class="volumeHigh" type="button"></button>
<div class="volume-slider-container">
<div class="volume-slider-container-inner">
<div id="volume-slider" class="volume-slider"></div>
</div>
</div>
<div class="volume-slider-range"></div>
<div class="videoTimer-container">
<span id="videoCurrentTime" class="videoTimer"></span> <span id="slash" class="videoTimer">/</span> <span id="videoTime" class="videoTimer"></span>
</div>
<button id="fullscreenToggle" class="fullscreen" type="button"></button>
</div>
</div>
</div>
This is my javascript code:
function initializeVideoPlayer()
{
var videoPlayers = document.querySelectorAll('.custom-video-player');
for (var i = 0; i < videoPlayers.length; ++i)
{
initControls(videoPlayers[i]);
}
}
function initControls(videoPlayerContainer)
{
var video = videoPlayerContainer.querySelector('.video');
var videoBarContainer = videoPlayerContainer.querySelector('.video-bar');
video.onerror = function()
{
console.log("Error: " + video.error.code);
};
// Timelines
var currentProcess = videoPlayerContainer.querySelector("div.currentProcess");
var currentBuffer = videoPlayerContainer.querySelector("div.currentBuffer");
// Buttons
var playPauseBtn = videoPlayerContainer.querySelector('#playPause');
video.addEventListener('timeupdate', updateTimeline);
video.addEventListener('click', togglePlayPause);
video.addEventListener('progress', updateBuffer);
playPauseBtn.addEventListener('click', togglePlayPause);
skipBackward.addEventListener('click', skipBackwardFunction);
skipForward.addEventListener('click', skipForwardFunction);
volumeBtn.addEventListener('click', setVolumeByBtn);
let mouseDown = false;
videoBarContainer.addEventListener('click', scrub);
videoBarContainer.addEventListener('mousemove', (e) => mouseDown && scrub(e));
videoBarContainer.addEventListener('mousedown', () => mouseDown = true);
videoBarContainer.addEventListener('mouseup', () => mouseDown = false);
function scrub(e)
{
var scrubTime = (e.offsetX / videoBarContainer.offsetWidth) * video.duration;
video.currentTime = scrubTime;
}
function skipForwardFunction()
{
video.currentTime += skipTime;
}
function skipBackwardFunction()
{
video.currentTime -= skipTime;
}
function updateBuffer()
{
var duration = video.duration;
if (duration > 0)
{
for (var i = 0; i < video.buffered.length; ++i)
{
if (video.buffered.start(video.buffered.length - 1 - i) < video.currentTime)
{
currentBuffer.style.width = (video.buffered.end(video.buffered.length - 1 - i) / duration) * 100 + "%";
break;
}
}
}
}
function updateTimeline()
{
// Timeline updaten
var percent = (video.currentTime / video.duration) * 100;
currentProcess.style.width = percent + "%";
// Aktuelle Zeit anzeigen
var min = Math.floor(video.currentTime / 60);
var sec = Math.floor(video.currentTime - min * 60);
if (sec < 10)
{
sec = "0" + sec;
}
if (min < 10)
{
min = "0" + min;
}
if (min >= 60 && min < 120)
{
min = "01:" + (min - 60);
}
else if (min >= 120 && min < 180)
{
min = "02:" + (min - 120);
}
else if (min >= 180 && min < 240)
{
min = "03:" + (min - 180);
}
else if (min >= 240 && min < 300)
{
min = "04:" + (min - 240);
}
else if (min >= 300 && min < 360)
{
min = "05:" + (min - 300);
}
else
{
min = "00:" + min;
}
// Gesamte Zeit berechnen
var minTotal = Math.floor(video.duration / 60);
var secTotal = Math.floor(video.duration - minTotal * 60);
if (secTotal < 10)
{
secTotal = "0" + secTotal;
}
if (minTotal < 10)
{
minTotal = "0" + minTotal;
}
if (minTotal >= 60 && minTotal < 120)
{
minTotal = "01:" + (minTotal - 60);
}
else if (minTotal >= 120 && minTotal < 180)
{
minTotal = "02:" + (minTotal - 120);
}
else if (minTotal >= 180 && minTotal < 240)
{
minTotal = "03:" + (minTotal - 180);
}
else if (minTotal >= 240 && minTotal < 300)
{
minTotal = "04:" + (minTotal - 240);
}
else if (minTotal >= 300 && minTotal < 360)
{
minTotal = "05:" + (minTotal - 300);
}
else
{
minTotal = "00:" + minTotal;
}
videoCurrentTime.innerHTML = min + ":" + sec;
videoTime.innerHTML = minTotal + ":" + secTotal;
if (video.ended)
{
playPauseBtn.className = "play";
}
}
function togglePlayPause()
{
if (video.paused)
{
playVideo();
}
else
{
playPauseBtn.className = "play";
video.pause();
}
}
function playVideo()
{
var playPromise = video.play();
if (playPromise !== undefined)
{
playPromise.then(_ => {
// Video started successfully
playPauseBtn.className = "pause";
}).catch(error => {
// Video was interrupted
playPauseBtn.className = "play";
});
}
}
}
window.onload = initializeVideoPlayer;
In order to debug the video, you can use this code:
const videoElement = document.getElementsByTagName('video')[0];
const b = HTMLMediaElement.prototype;
const allNames = new Set();
for (let o = b; o != Object.prototype; o = Object.getPrototypeOf(o)) {
for (let name of Object.getOwnPropertyNames(o)) {
allNames.add(name);
}
}
const array = Array.from(allNames).filter(x => /^on/.test(x)).map(x => x.substring(2));
array.forEach(x => videoElement.addEventListener(x, console.log));
This shows that an Event of type error occurs, followed by timeupdate and then pause.
To get the actual error, use videoElement.error which shows the following:
{
code: 3,
message: "PIPELINE_ERROR_DECODE: Failed to send audio packet for decoding: {timestamp=12176542 duration=21250 size=516 is_key_frame=1 encrypted=0}"
}
That means your file is corrupted, try to encode it in a different way. Also, maybe this answer will help: Audio playback halts/stops on Chrome 64

How to detect collision?

I am building a video game where a spaceship moves with controllers and it must avoid some fireballs in order to win. However now I would like to setup a collision system: when a fireball touches the spaceship, game is over (alert("game over")). Any help with this? Thanks!!!
let spaceship = document.querySelector("#icon")
//Fireball script
const fireballArray = []
function generateFireBallWithAttributes(el, attrs) {
for (var key in attrs) {
el.setAttribute(key, attrs[key])
};
return el
}
function createFireBalls(amount) {
for (let i = 0; i <= amount; i++) {
fireballArray.push(generateFireBallWithAttributes(document.createElement("img"), {
src: "Photo/fireball.png",
width: "40"
}))
}
}
createFireBalls(10)
fireballArray.forEach((fireballElement) => {
const fallStartInterval = setInterval(function() {})
document.querySelector("body").appendChild(fireballElement);
const fireballMovement = {
x: fireballRandom(fireballElement.offsetWidth),
y: 0
}
const fireLoop = function() {
fireballMovement.y += 2;
fireballElement.style.top = fireballMovement.y + "px";
if (fireballMovement.y > window.innerHeight) {
fireballMovement.x = fireballRandom(fireballElement.offsetWidth);
fireballElement.style.left = fireballMovement.x + "px";
fireballMovement.y = 0
}
}
fireballElement.style.left = fireballMovement.x + "px";
let fireInterval = setInterval(fireLoop, 1000 / ((Math.random() * (50)) + 75))
})
function fireballRandom(offset) {
return Math.floor(Math.random() * (window.innerWidth - offset))
}
//Spaceship moves into space + prevent going out borders
let hits = 0
let pos = {
top: 1000,
left: 570
}
const keys = {}
window.addEventListener("keydown", function(e) {
keys[e.keyCode] = true
})
window.addEventListener("keyup", function(e) {
keys[e.keyCode] = false
})
const loop = function() {
if (keys[37] || keys[81]) {pos.left -= 5}
if (keys[39] || keys[68]) {pos.left += 5}
if (keys[38] || keys[90]) {pos.top -= 4}
if (keys[40] || keys[83]) {pos.top += 4}
if (pos.left < 0) { pos.left = -1}
if (pos.top < 0) {pos.top = -1}
if (pos.left + spaceship.offsetWidth >= body.offsetWidth) {
pos.left = body.offsetWidth - spaceship.offsetWidth
}
if (pos.top + spaceship.offsetHeight >= body.offsetHeight) {
pos.top = body.offsetHeight - spaceship.offsetHeight
}
spaceship.setAttribute("data", body.offsetWidth + ":" + body.offsetHeight)
spaceship.style.left = pos.left + "px";
spaceship.style.top = pos.top + "px"
}
let sensibilty = setInterval(loop, 8)
<body>
<img src="Photo/Spaceship1.png" id="icon">
</body>
Check this out (hitboxes)
Also this
Your code is missing complete information. That said, as your game progresses with explicit and independent setIntervals on fireballs and spaceship, and you dont want to make bigger changes I suggest you call the checkCollision() function any time fireball moves or spaceship moves (that is in the loop and fireloop "animation functions").
The collision itself is done with the following:
function detectOverlap(fireball) {
const shipRect = spaceship.getBoundingClientRect();
const fireballRect = fireball.getBoundingClientRect();
//these two variables are of following type
//DOMRect {x: 570, y: 836, width: 104.484375, height: 112.828125, ...}
// this will test if the ship collides with specific fireball
if (
(shipRect.x + shipRect.width > fireballRect.x && shipRect.x < fireballRect.x + fireball.width)
&& (shipRect.y + shipRect.height > fireballRect.y && shipRect.y < fireballRect.y + fireball.height)
) {
return true;
} else {
return false;
}
};
function checkCollision() {
let collision = false;
fireballArray.forEach(fireball => {
if (detectOverlap(fireball)) { collision = true };
});
// this is satisfied if the ship collides with any fireball
if (collision === true) {
// do some logic on collision
console.log('collision');
}
};
This will do rectangle vs rectangle collision detection. This might not fit the best, but it is a good first approximation.
NOTE: You can check the devtools console (F12) to assess the correct collision detection.

an if statement returns true, but the condition won't trigger

I have an if statement in my code as you can see below. When I check in console log when those two elements collide with each other, the if statement becomes true, but it won't stop my interval function. I wonder what would have caused it to not work as it should?
var animationTimer = setInterval(bladAnimation, 30);
document.onkeydown = function(event) {
if (event.keyCode == 37) {
// <--
fx = -15;
fy = 0;
froskAnimation()
}
if (event.keyCode == 38) {
// opp
fy = -15;
fx = 0;
froskAnimation()
}
if (event.keyCode == 39) {
// -->
fx = 15;
fy = 0;
froskAnimation()
}
if (event.keyCode == 40) {
// ned
fy = 15;
fx = 0;
froskAnimation()
}
}
function froskAnimation() {
Xfrosk = fx + Xfrosk;
Yfrosk = fy + Yfrosk;
if ((Yfrosk + 70 > maxY) || (Yfrosk < minY)) {
Yfrosk = Yfrosk - fy;
}
if ((Xfrosk + 70 > maxX) || (Xfrosk < minX)) {
Xfrosk = Xfrosk - fx;
}
frosk.style.left = Xfrosk + "px";
frosk.style.top = Yfrosk + "px";
console.log(Xfrosk)
}
function bladAnimation() {
Yblad = by + Yblad;
if ((Yblad + 70 > maxY) || (Yblad < minY)) {
by = by * -1;
}
blad.style.top = Yblad + "px";
}
if (blad.x < frosk.x + frosk.width && blad.x + blad.width > frosk.x
&& blad.y < frosk.y + frosk.height && blad.y + blad.height > frosk.y) {
clearInterval(animationTimer);
}
full code here: https://codepen.io/ctrlvi/pen/jXbJYG
That condition is executed only once, when your javascript is loaded. At that point the condition is probably false. You should move it at the end of bladAnimation (I suppose what you're trying to do is stop the self-moving block when it hits the other one).
function bladAnimation() {
Yblad = by + Yblad;
if ((Yblad + 70 > maxY) || (Yblad < minY)) {
by = by * -1;
}
blad.style.top = Yblad + "px";
if (blad.x < frosk.x + frosk.width && blad.x + blad.width > frosk.x
&& blad.y < frosk.y + frosk.height && blad.y + blad.height > frosk.y) {
clearInterval(animationTimer);
}
}

Back button is not working when using history.pushState() in ReactJs

Currently, I am working on a ReactJs project where I've created infinite scrolling on the basis of scrolling events. My client wanted to have URL changing while scrolling up and down.
For achieving this functionality I've used history.pushState() which updating URL like:- /#/page/1...2...3 up to n.
But the problem is when I am clicking back button from the browser, it is going to the previous state rather than the previous page (as the nature of history.pushState()).
I would appreciate if anyone helps me out to sort it out.
Thanks in advance.
Here is my code
import React, { Component } from 'react';
import ComponentView from './view';
import axios from 'axios';
import { connect } from 'react-redux';
import { HashLink as Link } from 'react-router-hash-link';
import { createAction,ActionNames } from '../../redux/actions/index';
import createHistory from "history/createBrowserHistory";
import { BrowserRouter } from 'react-router-dom';
/**
* #name Product Grid Component
* #type Component
* #author Inderdeep Singh
*/
class Main extends Component {
/**
* Constructor
* #param props
*/
state = {
items: [],
isLoading: true,
cursor: 0
}
constructor(props){
super(props);
this.pageSize = 10;
this.state = {
data:[],
link:'',
loading:true,
items: [],
isLoading: false,
loadAll:false,
cursor: 0,
arrSize: 12,
productsLen:0,
section:0,
scrollUp:0,
url:'',
sectionSize:'',
sectionSizeLim:1
}
this.handleOnScroll = this.handleOnScroll.bind(this);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleOnScroll);
}
clickBackButton(){
const history = createHistory();
var myarray = [];
var url = history.location;
myarray.push(url);
$(window).on('popstate', function() {
var hashLocation = location.hash;
var hashSplit = hashLocation.split("/");
var hashName = hashSplit[1];
if (hashName !== '') {
var hash = window.location.hash;
if (hash === '') {
var number= url.hash;
number= number.split('/');
this.console.log("nagesh "+number[2]);
}
}
});
}
/**
* Component Did Mount
*/
componentDidUpdate(props){
this.clickBackButton();
}
componentDidMount(){
var url = window.location.href;
this.setState({url:url})
if(url.indexOf('#')>-1){
if(url.indexOf('kategori')>-1){
url = url.split('/');
var pageNum = url[6];
var catName = url[4];
var timesRun = 0;
var Scrolling = setInterval(function () {
timesRun += 1;
if(timesRun <= pageNum){
window.scrollTo(0, pageNum * 1930);
var fact ='/kategori/'+catName+'/#/page/'+timesRun;
history.pushState(null,null,fact);
}
else{
clearInterval(Scrolling)
}
},1000);
}
else if(url.indexOf('produkt')>-1){
url = url.split('/');
var pageNum = url[6];
var catName = url[4];
var timesRun = 0;
var Scrolling = setInterval(function () {
timesRun += 1;
if(timesRun <= pageNum){
window.scrollTo(0, pageNum * 1930);
var fact ='/produkt/'+catName+'/#/page/'+timesRun;
history.pushState(null,null,fact);
}
else{
clearInterval(Scrolling)
}
},1000);
}
else{
url = url.split('#');
url = url[1].split('/');
url = url[2];
var timesRun = 0;
var Scrolling = setInterval(function () {
timesRun += 1;
if(timesRun <= url){
window.scrollTo(0, url * 1930);
history.pushState(null,null,'/#/page/'+timesRun);
}
else{
clearInterval(Scrolling)
}
},1000);
}
}
const {emitter} = this.props;
emitter.addListener("REFRESH_PRODUCTS",(query)=>{
this.getProducts(1,query)
})
this.setState({data:this.props.data})
window.addEventListener('scroll', this.handleOnScroll);
this.doQuery();
}
componentWillReceiveProps(newProps){
if(JSON.stringify(this.props.query)!=JSON.stringify(newProps.query)){
this.getProducts(1,newProps.query)
}
}
doQuery = () => {
this.setState({ isLoading: true, error: undefined })
axios.post('/getProducts')
.then((res) => {
this.setState({
productsLen:res.data.results.length,
sectionSize:parseInt(res.data.results.length/12)
});
})
}
handleOnScroll() {
var self = this;
function callURL(ss){
var url = window.location.href;
setTimeout(
self.setState({
arrSize: self.state.arrSize + 12,
isLoading: true
}), 3000);
var url = window.location.href;
if(self.state.sectionSizeLim<=self.state.sectionSize){
self.setState({
sectionSizeLim: self.state.sectionSizeLim + 1,
})
}
if (self.state.arrSize <= self.props.product_list.length) {
var sect = self.state.section;
if (url.indexOf('#') > -1) {
url = url.split('#');
url = url[1].split('/');
url = url[2];
if (sect <= url) {
sect = sect + 1;
}
}
else {
sect = sect + 1;
}
self.setState({
isLoading: true,
section: sect
})
}
else {
self.setState({
isLoading: false,
loadAll: true
})
}
if(ss==0){
if (self.state.url.indexOf('kategori') > -1) {
var url = self.state.url.split('/');
var fact = '/kategori/' + url[4] ;
// history.pushState(null, null, fact);
// window.location.hash = fact;
// window.location.hash = '';
// window.location.href.split('#')[0];
window.history.pushState("object or string", "Title", fact,"/");
}
else if (self.state.url.indexOf('produkt') > -1) {
var url = self.state.url.split('/');
var fact = '/produkt/' + url[4] ;
// history.pushState(null, null, fact);
// window.location.hash = fact;
// window.location.hash = '';
// window.location.href.split('#')[0];
window.history.pushState("object or string", "Title", fact,"/");
}
else {
// history.pushState(null, null, '/');
// window.location.hash = '';
window.history.pushState("object or string", "Title", "/");
}
}
else{
if (self.state.url.indexOf('kategori') > -1) {
var url = self.state.url.split('/');
var fact = '/kategori/' + url[4] + '/page/' + ss;
// history.pushState(null, null, fact);
// window.location.hash = fact;
window.location.hash = '/page/' + ss;
}
else if (self.state.url.indexOf('produkt') > -1) {
var url = self.state.url.split('/');
var fact = '/produkt/' + url[4] + '/page/' + ss;
// history.pushState(null, null, fact);
// window.location.hash = fact;
window.location.hash = '/page/' + ss;
}
else {
// history.pushState(null, null, '/#/page/' + ss);
window.location.hash = '/page/' + ss;
}
}
}
var h = ($("html").scrollTop());
if(h == 0 ){
callURL(0);
}
else if(h >= 1500 && h <= 1930){
callURL(0);
}
else if (h >= 1930 && h <= 3860) {
callURL(1)
}
else if (h >= 3860 && h <= 5790) {
callURL(2)
}
else if (h >= 5790 && h <= 7720) {
callURL(3)
}
else if (h >= 7720 && h <= 9650) {
callURL(4)
}
else if (h >= 9650 && h <= 11580) {
callURL(5)
}
else if (h >= 11580 && h <= 13510) {
callURL(6)
}
else if (h >= 13510 && h <= 15440) {
callURL(7)
}
else if (h >= 15440 && h <= 17370) {
callURL(8)
}
else if (h >= 17370 && h <= 19300) {
callURL(9)
}
else if (h >= 19300 && h <= 21230) {
callURL(10)
}
else if (h >= 21230 && h <= 23160) {
callURL(11)
}
else if (h >= 23160 && h <= 25090) {
callURL(12)
}
else if (h >= 25090 && h <= 27020) {
callURL(13)
}
else if (h >= 27020 && h <= 28950) {
callURL(14)
}
else if (h >= 28950 && h <= 30880) {
callURL(15)
}
else if (h >= 30880 && h <= 32810) {
callURL(16)
}
else if (h >= 32810 && h <= 34740) {
callURL(17)
}
else if (h >= 34740 && h <= 36670) {
callURL(18)
}
else if (h >= 36670 && h <= 38600) {
callURL(19)
}
else if (h >= 38600 && h <= 40530) {
callURL(20)
}
else if (h >= 40530 && h <= 42460) {
callURL(21)
}
else if (h >= 42460 && h <= 44390) {
callURL(22)
}
else if (h >= 44390 && h <= 46320) {
callURL(23)
}
else if (h >= 46320 && h <= 48250) {
callURL(24)
}
else if (h >= 48250 && h <= 50180) {
callURL(25)
}
else if (h >= 50180 && h <= 52110) {
callURL(26)
}
else if (h >= 52110 && h <= 54040) {
callURL(27)
}
else if (h >= 54040 && h <= 55970) {
callURL(28)
}
else if (h >= 55970 && h <= 57900) {
callURL(29)
}
else if (h >= 57900 && h <= 59830) {
callURL(30)
}
else if (h >= 59830 && h <= 61760) {
callURL(31)
}
else{
console.log(h);
}
var scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
var scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;
var scrollHeights = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;
scrollHeight = scrollHeight - 1000;
var clientHeight = document.documentElement.clientHeight || window.innerHeight;
var scrolledToBottom = Math.ceil(scrollTop + clientHeight) >= scrollHeight;
var scrollToTop = Math.ceil(scrollTop - clientHeight) >= scrollHeight;
}
/**
* Get products
* #param page
*/
getProducts(page,customQuery){
page = page || 1;
// console.log(page);
const {getProducts,query} = this.props;
let obj = {
...query,
...customQuery,
query : {
...(query || {}).query,
...(customQuery || {}).query
},
limit : 5000,
skip : 0
};
obj.query = {
...obj.query,
state : 'published'
}
}
/**
* Render the view
* #returns {*}
*/
render() {
return (ComponentView.bind(this))();
}
}
function bindAction(dispatch) {
return {
getProducts : (data)=>{
return dispatch(createAction(ActionNames.GET_PRODUCTS,data));
}
};
}
/**
* Map the shared state to properties
* #param state
* #returns Object
*/
const mapStateToProps = state => {
// console.log(state)
return {
data: state.products.results || [],
count : state.products.count,
hasMore : state.products.hasMore,
emitter : state.emitter
};
};
Main.displayName = 'Product Grid';
export default connect(mapStateToProps,bindAction)(Main);
Why don't you try replaceState() method instead of pushState().
Check it out here

window.location,hash gives problem when clicking the browser back button in React JS

I am working on someone else written code.
We are loading content from the database depending on the scroll of the user. When the user scrolls the data keeps loading until all data is retrieved from the DB. The client wants to see the section number in which Data is being loaded.
To show the number in the URL, the previous developer has used window.location.hash() but because of this, we are not able to take the user to the previous page when they click on the back button. Instead, it keeps on jumping on the page for few times and then goes back.
I cannot understand what else do i need to do to fix it. Below is the code:
import React, { Component } from 'react';
import ComponentView from './view';
import axios from 'axios';
import { connect } from 'react-redux';
import { HashLink as Link } from 'react-router-hash-link';
import { createAction,ActionNames } from '../../redux/actions/index';
/**
* #name Product Grid Component
* #type Component
* #author Inderdeep Singh
*/
class Main extends Component {
/**
* Constructor
* #param props
*/
state = {
items: [],
isLoading: true,
cursor: 0
}
constructor(props){
super(props);
this.pageSize = 10;
this.state = {
data:[],
link:'',
loading:true,
items: [],
isLoading: false,
loadAll:false,
cursor: 0,
arrSize: 12,
productsLen:0,
section:0,
scrollUp:0,
url:'',
sectionSize:'',
sectionSizeLim:1
}
// if(props.query){
// this.getProducts();
// }
this.handleOnScroll = this.handleOnScroll.bind(this);
}
componentWillMount() {
// this.loadMore()
// console.log(this.props);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleOnScroll);
}
/**
* Component Did Mount
*/
componentDidMount(){
var url = window.location.href;
this.setState({url:url})
if(url.indexOf('#')>-1){
if(url.indexOf('kategori')>-1){
url = url.split('/');
var pageNum = url[6];
var catName = url[4];
var timesRun = 0;
var Scrolling = setInterval(function () {
timesRun += 1;
if(timesRun <= pageNum){
window.scrollTo(0, pageNum * 1930);
var fact ='/kategori/'+catName+'/#/page/'+timesRun;
window.location.hash = "/"+ss;
// history.pushState(null,null,fact);
}
else{
clearInterval(Scrolling)
}
},1000);
}
else if(url.indexOf('produkt')>-1){
url = url.split('/');
var pageNum = url[6];
var catName = url[4];
var timesRun = 0;
var Scrolling = setInterval(function () {
timesRun += 1;
if(timesRun <= pageNum){
window.scrollTo(0, pageNum * 1930);
var fact ='/produkt/'+catName+'/#/page/'+timesRun;
window.location.hash = "/"+ss;
// history.pushState(null,null,fact);
}
else{
clearInterval(Scrolling)
}
},1000);
}
else{
url = url.split('#');
url = url[1].split('/');
url = url[2];
var timesRun = 0;
var Scrolling = setInterval(function () {
timesRun += 1;
if(timesRun <= url){
window.scrollTo(0, url * 1930);
// history.pushState(null,null,'/#/page/'+timesRun);
window.location.hash = "/"+ss;
}
else{
clearInterval(Scrolling)
}
},1000);
}
}
const {emitter} = this.props;
emitter.addListener("REFRESH_PRODUCTS",(query)=>{
this.getProducts(1,query)
})
this.setState({data:this.props.data})
// this.loadMore()
window.addEventListener('scroll', this.handleOnScroll);
this.doQuery();
}
componentWillReceiveProps(newProps){
if(JSON.stringify(this.props.query)!=JSON.stringify(newProps.query)){
this.getProducts(1,newProps.query)
}
// console.log(this.state.arrSize);
}
// scrollIt=() => { window.scrollTo(0, 1000)}
doQuery = () => {
this.setState({ isLoading: true, error: undefined })
axios.post('/getProducts')
.then((res) => {
// console.log(parseInt(res.data.results.length/12))
this.setState({
// items: [...state.items, ...res.items],
// cursor: res.cursor,
// isLoading: false
// newData: this.state.newData.slice().concat(res.data)
// newData: this.state.olddata.concat(res.data.results)
productsLen:res.data.results.length,
sectionSize:parseInt(res.data.results.length/12)
});
})
}
handleOnScroll() {
var self = this;
function callURL(ss){
// var self = this;
var url = window.location.href;
setTimeout(
self.setState({
arrSize: self.state.arrSize + 12,
isLoading: true
}), 3000);
var url = window.location.href;
if(self.state.sectionSizeLim<=self.state.sectionSize){
self.setState({
sectionSizeLim: self.state.sectionSizeLim + 1,
})
}
if (self.state.arrSize <= self.props.product_list.length) {
var sect = self.state.section;
if (url.indexOf('#') > -1) {
url = url.split('#');
url = url[1].split('/');
url = url[2];
if (sect <= url) {
sect = sect + 1;
}
}
else {
sect = sect + 1;
}
self.setState({
isLoading: true,
section: sect
})
}
else {
self.setState({
isLoading: false,
loadAll: true
})
}
if(ss==0){
if (self.state.url.indexOf('kategori') > -1) {
var url = self.state.url.split('/');
var fact = '/kategori/' + url[4] ;
// history.pushState(null, null, fact);
window.location.hash = "/"+ss;
// window.location.hash = '';
// window.location.href.split('#')[0];
// window.history.pushState("object or string", "Title", fact,"/");
}
else if (self.state.url.indexOf('produkt') > -1) {
var url = self.state.url.split('/');
var fact = '/produkt/' + url[4] ;
// history.pushState(null, null, fact);
window.location.hash = "/"+ss;
// window.location.hash = '';
// window.location.href.split('#')[0];
// window.history.pushState("object or string", "Title", fact,"/");
}
else {
// history.pushState(null, null, '/');
var fact = '/' + ss ;
window.location.hash = "/"+ss;
// window.history.pushState("object or string", "Title", "/");
}
}
else{
if (self.state.url.indexOf('kategori') > -1) {
var url = self.state.url.split('/');
var fact = '/kategori/' + url[4] + '/page/' + ss;
// history.pushState(null, null, fact);
// window.location.hash = fact;
window.location.hash = "/"+ss;
}
else if (self.state.url.indexOf('produkt') > -1) {
var url = self.state.url.split('/');
var fact = '/produkt/' + url[4] + '/page/' + ss;
// history.pushState(null, null, fact);
// window.location.hash = fact;
window.location.hash = "/"+ss;
}
else {
// history.pushState(null, null, '/#/page/' + ss);
window.location.hash = "/"+ss;
}
}
}
var h = ($("html").scrollTop());
if(h == 0 ){
callURL(0);
}
else if(h >= 0 && h <= 1930){
callURL(0);
}
else if (h >= 1930 && h <= 3860) {
callURL(1)
}
else if (h >= 3860 && h <= 5790) {
callURL(2)
}
else if (h >= 5790 && h <= 7720) {
callURL(3)
}
else if (h >= 7720 && h <= 9650) {
callURL(4)
}
else if (h >= 9650 && h <= 11580) {
callURL(5)
}
else if (h >= 11580 && h <= 13510) {
callURL(6)
}
else if (h >= 13510 && h <= 15440) {
callURL(7)
}
else if (h >= 15440 && h <= 17370) {
callURL(8)
}
else if (h >= 17370 && h <= 19300) {
callURL(9)
}
else if (h >= 19300 && h <= 21230) {
callURL(10)
}
else if (h >= 21230 && h <= 23160) {
callURL(11)
}
else if (h >= 23160 && h <= 25090) {
callURL(12)
}
else if (h >= 25090 && h <= 27020) {
callURL(13)
}
else if (h >= 27020 && h <= 28950) {
callURL(14)
}
else if (h >= 28950 && h <= 30880) {
callURL(15)
}
else if (h >= 30880 && h <= 32810) {
callURL(16)
}
else if (h >= 32810 && h <= 34740) {
callURL(17)
}
else if (h >= 34740 && h <= 36670) {
callURL(18)
}
else if (h >= 36670 && h <= 38600) {
callURL(19)
}
else if (h >= 38600 && h <= 40530) {
callURL(20)
}
else if (h >= 40530 && h <= 42460) {
callURL(21)
}
else if (h >= 42460 && h <= 44390) {
callURL(22)
}
else if (h >= 44390 && h <= 46320) {
callURL(23)
}
else if (h >= 46320 && h <= 48250) {
callURL(24)
}
else if (h >= 48250 && h <= 50180) {
callURL(25)
}
else if (h >= 50180 && h <= 52110) {
callURL(26)
}
else if (h >= 52110 && h <= 54040) {
callURL(27)
}
else if (h >= 54040 && h <= 55970) {
callURL(28)
}
else if (h >= 55970 && h <= 57900) {
callURL(29)
}
else if (h >= 57900 && h <= 59830) {
callURL(30)
}
else if (h >= 59830 && h <= 61760) {
callURL(31)
}
else{
console.log(h);
}
var scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
var scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;
var scrollHeights = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;
scrollHeight = scrollHeight - 1000;
var clientHeight = document.documentElement.clientHeight || window.innerHeight;
var scrolledToBottom = Math.ceil(scrollTop + clientHeight) >= scrollHeight;
var scrollToTop = Math.ceil(scrollTop - clientHeight) >= scrollHeight;
}
/**
* Get products
* #param page
*/
getProducts(page,customQuery){
page = page || 1;
// console.log(page);
const {getProducts,query} = this.props;
let obj = {
...query,
...customQuery,
query : {
...(query || {}).query,
...(customQuery || {}).query
},
// limit : this.pageSize,
limit : 5000,
// skip : (page-1)*this.pageSize
skip : 0
};
obj.query = {
...obj.query,
state : 'published'
}
getProducts(obj).then(action=>{
// // if(page>1){
// document.getElementById('product-grid').scrollIntoView();
// // }
})
}
/**
* Render the view
* #returns {*}
*/
render() {
return (ComponentView.bind(this))();
}
}
/**
* Bind Actions
* #param dispatch
* #returns Object
*/
function bindAction(dispatch) {
return {
getProducts : (data)=>{
return dispatch(createAction(ActionNames.GET_PRODUCTS,data));
}
};
}
/**
* Map the shared state to properties
* #param state
* #returns Object
*/
const mapStateToProps = state => {
// console.log(state)
return {
data: state.products.results || [],
count : state.products.count,
hasMore : state.products.hasMore,
emitter : state.emitter
};
};
//Set display name to be used in React Dev Tools
Main.displayName = 'Product Grid';
export default connect(mapStateToProps,bindAction)(Main);
This is the site on which we are getting the problem. https://www.tagminepenge.dk/
Go on some page and scroll down then try to click on the back button of the browser. You will understand the issue.
Thank you in advance.
This happens because every time you call window.location a new url is pushed in the browser history stack. To solve it use history.replace provided by the react router it will replace the current url in the history stack so when you go back want make the same problem.
history
import React, {Component} from 'react';
export default class Logout extends Component {
constructor(props) {
super(props);
}
Logout = () => {
this.props.history.replace('/');
}
render() {
return (
<div>
<h1>Your Links</h1>
<button onClick={this.Logout}>Logout</button>
</div>
);
}
}

Categories

Resources