mirari / vue-fullscreen

A simple Vue.js component for fullscreen
MIT License
439 stars 50 forks source link

TypeError: $event.stopPropagation is not a function stopPropagation called earlier #22

Closed BonBonSlick closed 4 years ago

BonBonSlick commented 4 years ago

We track modal window click if it is outside modal content, close modal

 <em @click.stop="hideModal" />

The button is outside modal, we have to stopPropagination in order to prevent closing modal and open fullscreen

<em @click.stop="toggleFullScreeMode"
 v-if="!isFullScreen"
                            />

This way error is thrown

[Vue warn]: Error in v-on handler: "TypeError: $event.stopPropagation is not a function"

found in

---> <Fullscreen>
       <ImageModal> at src/components/public/partials/modal/image_modal.vue
         <PublicGallery> at src/components/public/pages/gallery.vue
           <PublicBasicLayout> at src/components/public/layouts/basic.vue
             <App> at src/App.vue
               <Root>
warn @ vue.js:633
logError @ vue.js:1892
globalHandleError @ vue.js:1887
handleError @ vue.js:1847
invokeWithErrorHandling @ vue.js:1870
invoker @ vue.js:2187
invokeWithErrorHandling @ vue.js:1862
Vue.$emit @ vue.js:3888
fullScreenCallback @ vue-fullscreen.min.js:1
vue.js:1896 TypeError: $event.stopPropagation is not a function
    at change (image_modal.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options:17)
    at invokeWithErrorHandling (vue.js:1862)
    at VueComponent.invoker (vue.js:2187)
    at invokeWithErrorHandling (vue.js:1862)
    at VueComponent.Vue.$emit (vue.js:3888)
    at VueComponent.fullScreenCallback (vue-fullscreen.min.js:1)
mirari commented 4 years ago

I need more info to find out the problem, it is better to provide an online example, like this: https://codepen.io/mirari/pen/vjzXJN

I think it might be ImageModal's problem, find the context for $event

BonBonSlick commented 4 years ago

Can not reproduce https://codepen.io/asdasdddd/pen/jOEzojj

Maybe because we do not use vue-modal package?

We do not use a vue-modal package, own simple div with state isHidden. https://codepen.io/asdasdddd/pen/jOEzojj When modal opened, it contains an image only and 2 buttons, toggle fullscreen and close modal As you can see custom Vue directive handles click outside the image to toggle modal, hide the image. In our case, toggle fullscreen is outside of the image. Error is thrown, this is from local env.


{
          ref: "fullscreen",
          on: {
            change: function($event) {
              $event.stopPropagation()
              return _vm.fullscreenChange($event)
            }
          }
        },

It seems we missing something.

// ERROR
    <fullscreen @change.stop="fullscreenChange"

// SUCCESS modal window closed because click is outside of image!
    <fullscreen @change="fullscreenChange"

// SUCCESS modal window closed because click is outside of image!
        <fullscreen :fullscreen.sync="isFullScreen"
BonBonSlick commented 4 years ago

Solved this way

 <fullscreen @change="fullscreenChange"
...
  <em @click.stop="hideModalWindow($event)"  />
...
                                             v-click-outside="hideModalWindow"
...

      hideModalWindow (event) {
        if ('EM' !== event.srcElement.tagName) {
          this.hideModal();
        }
      },
BarnabasSzabolcs commented 2 years ago

I have a solution for

[Vue warn]: Error in v-on handler: "TypeError: $event.stopPropagation is not a function"

The problem is that "@click" events are often non-native, when emitted from custom components. Hence, $event does not have a stopPropagation function anymore.

Solution: instead of writing this.$emit('click', myData) write

event.data = myData
this.$emit('click', event)

This should work if event is a native click event. If not, then try and go up one level.

Suggestion for fullscreen devs:

If fullscreen does have a @click event then it is a nicer api to provide the native click event so the users can use @click.stop as expected.

mirari commented 2 years ago

I have a solution for

[Vue warn]: Error in v-on handler: "TypeError: $event.stopPropagation is not a function"

The problem is that "@click" events are often non-native, when emitted from custom components. Hence, $event does not have a stopPropagation function anymore.

Solution: instead of writing this.$emit('click', myData) write

event.data = myData
this.$emit('click', event)

This should work if event is a native click event. If not, then try and go up one level.

Suggestion for fullscreen devs:

If fullscreen does have a @click event then it is a nicer api to provide the native click event so the users can use @click.stop as expected.

The way to modify custom components is not a universal approach. I think you should use @click.native.stop.

BarnabasSzabolcs commented 2 years ago

Your suggestion looked promising, @mirari . I have tried it for my situation right away and it does not work. The reason may be that emitted custom events do not have any native events behind them.

No worries otherwise I don't use vue-fullscreen, I just posted my suggestion since it solves the problem of the OP.

Best of luck, Barney

rdhelms commented 1 year ago

@BarnabasSzabolcs Thanks so much for documenting your solution. We were migrating a component using a custom click event from Vue 2 to Vue 3 and ran into this exact error, and passing the native click event worked like a charm 💯