上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

[油猴脚本开发指南]SweetAlert2进阶

[复制链接]

189

主题

1474

帖子

763

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
763
发表于 2021-11-21 22:59:55 | 显示全部楼层 | 阅读模式

前言

我们之前已经学了SweetAlert2,这节课我们简单进行一下进阶的学习~

对话框重用

我们可以使用Swal.mixin来创建可重用的对话框

const Toast = Swal.mixin({
  toast: true,
  position: 'top-end',
  showConfirmButton: false,
  timer: 3000,
  timerProgressBar: true,
  didOpen: (toast) => {
    toast.addEventListener('mouseenter', Swal.stopTimer)
    toast.addEventListener('mouseleave', Swal.resumeTimer)
  }
})

Toast.fire({
  icon: 'success',
  title: 'Signed in successfully'
})

模板声明

我们也可以在html中写template模板然后在Swal传入来触发弹窗

使用这种声明方式,在SSR情况下比较方便(本人未尝试)

代码如下

<template id="my-template">
  <swal-title>
    Save changes to "Untitled 1" before closing?
  </swal-title>
  <swal-icon type="warning" color="red"></swal-icon>
  <swal-button type="confirm">
    Save As
  </swal-button>
  <swal-button type="cancel">
    Cancel
  </swal-button>
  <swal-button type="deny">
    Close without Saving
  </swal-button>
  <swal-param name="allowEscapeKey" value="false" />
  <swal-param
    name="customClass"
    value='{ "popup": "my-popup" }' />
</template>

然后我们使用

Swal.fire({
  template: '#my-template'
})

触发弹窗,其中template就是我们的template标签的id名

支持的模板参数如下,因为这个感觉较为小众,所以我就没有尝试了

<swal-title>...</swal-title>
<swal-html>...</swal-html>
<swal-footer>...</swal-footer>
<swal-param name="..." value="..." />
<swal-button type="..." color="..." aria-label="...">...</swal-button>
<swal-image src="..." width="..." height="..." alt="..." />
<swal-icon type="..." color="...">...</swal-icon>
<swal-input type="..." label="..." placeholder="..." value="..." />
<swal-input-option value="...">...</swal-input-option>

声明式触发弹窗

我们也可以在html中通过声明属性的方式,然后触发弹窗,这时候我们需要使用的命令是bindClickHandler方法

例子如下

<button data-swal-template="#my-template">
  Trigger modal
</button>

<button data-swal-toast-template="#my-template">
  Trigger toast
</button>

然后我们在js写

Swal.bindClickHandler()

Swal.mixin({
  toast: true,
}).bindClickHandler('data-swal-toast-template')

bindClickHandler如果不填写任何字符串,则默认为'data-swal-template'读取属性的字符串作为模板

而如果传入了,则读取相应属性的模板

这里我是通过源码大概看了一下才理解的,官方一笔带过,大家有兴趣也可以看一下,代码如下

let bodyClickListenerAdded = false
const clickHandlers = {}

export function bindClickHandler (attr = 'data-swal-template') {
  clickHandlers[attr] = this

  if (!bodyClickListenerAdded) {
    document.body.addEventListener('click', bodyClickListener)
    bodyClickListenerAdded = true
  }
}

const bodyClickListener = (event) => {
  for (let el = event.target; el && el !== document; el = el.parentNode) {
    for (const attr in clickHandlers) {
      const template = el.getAttribute(attr)
      if (template) {
        clickHandlers[attr].fire({ template })
        return
      }
    }
  }
}

处理按钮的返回值

当用户单击按钮的时候,Swal.fire返回的promise将返回一个SweetAlertResult对象

键值如下

isConfirmed:当确认按钮被点击,返回的result的这个属性将为true

isDenied:当拒绝按钮被点击,返回的result的这个属性将为true,当弹窗有输入结果的时候,可以使用returnInputValueOnDeny: true返回输入的值

isDismissed:当取消按钮被点击,返回的result的这个属性将为true,而dismiss属性将为Swal.DismissReason.cancel

value:该值来源于窗口弹出,返回的result的这个属性有多种可能的值,当点击确认按钮时为true,拒绝为false,和存在输入框的时候为输入框的值

