奇怪的input -前端监控之采坑篇
大坑描述
在录屏收集时, 对于部分js设置的输入框值无法获取到,但是该元素确实已加入mutation监控。
问题分析
demo中可以看出
-
input 输入框,对于不同的type, 在数据变更时,浏览器的操作是不同的
-
对于input 隐藏域, 无论操作的是attr还是展示value,都会反应到value属性上
-
radio或checkbox类型,手动点击选择不会触发mutation监听
-
textarea的效果和input普通输入框一致
解决方案
利用Object.defineProperty
修改原对象value(checked)属性的set方法, 手动监听
这边涉及到的输入Element对象如下
HTMLInputElement
, HTMLSelectElement
, HTMLTextAreaElement
修改绑定代码如下:
function wrapInput(reporter) {
function wrap(e, r) {
var i = Object.getOwnPropertyDescriptor(e.prototype, r);
return Object.defineProperty(e.prototype, r, {
set: function set(e) {
var node = this, n = mirrorNode.getId(node);
if(n) {
// 取该node的上一个属性值
var last = elementMap[n];
if(!last || (r === 'value' && last.text != e) || (r === 'checked' && last.isChecked != e)) {
// setTimeout的作用,用于延迟执行,便于将新属性值写入缓存
setTimeout(function() {
// 用于触发change方法
eventDoMap("change", reporter)({target: node, type: "change"})
})
}
}
return i.set.call(this, e);
}, get: function get() {
return i.get.call(this);
}
}), /**该方法定义了还原方法**/function () {
return Object.defineProperty(e.prototype, r, i);
};
}
var p = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value"),
f = [];
p && p.set && (f = f.concat([wrap(HTMLInputElement, "value"), wrap(HTMLInputElement, "checked"), wrap(HTMLSelectElement, "value"), wrap(HTMLTextAreaElement, "value")]));
return function () {
// 此处用于还原重写
f.forEach(function (e) {
return e();
});
};
}
标题:奇怪的input -前端监控之采坑篇
作者:hugh0524
地址:https://blog.uproject.cn/articles/2019/11/28/1574915423705.html
0 0