我对了解事件系统有疑问

时间:2019-11-09 15:42:14

标签: javascript node.js vue.js nuxt.js

我有这个代码:

<template>

  <div class="chart"
       v-bind:style="chartStyleObject"
       v-on:mousedown.left="initHandleMousedown($event)"
       v-on:mouseup.left="initHandleMouseup()"
       v-on:mouseout="initHandleMouseup()">

    <div class="chartContent">
    </div>
    <!--   <div class="chartContent">  end   -->

  </div>
  <!--   <div class="chart">   end   -->

</template>

<script>
  import axios from 'axios';

export default{

created () {
},

data () {
  return {
    ticket: null,

    chartStyleObject: {
      width: '500px',
      widthWrapper: '1600px',
      heightWrapper: '500px',
      height: '247px',
      marginTop: '15px',
      marginRight: '0px',
      marginBottom: '0px',
      marginLeft: '15px',
    },

    XCoord: null,
    YCoord: null,

  }
},

methods: {

  initHandleMousedown(event) {
    this.startMousedownXCoord = event.clientX;
    this.startMousedownYCoord = event.clientY;
    this.XCoord = event.clientX;
    this.YCoord = event.clientY;

    console.log('XCoord', this.XCoord);
    console.log('YCoord', this.YCoord);

    window.addEventListener('mousemove', this.initHandleMouseMove);
  },

  initHandleMouseMove(event) {

      this.XCoord = event.clientX;
      this.YCoord = event.clientY;

      console.log('XCoord', this.XCoord);
      console.log('YCoord', this.YCoord);

  },

  initHandleMouseup() {
    window.removeEventListener('mousemove', this.initHandleMouseMove);
  },

  },

}

</script>

<style scoped>

.chart{
  position: relative;
  border-radius: 10px;
  padding: 27px 10px 10px 10px;
  background-color: #45788b;
  box-sizing: border-box;
  cursor: move;
}
.chart .chartContent{
  position: relative;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  margin: 0 0 0 0;
  background-color: #2f2c8b;
}



</style>

HTML design consists of 2 blocks:
(parent and child)
The event is tied to the parent tag `<div class =" chart ">`
Also, the parent block has padding on all 4 sides:

введите сюда описание изображения

如果在不影响填充空间的情况下单击父块并用鼠标驱动(按住按钮),将触发mousemove事件而不会出现问题。 但是,一旦鼠标光标触摸了填充区域,该事件就会停止起作用。
如果单击填充,该事件也将正常运行-但是,如果我将鼠标光标移到填充外部(内部空间)之外的块空间上,该事件将停止工作
问题:
为什么会发生这种情况-对于js + nuxt.js,这种行为是否正常?

2 个答案:

答案 0 :(得分:3)

我无法完全按照您对页面各个区域的描述进行操作,但可以尝试解释一下我认为您看到的内容。

关键在于您拥有一个mouseout侦听器,该侦听器将删除您的mousemove侦听器。 mouseout事件传播,这意味着即使mouseout发生在子元素上,它也会触发。与mouseleave相比,后者仅在事件发生在元素本身上时才会触发。

以下示例说明了mouseout侦听器将如何触发,即使鼠标光标没有离开根元素也是如此。只需将光标移到孩子的外面就可以了。

document.getElementById('outer').addEventListener('mouseout', () => {
  document.getElementById('out').innerHTML += 'mouseout\n'
})
div {
  border: 1px solid;
  display: inline-block;
  padding: 20px;
}
<div id="outer">
  <div></div>
</div>
<pre id="out"></pre>

我怀疑当您观察到该事件不再起作用时,实际上正在发生的是mouseout事件正在发生,并且正在删除mousemove侦听器。

答案 1 :(得分:1)

正确的答案是正确的。我仅提供此答案来说明如何使用您自己的代码。我更改的唯一一行是此v-on:mouseleave="initHandleMouseup()。请注意,我将其从mouseout更改为mouseleave。

总结:

  • mouseleave每个元素被触发一次,无论其子元素如何 徘徊。
  • mouseout每次元素被抛弃时(无论是否 将鼠标移开或将鼠标悬停在其子代上。

new Vue({
  el: "#app",
  template: `

  <div class="chart"
       v-bind:style="chartStyleObject"
       v-on:mousedown.left="initHandleMousedown($event)"
       v-on:mouseup.left="initHandleMouseup()"
       v-on:mouseleave="initHandleMouseup()">

    <div class="chartContent">
    </div>
    <!--   <div class="chartContent">  end   -->

  </div>
  <!--   <div class="chart">   end   -->

`,
  created: function() {},

  data() {
    return {
      ticket: null,

      chartStyleObject: {
        width: '500px',
        widthWrapper: '1600px',
        heightWrapper: '500px',
        height: '247px',
        marginTop: '15px',
        marginRight: '0px',
        marginBottom: '0px',
        marginLeft: '15px',
      },

      XCoord: null,
      YCoord: null,

    }
  },

  methods: {

    initHandleMousedown: function(event) {
      this.startMousedownXCoord = event.clientX;
      this.startMousedownYCoord = event.clientY;
      this.XCoord = event.clientX;
      this.YCoord = event.clientY;

      console.log('XCoord', this.XCoord);
      console.log('YCoord', this.YCoord);

      window.addEventListener('mousemove', this.initHandleMouseMove);
    },

    initHandleMouseMove: function(event) {

      this.XCoord = event.clientX;
      this.YCoord = event.clientY;

      console.log('XCoord', this.XCoord);
      console.log('YCoord', this.YCoord);

    },

    initHandleMouseup: function() {
      window.removeEventListener('mousemove', this.initHandleMouseMove);
    }
  }
});
.chart {
  position: relative;
  border-radius: 10px;
  padding: 27px 10px 10px 10px;
  background-color: #45788b;
  box-sizing: border-box;
  cursor: move;
}

.chart .chartContent {
  position: relative;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  margin: 0 0 0 0;
  background-color: #2f2c8b;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id='app'></div>

要查看mouseout/mouseovermouseenter/mouseleave事件之间的区别,请参见此演示(摘自jQuery documentation):

var i = 0;
$("div.overout")
  .mouseout(function() {
    $("p", this).first().text("mouse out");
    $("p", this).last().text(++i);
  })
  .mouseover(function() {
    $("p", this).first().text("mouse over");
  });

var n = 0;
$("div.enterleave")
  .on("mouseenter", function() {
    $("p", this).first().text("mouse enter");
  })
  .on("mouseleave", function() {
    $("p", this).first().text("mouse leave");
    $("p", this).last().text(++n);
  });
div.out {
  width: 40%;
  height: 120px;
  margin: 0 15px;
  background-color: #d6edfc;
  float: left;
}

div.in {
  width: 60%;
  height: 60%;
  background-color: #fc0;
  margin: 10px auto;
}

p {
  line-height: 1em;
  margin: 0;
  padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="out overout">
  <p>move your mouse</p>
  <div class="in overout">
    <p>move your mouse</p>
    <p>0</p>
  </div>
  <p>0</p>
</div>

<div class="out enterleave">
  <p>move your mouse</p>
  <div class="in enterleave">
    <p>move your mouse</p>
    <p>0</p>
  </div>
  <p>0</p>
</div>