In project development, you need to make an Ajax request when a button is clicked and pop up a new window page when the request is complete. Window.open is the natural implementation, but it will be blocked by the browser
Analysis of the
When the browser detects a new pop-up created by a non-user action, it blocks it. Because the browser thinks it might be an AD, not a page the user wants to see.
Window.open will not be blocked when it triggers events for the user inside or when they are loaded, and will be blocked as soon as the pop-up code is moved inside Ajax or a piece of asynchronous code.
Example code intercepted
For example, the following code would be blocked:
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{{msg}}</h3>
<button ref='btn' type="button" @click="clickHandler">click</button>
</div>
</template>
<script>
export default {
props: {
msg: {
required: true.type: String
}
},
data () {
return {
url: 'http://www.baidu.com/',
}
},
mounted () {
setTimeout((a)= > {
window.open(this.url, '_blank')},100)}}</script>
Copy the code
The solution
1. The code that opens a new window is bound to click’s event callback to avoid most browser pop-ups:
Example code:
Button’s click event triggers a callback function called clickHandler that opens a new window without being blocked by the browser.
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{{msg}}</h3>
<button ref='btn' type="button" @click="clickHandler">click</button>
</div>
</template>
<script>
export default {
props: {
msg: {
required: true.type: String
}
},
data () {
return {
url: 'http://www.baidu.com/',
}
},
mounted () {
},
methods: {
clickHandler () {
window.open(this.url, '_blank')}}}</script>
Copy the code
2. Implementation via form submission (beta, will be blocked)
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{{msg}}</h3>
<form action="http://www.baidu.com" ref="form" method="get" target="_blank" style="display: none"></form>
</div>
</template>
<script>
export default {
props: {
msg: {
required: true.type: String
}
},
data () {
return {
url: 'http://www.baidu.com/',
}
},
mounted () {
setTimeout((a)= > {
this.$refs.form.submit()
}, 1000)},methods: {}}</script>
Copy the code
If the form submits an event triggered by the button click event, it will not be blocked by the browser
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{{msg}}</h3>
<form action="http://www.baidu.com" ref="form" method="get" target="_blank" style="display: none"></form>
<button type="button" @click='clickHandler'>button</button>
</div>
</template>
<script>
export default {
props: {
msg: {
required: true.type: String
}
},
data () {
return {
url: 'http://www.baidu.com/',
}
},
mounted () {},
methods: {
clickHandler () {
this.$refs.form.submit()
}
}
}
</script>
Copy the code
3. Pop up the window first, then redirect (Optimal)
The page is opened by a user click (the action must be triggered by a user click), and then the page is redirected
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{{msg}}</h3>
<button ref="btn" @click="clickHandler">button</button>
</div>
</template>
<script>
export default {
props: {
msg: {
required: true.type: String
}
},
data () {
return {
url: 'http://www.baidu.com/'.newTab: null
}
},
mounted () {},
methods: {
clickHandler () {
this.newTab = window.open('about:blank')
let $ajax = new Promise((resolve, reject) = > {
setTimeout((a)= > {
resolve()
}, 1000)
})
$ajax.then((a)= > {
this.newTab.location.href = this.url
setTimeout((a)= > {
this.newTab = null
}, 1)})}}}</script>
Copy the code