朱焱伟 发表于 2023-4-5 10:00:06

实现绿色的this.$message简易消息提示效果

本帖最后由 朱焱伟 于 2023-4-5 16:10 编辑

# 实现绿色的this.$message简易消息提示效果

## 需求
需要:原生实现好看点的简易消息提示。
很多时候,我们脚本成功做事后,都会来上一根事后的`this.$message`,也就是好看一点的消息提示。`alert`未免太丑,而额外引入像`sweetAlert`或`element-ui`这样的第三方库,在写简单油猴脚本的情况下,并不值当。论坛里的wwwwwllllk老哥写过很多有用的脚本,很不错;但是有一点,就是工程化之后弄出来的代码太长了。把好看的message全局提示组件,从`ant-design`里import过来,比较美观。这样写爽是爽了,正常的网站开发这样也没问题,不过我们是油猴环境,编译前本来几十行的代码弄成几千行,我感觉不太好。若给体积比较大的脚本多发请求,估计能把脚本站弄挂。
所以,我希望有这么一个简单的message消息提示的实现,网上估计也有挺多类似的吧。写本帖的目的,大概在于:以后遇到类似情况的时候,翻到这个帖子来复制粘贴。
话不多说了,直接来吧!

## 代码(更新后)
听从评论区cxxjackie建议,把style改成了cssText的写法,代码更短了点,可读性也好。
```javascript
// My Message 实现类似this.$message的效果
class Message {
    constructor() {
      this.container = document.createElement('div');
      this.container.id = 'messageContainer';
      this.container.style.cssText = 'position: fixed; top: 20px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; justify-content: center; z-index: 9999;';
      document.body.appendChild(this.container);
    }
    show(message, iconType) {
      const p = document.createElement('p');
      p.style.cssText = 'margin: 10px; padding: 10px; background-color: #f5f5f5; border-radius: 4px; display: flex; align-items: center;';
      let icon;
      if (iconType === 'tick') {
            icon = document.createElement('span');
            icon.style.cssText = 'width: 16px; height: 16px; background-color: green; border-radius: 50%; margin-right: 10px;';
            const checkmark = document.createElementNS("http://www.w3.org/2000/svg", "svg");
            checkmark.setAttribute("viewBox", "0 0 24 24");
            checkmark.setAttribute("width", "16");
            checkmark.setAttribute("height", "16");
            const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
            path.setAttribute("d", "M9 16.2l-3.6-3.6c-.8-.8-.8-2 0-2.8s2-.8 2.8 0L9 11.6l6.2-6.2c.8-.8 2-.8 2.8 0s.8 2 0 2.8L11.8 16.2c-.4.4-.8.6-1.3.6-.5 0-.9-.2-1.3-.6z");
            path.setAttribute("fill", "white");
            checkmark.appendChild(path);
            icon.appendChild(checkmark);
      } else {
            icon = document.createElement('span');
            icon.style.cssText = 'width: 16px; height: 16px; background-color: green; border-radius: 50%; margin-right: 10px;';
      }
      p.appendChild(icon);
      const text = document.createTextNode(message);
      p.appendChild(text);
      this.container.appendChild(p);
      setTimeout(() => {
            this.container.removeChild(p);
      }, 3000);
    }
}

// 使用示例
const message = new Message();
// message.show('这是一条消息提示');
message.show('这是一条消息提示', 'tick'); // 显示绿色勾图标的消息提示
```

## 代码解释
以上代码中,我们将消息提示功能封装成了一个名为 Message 的 class。在构造函数中,我们创建了一个 div 元素作为消息容器;在 show 方法中,我们将消息添加到容器中,并设置了定时器来自动移除消息。最后,我们可以根据需要实例化 Message 类,并调用其 show 方法来显示消息。
希望这个示例能够帮助您理解如何使用类来进行进一步的封装。
在上述脚本中,我们使用了SVG(可缩放矢量图形)来渲染白色对号,从而实现更符合您要求的图标效果。我们通过创建`<svg>`和`<path>`元素来生成一个带有白色对号的绿色圆形图标。同时在show方法内部增加了iconType参数,用于传递需要显示的图标类型。当`iconType`为`'tick'`时,创建了一个带有白色对号的绿色圆形图标,与您所描述的对号图标相似。

