Html 尝试使用 v-on:blur 使上下文菜单消失......但它不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45838800/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 14:52:36  来源:igfitidea点击:

Trying to use v-on:blur for making disappear a context menu...but it doesn't work

htmlvue.jsonblur

提问by Bénédicte Lagouge

I am coding a simple context menu in vue.js. When I do a right click on a peculiar element, it opens the menu (using @contextmenu.prevent).This works.

我在 vue.js 中编写了一个简单的上下文菜单。当我右键单击一个特殊的元素时,它会打开菜单(使用@contextmenu.prevent)。这有效。

But when I click outside of the menu I want it to disappear. This doesn't work... I am using v-on:blur for this, also tried @blur . None of them doesn't work. Here is my html :

但是当我在菜单外单击时,我希望它消失。这不起作用......我为此使用 v-on:blur ,也尝试过 @blur 。它们都不起作用。这是我的 html:

<!-- my context menu -->
<ul class="context-menu"
    ref="contextMenuTrack"
    v-if="openedMenu === 'contextMenuTrack'"
    v-bind:style="{top: top, left: left}"
    v-on:blur="closeMenu()">
    <li v-on:click="removeTrack(project.structure.tracks.indexOf(targetOfMenu));closeMenu()">delete track</li>
</ul>
<div>

    [ ...... stuff here ......]

    <!-- Where the menu is called-->
    <li class="track"
         v-for="track in project.structure.tracks">
        <div class="track-name-row">
            <li @contextmenu.prevent="openContextMenuTrack(track,$event)"
                v-on:click="expandTrack(project.structure.tracks.indexOf(track))"
                class="track-color-viewer"></li>

                [ .... other li tags .....]
        </div>
    </li>

    [ ...... stuff here ......]

</div>

Here is the datas used for the menu of my Vue component:

这是用于我的 Vue 组件菜单的数据:

data() {
    return {
        //the kind of menu which is opened
        openedMenu: undefined,
        //the coordinate of the menu
        top: "0px",
        left: "0px",
        //the element which is targeted by the menu
        targetOfMenu: undefined
    };
},

And here are the methods used for the menu in my Vue.js component :

以下是我的 Vue.js 组件中用于菜单的方法:

 methods: {

    setMenu(top, left) {
        this.top = top - 170 + "px";
        this.left = left + "px";
    },

    // opening menu : calling set menu whith x and y
    openContextMenuTrack(track, event) {
        this.openedMenu = "contextMenuTrack";
        this.targetOfMenu = track;

        this.$nextTick((() => {
            this.$refs.contextMenuTrack.focus();
            this.setMenu(event.y, event.x);
        }).bind(this));
    },

    closeMenu() {
        this.openedMenu = undefined;
        this.targetOfMenu = undefined;
    }
}

回答by Linus Borg

the blurevent only exists for form controls (<input>etc.).

blur事件仅存在于表单控件(<input>等)中。

Your problem is generally solved by creating a custom directive that runs a method when you click outside of the menu.

您的问题通常可以通过创建一个自定义指令来解决,该指令在您单击菜单外部时运行一个方法。

Something like this:

像这样的东西:

https://www.npmjs.com/package/v-click-outside

https://www.npmjs.com/package/v-click-outside

<ul class="context-menu"
    ref="contextMenuTrack"
    v-if="openedMenu === 'contextMenuTrack'"
    v-bind:style="{top: top, left: left}"

    v-click-outside="closeMenu()">

    <li v-on:click="removeTrack(project.structure.tracks.indexOf(targetOfMenu));closeMenu()">delete track</li>
</ul>

Hope this helps

希望这可以帮助

Edit:

编辑:

An example with a better package (vue-clickaway):

一个更好的包的例子(vue-clickaway):

https://jsfiddle.net/Linusborg/hqkgp4hm/

https://jsfiddle.net/Linusborg/hqkgp4hm/

回答by Kaan Kü?üK

This would help if you are looking for unrecommended way ;) $refs would be tricky on having the same result.

如果您正在寻找不推荐的方式,这将有所帮助;) $refs 在获得相同结果时会很棘手。

let x = document.querySelector('.targetClass).addEventListener('click', (e) => 
{
  if(e.target.className == 'targetClass') {
    this.close()
  }
 })

回答by Katinka Hesselink

I just did this on a project:

我刚刚在一个项目中做到了这一点:

  created: function() {
    let self = this;
    window.addEventListener("click", function(e) {
      if (self.$el.querySelector('.targetClass') && !self.$el.querySelector('.targetClass').contains(e.target)) {
        this.close()
      }
    });
  },
  destroyed: function(){
    let self = this;
    window.removeEventListener("click", function(e) {
      if (self.$el.querySelector('.targetClass') && !self.$el.querySelector('.targetClass').contains(e.target)) {
        this.close()
      }
    });
  },