Skip to content

Instantly share code, notes, and snippets.

@skunkworker
Last active June 22, 2019 05:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skunkworker/e27152b4daac710b92976cc8725453f0 to your computer and use it in GitHub Desktop.
Save skunkworker/e27152b4daac710b92976cc8725453f0 to your computer and use it in GitHub Desktop.
Vuejs directive, have floating window (eg custom dropdown) always be visible on the page.
import Vue from 'vue'
let handleWindowResize
export function moveFromWindowLeft(el, binding) {
const showElement = binding.value
if (!showElement) {
el.style.display = "none"
return
}
el.style.display = ""
var buffer = 20
if (el.getBoundingClientRect().width != 0) {
var parentRect = el.parentElement.getBoundingClientRect();
var rect = el.getBoundingClientRect(),
scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
var pos = { top: rect.top + scrollTop, left: rect.left + scrollLeft }
var offset = window.innerWidth - (rect.left + rect.width)
var buffer = 10
var absoluteXOffset = window.innerWidth - (rect.width + buffer)
var offset = absoluteXOffset - parentRect.left;
// console.log("offset ",offset)
var rightStyle = "right: unset"
if (offset < 0) {
el.style.right = "unset !important"
var leftStyle = "left: "+Math.round(offset)+"px"
var styleString = [rightStyle, leftStyle].join("; ")+";"
el.setAttribute("style", styleString);
} else {
el.setAttribute("style","")
}
}
}
Vue.directive('always-show', {
componentUpdated(el, binding, vnode) {
// console.log('componentUpdated')
moveFromWindowLeft(el,binding)
},
update(el, binding, vnode) {
// console.log('update')
moveFromWindowLeft(el,binding)
},
inserted(el, binding, vnode) {
// console.log('inserted')
moveFromWindowLeft(el,binding)
},
bind(el, binding, vnode) {
// console.log('bind')
handleWindowResize = (e) => {
moveFromWindowLeft(el,binding)
}
window.addEventListener('resize', handleWindowResize)
},
unbind(el, binding, vnode) {
// console.log('unbind')
window.removeEventListener('resize', handleWindowResize)
}
})
<div v-always-show="someShowVariable"></div>
@skunkworker
Copy link
Author

The function of this code would be to takeover a v-show dropdown menu that could possibly go on the right side of the screen, and always make it fully visible with a buffer. I didn't know of an existing Vuejs directive so I wrote this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment