上次发的文章《评论自动填写个人信息》所记方法一直觉得很好用,奈何个别网站用不了,其中就包括自己的博客。没办法换了个折中的法子,用输入法自带的自定义短语功能来加快填写速度。但这个方法也有不少问题,一是昵称、邮箱、网址这三项不少博客不能全部自动填写,总有那么一两项输入法调不出自定义的短语,这种情况在移动端上最为明显。二是操作步骤还是有点多,效率并不怎么高。
今天不死心,鼓捣了好长时间,终于把这个书签脚本自动填写评论信息的方法优化了一下,顺便也把在用的这个主题评论提交方面,自身存在的问题处理掉了,现将相关解决方法记录如下:
书签脚本不能在我的博客发挥作用的解释:
自动填写评论信息书签脚本,是通过直接操作 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;
});
},
},
};