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

时间:2016-12-05 10:01:34

标签: 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>

2 个答案:

答案 0 :(得分:1)

Mozilla文档建议

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

并说明:

  

自2011年5月25日起,HTML5规范声明在此事件期间可能会忽略对window.alert(),window.confirm()和window.prompt()方法的调用。有关更多详细信息,请参阅HTML5规范。

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

This question似乎与你的重复。

This answer建议,为避免出现奇怪的浏览器行为,您应该只在设置处理程序以防止某些事情发生时(即导航时应触发确认对话框)

答案 1 :(得分:0)

  

但是我怎么能让它保持在同一页面上,并在他确认他想要离开之前阻止导航?

添加return false;以停止活动。

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!");
    return false;  // <==== add this
}

返回false; 在您调用它时会执行3个单独的操作:

event.preventDefault(); - 它会停止浏览器的默认行为。

event.stopPropagation(); - 它阻止事件传播(或“冒泡”)DOM。

停止执行callback并在调用时立即返回。