Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Menus showing up off screen #8

Open
justintilson opened this issue Apr 4, 2019 · 21 comments
Open

Menus showing up off screen #8

justintilson opened this issue Apr 4, 2019 · 21 comments

Comments

@justintilson
Copy link

justintilson commented Apr 4, 2019

I'm trying to get your context menus working in a modal 'window' but they are not displaying where the right click occurs, instead they seem to be hanging off the bottom of the screen. It's not a z-index issue as yours (10000) is way higher than mine (1000). The following screenshot is the best way I can think of to illustrate what is going on:

context-menu-hiding

I'm quite certain I've set up my template as per your instructions.

<template>
  <div>
    <div class="item-wrapper" style="min-height: 500px;">
      <div class="fmgr-folder" v-for="folder in folders">
        <div @contextmenu.prevent.stop="handleClickFolder($event, folder)" class="item-wrapper__item">
          <img src="static/img/file-manager/icon-folder.png" />
          {{ folder.name }}
        </div>
      </div>
      <div class="fmgr-file" v-for="file in files">
        <div @contextmenu.prevent.stop="handleClickFile($event, file)" class="item-wrapper__item">
          <img :src="icon(file)" />
          {{ file.name }}
        </div>
      </div>
    </div>
    <vue-simple-context-menu
      elementId="folder-menu"
      :options="folderOptions()"
      ref="folderContextMenu"
      @optionClicked="optionClicked">
    </vue-simple-context-menu>
    <vue-simple-context-menu
      elementId="file-menu"
      :options="fileOptions()"
      ref="fileContextMenu"
      @optionClicked="optionClicked">
    </vue-simple-context-menu>
  </div>
</template>

CSS is imported and successfully hiding the content of :options

import VueSimpleContextMenu from 'vue-simple-context-menu'
import 'vue-simple-context-menu/dist/vue-simple-context-menu.css'

The showMenu function is being called as expected. Seems like a CSS conflict of some sort.

this.$refs.folderContextMenu.showMenu(event, item)

Any suggestions on where to poke at the CSS?

EDIT: If I manually change the top and left values in Chrome's Inspect window, I'm able to get move the menu on to the screen.

@johndatserakis
Copy link
Owner

Hey there - hmm, yea seems strange as the z-index should be taking care of that. Are you sure the modal component parent has a low z-index set? Maybe it's not set at the root.

The left and top properties are set by the library, dynamically. My guess is that the modal is throwing off the values that the library is getting - like maybe offsetting that by a certain amount.

What modal component are you using? It's tough to get a good idea of what's going on because there could be a lot going on with that. If you can make a simple repro git that demonstrates this issue then I'll dig into it for sure.

I would say - I noticed you have style="min-height: 500px;" set on the item-wrapper. Trying removing that and testing, as maybe that's holding up the process in a weird sorta.

Sorry you're having issues - I'll be standing by.

@justintilson
Copy link
Author

I created a stripped down version of my project and your menu system is working fine in that context. I must have some CSS somewhere that is clobbering the generated top/left coordinates.

My project has taken a different turn where I no longer need context menus. I don't think it makes sense to pour any more time into this rabbit hole. Thx for responding.

@kofiasare
Copy link

Hi @johndatserakis,
I'm having a similar issue as the above. However, the context menu happens to be positioned farther away from the top.

By inspection, I see that "top left" dynamic values (especially the top) assigned to the element are probably huge.

Please see if you can help me out.

Thanks in advance.

Attached is a screenshot of the challenge.
Screen Shot 2019-04-06 at 9 28 07 PM

@johndatserakis
Copy link
Owner

@justintilson - ok hmm yea maybe something was giving it trouble. Hopefully it goes better next time you try to use it.

@kofiasare - Hmm, the user above wasn't able to replicate the issue in a clean project. Are you able to replicate this in a repro project so I can take a look? Sometimes there may be some other css in your project that's causing an issue.

In my use I really have never had the menu not show up in the right spot so it's tough for me to debug the issue. In your screenshot where did you click to show the menu? The top and left values don't seem too large - but it depends on where you clicked of course.

Let me know.

@johndatserakis
Copy link
Owner

Hey @kofiasare - any update or reproduction project I can look at to help out? Thanks

@johndatserakis
Copy link
Owner

Let me know if you continue to have trouble with this - closing for now.

@dnalneh
Copy link

dnalneh commented May 27, 2019

I have the same issue and I think it is because I use a vue-instance only on a part (see red border area) of a web-app. The blue spot is the point I clicked to open the menu.
issue

So the width and height of the left respectively top area is added, but should not.

Maybe use clientX over pageX?
https://stackoverflow.com/questions/6073505/what-is-the-difference-between-screenx-y-clientx-y-and-pagex-y

@johndatserakis
Copy link
Owner

Ok let me look into this - thanks a bunch for the link and catching another example of the issue.

@johndatserakis
Copy link
Owner

Ok so I did some tests using clientX/clientY and I don't think it'll work with the current setup. In reading the stackoverflow post it made a bit of sense - but in practice I don't think it's the right route to take maybe.

Attached are 2 screenshots - one I had my browser full size on my screen, and the second I had the bottom pulled up a bit. As you can see in the second screenshot, the menu is way off. For reference - I clicked right on tip of the J in Jim.