dismiss:当点击取消按钮的时候存在该属性,为取消原因,关于取消原因可以查看接下来的内容

取消原因

当用户点击取消按钮的时候,Swal.fire将返回一个对象,包含了{ isDismissed: true,dismiss: reason },其中reason包含了取消的详细原因

原因如下

Swal.DismissReason.backdrop:点击了外部背景,相关配置为allowOutsideClick

Swal.DismissReason.cancel:点击了取消按钮,相关配置为showCancelButton

Swal.DismissReason.close:点击了关闭按钮,相关配置为showCloseButton

Swal.DismissReason.esc:按了esc键,相关配置为allowEscapeKey

Swal.DismissReason.timer:时间超时,对话框自动关闭,相关配置为timer

如果使用了Swal.close关闭窗口,则Promise返回的obj中isDismissed:为true,但dismiss属性为undefined

图标

如下

图片.png

输入类型

这里我们也可以限制对话框内的输入类型

首先是text类型

const ipAPI = '//api.ipify.org?format=json'

const inputValue = fetch(ipAPI)
  .then(response => response.json())
  .then(data => data.ip)

const { value: ipAddress } = await Swal.fire({
  title: 'Enter your IP address',
  input: 'text',
  inputLabel: 'Your IP address',
  inputValue: inputValue,
  showCancelButton: true,
  inputValidator: (value) => {
    if (!value) {
      return 'You need to write something!'
    }
  }
})

if (ipAddress) {
  Swal.fire(`Your IP address is ${ipAddress}`)
}

图片.png

inputLabel是显示的文本

inputValue是显示的值,如果是text,email,number,tel,textarea等类型,则可以传入一个promise值

inputValidator对其进行合法性校验

**const { value: ipAddress } = await Swal.fire**

这里做了一个结构,对Swal.fire返回的promise做了一个await语法糖,同步等待返回对象,同时对对象进行解构拿到value的值,叫变量ipAddress

并在最后显示出来。

然后是email类型,代码如下

const { value: email } = await Swal.fire({
  title: 'Input email address',
  input: 'email',
  inputLabel: 'Your email address',
  inputPlaceholder: 'Enter your email address'
})

if (email) {
  Swal.fire(`Entered email: ${email}`)
}

图片.png

非常简单,不解释

url类型

const { value: url } = await Swal.fire({
  input: 'url',
  inputLabel: 'URL address',
  inputPlaceholder: 'Enter the URL'
})

if (url) {
  Swal.fire(`Entered URL: ${url}`)
}

图片.png

password类型

const { value: password } = await Swal.fire({
  title: 'Enter your password',
  input: 'password',
  inputLabel: 'Password',
  inputPlaceholder: 'Enter your password',
  inputAttributes: {
    maxlength: 10,
    autocapitalize: 'off',
    autocorrect: 'off'
  }
})

if (password) {
  Swal.fire(`Entered password: ${password}`)
}

图片.png

maxlength最大长度

autocapitalize取消首字母大写

autocorrect关闭自动修正,这个可以百度一下看看

textarea类型

const { value: text } = await Swal.fire({
  input: 'textarea',
  inputLabel: 'Message',
  inputPlaceholder: 'Type your message here...',
  inputAttributes: {
    'aria-label': 'Type your message here'
  },
  showCancelButton: true
})

if (text) {
  Swal.fire(text)
}

inputAttributes添加到html对象的输入属性,其中键为属性名称,而值为添加的对应值

select类型

const { value: fruit } = await Swal.fire({
  title: 'Select field validation',
  input: 'select',
  inputOptions: {
    'Fruits': {
      apples: 'Apples',
      bananas: 'Bananas',
      grapes: 'Grapes',
      oranges: 'Oranges'
    },
    'Vegetables': {
      potato: 'Potato',
      broccoli: 'Broccoli',
      carrot: 'Carrot'
    },
    'icecream': 'Ice cream'
  },
  inputPlaceholder: 'Select a fruit',
  showCancelButton: true,
  inputValidator: (value) => {
    return new Promise((resolve) => {
      if (value === 'oranges') {
        resolve()
      } else {
        resolve('You need to select oranges :)')
      }
    })
  }
})

