-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pasting in content causes scroll to "jump" before going back to original position #1374
Comments
@jhchen I'm narrowing in on the culprit.... In the onPaste function below the line If I comment out that line the scroll does not jump anymore, but also after pasting in content, the cursor is still at the beginning of the pasted content, and not at the end. onPaste(e) {
if (e.defaultPrevented || !this.quill.isEnabled()) return;
let range = this.quill.getSelection();
let delta = new Delta().retain(range.index);
let scrollTop = this.quill.scrollingContainer.scrollTop;
this.container.focus(); // THIS LINE CAUSES SCROLL JUMPING
setTimeout(() => {
this.quill.selection.update(Quill.sources.SILENT);
delta = delta.concat(this.convert()).delete(range.length);
this.quill.updateContents(delta, Quill.sources.USER);
// range.length contributes to delta.length()
this.quill.setSelection(delta.length() - range.length, Quill.sources.SILENT);
this.quill.scrollingContainer.scrollTop = scrollTop;
this.quill.selection.scrollIntoView();
}, 1);
} |
@jhchen Good news, I fixed it! I think this fix should make it into the next update. Here is the code I added. The code goes into the Clipboard Module. I add code in 2 spots, in the class Clipboard extends Module {
constructor(quill, options) {
super(quill, options);
this.quill.root.addEventListener('paste', this.onPaste.bind(this));
this.container = this.quill.addContainer('ql-clipboard');
// NEW CODE BELOW
this.container.addEventListener('scroll', (e) => {
e.preventDefault();
e.stopPropagation();
if (this.scrollTop) {
this.quill.scrollingContainer.scrollTop = this.scrollTop
}
return false;
});
// END OF NEW CODE
this.container.setAttribute('contenteditable', true);
this.container.setAttribute('tabindex', -1);
this.matchers = [];
CLIPBOARD_CONFIG.concat(this.options.matchers).forEach((pair) => {
this.addMatcher(...pair);
});
} and the onPaste function onPaste(e) {
if (e.defaultPrevented || !this.quill.isEnabled()) return;
let range = this.quill.getSelection();
let delta = new Delta().retain(range.index);
let scrollTop = this.quill.scrollingContainer.scrollTop;
// NEW CODE BELOW... JUST THE ONE LINE
this.scrollTop = scrollTop;
// END OF NEW CODE
this.container.focus();
setTimeout(() => {
this.quill.selection.update(Quill.sources.SILENT);
delta = delta.concat(this.convert()).delete(range.length);
this.quill.updateContents(delta, Quill.sources.USER);
// range.length contributes to delta.length()
this.quill.setSelection(delta.length() - range.length, Quill.sources.SILENT);
this.quill.scrollingContainer.scrollTop = scrollTop;
this.scrollTop = null;
this.quill.selection.scrollIntoView();
}, 1);
} As you can see I added a function to hook into the scroll event of the ql-clipboard element. When the clipboard element is focused, it calls the scroll event... and in the scroll event function I set the scrollingContainer to be the saved scroll position. This works to keep the scroll position stable while pasting. Now, everytime I paste content, the scroll is completely stable. No jumping around or anything of the sort. Please let me know if you see any potential side effects, otherwise I recommend adding this change ASAP as the scroll jumping bug is pretty bad. |
@jhchen Found a solution which does not require scroll position manipulation. The problem is focusing on clipboard which is located below the editor. Hence I absolute positioned the clipboard with height and width 100%, top and left 0 and made its z-index=-1. This would place the clipboard behind the editor ensuring the focus on which does not scroll editor. Apply the below CSS to ql-clipboard
Also remove the scroll position manipulation on the onPaste event.
Please keep me in the loop if this is affecting anything else. Would be happy if the jumping issue is fixed which is persisting from a very long time. |
@deepakjtrigent I just tried this out and it does not solve the issue on mobile devices... And if you comment out the scroll position manipulation the scroll position jumps to a random spot on mobile. If we keep the scroll position manipulation the scroll position jumps real quick and then return to the scroll position on mobile. |
@sferoze Ok. I had just tried it on desktop, not on mobile. |
@sferoze thank you for digging into this and apologies for the delay. The volume of issues and notifications from random people poking on the internet unfortunately is such that that legitimate ones overlooked. I tried out your suggested code and the jumping still persists on an iPad running Safari 10. Is it consistently working for you? |
@jhchen no it is not working on mobile for me. The code I added does fix for desktop but does not fully fix the issue on mobile. Thanks! |
I don't have any new ideas on how to fix this on mobile. The two approaches are generally to avoid the flicker (which I don't think is possible at the moment) or to correct for it. The latter is the current approach but for whatever reason desktop browser it is not noticeable (perhaps performance). |
There is a way to prevent the flicker on desktop. I still notice the flicker on desktop with the current version of Quill. I have to use my own custom edited version with this code added to the contructor of Clipboard module _this.container.addEventListener('focus', function (e) {
e.preventDefault();
e.stopPropagation();
if (_this.scrollTop) {
_this.quill.scrollingContainer.scrollTop = _this.scrollTop;
}
return false;
});
_this.container.addEventListener('scroll', function (e) {
e.preventDefault();
e.stopPropagation();
if (_this.scrollTop) {
_this.quill.scrollingContainer.scrollTop = _this.scrollTop;
}
return false;
}); _this.scrollTop is the saved scrolltop position from the onpaste function. If you add this code it will improve stability of quill on paste. |
Hi there, What is the status of this issue? Do you think a fix for desktop could reach next version even if no satisfying one for mobile found? Thanks |
In 1.3.0, I fixed this on both desktop (Safari 10, macOS 10.12) and mobile (Safari, iOS 10.3) by modifying the Clipboard module's
Immediately prior to this:
Which makes sure the paste destination is both in view ( |
TLDR: No proposed solution seems to work better than the current one so this is still an open issue. Quill's paste works by adding a paste listener and shifting focus to another contenteditable container before the paste happens, and shifting focus back to the real editor after paste. The pasted content is then analyzed and inserted into Quill through standard APIs. This has two benefits:
The focus back onto Quill causes it to scroll to the top. You can try in this demo: https://jsfiddle.net/p2pgrxdc/. Scroll the blue div down and paste some text into it. Observe it scrolls to the top. I am unaware of any way to prevent this. If there is a way that would be key to solving this issue. So instead what Quill does is save the scroll position before the focus and restores it after. This causes a flicker on slower devices, like mobile. Personally on desktop I do not see any flicker but in theory this is perhaps I use a faster machine. Nevertheless for this reason it does for me make this issue harder to debug so I can only read the code and reason about it. Unless I am misunderstanding the code, the suggestions by @sferoze still save and restore scroll positions and would still induce the flicker. Indeed this would explain why it still manifests on mobile. The preventDefaults do not appear to do anything but I may be missing something here. Otherwise, because the flicker is so fast on desktop to a point it is indiscernible on many environments, I would be reluctant in this situation to make core changes based off anecdotal suggestions alone. |
The preventDefaults might not be doing anything but...
aren't these even listeners earlier hooks to restore scroll? For me, the scroll jumps on desktop with original Quill, but when I added those lines there is no jumping on desktop |
Hmm @sferoze can you try to place the line setTimeout(() => {
this.quill.scrollingContainer.scrollTop = scrollTop;
delta = delta.concat(this.convert()).delete(range.length);
this.quill.updateContents(delta, Quill.sources.USER);
// range.length contributes to delta.length()
this.quill.setSelection(delta.length() - range.length, Quill.sources.SILENT);
this.quill.focus();
}, 1); I believe this would make the restore run as soon as it possibly can. |
I tried saving the scroll position in the setTimeout like you mentioned, instead of right before it. No difference on desktop, but on mobile the jump is still visible. Saving the scroll position in the setTimeout actually makes the mobile jump a bit worse. So for now my custom fix remains the same. I also tried @ValueBerry css fix and it does not work on mobile in my testing on iOS 10.3 still an open issue, and for now the code I posted in my testing does the best job of fixing destop, and making mobile jump as small as possible. |
@jhchen why can we not set the scrolling container to $(window).scrollTop() always returns the proper scroll. on chrome on mac different browsers put the scroll on but |
Not sure what this means. Quill also does not use jQuery and cannot add it as a project dependency but now sure if the above misunderstanding would have clarified this example |
Ah let me clarify https://quilljs.com/docs/configuration/#scrollingcontainer For the scrolling container option:
I was hoping to be able to pass |
Not sure window is a DOM element but it is not the entity that has the scrollbars. |
how about the status of this issue? It is a big defect. |
For me all problems with scroll jumps were gone, after I had set |
Another workaround. I added |
@DmitrySkripkin Can you elaborate on your solution? Not sure I understand the adding |
Hello everyone! I`ve had a "scroll jump" problem when i select a text with more of two paragraphs in mobile devices, android and IOS. I tried configuring "scrollingContainer" but not works. Any one have ideas for this solution? |
doesn't work for me. |
I set scrollingContainer to
it fixed the problem for me. try it out. |
现在我解决了这个问题: Now I've solved the problem: |
@attacking do as you mentioned above, it really works! many thanks! |
this is how i fixed my problem: after: I don't know why, but seems like a css problem |
Glad to help you |
@change will make error. So scroll to top was not run in clipboard paste event. |
Following is my solution.
|
All you need to do was unset the outside container's overflow and change your container height. .quillWrapper {
overflow: unset !important;
height: 500px !important;
}
.ql-container {
height: 450px !important;
} |
this work for me !!! |
This works me either. |
Hi why when i undo the scrollbar wont scroll to the position where the text should be undo, with auto height, instead if i set a height for ql-editor it will scroll to the position when undo occurs? |
For me, it did not work until I added !important to the css, so now it looks like this:
|
This works. Thankyou Edit: This works for the scroll jump issue, but introduces a new issue with respect to the styling of the pasted content. @ArsalanSavand |
and where did you set this? |
thanks a lot! this worked for me :) |
In my case setting 'position: fixed !important;' fixes the issue only in Firefox
But this setup by nabinbhusal80 works fine both in Firefox and Chromium:
|
@deepakjtrigent I found an issue when I implemented the below changes:
If some text has been selected in the editor and we try to paste some text to replace with the selected text. Some of the text is missing when I pasted the new text. Depending on the number of characters in the old text. Quill.Issue.mp4 |
this fixed my problem
|
wow! this works fine!!!! thanks!! |
Quill 2.0 has been released (announcement post) with many changes and fixes. If this is still an issue please create a new issue after reviewing our updated Contributing guide 🙏 |
The Quill editor I am using auto grows as the user types. I also have multiple notes (Quill editors) on the screen at a time. I am using the scrollingContainer option correctly.
After pasting in content, Quill does resume the original scroll position but only after the screen flickers a bit. (This is because the scroll jumps to another location and then it set back right away, which causes the screen to "jump" or "flicker")
On mobile it is even worse, as the jump it very noticeable.
So the original scroll position is resumed but it looks very janky. Users will feel like the app is not solid with this side effect. Any advice on how to prevent this?
Steps for Reproduction
Expected behavior:
When pasting in content, there should be no flicker, jumping, flashes or what not. It should be stable and just accept the content like pasting in Word, or any other text editing program.
Actual behavior:
The screen jumps or flashes when pasting in content, but after it resumes its original scroll position. The issue here is the flash or jump which makes the app feel janky.
Platforms:
Chrome and Safari
Version:
1.2.2
The text was updated successfully, but these errors were encountered: