优雅的 alert()

把警示窗改为显示在页面右上角,显示几秒后会自动关闭。用鼠标点按信息窗口会立即关闭,并把内容拷贝到系统剪贴板。

  1. // ==UserScript==
  2. // @name elegant alert()
  3. // @name:zh-CN 优雅的 alert()
  4. // @name:zh-TW 優雅的 alert()
  5. // @description Display a non-blocking alert box at the top right corner, and automatically close after a few seconds. Click on the alert box will close it immediately and copy the alert message to clipboard.
  6. // @description:zh-CN 把警示窗改为显示在页面右上角,显示几秒后会自动关闭。用鼠标点按信息窗口会立即关闭,并把内容拷贝到系统剪贴板。
  7. // @description:zh-TW 把警示窗改為顯示在頁面右上角,顯示幾秒後會自動關閉。用滑鼠點按訊息窗口會立即關閉,並把內容複製到系統剪貼簿。
  8. // @namespace https://gf.qytechs.cn/zh-TW/users/393133-evan-tseng
  9. // @author Evan Tseng
  10. // @version 1.14
  11. // @match *://*/*
  12. // @run-at document-start
  13. // @grant none
  14. // @license MIT
  15. // ==/UserScript==
  16.  
  17. (function() {
  18. 'use strict';
  19. const boxFont = '400 15pt sans-serif',
  20. boxFontColor = '#222',
  21. boxBgColor = 'rgba(240,240,210,.85)',
  22. boxHoverColor = 'rgba(255,255,255,.9)',
  23. popFontColor = '#8ff',
  24. popBgColor = '#b00',
  25. countdownColor = 'rgba(100,100,240,.2)',
  26. popDuration = 1500, // the period of highlight poping (ms)
  27. duration = 7200, // message box default lifetime (ms)
  28. fadeOutDuration = 700, // message box disppearing duration (ms)
  29.  
  30. eaCSS = '@media screen and (max-width:40em) { .elegantAlertBoxWrapper>.eaNormal, .elegantAlertBoxWrapper>.eaClose { max-width:50vw } }' +
  31. '@media screen and (min-width:40em) { .elegantAlertBoxWrapper>.eaNormal, .elegantAlertBoxWrapper>.eaClose { max-width:20em } }' +
  32. '.elegantAlertBoxWrapper { position:fixed; top:8mm; right:12mm; max-height:calc(100vh - 16mm); z-index:2147483647 }' +
  33. '.elegantAlertBoxWrapper>div { position:relative; float:right; clear:right; font:' + boxFont + '!important; line-height:1; color:' + boxFontColor + '; background:' + boxBgColor + '; padding:.1em .6em; margin-bottom:.4em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; border-radius:1em; opacity:.2; cursor:pointer; box-shadow:inset 0 0 0 1px rgba(255,255,255,.8), 0 1px 2mm rgba(0,0,0,.7); user-select:none; -webkit-user-select:none; backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px) }' +
  34. '.elegantAlertBoxWrapper .eaBar { position:absolute; left:0; top:0; width:100%; height:100%; background:' + countdownColor + '; border-radius:3px; z-index:2 }' +
  35. '.elegantAlertBoxWrapper>.eaPop { opacity:1; max-width:75vw; max-height:3em; animation:elegantAlertPopping ' + popDuration + 'ms 1 }' +
  36. '.elegantAlertBoxWrapper>.eaNormal { opacity:1; max-height:4em; transition:.3s }' +
  37. '.elegantAlertBoxWrapper>.eaClose { background:' + boxBgColor + '; opacity:0; min-height:0; max-height:0; padding-top:0; padding-bottom:0; margin:0; overflow:hidden; transform:scale(0); transition:' + fadeOutDuration + 'ms; -ms-overflow-style:none }' +
  38. '.elegantAlertBoxWrapper>.eaNormal:hover { max-width:80vw; background:' + boxHoverColor + '; z-index:2; box-shadow:inset 0 0 0 1px #fff, 0 1px 2mm rgba(0,0,0,.8); transform:scale(1.03); transition:.2s }' +
  39. '.elegantAlertBoxWrapper>.eaNormal:active { box-shadow:inset 0 1px 1mm #000, 0 0 0 1px #777; transform:scale(.97); transition:50ms }' +
  40. '.elegantAlertTextCopy { position:absolute; top:-2em; left:0; width:8em; height:1em }' +
  41. '@keyframes elegantAlertPopping { 0% { opacity:.7 } 7% { color:' + popFontColor + '; background:' + popBgColor + '; opacity:1; } 9% { transform:scale(1.05) } 20% {color: '+boxFontColor+'; background:' + boxBgColor + '; } 30% { transform:scale(1) } }';
  42.  
  43. var cssElement = document.createElement('style');
  44. if(cssElement.styleSheet) cssElement.styleSheet.cssText = eaCSS;
  45. else cssElement.appendChild(document.createTextNode(eaCSS));
  46. cssElement.setAttribute('title', 'Elegant Alert');
  47. document.querySelector('head').appendChild(cssElement);
  48.  
  49. var alertWrapper = null;
  50. const ElegantAlertBox = function(msg, lifeTime = duration){
  51. if(!alertWrapper) {
  52. document.documentElement.appendChild(alertWrapper = document.createElement('div'));
  53. alertWrapper.setAttribute('class', 'elegantAlertBoxWrapper');
  54. }
  55. this.exist = true;
  56. this.createBox = function(msgText){
  57. var box = this,
  58. alBox = document.createElement('div');
  59. alertWrapper.appendChild(alBox);
  60. alBox.innerHTML = '<div class="eaBar"></div>' + msgText;
  61. alBox.setAttribute('class', 'eaPop');
  62. alBox.addEventListener('click', function(){
  63. let tmp = document.createElement('textArea');
  64. tmp.setAttribute('class', 'elegantAlertTextCopy');
  65. tmp.value = msgText;
  66. document.documentElement.appendChild(tmp);
  67. tmp.select();
  68. document.execCommand('copy');
  69. tmp.remove();
  70. box.close();
  71. });
  72. return alBox;
  73. };
  74. this.show = function(){
  75. var box = this;
  76. setTimeout(function(){
  77. box.elm.querySelector('.eaBar').setAttribute('style', 'width:0; transition:linear ' + lifeTime + 'ms');
  78. }, 30)
  79. setTimeout(function(){
  80. box.elm.setAttribute('class', 'eaNormal');
  81. setTimeout(function(){
  82. if(box.exist) box.close();
  83. }, lifeTime - popDuration);
  84. }, popDuration);
  85. };
  86. this.close = function(){
  87. var box = this;
  88. box.elm.setAttribute('class', 'eaClose');
  89. setTimeout(function(){
  90. if(box.exist) {
  91. box.elm.remove();
  92. box.elm = undefined;
  93. box.exist = undefined;
  94. if(!alertWrapper.hasChildNodes()) {
  95. alertWrapper.remove();
  96. alertWrapper = null
  97. }
  98. box = undefined;
  99. }
  100. }, fadeOutDuration);
  101. };
  102. this.elm = this.createBox(msg);
  103. this.show();
  104. };
  105.  
  106. window.alert = function(message){
  107. if(document.body) new ElegantAlertBox(message);
  108. else setTimeout(function(){ window.alert(message); }, 250);
  109. };
  110. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址