On IOS/Safari the page scroll to top when copying
ygodin opened this issue · 9 comments
OS: iOs 12
Device: iPhone XR, XS (and other)
Browser: Safari
ngx-clipboard version: 12.2.0
Angular version: 7.2.15
When you have scrollable content, if you click the target copy button, the page will scroll to top because of the of the inputElement inputElement.focus();
call that is made within the clearSelection function, looks like the fake text area yPosition is wrong.
I cannot reproduce this on other os/device, works great.
Thank you !
I am also experiencing this with any iOS device.
iOS Chrome scrolls to bottom on copy
I have the same issue on both Chrome and Safari on iOS (tested from 10.1 to 13), on iPhone (tested from 6 to X).
Works fine on other devices/os.
any quick workaround to deal with this problem till @maxisam applies a proper fix?
@ash67 , in the meantime, i've created this directive as a quick fix, using the work of @rproenca in his Clipboard.js
`
import { Directive, Input, Inject, PLATFORM_ID, HostListener, EventEmitter, ElementRef, Output } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
@directive({
selector: '[appCopyToClipboard]'
})
export class CopyToClipboardDirective {
@input() cbContent: string = "";
@output() cbOnSuccess: EventEmitter = new EventEmitter();
private textArea: HTMLTextAreaElement;
constructor(el: ElementRef,
@Inject(PLATFORM_ID) private platformId: Object
) { }
@HostListener('click') onClick() {
if (isPlatformBrowser(this.platformId)) {
this.copy();
this.cbOnSuccess.emit(this.cbContent);
}
}
copy() {
this.createTextArea();
this.selectText();
this.copyToClipboard();
}
isOS() {
return navigator.userAgent.match(/ipad|iphone/i);
}
createTextArea() {
this.textArea = document.createElement('textArea') as HTMLTextAreaElement;
this.textArea.style.position = "absolute";
this.textArea.style.left = "-9999px";
this.textArea.style.top = "-9999px";
this.textArea.readOnly = true;
this.textArea.value = this.cbContent;
document.body.appendChild(this.textArea);
}
selectText() {
var range: Range;
var selection: Selection;
if (this.isOS()) {
range = document.createRange();
range.selectNodeContents(this.textArea);
selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
this.textArea.setSelectionRange(0, 999999);
} else {
this.textArea.select();
}
}
copyToClipboard() {
document.execCommand('copy');
document.body.removeChild(this.textArea);
}
}
`
you can use it like this :
<button appCopyToClipboard [cbContent]="'hello world'" (cbOnSuccess)="isCopyClicked = true">Copy</button>
I'm using "isPlatformBrowser" because I'm using SSR, but you can get ride of it if you want.
any quick workaround to deal with this problem till @maxisam applies a proper fix?
@ash67 , in the meantime, i've created this directive as a quick fix, using the work of @rproenca in his Clipboard.js
`
import { Directive, Input, Inject, PLATFORM_ID, HostListener, EventEmitter, ElementRef, Output } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';@directive({
selector: '[appCopyToClipboard]'
})
export class CopyToClipboardDirective {
@input() cbContent: string = "";
@output() cbOnSuccess: EventEmitter = new EventEmitter();
private textArea: HTMLTextAreaElement;constructor(el: ElementRef, @Inject(PLATFORM_ID) private platformId: Object ) { } @HostListener('click') onClick() { if (isPlatformBrowser(this.platformId)) { this.copy(); this.cbOnSuccess.emit(this.cbContent); } } copy() { this.createTextArea(); this.selectText(); this.copyToClipboard(); } isOS() { return navigator.userAgent.match(/ipad|iphone/i); } createTextArea() { this.textArea = document.createElement('textArea') as HTMLTextAreaElement; this.textArea.style.position = "absolute"; this.textArea.style.left = "-9999px"; this.textArea.style.top = "-9999px"; this.textArea.readOnly = true; this.textArea.value = this.cbContent; document.body.appendChild(this.textArea); } selectText() { var range: Range; var selection: Selection; if (this.isOS()) { range = document.createRange(); range.selectNodeContents(this.textArea); selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); this.textArea.setSelectionRange(0, 999999); } else { this.textArea.select(); } } copyToClipboard() { document.execCommand('copy'); document.body.removeChild(this.textArea); }
}
`you can use it like this :
<button appCopyToClipboard [cbContent]="'hello world'" (cbOnSuccess)="isCopyClicked = true">Copy</button>
I'm using "isPlatformBrowser" because I'm using SSR, but you can get ride of it if you want.
@MarineMarin awesome, thanks for providing the solution. Much appreciated!
@MarineMarin Do you want to create a pull request? thx
@maxisam Is an official fix coming soon? This can create quite a disorienting effect for users. Otherwise tool is great. Glad I found it, was recommended to me by a coworker.
please try 12.2.2. Thanks @nicholasconfer for testing.