Why my page scroll when I resize on my browser? - javascript

I'm doing a dashboard and I am having a problem.
When I resize my window it scrolls by itself.
Everything is responsive but I do not understand why it scrolls.
Thanks you !
ps: I upload my site if you want check :)
https://edtmimi.000webhostapp.com/dashBoard/
Before resize
After resize
What I want

Update your profileScroll.js file to the code below.
When you resize your browser, the scroll position changes. Since you use this to animate and calculate the position for your pages, you need to recalculate them when resizing the window.
window.addEventListener('load', function () {
var delayInMilliseconds = 1;
function updateScrollPosition() {
if (window.scrollY != document.getElementById("homePage").offsetTop || window.scrollX != document.getElementById("homePage").offsetLeft) {
window.scroll(document.getElementById("homePage").offsetLeft, document.getElementById("homePage").offsetTop);
} else {
document.documentElement.style.animationFillMode = "forwards";
document.documentElement.style.animationDelay = "1s";
}
document.documentElement.style.scrollBehavior = "smooth";
}
setTimeout(function () {
updateScrollPosition();
}, delayInMilliseconds);
document.getElementById("profileButton").addEventListener("click", function () {
window.scrollTo(document.getElementById("profilePage").offsetLeft, document.getElementById("profilePage").offsetTop);
});
for (i = 0; i < document.getElementsByClassName("returnToHomePage").length; i++) {
document.getElementsByClassName("returnToHomePage")[i].addEventListener("click", function () {
window.scrollTo(document.getElementById("homePage").offsetLeft, document.getElementById("homePage").offsetTop);
});
}
document.getElementById("mailButton").addEventListener("click", function () {
window.scrollTo(document.getElementById("mailPage").offsetLeft, document.getElementById("mailPage").offsetTop);
});
document.getElementById("noteButton").addEventListener("click", function () {
window.scrollTo(document.getElementById("notePage").offsetLeft, document.getElementById("notePage").offsetTop);
});
document.getElementById("gameButton").addEventListener("click", function () {
window.scrollTo(document.getElementById("gamePage").offsetLeft, document.getElementById("gamePage").offsetTop);
});
document.getElementById("calendarButton").addEventListener("click", function () {
window.scrollTo(document.getElementById("calendarPage").offsetLeft, document.getElementById("calendarPage").offsetTop);
});
document.getElementById("voiceButton").addEventListener("click", function () {
window.scrollTo(document.getElementById("voicePage").offsetLeft, document.getElementById("voicePage").offsetTop);
});
document.getElementById("buyButton").addEventListener("click", function () {
window.scrollTo(document.getElementById("buyPage").offsetLeft, document.getElementById("buyPage").offsetTop);
});
document.getElementById("paramsButton").addEventListener("click", function () {
window.scrollTo(document.getElementById("paramsPage").offsetLeft, document.getElementById("paramsPage").offsetTop);
});
window.addEventListener('resize', function(){
updateScrollPosition();
});
});
But I would make it a bit more generic:
window.addEventListener('load', function() {
const delayInMilliseconds = 1;
let currentPageId = 'homePage';
function scrollToPage(pageId) {
currentPageId = pageId;
window.scrollTo(document.getElementById(pageId).offsetLeft, document.getElementById(pageId).offsetTop);
}
setTimeout(function() {
document.documentElement.style.animationFillMode = 'forwards';
document.documentElement.style.animationDelay = '1s';
document.documentElement.style.scrollBehavior = 'smooth';
scrollToPage(currentPageId);
}, delayInMilliseconds);
let actions = [
{ buttonId: 'profileButton', pageId: 'profilePage' },
{ buttonId: 'mailButton', pageId: 'mailPage' },
{ buttonId: 'noteButton', pageId: 'noteButton' },
{ buttonId: 'gameButton', pageId: 'gamePage' },
{ buttonId: 'calendarButton', pageId: 'calendarPage' },
{ buttonId: 'voiceButton', pageId: 'voicePage' },
{ buttonId: 'buyButton', pageId: 'buyPage' },
{ buttonId: 'paramsButton', pageId: 'paramsPage' },
];
// Make sure you use `let` instead of `var`. The scope of `var` is global.
for (let i = 0; i < actions.length; i++) {
document.getElementById(actions[i].buttonId).addEventListener('click', function() {
scrollToPage(actions[i]);
});
}
// Check all document clicks, if the target has the class 'returnToHomePage' go back to home page.
// This way you don't have to loop over the buttons
document.addEventListener('click', function(event) {
if (event.target.classList.contains('returnToHomePage')) {
scrollToPage('homePage');
}
});
window.addEventListener('resize', function() {
scrollToPage(currentPageId);
});
});

