李恒道 发表于 2021-11-1 11:03:19

[油猴脚本开发指南]SweetAlert2的漂亮对话框

# 前言

这节课我们学习sweetalert2来制作更漂亮的对话框

因为alert还是丑丑的,所以我们来看看sweetalert2吧~

# 引入

直接require地址https://cdn.jsdelivr.net/npm/sweetalert2@11即可

# 使用

关于文档我们可以查看https://sweetalert2.github.io/recipe-gallery/

# 例子

一个基础对话框

```javascript
Swal.fire('Any fool can use a computer')
```

![图片.png](data/attachment/forum/202111/01/113626fiiiuf638yvy3x3r.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

设置标题下文字以及icon

```javascript
Swal.fire(
'The Internet?',
'That thing is still around?',
'question'
)
```

![图片.png](data/attachment/forum/202111/01/113641sux93z5943zn3nr5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

带一个页脚

```javascript
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Something went wrong!',
footer: '<a href="">Why do I have this issue?</a>'
})
```

![图片.png](data/attachment/forum/202111/01/113650nffdluwl4floo0o7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

内部包含一个很长的图片的对话框

```javascript
Swal.fire({
imageUrl: 'https://placeholder.pics/svg/300x1500',
imageHeight: 1500,
imageAlt: 'A tall image'
})
```

![图片.png](data/attachment/forum/202111/01/113701jcl93vv4vmklck9g.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

一个带有自定义html和aria标签按钮的对话框

```javascript
Swal.fire({
title: '<strong>HTML <u>example</u></strong>',
icon: 'info',
html:
    'You can use <b>bold text</b>, ' +
    '<a href="//sweetalert2.github.io">links</a> ' +
    'and other HTML tags',
showCloseButton: true,
showCancelButton: true,
focusConfirm: false,
confirmButtonText:
    '<i class="fa fa-thumbs-up"></i> Great!',
confirmButtonAriaLabel: 'Thumbs up, great!',
cancelButtonText:
    '<i class="fa fa-thumbs-down"></i>',
cancelButtonAriaLabel: 'Thumbs down'
})
```

![图片.png](data/attachment/forum/202111/01/113717zocqtcnd2qdsduhn.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

title是标题

icon是图标

html代表html样式

如果同时提供text和html则优先html,注意不可以设置不可信任的html为此参数,否则可能导致被攻击

showclosebutton显示关闭按钮

showCancelButton显示取消按钮

focusConfirm聚焦元素,如果为false则不默认聚焦确定按钮

confirmButtonText使用该参数设置确认按钮的文本

confirmButtonAriaLabel用于设置标签描述

cancelButtonText使用该参数设置取消按钮的文本

cancelButtonAriaLabel用于设置取消标签的描述

一个带有三个按钮的对话框

```javascript
Swal.fire({
title: 'Do you want to save the changes?',
showDenyButton: true,
showCancelButton: true,
confirmButtonText: 'Save',
denyButtonText: `Don't save`,
}).then((result) => {
/* Read more about isConfirmed, isDenied below */
if (result.isConfirmed) {
    Swal.fire('Saved!', '', 'success')
} else if (result.isDenied) {
    Swal.fire('Changes are not saved', '', 'info')
}
})
```

showDenyButton显示拒绝按钮,如果为了显示三个按钮这将非常有用

![图片.png](data/attachment/forum/202111/01/113732w7whw5hyb5h57h5n.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

一个定位对话框

```javascript
Swal.fire({
position: 'top-end',
icon: 'success',
title: 'Your work has been saved',
showConfirmButton: false,
timer: 1500
})
```

![图片.png](data/attachment/forum/202111/01/113743y2q2o0mke33qlys2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

position用于定位

有以下属性**'top'** , **'top-start'** , **'top-end'** , **'center'** , **'center-start'** , **'center-end'** , **'bottom'** , **'bottom-start'** , or **'bottom-end'** .

timer是消失时间

一个使用animate.css动画效果的对话框

```javascript
Swal.fire({
title: 'Custom animation with Animate.css',
showClass: {
    popup: 'animate__animated animate__fadeInDown'
},
hideClass: {
    popup: 'animate__animated animate__fadeOutUp'
}
})
```

超出提纲了

![图片.png](data/attachment/forum/202111/01/113752mdc89b0zqbwbrba0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

一个确认后执行附加功能的对话框

```javascript
Swal.fire({
title: 'Are you sure?',
text: "You won't be able to revert this!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!'
}).then((result) => {
if (result.isConfirmed) {
    Swal.fire(
      'Deleted!',
      'Your file has been deleted.',
      'success'
    )
}
})
```

`confirmButtonColor`设置确认按钮颜色

`cancelButtonColor`设置取消按钮颜色

`confirmButtonText`设置确认按钮文本

![图片.png](data/attachment/forum/202111/01/113805nbk3c7loc3smcse0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

![图片.png](data/attachment/forum/202111/01/113811roqmx8ricmrtoh4h.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

一个带有取消执行其他操作的对话框

```javascript
const swalWithBootstrapButtons = Swal.mixin({
customClass: {
    confirmButton: 'btn btn-success',
    cancelButton: 'btn btn-danger'
},
buttonsStyling: false
})

swalWithBootstrapButtons.fire({
title: 'Are you sure?',
text: "You won't be able to revert this!",
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Yes, delete it!',
cancelButtonText: 'No, cancel!',
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
    swalWithBootstrapButtons.fire(
      'Deleted!',
      'Your file has been deleted.',
      'success'
    )
} else if (
    /* Read more about handling dismissals below */
    result.dismiss === Swal.DismissReason.cancel
) {
    swalWithBootstrapButtons.fire(
      'Cancelled',
      'Your imaginary file is safe :)',
      'error'
    )
}
})
```

这里用了mixin函数用于混入一些固定的操作选项

```javascript
const swalWithBootstrapButtons = Swal.mixin({
customClass: {
    confirmButton: 'btn btn-success',
    cancelButton: 'btn btn-danger'
},
buttonsStyling: false
})
```

customClass里用于控制按钮的选项

buttonStyling我没有查到具体文档解释,姑且算作取消按钮默认样式吧

根据查阅资料,这个真的是取消默认样式

![图片.png](data/attachment/forum/202111/01/113839ocs7xxq5949zdbgs.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

![图片.png](data/attachment/forum/202111/01/113847nhjiq1813e8f0fjb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

一个自定义图像的对话框

```javascript
Swal.fire({
title: 'Sweet!',
text: 'Modal with a custom image.',
imageUrl: 'https://unsplash.it/400/200',
imageWidth: 400,
imageHeight: 200,
imageAlt: 'Custom image',
})
```

![图片.png](data/attachment/forum/202111/01/113901ixx72ae4iioxazri.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

带有自定义宽度背景以及一只彩虹猫的对话框

```javascript
Swal.fire({
title: 'Custom width, padding, background.',
width: 600,
padding: '3em',
background: '#fff url(/images/trees.png)',
backdrop: `
    rgba(0,0,123,0.4)
    url("/images/nyan-cat.gif")
    left top
    no-repeat
`
})
```

![图片.png](data/attachment/forum/202111/01/113912u0yq02ntn0snlb1s.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

带有自定义计时器的对话框

```javascript
let timerInterval
Swal.fire({
title: 'Auto close alert!',
html: 'I will close in <b></b> milliseconds.',
timer: 2000,
timerProgressBar: true,
didOpen: () => {
    Swal.showLoading()
    const b = Swal.getHtmlContainer().querySelector('b')
    timerInterval = setInterval(() => {
      b.textContent = Swal.getTimerLeft()
    }, 100)
},
willClose: () => {
    clearInterval(timerInterval)
}
}).then((result) => {
/* Read more about handling dismissals below */
if (result.dismiss === Swal.DismissReason.timer) {
    console.log('I was closed by the timer')
}
})
```

`timerProgressBar`底部出现对话框的进度条

`didOpen`声明周期钩子,在弹出对话框后异步运行,并传入弹出的dom元素

`showLoading`显示一个进度组件

`getHtmlContainer`获取呈现html/text的dom元素

`getTimerLeft` 返回进度条剩余的时间

`willClose`一个生命周期钩子,当窗口关闭时同步运行,提供弹出的dom元素作为函数的参数

![图片.png](data/attachment/forum/202111/01/113924qrht34j52r6j44v2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

一个ajax请求实例

```javascript
Swal.fire({
title: 'Submit your Github username',
input: 'text',
inputAttributes: {
    autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Look up',
showLoaderOnConfirm: true,
preConfirm: (login) => {
    return fetch(`//api.github.com/users/${login}`)
      .then(response => {
      if (!response.ok) {
          throw new Error(response.statusText)
      }
      return response.json()
      })
      .catch(error => {
      Swal.showValidationMessage(
          `Request failed: ${error}`
      )
      })
},
allowOutsideClick: () => !Swal.isLoading()
}).then((result) => {
if (result.isConfirmed) {
    Swal.fire({
      title: `${result.value.login}'s avatar`,
      imageUrl: result.value.avatar_url
    })
}
})
```

`input`设置一个input的编辑框

`inputAttributes`设置input属性

`autocapitalize`设置为off的时候取消首字母大写

`showLoaderOnConfirm`当为loading的时候取消confirm按钮并显示加载组件

`preConfirm`在执行confirm按钮之前执行该函数,如果返回false为阻止弹窗关闭,undefined为默认结果,也可以返回其他值,可以通过result.value获取对应的值

`allowOutsideClick`如果设置为false则不允许点击对话框以外的背景来关闭对话框

![图片.png](data/attachment/forum/202111/01/113933yjkbuj2kvb6qcfhz.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

![图片.png](data/attachment/forum/202111/01/113943tnddlowzu6uoado6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

# 关于代码的同步运行和异步运行钩子

这里的sweetalert2的钩子分为两种,一种是同步运行一种是异步运行

同步运行的代码是在运行到某个位置之后调用你的函数,然后继续执行代码

而异步执行代码则是在执行到对应位置后,则保证在未来调用你的函数

关于这点可以看到源代码中的

```javascript
    if (typeof params.didOpen === 'function') {
      setTimeout(() => params.didOpen(popup));
    }
```

didOpen是一个异步代码,因为我们发现存在didOpen,则利用setTimeout进行回调并执行

setTimeout是一个异步代码,当主任务完成后,则会回调setTimeout触发didOpen函数

关于为什么使用异步钩子,我倾向的认为是为了完成窗口的绘制后,再允许用户进行一定的操控和修改

然后再回调钩子进行处理

王一之 发表于 2021-11-1 11:12:31

上个图吧 哥哥

Ne-21 发表于 2021-11-1 11:16:18


李恒道 发表于 2021-11-1 11:18:03

王一之 发表于 2021-11-1 11:12
上个图吧 哥哥

啊.这,我忘了,回头补上

李恒道 发表于 2021-11-1 11:18:08

Ne-21 发表于 2021-11-1 11:16


ggnb!

maxzhang 发表于 2021-11-1 11:39:13

gg真是高产似__ __

李恒道 发表于 2021-11-1 14:53:47

maxzhang 发表于 2021-11-1 11:39
gg真是高产似__ __

优秀

Hangover 发表于 2021-11-1 17:54:04

ggnb!!!👍*99999
页: [1]
查看完整版本: [油猴脚本开发指南]SweetAlert2的漂亮对话框