iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 21
0
Modern Web

初學者前端應用30天系列 第 21

[DAY21]vue按鍵監聽應用

  • 分享至 

  • xImage
  •  

我們這次來做簡單的按鍵監聽範例,利用button監聽按鍵,觸發事件,控制div的移動,超出範圍則會重新來過。

step 1

首先先設定好會用到的data和computed。

  data:()=>({
    w:"",
    h:"",
    leftcount:0,
    downcount:0,
    upcount:0,
    rightcount:0,
    detailleft:0,
    detailtop:0,
  }),
  computed:{
      divw(){
          return Math.floor(((this.w-100)/2)-10)
      },
      divh(){
          return Math.floor(((this.h-200)/2)-10)
      }
  },

第二步我們先新增所需的網頁元素,只有2個div和1個button,給他們各自的id樣式。

        <div id="all" >
            <div id="move"></div>
        </div>
        <button id="cc" class="btn btn-dark">
            開始/沒反應再按一次
        </button>

因為button要獲得焦點才能觸發按鍵,所以要再mounted()裡.focus() button。
抓取當前版面的尺寸,再新增2個div的css內容。

  mounted(){
    $("#cc").focus()

    var w = $(window).width();
    var h = $(window).height();
    this.w = w;
    this.h = h;
    $('#all').css({
        position: 'relative',
        width: this.w-100+"px",
        height: this.h-250+"px",
        'background-color': 'black',
        margin:'0 auto'
    });
    $('#move').css({
        position: "relative",
        top:(this.divh)+"px",
        left:(this.divw)+"px",
        width:"10px",
        height:"10px",
        "background-color": "red",
    });
  },

step 2

接著在button寫鍵盤監聽並對應其function,分別監聽w a s d鑑。
監聽程式碼為
v-on:keyup.(鍵盤對應的ascii)="觸發的function"

        <div id="all" >
            <div id="move"></div>
        </div>
        <button id="cc" class="btn btn-dark"
            @keyup.65="left"
            @keyup.83="down"
            @keyup.87="up"
            @keyup.68="right">
            開始/沒反應再按一次
        </button>

之後寫每個鍵盤的function,主要是用if else判斷是否是第一次點擊,若是第一次則會抓取computed的值來修改div的top和left來達到像移動的效果,若是超過一次則會抓取之前修改過的top和left來達到像移動的效果。

  methods:{
      left(){
        this.leftcount +=1
        if(this.leftcount == 1){
            $('#move').css({
                position: "relative",
                top:(this.divh)+"px",
                left:(this.divw-2)+"px",
                width:"10px",
                height:"10px",
                "background-color": "red",
            });
        }else{
            $('#move').css({
                position: "relative",
                top:(this.detailtop)+"px",
                left:(this.detailleft-2)+"px",
                width:"10px",
                height:"10px",
                "background-color": "red",
            });
        }
        this.detailleft = $('#move').position().left;
        this.detailtop = $('#move').position().top;
        $("#cc").focus()
      },
    },

step 3

最後要做是否超出邊界的功能,watch監聽top和left的變動來做出超出邊界後會重新開始的功能。

        detailtop:{
            immediate:false,
            handler(af,be){
                if((af<0)||af>(this.h-250)){
                    alert('超出邊界請重來');
                    setTimeout(function() {
                        window.location.reload()
                    }, 100);
                }
            }
        },
        detailleft:{
            immediate:false,
            handler(af,be){
                if((af<0)||af>(this.w-100)){
                    alert('超出邊界請重來');
                    setTimeout(function() {
                        window.location.reload()
                    }, 100);
                }
            }
        },

以下是全程式碼:

<template>
  <div class="home">
        <div id="all" >
            <div id="move"></div>
        </div>
        <button id="cc" class="btn btn-dark"
            @keyup.65="left"
            @keyup.83="down"
            @keyup.87="up"
            @keyup.68="right">
            開始/沒反應再按一次
        </button>
  </div>
</template>

<script>
// @ is an alias to /src
/*eslint-disable*/
export default {
  name: 'al',
  components: {
  },
  data:()=>({
    w:"",
    h:"",
    leftcount:0,
    downcount:0,
    upcount:0,
    rightcount:0,
    detailleft:0,
    detailtop:0,
  }),
  computed:{
      divw(){
          return Math.floor(((this.w-100)/2)-10)
      },
      divh(){
          return Math.floor(((this.h-200)/2)-10)
      }
  },
  watch:{
        detailtop:{
            immediate:false,
            handler(af,be){
                if((af<0)||af>(this.h-250)){
                    alert('超出邊界請重來');
                    setTimeout(function() {
                        window.location.reload()
                    }, 100);
                }
            }
        },
        detailleft:{
            immediate:false,
            handler(af,be){
                if((af<0)||af>(this.w-100)){
                    alert('超出邊界請重來');
                    setTimeout(function() {
                        window.location.reload()
                    }, 100);
                }
            }
        },
  },
  mounted(){
    $("#cc").focus()

    var w = $(window).width();
    var h = $(window).height();
    this.w = w;
    this.h = h;
    $('#all').css({
        position: 'relative',
        width: this.w-100+"px",
        height: this.h-250+"px",
        'background-color': 'black',
        margin:'0 auto'
    });
    $('#move').css({
        position: "relative",
        top:(this.divh)+"px",
        left:(this.divw)+"px",
        width:"10px",
        height:"10px",
        "background-color": "red",
    });
  },

  methods:{
      left(){
        this.leftcount +=1
        if(this.leftcount == 1){
            $('#move').css({
                position: "relative",
                top:(this.divh)+"px",
                left:(this.divw-2)+"px",
                width:"10px",
                height:"10px",
                "background-color": "red",
            });
        }else{
            $('#move').css({
                position: "relative",
                top:(this.detailtop)+"px",
                left:(this.detailleft-2)+"px",
                width:"10px",
                height:"10px",
                "background-color": "red",
            });
        }
        this.detailleft = $('#move').position().left;
        this.detailtop = $('#move').position().top;
        $("#cc").focus()
      },
      right(){
        this.rightcount +=1
        if(this.rightcount == 1){
            $('#move').css({
                position: "relative",
                top:(this.divh)+"px",
                left:(this.divw+2)+"px",
                width:"10px",
                height:"10px",
                "background-color": "red",
            });
        }else{
            $('#move').css({
                position: "relative",
                top:(this.detailtop)+"px",
                left:(this.detailleft+2)+"px",
                width:"10px",
                height:"10px",
                "background-color": "red",
            });
        }
        this.detailleft = $('#move').position().left;
        this.detailtop = $('#move').position().top;
        $("#cc").focus()
      },
      down(){
        this.downcount +=1
        if(this.downcount == 1){
            $('#move').css({
                position: "relative",
                top:(this.divh+2)+"px",
                left:(this.divw)+"px",
                width:"10px",
                height:"10px",
                "background-color": "red",
            });
        }else{
            $('#move').css({
                position: "relative",
                top:(this.detailtop+2)+"px",
                left:(this.detailleft)+"px",
                width:"10px",
                height:"10px",
                "background-color": "red",
            });
        }
        this.detailleft = $('#move').position().left;
        this.detailtop = $('#move').position().top;
        $("#cc").focus()
      },
      up(){
        this.upcount +=1
        if(this.upcount == 1){
            $('#move').css({
                position: "relative",
                top:(this.divh-2)+"px",
                left:(this.divw)+"px",
                width:"10px",
                height:"10px",
                "background-color": "red",
            });
        }else{
            $('#move').css({
                position: "relative",
                top:(this.detailtop-2)+"px",
                left:(this.detailleft)+"px",
                width:"10px",
                height:"10px",
                "background-color": "red",
            });
        }
        this.detailleft = $('#move').position().left;
        this.detailtop = $('#move').position().top;
        $("#cc").focus()
      },
  }
}
</script>
<style  scoped>
</style>>

上一篇
[DAY20]檔案閱讀器
下一篇
[DAY22] vue-good-table套件(上)
系列文
初學者前端應用30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言