Javascript - 在文件上传期间防止导航

标签 javascript vue.js

我有一个用于视频上传的 vue 组件,当用户在视频上传期间试图离开时,我会警告他,如果他这样做,他将丢失文件,如下所示:

       ready() {
            window.onbeforeunload = () => {
                if (this.uploading && !this.uploadingComplete && !this.failed) {
                    this.confirm('Are you sure you want to navigate away? Your video won't be uploaded if you do so!');
                }
            }
        }

我正在使用 sweetalert 来提醒用户。但是我怎样才能让它停留在同一页面上,并在他确认他想要离开之前阻止导航离开?

这是整个组件:

<script>
    function initialState (){
        return {
            uid: null,
            uploading: false,
            uploadingComplete: false,
            failed: false,
            title: null,
            link: null,
            description: null,
            visibility: 'private',
            saveStatus: null,
            fileProgress: 0
        }
    }
    export default {
        data: function (){
            return initialState();
        },
        methods: {
            fileInputChange() {
                this.uploading = true;
                this.failed = false;

                this.file = document.getElementById('video').files[0];

                this.store().then(() => {
                    var form = new FormData();

                    form.append('video', this.file);
                    form.append('uid', this.uid);

                    this.$http.post('/upload', form, {
                        progress: (e) => {
                            if (e.lengthComputable) {
                                this.updateProgress(e)
                            }
                        }
                    }).then(() => {
                        this.uploadingComplete = true
                    }, () => {
                        this.failed = true
                    });
                }, () => {
                    this.failed = true
                })
            },
            store() {
                return this.$http.post('/videos', {
                    title: this.title,
                    description: this.description,
                    visibility: this.visibility,
                    extension: this.file.name.split('.').pop()
                }).then((response) => {
                    this.uid = response.json().data.uid;
                });
            },
            update() {
                this.saveStatus = 'Saving changes.';

                return this.$http.put('/videos/' + this.uid, {
                    link: this.link,
                    title: this.title,
                    description: this.description,
                    visibility: this.visibility
                }).then((response) => {
                    this.saveStatus = 'Changes saved.';

                    setTimeout(() => {
                        this.saveStatus = null
                    }, 3000)
                }, () => {
                    this.saveStatus = 'Failed to save changes.';
                });
            },
            updateProgress(e) {
                e.percent = (e.loaded / e.total) * 100;
                this.fileProgress = e.percent;
            },
            confirm(message) {
              swal({
                title: message,
                text: null,
                type: "warning",
                showCancelButton: true,
                cancelButtonText: "Cancel",
                cancelButtonColor: '#FFF',
                confirmButtonColor: "#2E112D",
                confirmButtonText: "Yes, delete"
              }).then(function(){
                  this.$data = initialState();
              }.bind(this), function(dismiss) {
                // dismiss can be 'overlay', 'cancel', 'close', 'esc', 'timer'
                if (dismiss === 'cancel') { // you might also handle 'close' or 'timer' if you used those
                // ignore
                } else {
                  throw dismiss;
                }
              })
            }
        },
        ready() {
            window.onbeforeunload = () => {
                if (this.uploading && !this.uploadingComplete && !this.failed) {
                    this.confirm('Are you sure you want to navigate away? Your video won't be uploaded if you do so!');
                }
            }
        }
    }
</script>

最佳答案

Mozilla 文档建议

window.onbeforeunload = function(e) {
  var dialogText = 'Dialog text here';
  e.returnValue = dialogText;
  return dialogText;
};

同时声明:

Since 25 May 2011, the HTML5 specification states that calls to window.alert(), window.confirm(), and window.prompt() methods may be ignored during this event. See the HTML5 specification for more details.

Source包含有关原因和对现代浏览器的期望的许多其他详细信息。

This question似乎是你的副本。

This answer建议为了避免奇怪的浏览器行为,你应该只在它要防止某些事情时设置处理程序(也就是说,当导航离开时应该触发确认对话框)

关于Javascript - 在文件上传期间防止导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40971605/

相关文章:

Javascript Focus() 不适用于空文本区域

javascript - ResizeSensor具体如何使用?

javascript - ePub 未在 futurepress/epub.js 中定义

javascript - 防止点击 VuetifyJS 组合框后调用软键盘

javascript - 如何在用 JavaScript 或 NodeJs 编写的控制台应用程序中制作加载动画?

javascript - 从 url 中删除 webjars 版本

javascript - 链接到 Cordova 应用程序中的评论页面

javascript - 页面加载时Vue Infinite Loading多个请求问题

javascript - 一个 vue 实例中具有多个数据的类似组件

javascript - 将数组传递给 Laravel View 并将该数组用作 VueJS prop