## 代码来源
上面说的代码解释,礼貌得不像人话了。实际上,我自己没有写任何代码,这是问chatGPT问出来的。下面我把问的话列出来,7句话,让chatGPT给我写脚本。
- 1.写一个不需要依赖库的油猴脚本实现类似this.$message的效果
- 2.这个消息挪到中间上方,并且消息左边弄一个小的绿色对号
- 3.上面这个脚本能不能进一步封装,比如都弄进一个class里面
- 4.上面你的脚本里,左边是一个绿色的圆,能不能弄成绿色的勾的图标
- 5.这个脚本里绿色钩的图标画得不对
- 6.脚本对号图标看起来还是不对,应该像this.$message默认的那样,是个绿色圆形,里面是白色的像耐克logo的对号
- 7.上面脚本的图标里,请修改对号图标的实现

我指出它画的不好的地方,它说,马老师,对不起,对不起,生为AI我很抱歉,我不懂规矩。它可不是乱写的嗷,噔噔训练有素,每次修改后的脚本还都能跑。看来是有备而来。

## 例子
这个可以简单替代一下`this.$message`,代码不是很复杂,但让我写也不太会写。我不生产代码,我只是chatGPT的搬运工。
另外,我用chatGPT弄了个`按行驼峰命名单词转换器`,功能是:将每行以空格分隔的单词,按驼峰命名合并为一行,并提供复制功能。
比如,在文本框输入几行文本,会将`try to take over the world`这样的一行或多行句子,转换为`tryToTakeOverTheWorld`这样的驼峰命名的变量名。若文本行数多,可使用一键复制功能,会有绿色的消息提示复制成功。

