Code Monkey home page Code Monkey logo

vue.resize's Introduction

Vue.resize

GitHub open issues GitHub closed issues Npm download Npm version vue2 MIT License

Vue directive to detect HTML resize events based on CSS Element Queries with debouncing and throttling capacity.

Demo

demo gif

Typical usage

Simple

Use this option when you need to receive all the resize events.

The onResize function will be called each time the element resizes with the corresponding HTML element as only argument.

<div v-resize="onResize">

Throttle

Use throttle when you need to rate-limit resize events frequency.

  • With default timeout (150 ms):
<div v-resize:throttle="onResize">
  • With custom timeout (in ms):
<div v-resize:throttle.100="onResize">

Debounce

Use debounce when you only need to be notified when resize events ends.

  • With default timeout (150 ms):
<div v-resize:debounce="onResize">
  • With custom timeout (in ms):
<div v-resize:debounce.50="onResize">

Initial

Use this option to receive the resize callback right after the element is mounted on the DOM and visible.

<div v-resize.initial="onResize">

Installation

  • Available through npm:
 npm install vue-resize-directive --save
  • For Modules
// ES6
import resize from 'vue-resize-directive'
//...
export default {
    directives: {
        resize,
    }
//...
  
// ES5
var resize = require('vue-resize-directive')
  • For <script> Include

    Just include Vueresize.js after ResizeSensor.js from css-element-queries and lodash.js script.

vue.resize's People

Contributors

david-desmaisons avatar itee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue.resize's Issues

Add modifier for onset time

Currently it seems the resize handler is triggered during initial page render.

It would be handy for being able to give onset time as a modifier for this directive?

Not working with v-show

I couldn't get this to work if the component is being displayed using v-show.

After much debugging I found that the 'visibility listener' wasn't triggering when the component became visible.

After much more debugging (I didn't know how IntersectionObserver worked) I found that it appears that the 'root' option was causing the problem. The code has it set to 'document.documentElement', which you'd have thought would work, but actually seemed to be showing as an element of 0x0 pixels. Removing the 'root' option so that it became the default of the viewport made everything work correctly.

ie - changing

function listenToVisible(element, callback) {
const options = {
root: document.documentElement
};
.....

to

function listenToVisible(element, callback) {
const options = {
};
....

seems to have fixed the problem for me.

Why is vue-resize-directive not firing?

three steps

  1. npm install vue-resize-directive --save
// ES6
import resize from 'vue-resize-directive'
//...
export default {
    directives: {
        resize,
    }
//...

3.<div v-resize="onResize">

finnally div no effect

Can't run tests because IntersectionObserver is not defined

There seems to be a problem with some combination of Vue, Webpack, Mocha, vue-resize-directive, and the intersection-observer polyfill. (I've cross-posted this question to the Vue community more broadly, too.)

The v-resize directive does work just fine in a real browser. It's only the test that is failing to find the definition of IntersectionObserver.

Repro Steps

I created a new Vue project:

  1. vue create vue-resize-directive-test
    • selected Babel, Typescript, class-component syntax, and Mocha + Chai
  2. yarn test:unit on generated example code passes

Then I added the v-resize directive:

  1. yarn add vue-resize-directive
  2. added a placeholder Typescript definition file, typings/vue-resize-directive.d.ts:
declare module 'vue-resize-directive';
  1. updated tsconfig.json to include the definition:
    "paths": {
      "@/*": [
        "src/*"
      ],
      "*": [
        "typings/*"
      ]
    },
  1. added the directive to a component:
<template>
  <div class="hello" v-resize="onResize">
    Hello, World!
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import resize from 'vue-resize-directive';

@Component({ directives: {resize} })
export default class HelloWorld extends Vue {
  onResize() { console.log("Resized!") }
}
</script>
  1. yarn test:unit on generated example code fails with an error that "ReferenceError: IntersectionObserver is not defined":
 WEBPACK  Compiled successfully in 13052ms

 MOCHA  Testing...



  HelloWorld.vue
[Vue warn]: Error in directive resize inserted hook: "ReferenceError: IntersectionObserver is not defined"

found in

---> <HelloWorld> at src/components/HelloWorld.vue
       <Root>
ReferenceError: IntersectionObserver is not defined
    at u (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue-resize-directive/dist/Vueresize.js:1:1)
    at inserted (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue-resize-directive/dist/Vueresize.js:1:1)
    at callHook$1 (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:6620:1)
    at callInsert (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:6559:1)
    at wrappedHook (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:2225:1)
    at invokeWithErrorHandling (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:1847:1)
    at Object.invoker [as insert] (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:2165:1)
    at invokeInsertHook (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:6286:1)
    at VueComponent.patch [as __patch__] (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:6505:1)
    at VueComponent.Vue._update (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:3898:1)
    at VueComponent.updateComponent (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:4019:1)
    at Watcher.get (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:4419:1)
    at new Watcher (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:4408:1)
    at mountComponent (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:4026:1)
    at VueComponent../node_modules/vue/dist/vue.runtime.esm.js.Vue.$mount (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:8350:1)
    at mount (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/@vue/test-utils/dist/vue-test-utils.js:8649:1)
    at shallowMount (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/@vue/test-utils/dist/vue-test-utils.js:8677:1)
    at Context.it (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/tests/unit/example.spec.ts:8:1)
    at callFn (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runnable.js:372:21)
    at Test.Runnable.run (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runnable.js:364:7)
    at Runner.runTest (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:455:10)
    at /Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:573:12
    at next (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:369:14)
    at /Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:379:7
    at next (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:303:14)
    at Immediate._onImmediate (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:347:5)
    at runCallback (timers.js:694:18)
    at tryOnImmediate (timers.js:665:5)
    at processImmediate (timers.js:647:5)

I also repeated the same steps, but with plain Javascript instead of Typescript:

<template>
  <div class="hello" v-resize="onResize">
    Hello, World!
  </div>
</template>

<script>
import resize from 'vue-resize-directive';

export default {
  name: 'HelloWorld',
  directives: { resize },
  methods: {
    onResize: function() { console.log("Resized!") }
  }
}
</script>

Same error.

Debugging Info

I confirmed that the intersection-observer Node package exists in node_modules/, so I would have expected it to polyfill correctly.

I tried running the tests as yarn test:unit --require intersection-observer and/or --include node_modules/intersection-observer/intersection-observer.js, but that made no difference.

Version Info:

  • vue-resize-directive in package.json: 1.1.4
  • vue in package.json: 2.5.22
  • intersection-observer in node_modules:0.5.1
  • vue --version: 3.40
  • yarn --version: node-1.13.0
  • node --version: 10.11.0

TypeError: Cannot set property 'detach' of undefined

Hi,

i got some trouble using this package.

I use this code snippet:

import Vue from '../../../../node_modules/vue/dist/vue.esm'
import resize from 'vue-resize-directive'

export default Vue.component( 'MyResizableComponent', {
    template: `
        <div v-resize="onResize"></div>
    `,
    directives: {
        resize
    },
    methods:  {

        onResize ( event ) {

            const domElement = this.$el
            console.log(`client(w/h): ${domElement.clientWidth}/${domElement.clientHeight}`)
            console.log(`offset(w/h): ${domElement.offsetWidth}/${domElement.offsetHeight}`)
            console.log(`event: ${event}`)

        }

    }

} )

and i got this errors:

[Vue warn]: Error in directive resize inserted hook: "TypeError: Cannot set property 'detach' of undefined"

and

Cannot set property 'detach' of undefined at ResizeSensor

Apparently the this argument is not correctly bound here:

/**
           * Class for dimension change detection.
           *
           * @param {Element|Element[]|Elements|jQuery} element
           * @param {Function} callback
           *
           * @constructor
           */
          var ResizeSensor = function ResizeSensor(element, callback) {
              
              //...

              this.detach = function (ev) {
                  ResizeSensor.detach(element, ev);
              };
          };

Does not work on singleton tags

The directive fails with <img> elements and other singletons. The v-resize callback is not triggered. Probably because the resize-sensor is placed inside the target element and singletons cannot have elements inside them.

Strange behavior when used on custom components or root element of components

When I try to use v-resize on a component or root node, it will never fire.
However when I do this on the first element inside the root element of a custom component it works fine.

I tried adding the directive globally and in the modules themselves, all give the exact same results

Does not work (inside App.vue):

    <TheAppBar
      :icon="currentViewIcon"
      :caption="currentViewTitle"
      :busy="loading"

      @nav="$refs.nav.toggle()"

      v-resize="appBarResized"
    />

Also does not work on root element of component (inside TheAppBar.vue)

<template>
  <nav class="appbar" v-resize="onResize">
    <div class="row no-gutters">
      <div class="d-print-none col-auto">
        <button class="btn btn-sm btn-outline-secondary" @click="$emit('nav')"><fa-icon icon="bars" fixed-width /></button>
      </div>
      <div v-if="caption" class="col-auto ml-3 lead">
        <MenuIcon :icon="icon" /> {{ caption }}
      </div>
      <div v-if="busy" class="col-auto d-print-none ml-3 lead">
        <fa-icon icon="sync" spin />
      </div>
      <div class="col-auto ml-3 lead">
        <portal-target name="appBar" />
      </div>
    </div>
  </nav>
</template>

Works on first element inside root element of custom component (TheAppBar.vue):

<template>
  <nav class="appbar">
    <div class="row no-gutters" v-resize="onResize">
      <div class="d-print-none col-auto">
        <button class="btn btn-sm btn-outline-secondary" @click="$emit('nav')"><fa-icon icon="bars" fixed-width /></button>
      </div>
      <div v-if="caption" class="col-auto ml-3 lead">
        <MenuIcon :icon="icon" /> {{ caption }}
      </div>
      <div v-if="busy" class="col-auto d-print-none ml-3 lead">
        <fa-icon icon="sync" spin />
      </div>
      <div class="col-auto ml-3 lead">
        <portal-target name="appBar" />
      </div>
    </div>
  </nav>
</template>

would you add some warning tips

before the codeline: let callBack = () => value(el)
would you add some checklist like:
if (!value){
console.warning(method or v-resize is not implemented as to $el)
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.