2018年12月4日 星期二

vue自訂元件 自訂event

在vue裡自訂元件 除了最常用的props使用
也會需要自訂event 以如同@click般的使用
這部分 只要在元件內使用$emit(event-name)發送
就可以在使用元件時透過 @evnet-name來觸發handler

例 自訂子元件my-component
透過emit發送事件,並同時發送data1,data2資料
this.$emit('event-name',data1,data2)
下是三種可能的使用方式

子元件發送
this.$emit('event-name',data1,data2)

父元件接收方式
1.handler取得發送event時所帶的資料
  若只是設定myHandler 
  取得data1,data2 是來自$emit送出之參數
  <my-component @event-name="myHandler">
  myHandler(data1,data2) {}
  
2.handler取得使用者自帶的資料
  設定handler時為執行myHandler(data1,data2) 
  取得data1,data2 是來自使用時所傳遞之參數
  <my-component @event-name="myHandler(data1,data2)">
  myHandler(data1,data2) {}
  
3.handler取得event帶過來的資料,並帶使用者自訂資料
  event所帶的資料透過$event取得
  <my-component @event-name="myHandler($event,data1,data2)">
  myHandler(evt,data1,data2) {}
  拿到到evt是event帶來的資料,data1,data2是使用者帶的資料

子元件如何判斷是否被使用時設定了event handler
會需要依照 元件被使用時,是否有設定了eventHandler來做後續處理
可透過this.$listeners.[事件名稱]來確認

my-component子元件
this.emit('beforeClick')
this.emit('afterClick)
computed:{
  hasBeforeListener() {
    return this.$listeners && this.$listeners.beforeClick !== undefined
  },
  hasAfterListener() {
    return this.$listeners && this.$listeners.afterClick !== undefined
  }
}
這時候就會
this.hasBeforeListener的結果會是true
this.hasAfterListener的結果會是false

2018年11月25日 星期日

ios上 safari 視窗過度拖拉問題

在iphone上當在操作頁面的拖拉scroll
會造成整個視窗被拖拉上下移動
而讓原本該scroll的內容
在一個同時被拖動的視窗內移動
要修正這問題
需要在container內
對於使用者 touch過度拖拉的問題做修正
在網路上有找到解法
透過偵測touch事件 擋住不該往下繼續傳遞的事件
來讓視窗可以固定

最外層的container 加上scroll設定

 <div id='app' style="position:absolute; overflow:scroll; -webkit-overflow-scrolling: touch; top:0; left:0; bottom:0; right:0">

加上script
<script>
  var overscroll = function(el) {
    el.addEventListener('touchstart', function() {
      var top = el.scrollTop
        , totalScroll = el.scrollHeight
        , currentScroll = top + el.offsetHeight
      if(top === 0) {
        el.scrollTop = 1
      } else if(currentScroll === totalScroll) {
        el.scrollTop = top - 1
      }
    },{passive: false})
    el.addEventListener('touchmove', function(evt) {
      if(el.offsetHeight < el.scrollHeight)
        evt._isScroller = true
    },{passive: false})
  }
  overscroll(document.querySelector('.scroll'));
  document.body.addEventListener('touchmove', function(evt) {
    if(!evt._isScroller) evt.preventDefault()
  },{passive: false})
</script>

解決preventDefault失效問題

Chrome addEventListener 預設passive 為true
用來提升tocuch 與 mouse wheel的效能
但副作用是 他造成preventDefault失效

但如果 是監聽的事件內會用到preventDefault
停止事件的傳遞
必須將 passive 設為true 才有作用
例

document.body.addEventListener('touchmove', function(evt) {

  evt.preventDefault()

},{passive: false})

2018年11月21日 星期三

iphone下使用iframe的問題

記錄一下iphone上的問題
最近遇到一個case需要在parent頁面透過iframe開啟child頁面
child頁面的scroll就出問題了
整理一下幾個問題點


  1. css若position設定為fixed
    會有很多怪現象不要用
  2. iframe內要抓取child頁面的高度
    window.innerHeight會隨內容的多少而增減
    不要使用,改用screen.height取得真正的高度
    再做計算
  3. child頁要使用iscroll需要計算出外框的高度
    在iphone下高度用screen height取得高度後
    必須要扣掉parent 的 footer與header高度
    才會準確

2018年11月14日 星期三

SQL 一次更新多筆資料

一次更新多筆資料
SQL 一直不熟
紀錄一下會用到的語法

INSERT INTO tablename (id,position) VALUES //要更新的欄位一定要包含有pk的欄位

(6878,7),(6879,8),(6880,9) // 送入多筆要更新的資料

ON DUPLICATE KEY UPDATE

id=VALUES(id),position=VALUES(position) 

若要insert的資料值內容為null ,必須將值改成NULL才能插入
否則會出錯
例

INSERT INTO table(column_name) VALUES('null')
改成
INSERT INTO table(column_name) VALUES(NULL)