## 访问地址
在(https://scriptcat.org/script-show-page/939)安装脚本后,可去[https://www.sogou.com/dollarmsg](https://www.sogou.com/dollarmsg)看效果。
在[按行驼峰命名单词转换器の脚本站地址](https://scriptcat.org/script-show-page/940)安装脚本后,可去[https://www.sogou.com/camelfucker](https://www.sogou.com/camelfucker)使用。
这里我都是match了类似[https://www.sogou.com/*](https://www.sogou.com/scriptcat)的404地址,因为它干扰比较少,好改造。

## 相关链接
- (https://scriptcat.org/script-show-page/939)
- (https://www.sogou.com/dollarmsg)
- [按行驼峰命名单词转换器の脚本站地址](https://scriptcat.org/script-show-page/940)
- [按行驼峰命名单词转换器之脚本安装好后的访问地址`camelfucker`](https://www.sogou.com/camelfucker)
- (https://zhuanlan.zhihu.com/p/115108882)

## 初版代码
保留大肠原本的味道
```javascript
// 实现类似this.$message的效果(使用 class 封装)
class Message {
constructor() {
    this.container = document.createElement('div');
    this.container.id = 'messageContainer';
    this.container.style.position = 'fixed';
    this.container.style.top = '20px';
    this.container.style.left = '50%';
    this.container.style.transform = 'translateX(-50%)';
    this.container.style.display = 'flex';
    this.container.style.alignItems = 'center';
    this.container.style.justifyContent = 'center';
    this.container.style.zIndex = '9999';
    document.body.appendChild(this.container);
}

show(message, iconType) {
    const p = document.createElement('p');
    p.style.margin = '10px';
    p.style.padding = '10px';
    p.style.backgroundColor = '#f5f5f5';
    p.style.borderRadius = '4px';
    p.style.display = 'flex';
    p.style.alignItems = 'center';

    let icon;
    if (iconType === 'tick') {
      icon = document.createElement('span');
      icon.style.width = '16px';
      icon.style.height = '16px';
      icon.style.backgroundColor = 'green';
      icon.style.borderRadius = '50%';
      icon.style.marginRight = '10px';
      const checkmark = document.createElementNS("http://www.w3.org/2000/svg", "svg");
      checkmark.setAttribute("viewBox", "0 0 24 24");
      checkmark.setAttribute("width", "16");
      checkmark.setAttribute("height", "16");
      const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
      path.setAttribute("d", "M9 16.2l-3.6-3.6c-.8-.8-.8-2 0-2.8s2-.8 2.8 0L9 11.6l6.2-6.2c.8-.8 2-.8 2.8 0s.8 2 0 2.8L11.8 16.2c-.4.4-.8.6-1.3.6-.5 0-.9-.2-1.3-.6z");
      path.setAttribute("fill", "white");
      checkmark.appendChild(path);
      icon.appendChild(checkmark);
    } else {
      icon = document.createElement('span');
      icon.style.width = '16px';
      icon.style.height = '16px';
      icon.style.backgroundColor = 'green';
      icon.style.borderRadius = '50%';
      icon.style.marginRight = '10px';
    }

    p.appendChild(icon);
    const text = document.createTextNode(message);
    p.appendChild(text);
    this.container.appendChild(p);

    setTimeout(() => {
      this.container.removeChild(p);
    }, 3000);
}
}

// 使用示例
const message = new Message();
message.show('这是一条消息提示', 'tick'); // 显示绿色圆形,带白色对号的消息提示
```


wwwwwllllk 发表于 2023-4-5 10:49:03

只是自己太懒了,加上自己还是菜,其实用脚手架开发还是有很多好处的,可以实现github自动发布,同时好的项目也可以大家一起维护

wwwwwllllk 发表于 2023-4-5 10:51:31

我一直想用脚手架csdn脚本,实在是懒,加上做一款满足大多数人的脚本实在是不容易,gf的那个csdn代码量太多了,实在是想帮他改又懒得改。如果用脚手架就还好。

朱焱伟 发表于 2023-4-5 11:29:55

wwwwwllllk 发表于 2023-4-5 10:51
我一直想用脚手架csdn脚本,实在是懒,加上做一款满足大多数人的脚本实在是不容易,gf的那个csdn代码量太多 ...

确实,能用就行懒得弄了。实际上我弄简单脚本也会使用脚手架,不过确实简单的脚本写完后可以稍改造一下,算是个人偏好吧,this.$message也没什么不对,我发这个主要给自己以后复制粘贴用。

cxxjackie 发表于 2023-4-5 12:15:30

把style改成cssText的写法还能再短点,可读性也好。

脚本体验师001 发表于 2023-4-5 12:59:03

实际Message 是刚需,痛点楼主说的也透彻
如果脚本猫实现这个呢,@王一之 GM_message
别老说不兼容,以后可能要他们来兼容咱们,但是可但是,得把王一之当成生产队的

王一之 发表于 2023-4-5 14:40:12

脚本体验师001 发表于 2023-4-5 12:59
实际Message 是刚需,痛点楼主说的也透彻
如果脚本猫实现这个呢,@王一之 GM_message
别老说不兼容,以后可 ...

这个不好做,不会脚本猫实现的,脚本猫(扩展)只会去实现扩展层的东西

像这,没必要脚本猫内置实现,1是不同的作者需要不同的样式,2是需要兼容各种网站,这只有脚本作者才知道

这种东西应该是由@require去实现的

王一之 发表于 2023-4-5 14:41:15

实现些简单的感觉chatGPT没问题,但是我问他一些问题什么的,老是给我胡说八道,chatGPT:“你就说能不能跑吧”

王一之 发表于 2023-4-5 14:46:03

wwwwwllllk 发表于 2023-4-5 10:51
我一直想用脚手架csdn脚本,实在是懒,加上做一款满足大多数人的脚本实在是不容易,gf的那个csdn代码量太多 ...

做稍微大点的项目,还是很有必要脚手架的

可以分模块开发,不像userscript这样,全杂在一起

可以引用社区的包,很多包可能无法用@require

另外就是方便版本管理,好处很多

小脚本就直接上ScriptCat自带的编辑器了

涛之雨 发表于 2023-5-7 19:50:16

其实require了,管他多大你看着都是一行{:4_108:}

此外中间那一坨直接改成innerHTML不香吗

// My Message 实现类似this.$message的效果
class Message {
    constructor() {
      this.container = document.createElement('div');
      this.container.id = 'messageContainer';
      this.container.style.cssText = 'position: fixed; top: 20px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; justify-content: center; z-index: 9999;';
      document.body.appendChild(this.container);
    }

    show(message, iconType) {
      const p = document.createElement('p');
      p.style.cssText = 'margin: 10px; padding: 10px; background-color: #f5f5f5; border-radius: 4px; display: flex; align-items: center;';
      const icon = document.createElement('span');
      icon.style.cssText = 'width: 16px; height: 16px; background-color: green; border-radius: 50%; margin-right: 10px;';
      if (iconType === 'tick') {
            icon.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16"><path d="M9 16.2l-3.6-3.6c-.8-.8-.8-2 0-2.8s2-.8 2.8 0L9 11.6l6.2-6.2c.8-.8 2-.8 2.8 0s.8 2 0 2.8L11.8 16.2c-.4.4-.8.6-1.3.6-.5 0-.9-.2-1.3-.6z" fill="white"></path></svg>';
      }
      p.appendChild(icon);
      p.appendChild(document.createTextNode(message));
      this.container.appendChild(p);
      setTimeout(() => this.container.removeChild(p), 3000);
    }
}

// 使用示例
const message = new Message();
// message.show('这是一条消息提示');
message.show('这是一条消息提示', 'tick'); // 显示绿色勾图标的消息提示
页: [1] 2
查看完整版本: 实现绿色的this.$message简易消息提示效果