app接入网易严选:webview注入js的几个坑
消费贷款app“一刻千金”接入网易严选总结
主要任务列表
- 隐藏相关元素
- 商品列表页跳转事件绑定
- 获取商品信息(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技术栈,这里有两个问题:
- 没有使用href,跳转是通过绑定事件,而这个事件处理方法是匿名函数,不知道怎么去移除(使用了jquery的off和unbind,都不起作用知识有限,暂留问号???);
- 列表页下拉时,加载,所以给每个
<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了。

- 获得所选规格(颜色、尺码)的值keyList;
- 将jsonData.skuMap转为[k,v]的列表skuMapList(使用Object.entries);
- 根据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变为列表,循环过滤。
app接入网易严选:webview注入js的几个坑的更多相关文章
- iOS webview注入JS
- (void)webViewDidFinishLoad:(UIWebView *)webView { NSString *js = @"function imgAutoFit() { \ ...
- iOS app的webview注入JS遇到的坑
webview使用JSContext 向网页js注入时时机要选为网页加载完成后即放在 -(void)webViewDidFinishLoad:(UIWebView *)webView 方法 : -(v ...
- iOS WebView调用JS的一个小坑
假如调用一个函数,传入的参数为String,要以这样的格式传入: let resultStr="1234" self.webView.stringByEvaluatingJavaS ...
- 基于Node.js+MySQL开发的开源微信小程序B2C商城(页面高仿网易严选)
界面高仿网易严选商城(主要是2016年wap版) 测试数据采集自网易严选商城 功能和数据库参考ecshop 服务端api基于Node.js+ThinkJS+MySQL 计划添加基于Vue.js的后台管 ...
- WebView与JS的几种交互
http://www.jianshu.com/p/0042d8eb67c0 最近整理了一下原生与H5之间的交互方式,简单的做个总结.OC端与JS的交互,大致有这几种:拦截协议.JavaScriptCo ...
- WebView中Js与Android本地函数的相互调用
介绍 随着Html5的普及,html在表现力上不一定比原生应用差,并且有很强的扩展兼容性,所以越来越多的应用是采用Html与Android原生混合开发模式实现. 既然要实现混合开发,那么Js与Andr ...
- 一步一步 copy163: 网易严选 ---- vue-cli
面试点 组件间通信 生命周期函数 路由 - 参数 - 重定向 vuex 参考 网易严选商城小程序全栈开发,域名备案中近期上线(mpvue+koa2+mysql) 小程序服务端源码地址 小程序源码地址 ...
- WebView注入Java对象注意事项
在android4.2以前,注入步骤如下: webview.getSetting().setJavaScriptEnable(true); class JsObject { public String ...
- 4.22 注入js需要加 addjavascriptinterface
由于项目需要,再次使用到了android的webview,webview要加载的页面是html5的页面: 需要有点击webview中的控件的交互,所以需要在android应用中注入一个js对象: 通过 ...
随机推荐
- cocos2dx - android环境配置及编译
接上一节内容:cocos2dx - 伤害实现 本节主要讲Android环境配置及编译 在第一节中setup.py的配置里,我们没有配置对应的ndk,sdk,ant的路径,在这里需要先配置好环境变量. ...
- 转载:WPF MVVM之INotifyPropertyChanged接口的几种实现方式
原文地址:http://www.cnblogs.com/xiwang/ 序言 借助WPF/Sliverlight强大的数据绑定功能,可以比实现比MFC,WinForm更加优雅轻松的数据绑定.但是在使用 ...
- win10 uwp 改变鼠标
经常在应用需要修改光标,显示点击.显示输入,但是有些元素不是系统的,那么如何设置鼠标? 本文主要:UWP 设置光标,UWP 移动鼠标 设置光标 需要写一点代码来让程序比较容易看到,什么光标对于什么. ...
- VIM格式化代码(How to format code with VIM)
1) 按两下小写g,即gg,定位光标到第一行.(2) 按住Shift+v,即大写V,进入可视化编辑的列编辑模式.(3) Shift+g,即大写G,选中整个代码.(4) 按下等号=,格式化所有代码.
- Java常用类(一)String类详解
前言 在我们开发中经常会用到很多的常用的工具类,这里做一个总结.他们有很多的方法都是我们经常要用到的.所以我们一定要把它好好的掌握起来! 一.String简介 1.1.String(字符串常量)概述 ...
- VS连接数据库的通用方法(SQL/MySql)
在vs里面连接数据库的方法有很多,这里是通用的方法和基本操作 SQL /// <summary> /// 数据访问抽象基础类 /// Copyright (C) Maticsoft /// ...
- toString方法的用处
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Consolas; color: #a5b2b9 } p.p1 { margin: 0.0px ...
- EF 数据重复和缺失问题(select 错误 )
字段有 id,name,password,sex 1.错误举例: var data = db.User.Select(d => d): 2修正 var data = db.User.Sele ...
- 用C写的计算运行时间
#include <stdio.h> #include <stdlib.h> #include <time.h> int main( void ) { long i ...
- Oracle结合Mybatis实现取表中前10条数据
之前一直使用mysql和informix数据库,查表中前10条数据十分简单: 最原始版本: select top * from student 当然,我们还可以写的复杂一点,比如外加一些查询条件? 比 ...