I'm looking for resources that create scrolling functions like the ones found on these sites:
Outpost Journal
Unfold
Once the scroll bar hits the bottom of the page, I want it to loop back to the top.
I'm familiar with with the infinite scroll, and this is not what I want. I've also found scripts that will write/add the same content to the bottom of the page, but none that loop back to the top of the page.
Try this:
$('document').ready(function() {
$(document).scroll(function(){
if(document.documentElement.clientHeight +
$(document).scrollTop() >= document.body.offsetHeight )$(document).scrollTop(0);
});
});
if you want infinite scroll in both directions use
if (document.documentElement.clientHeight + $(window).scrollTop() >= $(document).height()) {
$(document).scrollTop(0)
} else if ($(window).scrollTop() < 0) {
$(document).scrollTop($(document).height())
}
(I know it's a late reply but it still helps users like me who just google stuff like this)
Here a solution that makes a duplicate of the body so the bottom and the top can be seen at the same time at a certain point so the transition is smoother.
$('document').ready(function() {
// We need to duplicate the whole body of the website so if you scroll down you can see both the bottom and the top at the same time. Before we do this we need to know the original height of the website.
var origDocHeight = document.body.offsetHeight;
// now we know the height we can duplicate the body
$("body").contents().clone().appendTo("body");
$(document).scroll(function(){ // detect scrolling
var scrollWindowPos = $(document).scrollTop(); // store how far we have scrolled
if(scrollWindowPos >= origDocHeight ) { // if we scrolled further then the original doc height
$(document).scrollTop(0); // then scroll to the top
}
});
});
mrida's answer was causing my browser to not be able to scroll, here is a modified version that worked for me:
$('document').ready(function() {
$(document).scroll(function(){
if (document.documentElement.clientHeight + $(window).scrollTop() >= $(document).height()) {
$(document).scrollTop(0);
}
});
});
Forked from #clankill3r's answer, create two copy of body, prepend and append to the original body, then you can scroll the page in two direction endless.
$('document').ready(function() {
var origDocHeight = document.body.offsetHeight;
var clone=$("body").contents().clone();
clone.appendTo("body");
clone.prependTo("body");
$(document).scroll(function(){
var scrollWindowPos = $(document).scrollTop();
if(scrollWindowPos >= origDocHeight ) {
$(document).scrollTop(0);
}
if(scrollWindowPos <= 0 ) {
$(document).scrollTop(origDocHeight);
}
});
});
Adding loop scroll backwards, upgrading #clankill3r answer. It should be something like this.
$('document').ready(function() {
// We need to duplicate the whole body of the website so if you scroll down you can see both the bottom and the top at the same time. Before we do this we need to know the original height of the website.
var origDocHeight = document.body.offsetHeight;
// now we know the height we can duplicate the body
$("body").contents().clone().appendTo("body");
$(document).scroll(function(){ // detect scrolling
var scrollWindowPos = $(document).scrollTop(); // store how far we have scrolled
if(scrollWindowPos >= origDocHeight ) { // if we scrolled further then the original doc height
$(document).scrollTop(scrollWindowPos + origDocHeight); // then scroll to the top
} else if (scrollWindowPos == 0) { // if we scrolled backwards
$(document).scrollTop(origDocHeight);
}
});
});
I'm using it horizontally and it's working just fine. Hope someone finds it useful.
Posted a similar question: https://stackoverflow.com/a/65953934/7474712 and found the answer via this pen: https://codepen.io/vincentorback/pen/zxRyzj
Here's the code:
<style>
html,
body {
height: 100%;
overflow: hidden;
}
.infinite {
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.clone {
height: 50vw;
}
</style>
<script>
var doc = window.document,
context = doc.querySelector('.infinite'),
clones = context.querySelectorAll('.clone'),
disableScroll = false,
scrollHeight = 0,
scrollPos = 0,
clonesHeight = 0,
i = 0;
function getScrollPos () {
return (context.pageYOffset || context.scrollTop) - (context.clientTop || 0);
}
function setScrollPos (pos) {
context.scrollTop = pos;
}
function getClonesHeight () {
clonesHeight = 0;
for (i = 0; i < clones.length; i += 1) {
clonesHeight = clonesHeight + clones[i].offsetHeight;
}
return clonesHeight;
}
function reCalc () {
scrollPos = getScrollPos();
scrollHeight = context.scrollHeight;
clonesHeight = getClonesHeight();
if (scrollPos <= 0) {
setScrollPos(1); // Scroll 1 pixel to allow upwards scrolling
}
}
function scrollUpdate () {
if (!disableScroll) {
scrollPos = getScrollPos();
if (clonesHeight + scrollPos >= scrollHeight) {
// Scroll to the top when you’ve reached the bottom
setScrollPos(1); // Scroll down 1 pixel to allow upwards scrolling
disableScroll = true;
} else if (scrollPos <= 0) {
// Scroll to the bottom when you reach the top
setScrollPos(scrollHeight - clonesHeight);
disableScroll = true;
}
}
if (disableScroll) {
// Disable scroll-jumping for a short time to avoid flickering
window.setTimeout(function () {
disableScroll = false;
}, 40);
}
}
function init () {
reCalc();
context.addEventListener('scroll', function () {
window.requestAnimationFrame(scrollUpdate);
}, false);
window.addEventListener('resize', function () {
window.requestAnimationFrame(reCalc);
}, false);
}
if (document.readyState !== 'loading') {
init()
} else {
doc.addEventListener('DOMContentLoaded', init, false)
}
</script>
Related
I am attempting to show an image in a qx.ui.popup.Popup but am having trouble understanding how it can be centered on the screen. The demo browser has an example for placement but it's pretty hard to follow. Any help is appreciated.
Try capturing the "appear" event and moving the popup to the center of the widget that fills the screen. Example code and link to Qooxdoo Playground example: Qooxdoo Playground
// Document is the application root
var doc = this.getRoot();
var mypop = new qx.ui.control.ColorPopup();
mypop.exclude();
mypop.setValue("#23F3C1");
mypop.addListener("appear", function() {
var parent = this.getLayoutParent();
if (parent) {
var bounds = parent.getBounds();
if (bounds) {
var hint = this.getSizeHint();
var left = Math.round((bounds.width - hint.width) / 2);
var top = Math.round((bounds.height - hint.height) / 2);
if (top < 0) {
top = 0;
}
this.setLayoutProperties({
top: top,
left: left
});
}
}
}, mypop);
var mybtn = new qx.ui.form.Button("Open Popup");
mybtn.addListener("execute", function (e) {
//mypop.placeToWidget(mybtn);
mypop.show();
});
doc.add(mybtn, {
left: 20,
top: 20,
});
I have a large set of data that needs virtual scrolling and I use PrimeNg v13.4.0 with angular/cdk v13.3.7. I have exactly the same issue with PrimeNg demo. When scrolling down, the sticky header works well, but when scrolling up, it start jumping, the faster scroll, the bigger jump. Does anyone has any solution for this?
This issue and its pull request is added to version 13 future milestone which has no due date.
https://github.com/primefaces/primeng/milestone/175
For now you can do this solution:
If you slow down the wheel speed of the cdk-virtual-scroll-viewport, even slightly,
The thead works as it should without any jumping.
changeWheelSpeed(container, speedY) {
var scrollY = 0;
var handleScrollReset = function() {
scrollY = container.scrollTop;
};
var handleMouseWheel = function(e) {
e.preventDefault();
scrollY += speedY * e.deltaY
if (scrollY < 0) {
scrollY = 0;
} else {
var limitY = container.scrollHeight - container.clientHeight;
if (scrollY > limitY) {
scrollY = limitY;
}
}
container.scrollTop = scrollY;
};
var removed = false;
container.addEventListener('mouseup', handleScrollReset, false);
container.addEventListener('mousedown', handleScrollReset, false);
container.addEventListener('mousewheel', handleMouseWheel, false);
return function() {
if (removed) {
return;
}
container.removeEventListener('mouseup', handleScrollReset, false);
container.removeEventListener('mousedown', handleScrollReset, false);
container.removeEventListener('mousewheel', handleMouseWheel, false);
removed = true;
};
}
implement it in the ngAfterViewInit function:
ngAfterViewInit(): void {
const el = document.querySelector<HTMLElement>('.cdk-virtual-scroll-viewport');
this.changeWheelSpeed(el, 0.99);
}
In Protractor, I am trying to write a function to simulate clicking a responsive navigation menu item (i.e. menu is either a bar of dropdowns across the top or a hamburger link if mobile). The structure of the bar is defined by MEANJS with a few id="" attributes mixed in.
It seems to work exactly as I want when I run it one spec at a time, like so:
protractor app/tests/e2e/conf.js --suite mySuite
but when I run with the full test (that only has 4 tests in it), like so:
protractor app/tests/e2e/conf.js
I start to get this error intermittently (source of error is in 2 places below):
Failed: element not visible
Here's my function
commonPOs.clickNavBar = function(mainTab, linkUrl) {
var deferred = protractor.promise.defer();
var hamburger = element(by.id('nav-hamburger'));
var linkCssExpression = 'a[href*="' + linkUrl + '"]';
hamburger.isDisplayed().then(function(result) {
if ( result ) {
hamburger.click().then(function() {
var navBar = hamburger
.element(by.xpath('../..'))
.element(by.id('myapp-navbar'));
return clickItNow(mainTab, linkUrl, navBar);
});
} else {
return clickItNow(mainTab, linkUrl, element(by.id('myapp-navbar')));
}
});
return deferred.promise;
function clickItNow(mainTab, linkUrl, navBar) {
var link;
if(mainTab) {
// if mainTab was passed, need to
// click the parent first to expose the link
var parentLink;
if (mainTab == 'ACCTADMIN') {
parentLink = navBar.element(by.id('account-admin-menu'));
}
else {
parentLink = navBar.element(by.linkText(mainTab));
}
expect(parentLink.isPresent()).toBeTruthy();
parentLink.click(); // FIRST PLACE ERROR HAPPENS
link = parentLink.element(by.xpath('..')).element(by.css(linkCssExpression));
}
else {
link = navBar.element(by.css(linkCssExpression));
}
expect(link.isPresent()).toBeTruthy();
link.click(); // SECOND PLACE ERROR HAPPENS
return deferred.fulfill();
}
};
I have tried to use both of these but neither work:
browser.sleep(500);
browser.driver.wait(protractor.until.elementIsVisible(parentLink));
What NOOB async error am I making?
Self answer... but any better answer will win the green check mark!!!
EDITED - After more problems, found a nice 'waitReady()' contribution from elgalu.
There were a few obvious problems with my original code, but fixing them did not solve the problem. After working through what I could, the solution seemed to be the expect(navBar.waitReady()).toBeTruthy(); lines I added. I also had to split the nested function out. Anyway, here is the new code that seems to be working now. A better (comprehensive) answer will get the green checkmark! I'm pretty sure there's a flaw or 2 here.
commonPOs.clickNavBar = function(mainTab, linkUrl) {
var deferred = protractor.promise.defer();
var hamburger = element(by.id('nav-hamburger'));
hamburger.isDisplayed().then(function(result) {
if ( result ) {
hamburger.click().then(function() {
var navBar = hamburger
.element(by.xpath('../..'))
.element(by.id('myapp-navbar'));
return clickItNow(mainTab, linkUrl, navBar, deferred);
});
} else {
return clickItNow(mainTab, linkUrl, element(by.id('myapp-navbar')), deferred);
}
});
return deferred.promise;
};
function clickItNow(mainTab, linkUrl, navBar, deferred) {
var targetLink;
var linkCssExpression = 'a[href*="' + linkUrl + '"]';
expect(navBar.waitReady()).toBeTruthy();
if(mainTab) {
// if mainTab was passed, neet to
// click the parent first to expose the link
var parentTabLink;
if (mainTab == 'ACCTADMIN') {
parentTabLink = navBar.element(by.id('account-admin-menu'));
}
else {
parentTabLink = navBar.element(by.id('main-menu-' + mainTab));
}
// expect(parentTabLink.isDisplayed()).toBeTruthy();
expect(parentTabLink.waitReady()).toBeTruthy();
parentTabLink.click();
targetLink = parentTabLink.element(by.xpath('..')).element(by.css(linkCssExpression));
}
else {
targetLink = navBar.element(by.css(linkCssExpression));
}
expect(targetLink.isDisplayed()).toBeTruthy();
targetLink.click().then(function() {
return deferred.fulfill();
});
}
I am trying to change the background image based on window resize. I am getting the correct output in console in terms of the image path that I need. But for some reason the url just doesn't update in the div.
This is in a directive:
angular.element($window).on('resize', function(){
waitForFinalEvent(function(){
checkSize();
}, 500);
});
$scope.index = 0;
var checkSize = function(){
var width = angular.element($window).width();
var height = angular.element($window).height()
console.log('w: ' +width);
console.log('h: '+height);
$scope.index ++;
if(width < 1050 && width > 800 ) {
$scope.slideImage = $scope.displaySlideImageM;
console.log('here1: ' +$scope.slideImage);
} else if(width < 799 && height < 800) {
$scope.slideImage = $scope.displaySlideImageM;
console.log('here2: ' +$scope.slideImage);
} else if(width < 799 && height > 800) {
$scope.slideImage = $scope.displaySlideImageP;
console.log('here3: ' +$scope.slideImage);
} else {
$scope.slideImage = $scope.displaySlideImageO;
console.log('here4: ' +$scope.slideImage);
}
}
var waitForFinalEvent = (function () {
var timers = {};
return function (callback, ms) {
if (timers) {
clearTimeout(timers);
}
timers = setTimeout(callback, ms);
};
})();
html:
<div class="result-slide" ng-style="{'background-image':'url('+ slideImage +'?v='+ index +')'}"></div>
As you can see I tried adding a random param to the end of the url with ?v=n to attempt to trigger the refresh. But although the index changes, the physical slideImage url isn't updating.
Can someone please shed some light to this issue?
A quick scan of your code shows that you should be using $timeout, instead of setTimeout. While both things execute the timer fine, setTimeout occurs outside of angular so the $scope assignments will not be updated. If you do use setTimeout, then you need to wrap your assignment code in $scope.apply().
You can read about it more here. https://docs.angularjs.org/api/ng/service/$timeout
Question Answer below
Hello I'm looking a simple way to change the colour of a progress bar, what I'm trying to do with it, would look like this:
function (progressBar, value) {
if (value < 40) {
progressBar.setColor('red');
} else if (value >= 40 && value <= 80) {
progressBar.setColor('yellow');
} else {
progressBar.setColor('green');
}
}
Then some kind of way to change the colour through the style with the method progressbar already have, setUI, or other kind of way that it could work would be great as well.
Thanks.
Solution
I found the way to do it, here it is, I create a custom progress bar, where I use the listener update, then this one is going to receive the actual value of the progress bar, and the bar itself, I take the obj and find the styles of the progress bar, where I modify backgroundColor and the borderRightColor with the hex color I want and set the backgroundImage to and empty URL then it will allow the backgroundcolor to show up.
Also I create the option to send a default color.
Here is the code:
Ext.define("progressBarCustom", {
extend: 'Ext.ProgressBar',
alias: 'widget.progressBarCustom',
max: null,
ave: null,
min: null,
color: null,
initComponent: function () {
var me = this;
me.width = 300;
me.margin = '5 5 0 5';
me.callParent(arguments);
},
listeners: {
update: function (obj, val) {
if (this.max != null && this.ave != null && this.min != null) {
if (val * 100 <= this.min) {
obj.getEl().child(".x-progress-bar", true).style.backgroundColor = "#FF0000";
obj.getEl().child(".x-progress-bar", true).style.borderRightColor = "#FF0000";
obj.getEl().child(".x-progress-bar", true).style.backgroundImage = "url('')";
} else if (val * 100 <= this.ave) {
obj.getEl().child(".x-progress-bar", true).style.backgroundColor = "#FFFF00";
obj.getEl().child(".x-progress-bar", true).style.borderRightColor = "#FFFF00";
obj.getEl().child(".x-progress-bar", true).style.backgroundImage = "url('')";
} else {
obj.getEl().child(".x-progress-bar", true).style.backgroundColor = "#009900";
obj.getEl().child(".x-progress-bar", true).style.borderRightColor = "#009900";
obj.getEl().child(".x-progress-bar", true).style.backgroundImage = "url('')";
}
} else if (this.color != null) {
obj.getEl().child(".x-progress-bar", true).style.backgroundColor = this.color;
obj.getEl().child(".x-progress-bar", true).style.borderRightColor = this.color;
obj.getEl().child(".x-progress-bar", true).style.backgroundImage = "url('')";
}
}
}
});
Then if you are going to create a new progressbar with the color changes here is the code:
Ext.create('progressBarCustom', {
min : 0.20,
ave : 0.60,
max : 0.80
});
or just with a default color:
Ext.create('progressBarCustom', {
color : "#4D0099"
});
Any suggestion would be received, thanks :).
I would suggest adding a listener that calls your function on the move event as this appears to contain the positions you need. Documentation link.
For the setColor aspect I believe you want to set the components style elements. Documentation link. Hope that helps.