上次发的文章《评论自动填写个人信息》所记方法一直觉得很好用,奈何个别网站用不了,其中就包括自己的博客。没办法换了个折中的法子,用输入法自带的自定义短语功能来加快填写速度。但这个方法也有不少问题,一是昵称、邮箱、网址这三项不少博客不能全部自动填写,总有那么一两项输入法调不出自定义的短语,这种情况在移动端上最为明显。二是操作步骤还是有点多,效率并不怎么高。
今天不死心,鼓捣了好长时间,终于把这个书签脚本自动填写评论信息的方法优化了一下,顺便也把在用的这个主题评论提交方面,自身存在的问题处理掉了,现将相关解决方法记录如下:
书签脚本不能在我的博客发挥作用的解释:
自动填写评论信息书签脚本,是通过直接操作 DOM 将评论表单中的昵称、邮箱和网址字段填写的,在 Vue.js 应用中,表单输入通常使用 v-model 进行数据绑定。当直接通过 JavaScript 修改输入元素的 value 属性时,Vue.js 无法检测到这些更改,因为它依赖于 input 事件来同步数据。
为了让 Vue.js 识别到通过脚本填写的内容,需要在修改输入值后,手动触发 input 事件。这将通知 Vue.js 数据模型已经更新,从而正确地同步数据。
新的评论自动填写个人信息书签脚本解决了这个问题,现记录如下:(使用方法见上篇)
javascript:(function()%7Bvar%20lauthor=%5B%22%23author%22,%22input%5Bname='comname'%5D%22,%22%23inpName%22,%22input%5Bname='author'%5D%22,%22%23ds-dialog-name%22%5D,lmail=%5B%22%23mail%22,%22%23email%22,%22input%5Bname='commail'%5D%22,%22%23inpEmail%22,%22input%5Bname='email'%5D%22,%22%23ds-dialog-email%22%5D,lurl=%5B%22%23url%22,%22input%5Bname='comurl'%5D%22,%22%23inpHomePage%22,%22%23ds-dialog-url%22,%22input%5Bname='url'%5D%22%5D;for(var%20i=0;i%3Clauthor.length;i++)%7Bvar%20author=document.querySelector(lauthor%5Bi%5D);if(author!=null)%7Bauthor.value='沉沦';var%20event=document.createEvent('Event');event.initEvent('input',true,true);author.dispatchEvent(event);break;%7D%7Dfor(var%20j=0;j%3Clmail.length;j++)%7Bvar%20mail=document.querySelector(lmail%5Bj%5D);if(mail!=null)%7Bmail.value='admin@kkn.me';var%20event=document.createEvent('Event');event.initEvent('input',true,true);mail.dispatchEvent(event);break;%7D%7Dfor(var%20k=0;k%3Clurl.length;k++)%7Bvar%20url=document.querySelector(lurl%5Bk%5D);if(url!=null)%7Burl.value='https://kkn.me';var%20event=document.createEvent('Event');event.initEvent('input',true,true);url.dispatchEvent(event);break;%7D%7D%7D)();
现用主题使用此书签脚本存在的问题:
当读者是首次发表评论时,使用书签代码自动填写昵称、邮箱和网址后,昵称和网址会被自动清空。这是因为在这个主题的 CommentForm 组件中,有一段代码会在邮箱字段改变后,自动获取用户信息并更新 this.form.author 和 this.form.url。如果获取到的 author 和 url 为空,就会将书签脚本填写的昵称和网址清空。为了避免昵称和网址被清空,需要在 author 和 url 有值时才更新 this.form.author 和 this.form.url。
另外这个主题本身还存在一个比较明显的问题,就是评论提交时不会正确验证必填项,造成即使你不填写必填的邮箱和昵称信息,提交评论后前端仍然反馈错误的“评论提交成功”提示。
现将这个主题 modules.js 中修改后的整个评论表单代码记录如下:(修改后的代码,可以确保昵称和网址不会在使用上述新的书签脚本后,自动填写的信息被清空。并且修复了评论提交时不会正确验证必填项,避免了提示成功但实际提交失败的情况。)
this.CommentForm = { name: 'comment-form', template: ` <form method="post" action id="comment_form" :class="{ 'small-size': reply.id }" @submit="e => e.preventDefault()"> <div class="form-group w-100"> <div v-show="!userId" slot="content-top" class="user-info flex-center w-100"> <input v-for="(item, index) in inputs" :key="item.key" class="form-input" type="text" v-model="form[item.bind.name]" v-bind="item.bind" :disabled="sending" @input="() => item.event && item.event()" /> </div> <div class="d-flex"> <figure class="user-avatar s-rounded"> <img class="s-rounded" :src="avatar" :alt="form.author" /> </figure> <div class="d-flex flex-wrap w-100"> <editor class="w-100" ref="editor" @submit="submit" v-bind="info.editor" /> </div> </div> </div> </form> `, components: { Editor: that.Editor }, props: { info: { type: Object, default: () => ({}), }, reply: { type: Object, default: () => ({}), }, }, data() { return { sending: false, inputs: [ { bind: { name: 'email', placeholder: '邮件', required: true, autocomplete: 'email' }, event: $h.debounce(() => { $h.visitor(this.form.email, ({ author, avatar, url }) => { this.avatar = avatar; // 仅在返回的 author 有值且当前 form.author 为空时更新 if (!this.form.author && author) { this.form.author = author; } // 仅在返回的 url 有值且当前 form.url 为空时更新 if (!this.form.url && url) { this.form.url = url; } }); }, 600), }, { bind: { name: 'author', placeholder: '昵称', required: true, autocomplete: 'name' } }, { bind: { name: 'url', placeholder: '网址', autocomplete: 'url' } }, ], avatar: 'data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=', userId: '', form: { comment_post_ID: null, comment_parent: null, author: '', email: '', url: '', comment: '', }, }; }, watch: { info: { deep: true, immediate: true, handler({ post_id, visitor }) { this.userId = visitor.user_id; if (visitor.email !== this.form.email) { $h.visitor(visitor.email, ({ avatar }) => { this.avatar = avatar; }); } // 修改 this.form 赋值方式,避免覆盖已有的 author 和 url this.form = { ...this.form, comment_post_ID: post_id, email: visitor.email || this.form.email, author: this.form.author || visitor.author || '', url: this.form.url || visitor.url || '', }; }, }, reply: { deep: true, immediate: true, handler(data) { this.form.comment_parent = data.id; }, }, }, methods: { submit({ content, upload }) { if (!content) { this.$toast({ type: 'error', message: '请输入评论内容' }); return; } // 验证必填字段 if (!this.userId && (!this.form.author || !this.form.email)) { this.$toast({ type: 'error', message: '请填写昵称和邮箱' }); return; } this.form.comment = content; this.sending = true; $h.ajax({ query: { action: 'submit_comment' }, data: this.form, method: 'POST', }) .then(response => { if (response && response.success) { this.$refs.editor.clear(); this.$toast({ type: 'success', message: '评论提交成功' }); this.$emit('append', response.data); } else { const errorMsg = response && response.message ? response.message : '评论提交失败'; this.$toast({ type: 'error', message: errorMsg }); } }) .catch(error => { const errorMsg = error && error.message ? error.message : '评论提交失败,请重试'; this.$toast({ type: 'error', message: errorMsg }); }) .finally(() => { this.sending = false; }); }, }, };