Wrong placement of RadContextMenu and RadTooltip in Chrome 61

7 posts, 0 answers
  1. Telerik Admin
    Telerik Admin avatar
    1696 posts
    Member since:
    Oct 2004

    Posted 21 Sep Link to this post

    Chrome 61 introduced a breaking change that breaks the positioning of the context menu and the tooptip. 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.

    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
                // Check https://bugzilla.mozilla.org/show_bug.cgi?id=189112#c7
                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>


  2. Count
    Count avatar
    1 posts
    Member since:
    Nov 2017

    Posted 02 Nov in reply to Telerik Admin Link to this post

    I had to exclude Edge as follows, or context menu positioning was off:

     

    if ((!$telerik.quirksMode && !$telerik.isSafari && !Telerik.Web.Browser.edge) ||
    (Telerik.Web.Browser.chrome && Telerik.Web.Browser.version >= 61)) {
    canvas = document.documentElement;
    }

     

  3. Dan
    Dan avatar
    131 posts
    Member since:
    Feb 2011

    Posted 07 Nov Link to this post

    I believe we are having a similar problem - seems ok in Chrome at 100% zoom - or if you are scrolled to the top of the page.  At 110% zoom and scrolled down - the tooltip is displayed at an offset by our scroll height.

    We first noticed the problem with AjaxLoading Panels being displayed in the wrong place.  Is this also part of the critical fix?

  4. Rumen
    Admin
    Rumen avatar
    13278 posts

    Posted 10 Nov Link to this post

    Hello,

    I tested the reported behavior with RadTooltip and RadContextMenu and both controls behave properly with the provided fixes.

    Regarding the loading panels, we are not aware of this problem. Can you please provide an example in which we can reproduce the reported problem? You can upload the sample app via a support ticket or a storage service like DropBox.

    Best regards,
    Rumen
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. TRANSEPT
    TRANSEPT avatar
    6 posts
    Member since:
    Oct 2014

    Posted 27 Nov in reply to Telerik Admin Link to this post

    Hi Team, 

    I have same problem , Radcontextmenu on Radgrid , I used chrome 62.

    Using your provided code , it fixed my problem .

    it works fine for chrome , firefox and internet explorer, 

     

    Thanks for your efforts

     

  6. Ken
    Ken avatar
    1 posts
    Member since:
    Oct 2012

    Posted 08 Dec Link to this post

    Hello, thanks for posting the scripts it has helped.  We're seeing some strange behavior on longer pages though. 

    Could you visit the page below and let me know if you are also seeing the same?  

    When the page loads, the menu works fine. Scroll down a few inches and it still works, scroll down a few more inches and it stops working, scroll a few more inches and it works again.

    I'm not seeing this on shorter pages - just on longer ones like this. Is there something in the script(s) that could be modified to handle this? 

    Page: http://www.tms.org/UpcomingMeetings

    Thanks in advance,

    Ken

     

  7. Rumen
    Admin
    Rumen avatar
    13278 posts

    Posted 11 Dec Link to this post

    Hi Ken,

    The problem discussed in this forum sticky is related to RadContextMenu and its position under Chrome, Opera and Edge.

    I examined the provided page and noticed that it features an old version of RadMenu from 2014, but its position and sub-menu position was fine on my end during the whole scrolling. If you experience any troubles with the menu component please open a support ticket and provide a video or screenshots demonstrating the problem.

    Thank you!

    Best regards,
    Rumen
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top