2017-09-30 15 views
0

私はCordovaアプリを開発しています。そのために私はバインディングとスクリプトにVue.jsとjQueryを使用しています。私は自分でUIを開発しています。私はラジオボタンやチェックボックスなどのほとんどのUIのページ遷移やアニメーションを行うことができましたが、カスタムポップオーバーを開発することはできませんでした。私は次のコードを試しました。外部をクリックしたときにカスタムポップオーバーを閉じるにはどうすればよいですか?

Vue.directive('popover', { 
 
    bind: function(el, bindings, vnode) { 
 
     $(el).click(function() { 
 
      var pageEl = $(this).closest('.ui-page'); 
 
      pageEl.find('.drawer').toggleClass('active'); 
 

 
      $(el).closest('.ui-page').click(function(e) { 
 
//    $('.drawer', this).removeClass('active'); 
 
      }); 
 
     }); 
 
    } 
 
}) 
 

 
var pageInstace = new Vue({ 
 
    el: '#popover-page', 
 
    data: { 
 
     options: [1, 2, 3, 4, 5] 
 
    } 
 
})
html, 
 
body { 
 
    position: relative; 
 
    width: 100%; 
 
    height: 100%; 
 
} 
 

 
body { 
 
    font-family: 'Open Sans'; 
 
    font-size: 16px; 
 
    margin: 0; 
 
    overflow: hidden; 
 
} 
 

 
* { 
 
    box-sizing: border-box; 
 
} 
 

 
*, *:active, *:hover, *:focus { 
 
\t outline: 0; 
 
} 
 

 
button { 
 
    padding: 0; 
 
} 
 

 
img { 
 
    max-width: 100%; 
 
} 
 

 
.ui-page, 
 
.header, 
 
