Open mccambridge opened 7 years ago
Firefox and IE both have the same problem of a drag causing selection. The solution I found is just two steps:-
Define the following css class :-
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
const SortableItem = SortableElement(({value,SortableItemClassName}) =>
<li className="noselect">{value}</li>
);
Check both the reproduced problem and its solution by opening the sandbox in Firefox :- https://codesandbox.io/s/G6jPqD9oy
The source of solution is from Overflowstack
@wahabshah It doesn't work in Safari for me.
Here is my solution. Add the special sort start event handler to your sortable container:
const SortableList = SortableContainer(/* your container */);
ReactDOM.render(
<SortableList
items={[]} // your list items
onSortStart={(_, event) => event.preventDefault()} // it does the trick
onSortEnd={() => {}} // your sort end handler
/>,
document.getElementById('app')
);
Unfortunately it doesn't work when the pressDelay
or the distance
option is set.
I insist that this handler must be in react-sortable-hoc by default.
technically these aren't really solutions but more work-arounds. I think the real problem is because the framework decides to copy the element to the bottom of the body and hides the original one instead of actually changing the element. I used react-beautiful-dnd and they don't have these problems (though I have NO IDEA how in hell they get the grabbing cursor (i don't see it anywhere in the dom lol) but it works!
By the way this behavior is completely different on safari. (Just try to do a select all on safari). Safari for some reason selects the background as well as the text this is why there is some weird behavior when using this in safari (even when you use user-select: none)
Adding the user-select:none
style to the SortableItem
stops the user from being able to interact with the item. For example, they may wish to copy the contents. So instead I use the SortableContainers onSortStart
and onSortEnd
to set some state which is then passed into the SortableItem
to set when the class is added.
handleOnSortEnd () {
this.setState({ isSorting: false });
}
handleOnSortStart () {
this.setState({ isSorting: true });
}
const SortableItem = SortableElement(({value}) =>
<li className={ classnames({ "user-select-none": this.state.isSorting }) }>{value}</li>
);
I didn't have any luck with any of the above solutions so I came up with this. @wahabshah was where i started, but I then reversed the thinking. Apply user-select:none to everything but the items that can select. by using the asterisk * and :not() pseudo
*NOTE this will remove text selection form the entire page, for my application this is perfect.
*:not(.noselect){
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
Almost two years passed, and the issue is still there.
I also have this problem. Would be nice with a proper fix for this.
If you want to use pressDelay
or distance
, you could try something like this:
updateBeforeSortStart={() => {
function disableselect() {return false}
document.onselectstart = disableselect;
document.onmousedown = disableselect;
}}
onSortEnd={() => {
document.onselectstart = null;
document.onmousedown = null;
}}
If you want to use pressDelay
and distance
and solution by @denis-lukin did not work for you. You can try something like this:
updateBeforeSortStart={() => {
document.body.classList.add('not-selectable');
}}
onSortEnd={() => {
document.body.classList.remove('not-selectable')
}}
When I drag an item in Safari or IE 11, the text on other areas of the page that my mouse travels by gets selected. It's as if the browser doesn't know I'm dragging but thinks my mouse went down for the purpose of highlighting text on the page.
Great hoc! I definitely appreciate your work! :D