消费贷款app“一刻千金”接入网易严选总结

主要任务列表

  1. 隐藏相关元素
  2. 商品列表页跳转事件绑定
  3. 获取商品信息(skuid比较复杂)

隐藏元素

这部分没什么好讲的,使用原生js的document的api定位元素或者jQuery的选择器定位元素,然后隐藏(hide)或者移除(remove)

阻止列表页的事件

搜索到结果后,点击其中某个商品,希望跳转至改造过的详情页(改变了购买方式)。

搜索列表页的html主要结构如下:

<ul class="list">
<li class="item">
<a class="good" data-reactid="aaaaaa">商品1</a>
</li>
<li class="item">
<a class="good" data-reactid="bbbbbb">商品1</a>
</li>
<li class="item">
<a class="good" data-reactid="cccccc">商品1</a>
</li>
</ul>

以往接入京东、苏宁时,列表页商品跳转都是通过<a>标签设置href的,重新绑定事件,并使用preventDefault,可以防止href的跳转;

严选使用了react技术栈,这里有两个问题:

  1. 没有使用href,跳转是通过绑定事件,而这个事件处理方法是匿名函数,不知道怎么去移除(使用了jquery的off和unbind,都不起作用知识有限,暂留问号???);
  2. 列表页下拉时,加载,所以给每个<a>标签绑定事件,貌似不太友好也不太靠谱。

最后,采用事件委托的方式,只需给<ul>绑定一个点击事件,通过判断所点击当前元素,找出<a>标签所带的商品信息(取出属性data-reactid的值)。使用stopPropagation方法,可以阻断<a>的点击事件执行,完美。同时,也解决了下拉加载的问题。

使用jQuery:

$('ul').off('click').on('click', '.item', function(e) {
e.stopPropagation();
//e.currentTarget 当前点击的'.item'元素
var tag_a = $(e.currentTarget).find('a.good');
var data_reactid = tag_a.attr('data-reactid');
var product_id = data_reactid.match(/\$\d+/g)[0].replace('$', '');
var obj = {
link: 'http://m.you.163.com/item/detail?id=' + product_id,
type: '001'
}; console.log(obj);
postData(obj); //postData是与app通信的方法
});

原生js:

var ul = document.getElementsByClassName('list');
if(ul.length > 0) {
ul.addEventListener('click', function(e){
e.stopPropagation();
var path = e.path();//文档流
var a = path.filter(item => item.tagName == 'A')//寻找到a标签
var data_reactid = a[0].getAttribute('data-reactid');
var obj = {
link: 'http://m.you.163.com/item/detail?id=' + product_id,
type: '001'
}; console.log(obj);
postData(obj);//postData是与app通信的方法
})
}

使用事件委托的方式,还有个很大的好处。如果循环给<a>标签绑定点击事件,导致该页面存在大量事件处理程序,会影响性能。

在测试时,一直有个奇怪的问题:大量情况下,能确定该段js完整注入并执行,但是通过调试,就是观察不到ul的click事件;只有很小的几率成功。

并且webview注入该js时,确定是在页面渲染完成后才注入的。

后来猜想问题可能是react-router生命周期导致的,<ul>这一部分其实是在子路由里面,通过锚点形式。所以webview认为的页面渲染完成,可能其实不包括这段hash路由。

最后尝试将该事件绑定在<body>上,完美解决。

获取商品信息--skuid

京东、苏宁的商品id,在url上可以很直观地的出来;

而网易严选的商品页面,url中的search部分也有类似id的字段。只可惜,此id并不是需要下单商品的skuid。因为同样商品,不同规格(颜色、尺码等)时,skuid是不一样的。

经过大量不同商品页面的分析(其实也就试了两个)。

在商品详情页和选择规格的页面,有一个jsonData的全局变量,其中jsonData.skuMap类似下面的形式:

该商品有两个规格(颜色和尺码需要选择),很容易分析出,该如何确定,寻找skuid了。

  1. 获得所选规格(颜色、尺码)的值keyList;
  2. 将jsonData.skuMap转为[k,v]的列表skuMapList(使用Object.entries);
  3. 根据keyLlist,过滤筛选skuMapList,正常情况下,skuMapList只剩下一条数据。
function getSkuId() {
var spec_cons = document.getElementsByClassName('u-format');
var selObject = []
for (var i = 0; i < spec_cons.length - 1; i++) {
var element = spec_cons[i];
var selected = element.getElementsByClassName('tab-sel')[0];
if (selected) {
var str = selected.getAttribute('data-reactid');
var kv = str.match(/\$\d+/g);
var item = {
id: kv[0].replace('$', ''),
value: kv[1].replace('$', '')
}
selObject.push(item);
}
} polyfill();//解决老旧版本兼容性问题 var skuMapList = Object.entries(jsonData.skuMap);
for (var i = 0; i < selObject.length; i++) {
skuMapList = skuMapList.filter(function(item){
return item[0].indexOf(selObject[i].value) >= 0;
})
} var result_id = null; if(skuMapList.length == 1) {
result_id = skuMapList[0][1].id;
} return result_id;
}

老旧版本浏览器不支持Object.entries,Object.keys,Array.filter等方法,这里polyfill()就是检测兼容性:

方法参考 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript

function polyfill(){
if(!Object.keys){
Object.prototype.keys = function(){
//fun body
...
}
} if(!Object.entirs){
Object.prototype.keys = function(){
//fun body
...
}
} if(!Array.filter){
Array.prototype.keys = function(){
//fun body
...
}
}
}

最开始的算法中,找到所选规格的之后,通过拼接字符串得到skuMap的关键字。

如所选颜色color,尺寸size,那么key = color + ';' + size,最后的结果就是jsonData.skuMap[key]。

通过大量测试,发现有些情况key = size + ';' + color,导致取不到skuid。

所以改变算法,将skuMap变为列表,循环过滤。

最新文章

  1. Lua在单片机中的移植
  2. ThinkPhp 验证码不显示图片
  3. WebView 上传文件 WebChromeClient之openFileChooser函数
  4. 【转载】Unity 合理安排增量更新(热更新)
  5. 【POJ2104/2761】K-th Number
  6. 使用clusterprofile做聚类分析
  7. FZU 2171 线段树 区间更新求和
  8. php注册登录系统(一)-极简
  9. win8连接蓝牙听歌
  10. poj 1458 Common Subsequence【LCS】
  11. angular基础
  12. 用DOS命令来运行Java代码
  13. iis发布网站问题-由于权限不足而无法读取配置文件,无法访问请求的页面
  14. MySQL CURTIME() 函数
  15. uasrt配置
  16. 【转帖】解决远程连接MariaDB(mysql)很慢的方法
  17. IIS6 Gzip 网页GZIP压缩(转)
  18. oracle 字符处理
  19. Rendering Resources
  20. Css选择器(上) 让样式无孔不入

热门文章

  1. OpenWRT 添加应用程序开机启动方法
  2. Learning Scrapy 中文版翻译 第一章
  3. Debian 9 中手动设置有线网络
  4. CSS样式之表格,表单
  5. QT多标签浏览器(一)
  6. mysql批量更新数据,即:循环select记录然后更新某一字段
  7. Memcached理解
  8. 全面学习理解TLB(Translation Look-aside Buffer)地址变换高速缓存
  9. js 两个日期比较相差多少天
  10. DNS主从服务部署