.scroll-content { 
 
    position: absolute; 
 
    width: 100%; 
 
    top: 0; 
 
    left: 0; 
 
    overflow: hidden; 
 
} 
 

 
.ui-page { 
 
    height: 100%; 
 
    background-color: #fff; 
 
} 
 

 
.page-content { 
 
    position: relative; 
 
    height: 100%; 
 
    overflow-y: auto; 
 
    z-index: 1; 
 
} 
 

 
.header { 
 
    height: 54px; 
 
    box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.12), 0 1px 8px 0 rgba(0, 0, 0, 0.2); 
 
    background-color: #607D8B; 
 
    color: #fff; 
 
    display: flex; 
 
    align-items: center; 
 
    padding-left: 16px; 
 
    padding-right: 16px; 
 
    z-index: 1; 
 
} 
 

 
.scroll-content { 
 
    bottom: 0; 
 
    overflow: auto; 
 
} 
 

 
.scroll-content.has-header { 
 
    top: 54px; 
 
} 
 

 
.header button { 
 
    color: #fff; 
 
    height: 100%; 
 
} 
 

 
.header .header-title { 
 
    margin: 0 22px; 
 
    font-size: 18px; 
 
    font-weight: 600; 
 
    width: 100%; 
 
    white-space: nowrap; 
 
    text-overflow: ellipsis; 
 
    overflow: hidden; 
 
} 
 

 
.header .buttons { 
 
    position: relative; 
 
    display: flex; 
 
} 
 

 
.header .buttons button { 
 
    padding: 4px 8px; 
 
} 
 

 
.header .buttons button:last-child { 
 
    padding: 4px 0 4px 8px; 
 
} 
 

 
.btn { 
 
    position: relative; 
 
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); 
 
    border: none; 
 
    padding: 8px 16px; 
 
    font-size: 16px; 
 
    border-radius: 4px; 
 
    font-family: unset; 
 
    overflow: hidden; 
 
} 
 

 
.btn-clear { 
 
    background-color: transparent; 
 
    border: none; 
 
} 
 

 
.item { 
 
    position: relative; 
 
    display: flex; 
 
    overflow: hidden; 
 
    border-bottom: 1px solid #bdbdbd; 
 
} 
 

 
.drawer { 
 
    position: absolute; 
 
    background-color: #fff; 
 
    z-index: 4; 
 
    top: 60px; 
 
    right: 4px; 
 
    border-radius: 2px; 
 
    box-shadow: 0px 2px 8px 2px rgba(0, 0, 0, 0.4); 
 
    transform: scale(0, 0); 
 
    transform-origin: top right; 
 
    transition: transform ease 0.3s; 
 
    min-width: 180px; 
 
} 
 

 
.drawer.active { 
 
    transform: scale(1, 1); 
 
} 
 

 
.drawer .drawer-content { 
 
    position: relative; 
 
    padding: 4px 0; 
 
} 
 

 
.drawer .drawer-content:after { 
 
    content: ''; 
 
    position: absolute; 
 
    border: 8px solid transparent; 
 
    border-bottom-color: #fff; 
 
    top: -14px; 
 
    right: 22px; 
 
} 
 

 
.drawer .item { 
 
    padding: 12px 16px; 
 
    font-size: 14px; 
 
} 
 

 
.drawer .item:last-child { 
 
    border-bottom: none; 
 
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script> 
 

 
<div class="ui-page" id="popover-page"> 
 
    <div class="page-content"> 
 
     <div class="header"> 
 
      <div class="header-title"> 
 
       Page Title 
 
      </div> 
 
      <button class="btn-clear" v-popover>Popover</button> 
 
     </div> 
 
     <div class="drawer"> 
 
      <div class="drawer-content"> 
 
       <div class="item" v-for="option in options">{{ option }}</div> 
 
      </div> 
 
     </div> 
 
     <div class="scroll-content has-header"> 
 
      <div class="page-content"> 
 
       <p>Some Content</p> 
 
      </div> 
 
     </div> 
 
    </div> 
 
</div>

これは、ボタンのクリックでポップオーバーを切り替えるため正常に動作します。私はそんなに試しました。しかし、ポップオーバーの外側をクリックするとポップオーバーを隠すことができませんでした。

サイドバーをクリックしたときにポップオーバーを非表示にするにはどうすればよいですか?

+0

https://jsfiddle.net/1u1n5g3y/ – Harish

答えて

1

これを試してください。私はjQueryの

$('body').click(function(e) { 
    if (!$(e.target).closest('.drawer').length){ 
    $(".drawer").removeClass("active"); 
    } 
}); 

$('body').click(function(e) { 
 
    if (!$(e.target).closest('.drawer').length){ 
 
     $(".drawer").removeClass("active"); 
 
    } 
 
}); 
 

 
Vue.directive('popover', { 
 
    bind: function(el, bindings, vnode) { 
 
     $(el).click(function(e) { 
 
      e.stopPropagation(); 
 
      var pageEl = $(this).closest('.ui-page'); 
 
      pageEl.find('.drawer').toggleClass('active'); 
 

 
      $(el).closest('.ui-page').click(function(e) {     
 
//    $('.drawer', this).removeClass('active'); 
 
      }); 
 
     }); 
 
    } 
 
}) 
 

 
var pageInstace = new Vue({ 
 
    el: '#popover-page', 
 
    data: { 
 
     options: [1, 2, 3, 4, 5] 
 
    } 
 
})
html, 
 
body { 
 
    position: relative; 
 
    width: 100%; 
 
    height: 100%; 
 
} 
 

 
body { 
 
    font-family: 'Open Sans'; 
 
    font-size: 16px; 
 
    margin: 0; 
 
    overflow: hidden; 
 
} 
 

 
* { 
 
    box-sizing: border-box; 
 
} 
 

 
*, *:active, *:hover, *:focus { 
 
\t outline: 0; 
 
} 
 

 
button { 
 
    padding: 0; 
 
} 
 

 
img { 
 
    max-width: 100%; 
 
} 
 

 
.ui-page, 
 
.header, 
 
.scroll-content { 
 
    position: absolute; 
 
    width: 100%; 
 
    top: 0; 
 
    left: 0; 
 
    overflow: hidden; 
 
} 
 

 
.ui-page { 
 
    height: 100%; 
 
    background-color: #fff; 
 
} 
 

 
.page-content { 
 
    position: relative; 
 
    height: 100%; 
 
    overflow-y: auto; 
 
    z-index: 1; 
 
} 
 

 
.header { 
 
    height: 54px; 
 
    box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.12), 0 1px 8px 0 rgba(0, 0, 0, 0.2); 
 
    background-color: #607D8B; 
 
    color: #fff; 
 
    display: flex; 
 
    align-items: center; 
 
    padding-left: 16px; 
 
    padding-right: 16px; 
 
    z-index: 1; 
 
} 
 

 
.scroll-content { 
 
    bottom: 0; 
 
    overflow: auto; 
 
} 
 

 
.scroll-content.has-header { 
 
    top: 54px; 
 
} 
 

 
.header button { 
 
    color: #fff; 
 
    height: 100%; 
 
} 
 

 
.header .header-title { 
 
    margin: 0 22px; 
 
    font-size: 18px; 
 
    font-weight: 600; 
 
    width: 100%; 
 
    white-space: nowrap; 
 
    text-overflow: ellipsis; 
 
    overflow: hidden; 
 
} 
 

 
.header .buttons { 
 
    position: relative; 
 
    display: flex; 
 
} 
 

 
.header .buttons button { 
 
    padding: 4px 8px; 
 
} 
 

 
.header .buttons button:last-child { 
 
    padding: 4px 0 4px 8px; 
 
} 
 

 
.btn { 
 
    position: relative; 
 
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); 
 
    border: none; 
 
    padding: 8px 16px; 
 
    font-size: 16px; 
 
    border-radius: 4px; 
 
    font-family: unset; 
 
    overflow: hidden; 
 
} 
 

 
.btn-clear { 
 
    background-color: transparent; 
 
    border: none; 
 
} 
 

 
.item { 
 
    position: relative; 
 
    display: flex; 
 
    overflow: hidden; 
 
    border-bottom: 1px solid #bdbdbd; 
 
} 
 

 
.drawer { 
 
    position: absolute; 
 
    background-color: #fff; 
 
    z-index: 4; 
 
    top: 60px; 
 
    right: 4px; 
 
    border-radius: 2px; 
 
    box-shadow: 0px 2px 8px 2px rgba(0, 0, 0, 0.4); 
 
    transform: scale(0, 0); 
 
    transform-origin: top right; 
 
    transition: transform ease 0.3s; 
 
    min-width: 180px; 
 
} 
 

 
.drawer.active { 
 
    transform: scale(1, 1); 
 
} 
 

 
.drawer .drawer-content { 
 
    position: relative; 
 
    padding: 4px 0; 
 
} 
 

 
.drawer .drawer-content:after { 
 
    content: ''; 
 
    position: absolute; 
 
    border: 8px solid transparent; 
 
    border-bottom-color: #fff; 
 
    top: -14px; 
 
    right: 22px; 
 
} 
 

 
.drawer .item { 
 
    padding: 12px 16px; 
 
    font-size: 14px; 
 
} 
 

 
.drawer .item:last-child { 
 
    border-bottom: none; 
 
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script> 
 

 
<div class="ui-page" id="popover-page"> 
 
    <div class="page-content"> 
 
     <div class="header"> 
 
      <div class="header-title"> 
 
       Page Title 
 
      </div> 
 
      <button class="btn-clear" v-popover>Popover</button> 
 
     </div> 
 
     <div class="drawer"> 
 
      <div class="drawer-content"> 
 
       <div class="item" v-for="option in options">{{ option }}</div> 
 
      </div> 
 
     </div> 
 
     <div class="scroll-content has-header"> 
 
      <div class="page-content"> 
 
       <p>Some Content</p> 
 
      </div> 
 
     </div> 
 
    </div> 
 
</div>

+0

ありがとう@ankitaを追加しました。私はそれを試してみます。 – Harish

+0

@ハリッシュ、大歓迎.... –

+0

@ハリッシュこの回答が役に立ったら、それを受け入れてください。 –

1

Vue.directive('popover', { 
 
    bind: function(el, bindings, vnode) { 
 
     
 
     $(el).click(function() { 
 
      $(el).closest('.ui-page').find('.drawer').toggleClass('active');   
 
     }); 
 
     $('body').on('click', $(el).closest('.ui-page'), function(e) { 
 
      var $drawer = $(el).closest('.ui-page').find('.drawer'); 
 
      var $target = $(e.target); 
 

 
      if ($target.closest($(el)).length <= 0 
 
       && $drawer.hasClass('active') 
 
       && $target.closest('.drawer').length <= 0) { 
 
       $drawer.removeClass('active'); 
 
      } 
 
     }); 
 
    } 
 
}) 
 

 
var pageInstace = new Vue({ 
 
    el: '#popover-page', 
 
    data: { 
 
     options: [1, 2, 3, 4, 5] 
 
    } 
 
})
html, 
 
body { 
 
    position: relative; 
 
    width: 100%; 
 
    height: 100%; 
 
} 
 

 
body { 
 
    font-family: 'Open Sans'; 
 
    font-size: 16px; 
 
    margin: 0; 
 
    overflow: hidden; 
 
} 
 

 
* { 
 
    box-sizing: border-box; 
 
} 
 

 
*, *:active, *:hover, *:focus { 
 
\t outline: 0; 
 
} 
 

 
button { 
 
    padding: 0; 
 
} 
 

 
img { 
 
    max-width: 100%; 
 
} 
 

 
.ui-page, 
 
.header, 
 
.scroll-content { 
 
    position: absolute; 
 
    width: 100%; 
 
    top: 0; 
 
    left: 0; 
 
    overflow: hidden; 
 
} 
 

 
.ui-page { 
 
    height: 100%; 
 
    background-color: #fff; 
 
} 
 

 
.page-content { 
 
    position: relative; 
 
    height: 100%; 
 
    overflow-y: auto; 
 
    z-index: 1; 
 
} 
 

 
.header { 
 
    height: 54px; 
 
    box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.12), 0 1px 8px 0 rgba(0, 0, 0, 0.2); 
 
    background-color: #607D8B; 
 
    color: #fff; 
 
    display: flex; 
 
    align-items: center; 
 
    padding-left: 16px; 
 
    padding-right: 16px; 
 
    z-index: 1; 
 
} 
 

 
.scroll-content { 
 
    bottom: 0; 
 
    overflow: auto; 
 
} 
 

 
.scroll-content.has-header { 
 
    top: 54px; 
 
} 
 

 
.header button { 
 
    color: #fff; 
 
    height: 100%; 
 
} 
 

 
.header .header-title { 
 
    margin: 0 22px; 
 
    font-size: 18px; 
 
    font-weight: 600; 
 
    width: 100%; 
 
    white-space: nowrap; 
 
    text-overflow: ellipsis; 
 
    overflow: hidden; 
 
} 
 

 
.header .buttons { 
 
    position: relative; 
 
    display: flex; 
 
} 
 

 
.header .buttons button { 
 
    padding: 4px 8px; 
 
} 
 

 
.header .buttons button:last-child { 
 
    padding: 4px 0 4px 8px; 
 
} 
 

 
.btn { 
 
    position: relative; 
 
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); 
 
    border: none; 
 
    padding: 8px 16px; 
 
    font-size: 16px; 
 
    border-radius: 4px; 
 
    font-family: unset; 
 
    overflow: hidden; 
 
} 
 

 
.btn-clear { 
 
    background-color: transparent; 
 
    border: none; 
 
} 
 

 
.item { 
 
    position: relative; 
 
    display: flex; 
 
    overflow: hidden; 
 
    border-bottom: 1px solid #bdbdbd; 
 
} 
 

 
.drawer { 
 
    position: absolute; 
 
    background-color: #fff; 
 
    z-index: 4; 
 
    top: 60px; 
 
    right: 4px; 
 
    border-radius: 2px; 
 
    box-shadow: 0px 2px 8px 2px rgba(0, 0, 0, 0.4); 
 
    transform: scale(0, 0); 
 
    transform-origin: top right; 
 
    transition: transform ease 0.3s; 
 
    min-width: 180px; 
 
} 
 

 
.drawer.active { 
 
    transform: scale(1, 1); 
 
} 
 

 
.drawer .drawer-content { 
 
    position: relative; 
 
    padding: 4px 0; 
 
} 
 

 
.drawer .drawer-content:after { 
 
    content: ''; 
 
    position: absolute; 
 
    border: 8px solid transparent; 
 
    border-bottom-color: #fff; 
 
    top: -14px; 
 
    right: 22px; 
 
} 
 

 
.drawer .item { 
 
    padding: 12px 16px; 
 
    font-size: 14px; 
 
} 
 

 
.drawer .item:last-child { 
 
    border-bottom: none; 
 
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script> 
 

 
<div class="ui-page" id="popover-page"> 
 
    <div class="page-content"> 
 
     <div class="header"> 
 
      <div class="header-title"> 
 
       Page Title 
 
      </div> 
 
      <button class="btn-clear" v-popover>Popover</button> 
 
     </div> 
 
     <div class="drawer"> 
 
      <div class="drawer-content"> 
 
       <div class="item" v-for="option in options">{{ option }}</div> 
 
      </div> 
 
     </div> 
 
     <div class="scroll-content has-header"> 
 
      <div class="page-content"> 
 
       <p>Some Content</p> 
 
      </div> 
 
     </div> 
 
    </div> 
 
</div>

関連する問題