*** Update from 6 June 2018 ***
The problem discussed below has been fixed in R2 2018 (2018.2.516).
*** End of update ***
Chrome 61 introduced a breaking change that breaks the positioning of the context menu and the tooltip. The issue manifests only when the page is scrolled down.
The wrong position (placement) of the context menu affects:
- RadContextMenu of RadGrid
- RadContextMenu and RadMenu used as a context menu
- RadContextMenu in RadTreeView and other controls
- RadCalendar's Popup
- RadTooltip
Details and Resolution:
The positioning problem is due to the following breaking change in Chrome 61 (see full release notes):
To align with the spec and preserve browser consistency, the scrollingElement is now the documentElement in standards mode.
Chrome 61 has changed the behavior of document.scrollingElement to return document.documentElement instead of document.body to match the CSSOM View specification and this broke the positioning of the tooltip and context menu (when the EnableScreenBoundaryDetection is enabled).
The problems with the incorrect positioning of the tooltip and context menu are logged with Critical priority here and here and will be fixed in the next official release.
If you experience it, try the solutions proposed below in all browsers and share your feedback with us.
*** Update from 22 Dec 2017 ***
Since this issue can affect many controls (tooltip, window, loading panel, menu, etc.), a common solution may be to avoid the breaking change in Chrome by changing the scrolling container to a <div> of your own inside the <form and ensuring the higher-level elements do not scroll.
You can find an example at the end of the following KB article: https://www.telerik.com/support/kb/aspnet-ajax/details/incorrect-positioning-of-controls.
*** End of update ***
Solution 1 (for RadContextMenu)
Place the following override above (before) the RadTreeView or standalone RadContextMenu declaration in your project. This works also for a standalone context menu (for example outside of RadTreeView).
*** Updated on 10.5.2017 ***
New override that works for RadCalendar's Popup, RadTooltip, RadGrid's Column resizing and context menus, RadMenu and RadContextMenu:
<script>
$telerik.getViewPortSize =
function
() {
var
width = 0;
var
height = 0;
var
canvas = document.body;
if
((!$telerik.quirksMode && !$telerik.isSafari) ||
(Telerik.Web.Browser.chrome && Telerik.Web.Browser.version >= 61)) {
canvas = document.documentElement;
}
if
(window.innerWidth) {
// Seems there's no completely reliable way to get the viewport size in Gecko, this should be the best one
width = Math.max(document.documentElement.clientWidth, document.body.clientWidth);
height = Math.max(document.documentElement.clientHeight, document.body.clientHeight);
if
(width > window.innerWidth)
width = document.documentElement.clientWidth;
if
(height > window.innerHeight)
height = document.documentElement.clientHeight;
}
else
{
width = canvas.clientWidth;
height = canvas.clientHeight;
}
width += canvas.scrollLeft;
height += canvas.scrollTop;
if
($telerik.isMobileSafari) {
width += window.pageXOffset;
height += window.pageYOffset;
}
return
{ width: width - 6, height: height - 6 };
}
</script>
The old override below should be replaced by the code above.
<script>
Telerik.Web.UI.RadMenu._getViewPortSize =
function
() {
var
viewPortSize = $telerik.getViewPortSize();
// The document scroll is not included in the viewport size
// calculation under FF/quirks and Edge.
var
quirksMode = document.compatMode !=
"CSS1Compat"
;
if
(($telerik.isFirefox && quirksMode) || Telerik.Web.Browser.edge) {
viewPortSize.height += document.body.scrollTop;
viewPortSize.width += document.body.scrollLeft;
}
else
if
(Telerik.Web.Browser.chrome) {
viewPortSize.height += Math.max(document.body.scrollTop, document.scrollingElement.scrollTop);
viewPortSize.width += Math.max(document.body.scrollLeft, document.scrollingElement.scrollLeft);
}
return
viewPortSize;
};
</script>
<telerik:RadTreeView RenderMode=
"Lightweight"
ID=
"RadTreeView2"
runat=
"server"
>
<ContextMenus>
<telerik:RadTreeViewContextMenu ID=
"RadTreeViewContextMenu1"
runat=
"server"
RenderMode=
"Lightweight"
>
<Items>
...
*** End of update ***
Solution 2 (for RadContextMenu)
Set EnableScreenBoundaryDetection to false. This will disable the screen boundary detection and some parts of the context menu could be rendered beneath the browser borders when there isn't enough space to be rendered on the visible screen. You will have to use the browser scrollbars to show the hidden part of the menu.
Solution 3 (for RadTooltip)
Use the _getPosRelativeToMouse override to solve the problem:
<telerik:RadToolTipManager ID=
"RadToolTipManager1"
AutoTooltipify=
"true"
runat=
"server"
>
</telerik:RadToolTipManager>
<script>
Telerik.Web.UI.RadToolTip.prototype._getPosRelativeToMouse =
function
(targetBounds) {
var
elemX = targetBounds.x;
var
elemY = targetBounds.y;
//Get last recorded mouse position
var
pos =
this
._getMousePosition();
var
mouseX = pos.clientX;
var
mouseY = pos.clientY;
//Take into consideration the offsetScroll!
var
standard = $telerik.standardsMode;
//$telerik.standardsMode does not do a good job! Extra check is needed for FF!!
//And yet another check needed for Safari! It should always be set to false in order to get the calculations right
if
(!$telerik.isIE && document.compatMode !=
"CSS1Compat"
) standard =
false
;
else
if
($telerik.isSafari && !(Telerik.Web.Browser.chrome && Telerik.Web.Browser.version >= 61)) standard =
false
;
if
(standard) {
elemX -= $telerik.getCorrectScrollLeft(document.documentElement);
elemY -= document.documentElement.scrollTop;
}
else
//NEW: Add support for quircksmode
{
elemX -= $telerik.getCorrectScrollLeft(document.body);
elemY -= document.body.scrollTop;
}
//Calculate the position of the mouse, relative to the targetcontrol
var
deltaX = mouseX - elemX;
var
deltaY = mouseY - elemY;
return
{ x: deltaX, y: deltaY };
}
</script>