I recently discovered a functionality of jQuery Chosen which automatically scrolls the .chosen-results Container downwards when you hover the bottom of the container.
I already found the function (result_do_highlight) which does that: here
This is the part where the automatic scroll happens in the function:
if high_bottom >= visible_bottom
#search_results.scrollTop if (high_bottom - maxHeight) > 0 then (high_bottom - maxHeight) else 0
else if high_top < visible_top
#search_results.scrollTop high_top
Is there a way to prevent scrolling?
Thank you in advance
EDIT
I forked the Chosen-git and added a workaround: github.com/puresamari/chosen
here is how to use it:
Changes from my side
I added the funtionallity to disable the automatic scroll towards the highlighted option:
Use it like this:
$('your_select').chosen({
scroll_to_highlighted: false
});
the parameter ´scroll_to_highlighted´ is optional and default true
I forked the Chosen-git and added a workaround: github.com/puresamari/chosen
here is how to use it:
Changes from my side
I added the funtionallity to disable the automatic scroll towards the highlighted option:
Use it like this:
$('your_select').chosen({
scroll_to_highlighted: false
});
the parameter ´scroll_to_highlighted´ is optional and default true
Related
I have a site where I have each section as 100vh so it fills the height of the screen perfectly. The next step I wanted to implement was disabling the regular scrolling, and on scroll force the screen to jump smoothly to the top of the next 100vh section. Here is the example of this animation / feature:
https://www.quay.com.au/
I was having a hard time finding any answers for this as most things just deal with smooth scrolling when clicking on anchors, not actually forcing div relocation when the user scrolls up / down.
I just wanted to know what code I would need do this...
Thanks, been using stack overflow for a while but first post, let me know if there is anything I can do to make this more clear.
disclaimer: this solution needs some testing and probably a bit of improvements, but works for me
if you don't want to use a plugin and prefer a vanilla JavaScript solution I hacked together a small example how this can be achieved with JS features in the following codepen:
https://codepen.io/lehnerchristian/pen/QYPBbX
but the main part is:
function(e) {
console.log(e);
const delta = e.deltaY;
// check which direction we should scroll
if (delta > 0 && currentlyVisible.nextElementSibling) {
// scroll downwards
currentlyVisible = currentlyVisible.nextElementSibling;
} else if (delta < 0 && currentlyVisible.previousElementSibling) {
// scroll upwards
currentlyVisible = currentlyVisible.previousElementSibling;
} else {
return false;
}
// perform scroll
currentlyVisible.scrollIntoView({ behavior: 'smooth' });
e.preventDefault();
e.stopPropagation();
}
what it does is that it listens for the wheel event and then calls the callback, which intercepts the scroll event. inside the callback the direction is determined and then Element.scrollIntoView() is called to let the browser do the actual scrolling
check https://caniuse.com/#search=scrollintoview for browser support, if you're going for this solution
Is there a way to disable the bounce effect in a scrolling div?
So far I have tried these things but none worked. Please help!
How to disable vertical bounce/scroll on iPhone in a mobile web application
Can't disable bounce with UIScrollView and pagingEnabled=YES
ipad safari: disable scrolling, and bounce effect?
Disable UITableView vertical bounces when scrolling
And
http://www.iphonedevsdk.com/forum/iphone-sdk-development/996-turn-off-scrolling-bounces-uiwebview.html
Thanks!
If you're using Cordova 1.7, just open the Cordova.plist file and set the key UIWebViewBounce to NO.
Open your phoneGap project's config.xml file and change UIWebViewBounce from default true to false:
<preference name="UIWebViewBounce" value="false" />
Can't imagine why the default is true...
Based on your comment, the code your are using is the disable scrolling altogether. If you want scrolling, but without the bounce effect, try something like this:
var xStart, yStart = 0;
document.getElementById("scrollableDiv").addEventListener('touchstart',function(e) {
xStart = e.touches[0].screenX;
yStart = e.touches[0].screenY;
});
document.getElementById("scrollableDiv").addEventListener('touchmove',function(e) {
var xMovement = Math.abs(e.touches[0].screenX - xStart);
var yMovement = Math.abs(e.touches[0].screenY - yStart);
if((yMovement * 3) > xMovement) {
e.preventDefault();
}
});
I found this solution here. Let me know if it works for you.
This will help you out place the .scroll class on the element you wish to still have scrolling.
Whats happening is all touch moves are disabled by default. If the element you wish to scroll has the .scroll class on it then it sets the gate to true to allow it to pass.
On touch end you reset the gate to false.
This works on IOS5 and 6 and could work in Chrome and Safari
Look # this post to extend it How to prevent page scrolling when scrolling a DIV element?
The only catch to this is that if you over scroll the scrollable element the elastic effect allows the scroll to be passed up the tree while scroll is set to true. Manually setting the scroll position gets overridden by the dreaded bounce effect.
I bet those Apple friggers have a native implementation of scroll running in a set time out with each step hard wired in. So if you scroll to -20, I think it hard wires each step into a loop not checking where it was. Scrolling to -20 -19 -18 etc in sequence. We must think of a way around this! ( in fact typing it out load I have an idea! )
$(function(){
var scroll = false
var scroll_element;
$('body').on('touchmove',function(e){
if(!scroll){
e.preventDefault()
}
})
$('body').on('touchend',function(e){
scroll = false
})
$('.scroll').on('touchstart',function(e){
scroll_element = this
scroll = true
})
})
I know this may not be the best way but it works.
Here is what I did -
#scrollableDiv {
position:fixed;
top:50px;
width:300px;
height:500px;
word-wrap: break-word;
overflow-y: scroll;
}
document.getElementById("scrollableDiv").innerHTML = longText;
document.getElementById("scrollableDiv").scrollTop = 0;
I do not know how to solve this situation:
I`ve got the html/css looks like this:
Image showing how my css/html looks like and what is displayed on the screen after landing on page:
The when I scroll down I see green element:
scrolling down ->
After continuing to scrolling down I saw full green element and the if I scroll down I want to have this element like in css language: position fixed bottom 0. See image below:
I ve saw full element -> same link but image called problem3.png
and then I scroll below and I want to have it fixed at the bottom of the page, like on this image:
Fixed element on screen - What I want and I do not know how to do that -> same link but image called problem4.png (stupid spam prevention mechanism)
Is it possible to solve this situation ?
To sum up: I`ve got two divs, one above and second below, Wheen I scroll down I suddenly see another element (green div) and when i continue to scroll down I WANT TO HAVE THIS GREEN DIV FIXED AT THE BOTTOM OF THE PAGE.
Ofcourse, when I scroll up (back on the top) I want to "park" that green div at the top of the second div.
Is there any way to solve this situation with jQuery (Javascript) / html / css ?
Thank you in advance
I think you'll have to show some of your html structure. There are lots of ways to achieve this kind of effect. Fundamentally, in javascript terms you'll be looking to:
Add an event listener to the window scroll that checks whether the green element is fully in view
If it is in view, add a class (or change it's css) that fixes it's position where you want
Change your window scroll method so that it's checking the relative offset of the red div to the top of the screen. If it goes below the position where the green div should be fixed, remove the class you added earlier.
That sounds complicated, but it's not too bad. The javascript would be something like:
$(function() {
$(window).scroll(function() {
if($(".divToFix").hasClass("fixedAtBase")){
if(Utils.underView($(".redDiv"), $(".divToFix").height())) $(".divToFix").removeClass("fixedAtBase");
} else {
if(Utils.inView($(".divToFix"))) $(".divToFix").addClass("fixedAtBase");
}
});
});
Utils = {
underView: function(element, offset) {
return (($(window).height() + $(window).scrollTop() - offset) <= element.offset().top);
},
aboveView: function(element) {
return ($(window).scrollTop() >= element.offset().top + element.height());
},
inView: function(element) {
return (Utils.aboveView(element) !== true && Utils.underView(element, element.height()) !== true);
}
};
Bear in mind I've not tested that or anything.
edit - here's a demo
I am using the most wonderful javascript tool iScroll4 http://cubiq.org/iscroll-4 on a mobile website for iOS and Android. Here is what my layout looks like:
The horizontally scroll-able area is making use of iScroll4 with the following settings:
var myScroll = new iScroll('frame', { hScrollbar: false, vScrollbar: false, vScroll: false })
The horizontal scrolling part works great. This issue is what happens when a user attempts to scroll up or down the page placing their finger on the horizontal scrolling area. So I need native vertical scrolling, and iScroll horizontal scrolling on the same area.
What I have tried so far:
Removing e.preventDefault() in the iScroll code (allows for native scrolling, but in BOTH axes).
Removing e.preventDefault() and then disabling horizontal scrolling page wide with this:
var touchMove;
document.ontouchstart = function(e){
touchMove = e.touches[0];
}
document.ontouchmove = function(e){
var theTouch = e.touches[0] || e.changedTouches[0];
var Xer = rs(touchMove.pageX - theTouch.pageX).toPos();
var Yer = rs(touchMove.pageY - theTouch.pageY).toPos();
touchMove = theTouch;
if(Yer > Xer){ e.preventDefault(); }
}
which seems to do nothing. How can I allow for native vertical scrolling in the horizontal scrolling area, without loosing the horizontal scrolling of iScroll? I am really stumped here. Thanks in advance.
(just for the record rs(foo).toPos() is a function that makes foo a positive number regardless of its value).
If you would like to achieve the effect described by Fresheyeball without hacking the core, and without changing from iScroll to swipeview, then iScroll 4 does offer you its event listeners to work with.
myScroll = new iScroll('scrollpanel', {
// other options go here...
vScroll: false,
onBeforeScrollMove: function ( e ) {
if ( this.absDistX > (this.absDistY + 5 ) ) {
// user is scrolling the x axis, so prevent the browsers' native scrolling
e.preventDefault();
} else {
// delegate the scrolling to window object
window.scrollBy( 0, -this.distY );
}
},
});
By doing so, the onBeforeScrollMove-Handler checks whether the scroll direction seems to be horizontal, and then prevents the default handler, thus effectively locking the scroll action to the X-Axis (try commenting it out, you'll see the difference). Otherwise, if the scroll direction needs to be vertical, we make the browser scroll via the window.scrollBy() method. This is not exactly native, but does the job just fine.
Hope that helps
Lukx
[EDIT]
My original solution, which didn't use window.scrollBy() ,did not work on slower Samsung phones, which is why I needed to adapt the answer.
Suggested edit to #Lukx's excellent solution. New versions of iScroll4 place the e.preventDefault() in onBeforeScrollMove which can be overridden. By placing the if block into this option, default is not prevented for vertical scrolling, and vertical can scroll natively.
myScroll = new iScroll('scrollpanel', {
// other options go here...
vScroll: false,
onBeforeScrollStart: function ( e ) {
if ( this.absDistX > (this.absDistY + 5 ) ) {
// user is scrolling the x axis, so prevent the browsers' native scrolling
e.preventDefault();
}
},
});
With iscroll 5, you can set eventPassthrough: true to achieve this. See http://iscrolljs.com/#configuring
OLD ANSWER
UPDATE a special pluggin has been written just to address this problem:
http://cubiq.org/swipeview
I found a way!
add a variable to the top of the document: if android is 15 and is iOS is 3
var scrollTolerance = ( rs().isDevice('android') )?15:3;
disable the original e.preventDefault(); for scrolling. This is under onBeforeScrollStart:
the in _move just under
timestamp = e.timeStamp || Date.now();
add this line
if( Math.sqrt(deltaX*deltaX) > scrollTolerance){e.preventDefault();}
What this does is the following:
the scrollTolerance sets, you guessed it, a tolerance for finger direction. We don't want to demand a perfect vertical angle to get the up down native scroll. Also iOS does not detect properly and will never be higher than 4 for some reason so I used 3. Then we disable iScroll's standard e.preventDefault(); which prevents native vertical scrolling on our bi-scrollable area. Then we insert e.preventDefault(); only upon move and based on finger direction from tolerance.
This does not work perfect. But is acceptable and works on iOS and Android. If anyone sees better ways please post here. This is something I (and assume others) need to use regularly, and we should have a perfect rock solid solution.
Thanks.
Please test this solution from Adam.
https://gist.github.com/hotmeteor/2231984
I think the trick is to add the check in onBeforeScrollMove. First get the initial touch position in onBeforeScrollTouchStart and then in onBeforeScrollMove check the new position and then disable the required scroll based on the difference.
iScroll 5 supports native scrolling of any axis!
http://iscrolljs.com/
on iScroll5 just set eventPassthrougt to true. That fixes it.
Is there a way to tell if you have scrolled passed the center of the web page or in other words, when you have scrolled passed exactly half of the web page and your scrollbar is situated in the lower half of the browser window?
I want to be able to trigger this:
$('.pineapple-man').show(); when I have scrolled down passed half of the page?
Is this possible at all?
Your help would be so kind!
You can get the pixel amount of an element has been scrolled by using .scrollTop(). To listen to scroll events use .scroll().
When you want to identify the halfway, use height of the scroll:
$(window).scroll(function () {
if ($(window).scrollTop() > $('body').height() / 2) {
$('.pineapple-man').show();
}
});
If you are scrolling some other element than the whole window/body, please feel free to change the selectors.
To make the showing one-timer, add the removal of scroll event listener, by adding the following after the .show() call:
$(window).unbind('scroll');
I guess you want to do something like this:
if($(document).scrollTop() > $(document).height()/2){
$('.pineapple-man').show();
}
where scrollTop() gets the current horizontal position and height() defines the document height.
See the scroll event and the scrollTop method.
you can use the focus event if you scroll down to it (just like jQuery uses for their comments)
jQuery('selector').focus(function() {
jQuery('.page').show();
});