Related

How to stop a timeout if it is running in javascript

I have a timeout setup like this below:
var someObj = {
init: function() {
someObj.timeout();
someObj.someWork();
},
timeout : setTimeout(function() {
someObj.myFunc();
}, 15000),
myFunc: function() {
console.log('myFunction called');
},
someWork: function(){
console.log('some work');
if(this.timeout !== null){
console.log('clearing timeout...');
clearTimeout(this.timeout);
}
}
}
$(function() {
someObj.init();
});
I want to stop the timeout if it is assigned to timeout variable and not null.
Jsfiddle link: https://jsfiddle.net/jy2p7jtd/17/
Is it possible?
Update:
Is this valid way to assign a timeout and clear it?
var someObj = {
timeout :null,
init: function() {
someObj.make();
someObj.someWork();
},
make: function(){
this.timeout = setTimeout(function() {
console.log('myFunction called');
}, 15000)
},
someWork: function(){
console.log('timeout is ', this.timeout);
if(this.timeout !== null){
console.log('clearing timeout...');
clearTimeout(this.timeout);
}
}
}
$(function() {
someObj.init();
});
updated link: https://jsfiddle.net/jy2p7jtd/41/
declare another property timeoutId:null and check if it is present then clear it.
var someObj = {
timeoutId: null,
init: function() {
this.timeoutId = this.timeout();
someObj.someWork();
},
timeout: function() {
return setTimeout(function() {
someObj.myFunc();
}, 15000)
},
myFunc: function() {
console.log('myFunction called');
},
someWork: function() {
console.log('some work');
if (this.timeoutId) {
console.log('clearing timeout...');
clearTimeout(this.timeoutId);
}
}
}
$(function() {
someObj.init();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
clearTimeout() prevents the function set with the setTimeout() to execute.

#onmouseup not firing at vuejs 2

Full code: https://github.com/kenpeter/test_vue_simple_audio_1
I attach #onmouseup to input range. When I drag the slider, progressChange seems not be called.
<input
type="range"
:min="0"
:step="1"
v-model="current"
:value="current"
:max="duration"
#onmouseup="progressChange()"
/>
Here is the methods
methods: {
timeChange: function () {
this.current = this.$refs.player.currentTime;
},
getDuration: function () {
this.duration = this.$refs.player.duration;
},
toggleStatus: function () {
var player = this.$refs.player;
this.isPause ? player.play() : player.pause();
this.isPause = !this.isPause;
},
next: function () {
if (this.audioIndex == this.songs.length - 1) {
if (this.repeat) {
this.audioIndex = 0;
}
} else {
this.audioIndex++;
}
},
prev: function () {
if (this.audioIndex == 0) {
if (this.repeat) {
this.audioIndex = this.songs.length - 1;
}
} else {
this.audioIndex--;
}
},
progressChange() {
console.log("progress change");
},
To answer this question for future reference for people who would be looking for similar issues:
The issue was the wrong name on calling event as VueJS uses syntax of #even where # replaces 'on`, so you have to use:
#mouseup
#click
#keyup:keyname
#input
#customEventEmitedByComponent

Delete items synchronously angularjs

I have to delete items in a for loop the moment I close a bootstrap modal.
Currently I am setting a delay of 3 secs on the modal close, so that the delete can happen within those 3secs in the background but this is not very efficient.
What is the best way to ensure that the modal closes only when all the items are deleted successfully? Perhaps by making the delete synchronous ? Or promises?
$scope.idList = [1, 2, 3];
$scope.deleteItems = function(deleteList){
angular.forEach( deleteList, function(item) {
DeleteAPI.remove({itemId: item}, {}, $scope.delSuccess, $scope.delError);
});
}
$scope.close = function(){
var pmodal = $modal.open( {
templateUrl: 'route/pmodal.html',
controller: 'DeleteCtrl'
} );
pmodal.result.then(
function(check) {},
function(check) {
if ( check=='proceed' ) {
$scope.deleteItems( $scope.idList );
$timeout( function() {
$modalInstance.dismiss('cancel');
}, 3000);
}
},
function(check) {}
);
}
You can use $q.all or you can simple count responses as Javascript is not multithread:
pmodal.result.then(
var success = 0;
var failed = 0;
var check = function() {
if (success + failed == deleteList.length) {
if (failed != 0) {
// do smth?
} else {
$modalInstance.dismiss('cancel');
}
}
}
angular.forEach( deleteList, function(item) {
DeleteAPI.remove({itemId: item}, {}, function() {
success++;
check();
}, function() {
failed++;
check();
});
});

How to call a script on success of $.ajax

The goal
Call a script (to be more specific, qTip2 script) on success of $.ajax function from jQuery.
The problem
I have the following script to work with KnockoutJS:
$.ajax({
url: "/ProductsSummary/List?output=json",
dataType: "json",
success: function (data) {
var mappingOptions = {
create: function (options) {
return (new (function () {
this.finalMeasure = ko.computed(function () {
return this.quantity() > 1 ? this.measure() + "s"
: this.measure();
}, this);
this.infoComposition = ko.computed(function () {
return this.quantity() + ' ' + this.finalMeasure();
}, this);
ko.mapping.fromJS(options.data, {}, this);
})());
}
};
ViewModel.Summary.products = ko.mapping.fromJS(data, mappingOptions);
ko.applyBindings(ViewModel);
$("ul.products-list li").each(function () {
var $productId = $(this).data("productid"),
$match = $(".summary")
.find("li[data-productid=" + $productId + "]")
.length > 0;
if ($match) {
$(this).find("button.action").addClass("remove");
} else {
$(this).find("button.action").addClass("add");
}
});
}
});
In the following fragment, I set a class to a button to define its style, but I have no success because I need to call the qTip2 again to render the new tooltip. See:
$("ul.products-list li").each(function () {
var $productId = $(this).data("productid"),
$match = $(".summary")
.find("li[data-productid=" + $productId + "]")
.length > 0;
if ($match) {
$(this).find("button.action").addClass("remove");
} else {
$(this).find("button.action").addClass("add");
}
});
To make the things work, I have to call the qTip2 script after this fragment, but it was previously called.
To do not be redundant or practice the DRY concept, how can I call, inside of the "on success", qTip2 script again?
A little of code
My qTip2 Script:
$(function () {
var targets = $("ul.products-list li .controls
button.action.add").attr('oldtitle', function () {
var title = $(this).attr('title');
return $(this).removeAttr('title'), title;
}),
shared_config = {
content: {
text: function (event, api) {
return $(event.currentTarget).attr('oldtitle');
}
},
position: {
viewport: $(window),
my: "bottom center",
at: "top center",
target: "event"
},
show: {
target: targets
},
hide: {
target: targets
},
style: "qtip-vincae qtip-vincae-green"
};
$('<div/>').qtip(shared_config);
$('<div/>').qtip($.extend(true, shared_config, {
content: {
text: function (event, api) {
var target = $(event.currentTarget),
content = target.data("tooltipcontent");
if (!content) {
content = target.next("div:hidden");
content && target.data("tooltipcontent", content);
}
return content || false;
}
},
position: {
my: "top center",
at: "bottom center",
viewport: $(".content"),
container: $(".content")
},
show: {
event: "click",
effect: function () {
$(this).show(0, function () {
$(this).find("input[name=productQuantity]").focus();
});
}
},
hide: {
event: "click unfocus",
fixed: false
},
events: {
hide: function (event, api) {
$($(this).find("input[type=text].quantity")).val("");
$($(this).find("button")).prop("disabled", true);
}
},
style: "qtip-vincae qtip-vincae-grey"
}));
});
Thanks in advance.
As I see it you should call simply $(this).find("button.action").qtip() or .qtip(...) and set/update what you want.
This demo could be your cheat-sheet:
http://craigsworks.com/projects/qtip2/demos/#validation

To apply .delay() on mouseenter in my plugin

I got a div, that on mouseenter, is suppose to show another div. I'm not sure how to achive this in a plugin. This is my code and what I have tried so far.
Code: JsFiddle
<div class="hover-me"></div>
<div class="show-me"></div>
var Nav = {
hover_me: $('.hover-me'),
show_me: $('.show-me'),
init: function() {
Nav.toggle_display();
console.log('init');
},
toggle_display: function() {
Nav.hover_me.mouseenter(function() {
Nav.show();
});
Nav.hover_me.mouseleave(function () {
Nav.hide();
});
},
show: function() {
Nav.show_me.fadeIn();
},
hide: function() {
Nav.show_me.fadeOut();
}
};
I tried to do this, without any luck.
Nav.hover_me.mouseenter(function() {
Nav.delay(1000).show();
});
see Jimbo's comment:
var Nav = {
// [...]
timeoutId: undefined,
// [...]
};
Nav.hover_me.mouseenter(function() {
Nav.timeoutId = setTimeout(function() {
Nav.show();
}, 1000);
});
Nav.hover_me.mouseleave(function () {
if (Nav.timeoutId) { clearTimeout(Nav.timeoutId); }
Nav.hide();
});
SEE THE FIDDLE

Categories

Resources