I am using HTML5 Drag and Drop API to reorganize elements in a vertical list. The list is an overflow-y: scroll div. On macOS Chrome and macOS Firefox, if an item is dragged very close (~20px) to the inside edge of the container, the container is scrolled. This behaviour is not present on macOS Safari.
JSFiddle Demo
I am interested in how to implement a modified version of this behaviour for all modern browsers:
How to have a larger scroll activation region. On macOS Chrome it must be inside the container and is relatively small (20px). Preferably it could be increased to something like 15% of the container height.
Preferably the region would remain inside the list (so if you scroll outside the list the container is not scrolled)
How to disable the apparently undocumented Chrome scrolling behaviour. (Assuming it isn't possible to "enable" this feature on Safari, Edge).
Constraints:
A raw JavaScript / html / css solution is acceptable
I am using React, so a React library that works with raw JS HTML5 Drag n Drop would also be acceptable
No jQuery
Edit: Updated browser support description, updated JSFiddle to support macOS Firefox.
Related
Recently I've been working on building a tree-view component library for Angular, as ngx-tree.
Problem
Soon after I figured out how to implement a virtual-scroll feature for this library for performance with large data set, and got it to run properly in Firefox, I am trapped by a weird scrolling behavior in Blink-included browsers(like Chromium, Chrome, Opera).
Demo link
Here is the demo plunkr -- https://embed.plnkr.co/xMpmK5EBC46tDKpYFpw8 see Update #1 below
Situation
In Firefox, Edge and IE 11, my library with virtual scroll feature works in expectation with smooth scrolling.
However, in Chrome and Opera, when I scroll to some positions inside the tree-view, the position of the scrollbar(which is the scrollTop property of scroll area) jump up and down, causes a flickering tree-view and break down the virtual-scroll feature.
browser detail version
Chrome - 59.0.3071.115
Firefox - 54.0
Edge - 40.15063.0.0
other browsers
In China, there are some shelled browsers derived from Chromium project(like 360se, QQ browser, Sogou browser, UC browser) with older version of V8 and blink. And they don't have that weird scroll behavior.
Some Assumption
Is it caused by some optimization on the scroll implementation(like smooth scrolling) by the Chromium team?
Hope to get some guides!!! (≧﹏ ≦)
Update #1
Demo link update with event log: https://embed.plnkr.co/GpQBZsguhZZOQWWbZnqI/
One must test the scrolling before opening devtool to see the logs
I have to explain a little more how the virtual-scrolling works and what's causing the flickering.
First, see the design of Virtual Scrolling.
A key point of virtual scrolling is, we create a fake scroll area the same size as that area without virtual scrolling instrumented. So in an optimal situation, the scrollbar position of the scroll area ought not to change until some expected events trigger its changes. For scroll event, we update the view for every animation frame.
Within a height-fixed scrolling area, we assume a truth that the scrollTop property will not change with a large percentage, if we simulate the those unrendered elements' height properly(there could be a bit of deviation for the calculation accuracy) within an animation frame.
However, based on my observed results, the blink-series browsers seems to perform a different strategy to update the scrollTop of the scrollable element. Its timing to update the scrollTop is different than none-blink-series browsers. That all I've figured out so far.
Sample gifs
Here I made some gifs to show the output of Chrome, Firefox, and Edge.
Chrome
Firefox
Edge
You're pulling the library from the virtual-scroll-demo-branch branch:
'ngx-tree': 'https://rawgit.com/e-cloud/ngx-tree/virtual-scroll-demo-branch/src/lib',
That branch is 105 commits behind master. It incorrectly sets margin-top on one of the inner elements. This is fixed in newer versions.
Edit: The developer actually referenced this Stack Overflow question in their commit message.
On this page http://bit.ly/202URGh, when I click on Book Size (Second row icons) and then click on Book type (First row icons), the image collapses into the other div.
I have added clearfix, but that seems to have had no effect. This seems to be a problem only in Safari on Mac. Other browsers work fine.
Can someone help. My problem is compounded because I don't have a Mac to test.
I understood the source of the problem. Issue was because I was trying to get the height of image dynamically. Safari (and webkit based browsers) do not seem to support dynamic height computation. Jquery was returning the height as zero and hence the div was collapsing.
I made a click and drag scrolling Image Viewer here.
It works like a charm in FF and Chrome, but IE is behaving weird. The diagonal movement is jagged, as if the scrolling is slow and every movement is seperately visible.
I'm scrolling the DIV like this (viewPort is a jQuery object).
viewPort[0].scrollTop = newy;
viewPort[0].scrollLeft = newx;
Is anybody able to create a smooth movement in IE9 and IE10?
Edit:
I'm using IE10 on Windows 7. I've seen it working on IE10 on Windows 8.
It is always a good practice, when dealing with mousemove/touchmove, to apply UI changes in a requestAnimationFrame callback. Consider this jsfiddle
I am not sure if this helps, but it is definitely some better approach.
There is event better solution with transforms. You apply for an image position:absolute styles and for the container overflow:hidden and position:relative. After that, you change not the scrollLeft/scrollTop of the container, but translate(Xpx,Ypx) for the image itself.
Chrome used to improperly exclude the scroll bar in its media queries. This means that with 1000px of visible space and a 17px scroll bar, other browsers would report 1017px as a width so far as Media Query is concerned, but webkit browsers (such as Chrome and Safari) did not do this.
These browsers could hit a specific size where a scroll bar would appear in one resolution, then change resolutions to another where it would appear, then it would go back to when it didn't... the solution caused an ugly blank space to appear where the scroll bar should, but it did not. It came out looking like a glitch, and the DOM resize events did not fire properly so it was not something you could react to properly in JS.
However, now in Chrome 29, this appears to have changed. Now they are going off of how the specification works and including the scroll bar in their media query calculations... just like Firefox and Internet Explorer (and how the specification says they should have all along). This fixes the bugs, but causes another problem in that the JS to try to detect the Chrome/Safari issue now will have false positives, because it is not a concern with newer versions of Chrome and I assume eventually Opera and Safari as well.
In light of all of this, I cannot find any information anywhere on when this was fixed in either Chrome or Webkit. I hate having to resort to browser version testing in my JS to work around these flaws, but I am just guessing blindly on Chrome 29+ for the moment as a temporary patch and would love an authoritative answer... I have tested in Safari 6.0.5, but the old method is still being used...
Does anybody know in what version of Chrome and/or Webkit this was fixed?
Chrome is no longer using the webkit engine as of Chrome v. 28 it now uses the Blink Rendering Engine. So no need to be detecting this for chrome unless you need it for previous versions.
For more on Blink: Blink Documnetation
For more on the Release: Next Web Article on Webkit/Blink Switch
I have a horizontally scrolling div with sections inside. I'm using Ariel Flesler's scrollTo plugin to scroll from one section to another.
Please see: http://jsfiddle.net/carienf/qZeEe/
The fiddle works perfectly in IE 9, Safari 5.1, Opera 11.5 and Chrome 14 (all the latest versions). I can click on a link to scroll to the corresponding section and scroll or mousewheel around in it.
Problem:
In Firefox 7 (and earlier), when I have scrolled to Section 2 or Section 3 and then scroll down using the scrollbar, my position is reset to the first section. This also happens when I resize the browser window. If I scroll using the mousewheel, Firefox behaves (in other words, I stay in the current section).
My question is pretty much an exact repeat of this question: Problem mixing overflow-x, FireFox, and Javascript
Only, the accepted answer (which is to allow the horizontal scrollbar to be visible) doesn't work for my specific case. Also, the guy who posted the question has removed his example. I really need that scrollbar to stay hidden and I really don't like the idea of hiding it behind a div.
Is there a way (other than setting overflow to "auto") to stop Firefox from resetting my scroll position? Or some other way to hide the scrollbar?
UPDATE: Updated Firefox to 8.0 (still a beta version) and then the behaviour is consistent with the other browsers.
I can see a couple of options.
clip off the scroll bar. Takes some measuring and you have to position absolutely.
Add a 2nd div outside that does the vertical scrolling. That breaks your code as it currently stands, but it does resolve the scrolling problem. jsfiddle.net/s2YFM
I just ran into the same exact issue. When my "modal window" pops up, I set html.noscroll { overflow: hidden }, which unfortunately causes the window to scroll-to-top.
Here's the only solution I could make work:
function RemoveScrollbar(html) {
var scrollTop = html.scrollTop;
html.addClass('noscroll');
html.scrollTop = scrollTop;
}
This is MooTools code, but super simple to convert to jQuery or other frameworks.