chrome插件的content.js注入到vue中改变了el-date-picker的input值,视图更新,数据不更新?

小弟不才,未经过系统学习,劳烦大神帮忙分析分析这个奇怪的问题。

我通过编写chrome插件,将content-script.js注入到了目标网站(目标网站前端用vue开发),试图通过popup.html页面的几个按钮,试图去操作目标页面的数据,以期望节约重复工作的时间,提升工作效率!

因为对jquery熟悉,所以最终生成的页面中有vue和jquery,我用此代码

$(function(){
    element=$(".el-date-editor").find("input");    
    element.val('2030-12-31');
    chufa(element[0],'input');
});
//这个函数我搜索出来说是绑定浏览器自身的事件触发,通过这个函数,我发现jquery可以更新vue生成的网页中的大部分input的展现形式,及input的value="值"
function chufa(element,eletype){
    var event = document.createEvent('HTMLEvents');
    event.initEvent(eletype, true, true);
    event.eventType = 'message';
    element.dispatchEvent(event);
}

操作下面的代码

<div class="el-date-editor">
<input type="text" autocomplete="off" name="" placeholder="请选择xx时间" class="el-input__inner">
</div>

通过chufa这个函数,我发现jquery可以更新vue生成的网页中的大部分input的展现形式,及input的value="值",但是唯独在vue的日期控件处失效了,vue的日期控件是否就是称之为:el-date-picker,就是下图中的这个小控件
image.png

我发现通过上图的代码,能够将我眼睛看到的日期input的输入框的值改变为2030-12-31,却无法真正的传递给vue,是vue双向绑定?亦或是vue没有被触发?
试图通过改变代码
chufa(element[0],'change');
或者
chufa(element[0],'blur');
或者
chufa(element[0],'input');
或者
chufa(element[0],'focus');
chufa(element[0],'input');
均无济于事。

很奇怪,这个问题困扰我好几个月了,这是我N次尝试突破此处困扰,遗憾的失败了...

特来贵宝地,寻求帮助,希望得到指导,不胜感激!

阅读 3k
2 个回答

content.js 运行在独立的沙箱里,与普通网页里的 JS 是隔离的,但是共享同一个 DOM。所以我们可以(也只可以)通过触发事件与网页里的 JS 进行数据交换。但是触发什么事件,就要看网页 JS 侦听什么事件。比如 Vue 默认侦听的是 input 事件,只有 .lazy 才会侦听 change 事件,所以你也得先尝试 input 事件。

至于组件,那可能性就更多了,建议看看源码,确定怎么触发以及从哪个节点开始触发。

我做过类似的自动化操作网页,建议分以下几个步骤来尝试:

1.首先用最简单的方式,比如直接修改input的值,或者直接触发click等。这种方式如果有效则最好,很快就能达到目的。但是对于框架封装的部分组件可能行不通,比如element-ui。

2.使用原生的Event事件去触发

new Event("value", { bubbles: true, cancelable: true })
new Event("focus", { bubbles: true, cancelable: true })
new Event("click", { bubbles: true, cancelable: true })

3.以上都不生效,需要特殊处理,比如input输入值,使用inputEvent

const input = document.querySelector(
                        '[for="addForm.0.hours"]+.el-form-item__content .el-input__inner'
                    );
const value = input.getAttribute("aria-valuenow");

const ev = new InputEvent("input", {
       inputType: "insertText",
       data:
             (value && Number(value) > 0) ||
                       info.productWorkTime,
       dataTransfer: null,
       isComposing: false,
 });
el.value = (value && Number(value) > 0) || info.productWorkTime;
el.dispatchEvent(ev);

4.还有些组件可能要先触发focus,再触发才行。

因为我也是偷懒,公司的工时系统每天要填很麻烦,就写了一个插件来完成。其中就实现了一套简单的流程来操作网页DOM,只需要按照规则填入DOM的选择器,和操作类型(click, value等),就能完成,其中还有轮询进行DOM查询等细节。

我的github上有例子,你可以参考一下
https://github.com/gxy5202/Au...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题