preventSelect: true breaks IE 11 text selection
Closed this issue · 6 comments
Under IE 11 (tested 11.0.9600), executing $(document).contextmenu( { preventSelect: true } )
breaks all text input controls (e.g. <input type="text" />
or <textarea></textarea>
) anywhere on the page, such that you can no longer drag the mouse to select anything in them (you can still click into them to type, but selection is broken), and persists from then on. Note that this happens as soon as the context menu is created by the above statement --- you do not need to actually open the context menu.
This behaviour is IE-only; Chrome & Firefox are fine. It took me ages to realise that the context menu was causing this, and track down the cause!
This was caused because the mandatory delegate
option was ommitted. Some browsers seem to interpret this as 'match all'. (I will add a check for this with the next release.)
The preventSelect
option then applied users-select: none
to the delegate selector.
Thank you again for answering!
(BTW, if delegate
is that mandatory, you might look at some of your documentation examples and put it in, because it's not there in most examples.)
In that case, I think I need some clarification on what to set your delegate
to. I am using an external framework with its own objects. It raises an event like itsObject.onContextMenu()
to which I can attach a handler, and in that handler I create & open your context menu programmatically (so the context menu has autotrigger: false
). I don't really have an HTML element on which I could place, say, a CSS class. I use $(document).contextmenu()
to create & open your menu.
So should I set perhaps delegate: 'body'
? And that will mean that, in IE 11 at least, it will not permanently block selections in all input controls?
OK, I have now played with delegate
when preventSelect: true
, and seen what you are doing to the page. It's complicated.
First, I think you should be aware of different behaviours under different browsers. I have a page body
, and it has a textarea
as a descendent. I have tried setting delegate: 'body'
and delegate: '#idTextArea'
. (These are not the right things as triggers of my context menu, but it exemplifies behaviour of user-select: none
.)
- Under Chrome, neither has any effect at all on selection in the textarea.
- Under IE11 they both block selection in textarea.
- Under Firefox,
textarea user-select: none
blocks textarea selection butbody user-select: none
does not block descendent textarea, despite Moz docs claiming it applies to sub-elements.
That explains why IE was blocking when the others were not.
That raises two questions:
-
Just what precisely do you want us to use
preventSelect: true
, which isuser-select: none
, for? Your docs state "Prevent accidental text selection of potential menu targets on doubleclick or drag", but that's not clear at all to me. I was using it because the element a user can right-click on can also be dragged; but I certainly don't want to block text selection inside it as per IE 11's behaviour. It seems I had just better not usepreventSelect: true
at all.... -
Now I understand the relationship between
delegate
&preventSelect
. However, doesdelegate
have any effect whenpreventSelect: false
? If so, precisely what? If you also read my previous post, if I am not sure what was right-clicked for the context menu what do you want me to setdelegate
to, because nowbody
looks dangerous....
Many thanks for your attention. I do hope this is of use to you too, and you don't take my comments as complaining!
Many thanks for your attention. I do hope this is of use to you too, and you don't take my comments as complaining!
Sure, I appreciate any kind of constructive feedback.
(BTW, if delegate is that mandatory, you might look at some of your documentation examples and put it in, because it's not there in most examples.)
Hmm, I thought I did that in most examples (only replacing with "..." where the advanced examples are focused on event handlers, for example). Which samples are you referring to?
Btw. If you think you can improve the Wiki: feel free to edit.
OK, I have now played with delegate when preventSelect: true, and seen what you are doing to the page. It's complicated.
Hopefully not ;) Let's forget about 'preventSelect' for now.
This plugin is based implemented as jQuery plugin, so we need this call syntax:
$("selector").contextmenu({...});
The selector defines the top/root element, where the context menu is attached to and listens for contextmenu
events.
This is may be the id of a container div. If you want menus for elements on the whole page, use document
or body
.
The plugin uses event delegation to catch events.
The delegate
option decides which elements can trigger a menu (other event targets are ignored).
Note that even if you open the menu programmatically, this is done by triggering a contextmenu
event on the target element. This element must be matched by the delegate
selector, otherwise it would be ignored.
I don't really have an HTML element
I think you probably have one, since you are passing it to contextmenu("open", ...)
?
Just what precisely do you want us to use preventSelect: true, which is
user-select: none
, for?
This is just a convenience feature and off by default. Right clicking on a span with text sometimes selects the word. Often we don't want this, so user-select: none
helps.
If you don't need that, don't set this option (especially if your delegate selector includes text inputs).
I don't really have an HTML element
I think you probably have one, since you are passing it to contextmenu("open", ...) ?
No, I don't! That is why I wrote that I am using $(document).contextmenu(...)
! And it is precisely because I am using document
that we have discovered all my text input controls anywhere on the page (under IE 11, which truly inherits the user-select: none
down the whole hierarchy) were getting blocked by the preventSelect: true
.
I agree that I do not need the preventSelect: true
, and now that I have removed it all is much better.
All that then leaves is --- assuming we are not using preventSelect
--- what precisely is the effect of the delegate
? I see that when the context menu is created you inject a class
onto the element (but without preventSelect
you do not inject the style: user-select: none
). Does that class have any effect/visuals (if it's placed on an element rather than the document)? Do you do anything other than that?
For example, at present my code does not even create the context menu (and then immediately open it) until the framework reports a right-click to me, whereas you normally expect the context menu to have been created in advance; so mine will not get any styling/behaviour before the first right-click. It also means I execute the create multiple times. You may not like that. I'm thinking I ought go change code to create all my context menus at document ready time instead of at click time....
Also, I don't get the distinction between the element contextmenu()
is called on versus the delegate
. Suppose:
$('#element_1').contextmenu( { delegate: '#element_2' } )
What happens/is done to/styled to element_1
and what happens to element_2
?