if (fruit) {
  Swal.fire(`You selected: ${fruit}`)
}

inputOptions为选项值

图片.png

radio类型

/* inputOptions can be an object or Promise */
const inputOptions = new Promise((resolve) => {
  setTimeout(() => {
    resolve({
      '#ff0000': 'Red',
      '#00ff00': 'Green',
      '#0000ff': 'Blue'
    })
  }, 1000)
})

const { value: color } = await Swal.fire({
  title: 'Select color',
  input: 'radio',
  inputOptions: inputOptions,
  inputValidator: (value) => {
    if (!value) {
      return 'You need to choose something!'
    }
  }
})

if (color) {
  Swal.fire({ html: `You selected: ${color}` })
}

这里他为了演示,返回了一个promise并设置一秒后结束promise

返回的值是对象,其中键是对应的值,而属性则是名字

图片.png

checkbox类型

const { value: accept } = await Swal.fire({
  title: 'Terms and conditions',
  input: 'checkbox',
  inputValue: 1,
  inputPlaceholder:
    'I agree with the terms and conditions',
  confirmButtonText:
    'Continue <i class="fa fa-arrow-right"></i>',
  inputValidator: (result) => {
    return !result && 'You need to agree with T&C'
  }
})

if (accept) {
  Swal.fire('You agreed with T&C :)')
}

设定了默认值以及单选框文本

file类型

const { value: file } = await Swal.fire({
  title: 'Select image',
  input: 'file',
  inputAttributes: {
    'accept': 'image/*',
    'aria-label': 'Upload your profile picture'
  }
})

if (file) {
  const reader = new FileReader()
  reader.onload = (e) => {
    Swal.fire({
      title: 'Your uploaded picture',
      imageUrl: e.target.result,
      imageAlt: 'The uploaded picture'
    })
  }
  reader.readAsDataURL(file)
}

这里没什么特别需要讲解的

range类型

Swal.fire({
  title: 'How old are you?',
  icon: 'question',
  input: 'range',
  inputLabel: 'Your age',
  inputAttributes: {
    min: 8,
    max: 120,
    step: 1
  },
  inputValue: 25
})

进度条类型,min为最小,max为最大,step为阶段提升值,inputValue为默认值

提示

不支持多个输入框输入

但是可以通过html以及preConfirm属性来实现。

在preConfirm你可以返回自定义结果,preConfirm可以接受一个promise

例子如下

const { value: formValues } = await Swal.fire({
  title: 'Multiple inputs',
  html:
    '<input id="swal-input1" class="swal2-input">' +
    '<input id="swal-input2" class="swal2-input">',
  focusConfirm: false,
  preConfirm: () => {
    return [
      document.getElementById('swal-input1').value,
      document.getElementById('swal-input2').value
    ]
  }
})

if (formValues) {
  Swal.fire(JSON.stringify(formValues))
}

主题

sweetalert2有多种主题

图片.png

图片.png

如何引入主题

可以直接引入对应的css文件以及sweetalert2的js文件

https://cdn.jsdelivr.net/npm/@sweetalert2/theme-dark@3/dark.css
https://cdn.jsdelivr.net/npm/sweetalert2@9/dist/sweetalert2.min.js
引入以上两个文件

关于css文件地址

你可以在

https://cdn.jsdelivr.net/npm/@sweetalert2/themes@latest/

找到对应的文件目录以及对应的css文件。

结语

拖了这么久终于给sweetalert2完结了...累死了

图片.png
混的人。

8

主题

48

帖子

19

积分

开发者

Rank: 6Rank: 6

积分
19

国庆纪念章中秋纪念章

发表于 2021-11-22 17:21:49 | 显示全部楼层
ggnb!!!
死混子没货,开始灌水了
回复

使用道具 举报

189

主题

1474

帖子

763

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
763
发表于 2021-11-22 20:13:47 | 显示全部楼层

呜呜呜
现在没人看,越到后期看的人越少了
混的人。
回复

使用道具 举报

发表回复

本版积分规则

快速回复 返回顶部 返回列表