Screen Shot 2019-05-28 at 10 07 01 PM

Screen Shot 2019-05-28 at 10 07 15 PM

I don't think the issue is due to the pageX/pageY use, but rather things like modals or other popups that change the site structure and then throw off the read.

@dnalneh - do you have an example repo where I can dig into this a bit? I haven't been able to reproduce the issue myself so I'd like to have an example to look into.

@dnalneh
Copy link

dnalneh commented May 29, 2019

@johndatserakis
I'm afraid but I'm not allowed to give you some code. I even tried to reproduce it in a simpler example but it works as expected.

This is my current workaround, maybe it will help other people:

       showResultMenu(event, item) {   
                // get left area
                var leftarea = document.getElementById('accordeon_area');

                // overwrite readonly properties pageX and pageY and set correct values
                Object.defineProperty(event, 'pageX', {
                    value: event.pageX - leftarea.clientWidth - 100,
                    writable: true
                });
                Object.defineProperty(event, 'pageY', {
                    value: event.pageY - 50,
                    writable: true
                });
               
                this.$refs.vueSimpleContextMenu1.showMenu(event, item)
            },

@johndatserakis
Copy link
Owner

Ok great - thanks for that. Maybe if we find out what exactly is causing the once-in-a-while issue then we can implement this fix in real time. I'll be keeping an eye on this.

@drewstaylor
Copy link

drewstaylor commented Sep 2, 2019

I have the same issue. The context menu is off-screen, but it seems to be override-able just using one CSS left value with important. I feel it may have to do with the fact my context menus need to popup from a sidebar menu that's already using fixed positioning.

@johndatserakis
Copy link
Owner

johndatserakis commented Sep 23, 2019

Hmm ok I see - thanks for the detail. Maybe the left !important override can help others who come across this.

Sorry to all for this issue. It's been tough to capture it in action. If anyone has a public example of the issue I'm totally down to dive in. It's definitely a tricky one considering the positioning factors. Hopefully the fixes from @dnalneh and @drewstaylor can help in a pinch.

@YoSev
Copy link
Contributor

YoSev commented Jan 18, 2020

I fixed it by forcing fixed positioning:

.vue-simple-context-menu {
  position: fixed !important;
}

Since you are using left with the mouse events x value, the menu is completly out of my screen too

@tomearly
Copy link

It tried

::v-deep .v-context { position: fixed !important; }

That worked for me

@germanllop
Copy link

germanllop commented Apr 10, 2020

I have the same issue, even with position fixed, because my contextmenu is inside a component, when it's rendered, it's offscreen (the component is placed as a right sidebar), if I override it to left: 0: top:0; it's apearing on the top left of the component, not the main screen.

I'm still trying to figure it out, how to get it out of the component, as dymically as it can be.

So far, only @johndatserakis workaround worked for me.

@JustusW
Copy link

JustusW commented May 31, 2020

The issue is with modern style frameworks using padding/margins on components for positioning. Position absolute will position absolute to the parent element (in this case the first element with set positioning) - thus ignoring the flow among its siblings - but not outside the flow of surrounding components.
If you add style="position: fixed; top: 0; left: 0;" on a div surrounding the menu it will work as expected.
I think you should add that in the framework.

@mwleinad
Copy link

Adding position fixed doesn't work if your website scrolls.
Position fixed add the scroll offset in top of the normal offset, so the more you scroll, the bigger the discrepancy with the context menu :(

@coofercat
Copy link

coofercat commented Feb 24, 2021

I too have had this issue. I figured out the problem is CSS related by hacking the menu to open at (0,0). Doing so, the menu appeared in the top left of the right-hand pane in my 2 column design (ie. not in the very top left of the screen).

This then throws off the X/Y calculations, which are based on the entire screen. In other words, the calculation "thinks" the screen is 900px wide (which it is), but position (0,0) is actually about (300,0), so the menu is placed 300px further to the right than it should be.

In my case, my right-hand pane (ie. a container div, probably half a dozen parents up from the context menu) had position: relative on it - using the browser web dev tools it seems to make no difference if I remove it or not - except that the context menu appears in the correct place with it removed. #csssucks ;-)

@SergiyShest
Copy link

SergiyShest commented Jan 31, 2022

Good afternoon.

The shift occurs if the context menu is not located in the visual root.
But if I have several components, each of which uses its own context menu,
then it is much more convenient to place the context menu along with the component.
In this case, the menu starts to be rendered indented from the edge of the component (not from the edge of the window).
I managed to find a solution that helped me and probably will be useful for the simple context menu component in general, especially if this solution is hidden inside the simple context menu.
The essence of the solution is that after the component is rendered, the context menu must be moved to the root.
That is, I add in my component in which I use the context menu:

mounted: function () {
     var menu = document.getElementById(this.contextMenuId);
      document.firstElementChild.appendChild(menu);
  },

In this case, all shifts are counted from document.firstElementChild.
To avoid repetition, I use this.contextMenuId generated randomly.
The code can be viewed at https://github.com/SergiyShest/Vue-tree

@17khba
Copy link

17khba commented Jan 23, 2024

position: fixed only places the element relative to the viewport when no ancestor element has transform, perspective or filter property set.
Reference: Vue teleport

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.