js层级选择框样式_IOS和JS的交互,看这一篇文章就够了
IOS和JS的交互,看这一篇文章就够了
创作不易,请珍惜,之后会持续更新,不断完善
Demo地址
目录
WKWebView使用、JS的交互
WKWebView使用、JS的交互
演示(本来想贴张GIF作为演示流程的,害,太模糊不清了还是算了,话说简书写起来不方便呀,图片大小清晰度也挺难看的,吐槽下),顺便列举下控制台的所有输出作为例证,相关输出用到的地方在代码注释处有写
控制台输出
创建WKWebView
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; // 创建wkWebView self.wkWebView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration]; self.wkWebView.UIDelegate = self; self.wkWebView.navigationDelegate = self; [self.view addSubview:self.wkWebView];
WKNavigationDelegate
页面加载完成之后调用, 定义一个全局变量 arr
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{ // 导航栏标题 self.title = webView.title; // 定义一个全局变量 arr NSString *jsStr = @"var arr = [5, '谢佳培', 'xiejiapei']; "; [self.wkWebView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) { // 页面加载完成之后调用, 定义一个全局变量 arr: (null)----(null) NSLog(@"页面加载完成之后调用, 定义一个全局变量 arr: %@----%@",result, error); }];}
拦截网页的跳转链接: 在发送请求之前,决定是否跳转,点击提交按钮的时候会调用该方法
提交.png
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{ // URL = @"lgedu://jsCallOC?username=Cooci&password=123456" // 获取请求的URL NSURL *URL = navigationAction.request.URL; // 获取URL Scheme,其作用为方便app之间互相调用而设计的 NSString *scheme = [URL scheme];
// 拦截lgedu if ([scheme isEqualToString:@"lgedu"]) { // url是地址, 在某个主机目录下的文件的唯一标识符(统一资源定位符url) // domain是域名, 比如baidu.com就是域名,而其对应的ip地址指向了百度的服务器 // host是主机, 默认情况http协议是80端口 https协议是443端口 NSString *host = [URL host];
// 主机名为jsCallOC if ([host isEqualToString:@"jsCallOC"]) { // 解析URL NSMutableDictionary *temDict = [self decoderUrl:URL]; NSString *username = [temDict objectForKey:@"username"]; NSString *password = [temDict objectForKey:@"password"]; // 用户名和密码:谢佳培------123456 NSLog(@"用户名和密码:%@------%@",username,password); } else { NSLog(@"不明地址 %@",host); } // 不允许跳转 decisionHandler(WKNavigationActionPolicyCancel); return; } // 允许跳转 decisionHandler(WKNavigationActionPolicyAllow);}
解析URL地址,取得JS中的值
// 解析URL地址- (NSMutableDictionary *)decoderUrl:(NSURL *)URL{ // URL = @"lgedu://jsCallOC?username=谢佳培&password=123456" // 分开参数 NSArray *params = [URL.query componentsSeparatedByString:@"&"]; NSMutableDictionary *tempDic = [NSMutableDictionary dictionary];
for (NSString *param in params) { // 分开键值对 NSArray *dictArray = [param componentsSeparatedByString:@"="];
if (dictArray.count 1) { /** 网络请求拼接中文参数,用户名登陆等很多地方会用到中文,UTF8编码显得颇为重要 * 编码: * NSString* hStr =@"你好啊"; * NSString* hString = [hStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; * NSLog(@"hString === %@",hString); // hString === %E4%BD%A0%E5%A5%BD%E5%95%8A * * 解码: * NSString*str3 =@"\u5982\u4f55\u8054\u7cfb\u5ba2\u670d\u4eba\u5458\uff1f"; * NSString*str5 = [str3 stringByRemovingPercentEncoding]; * NSLog(@"str5 ==== %@",str5);// str5 ====如何联系客服人员? */ // 取值, 中文解码 NSString *decodeValue = [dictArray[1] stringByRemovingPercentEncoding]; // 解码后放入tempDic [tempDic setObject:decodeValue forKey:dictArray[0]]; } }
return tempDic;}
JS中相关代码如下
>input type="button" value="提交" onclick="submit()" /br /< function submit(){ alert('点击了提交按钮,调用loadURL方法获得URL'); loadURL("lgedu://jsCallOC?username=谢佳培&password=123456"); }
function loadURL(url) { var iFrame; iFrame = document.createElement("iframe"); iFrame.setAttribute("src", url); iFrame.setAttribute("style", "display:none;"); iFrame.setAttribute("height", "0px"); iFrame.setAttribute("width", "0px"); iFrame.setAttribute("frameborder", "0"); document.body.appendChild(iFrame); iFrame.parentNode.removeChild(iFrame); iFrame = null; }
WKUIDelegate
使用OC样式的弹出警告框,覆盖JS的丑陋样式
// 警告框- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{ // 使用OC样式的弹出警告框,覆盖JS的丑陋样式 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提醒" message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *knowAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { // 回调完成 completionHandler(); }]; [alert addAction:knowAction]; [self presentViewController:alert animated:YES completion:nil];}
OC 调用 JS方法
通过 evaluateJavaScript
调用了JS中的showAlert
方法
演示图:
代码片段:OC
// JS方法 // alert('我是一个可爱的弹框 \n'+messgae+'\n'+arr[1]); // arr[1]来自在我们在页面加载完成后定义的全局变量arr // msg: 我是一个可爱的弹框 登陆成功 谢佳培 NSString *jsStr = [NSString stringWithFormat:@"showAlert('%@')",@"嗨,这是通过OC调用showAlert方法哦"];
// OC 调用 JS方法 [self.wkWebView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) { // OC 调用 JS方法: token----(null) // Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌, // 当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。 // 使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。 NSLog(@"OC 调用 JS方法: %@----%@",result, error); }];
代码片段:JS
function showAlert(messgae){ alert('我是一个可爱的弹框 \n'+messgae+'\n'+arr[1]); return "token"; }
WKUserContentController
调整按钮大小适应APP页面
configuration.userContentController = [self wkwebViewScalPreferences];
// 调整按钮大小适应APP页面- (WKUserContentController *)wkwebViewScalPreferences{ // js注入: json调整按钮大小脚本 NSString *jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
/** WKUserScript就是帮助我们完成JS注入的类,它能帮助我们在页面填充前或js填充完成后调用 * 参数1:脚本的源代码 * 参数2:脚本应注入网页的时间,是个枚举,End表示:在文档完成加载之后,但在其他子资源完成加载之前插入脚本 * 参数3:是否加入所有框架,还是只加入主框架 */ WKUserScript *wkUserScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES]; WKUserContentController *wkUserContentController = [[WKUserContentController alloc] init]; [wkUserContentController addUserScript:wkUserScript];
return wkUserContentController;}
MessgaeHandle
JS相关代码: 发送了消息
>input type="button" value="messgaeHandle" onclick="messgaeHandle()" /<>br /< function messgaeHandle(){ // js -- android alert('给messageHandlers页面发送了“青春气息”'); window.webkit.messageHandlers.messgaeOC.postMessage("青春气息"); }
在viewWillAppear
中监听消息,但是注意在viewWillDisappear需要移除,否则会造成循环引用,不会调用到dealloc方法
// 循环引用:self - webView - configuration - userContentController - self- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated];
// 添加scriptMessageHandler到所有的frames中, // html5中需要添加window.webkit.messageHandlers.>name<.postmessage>messageBody [self.wkWebView.configuration.userContentController addScriptMessageHandler:self name:@"messgaeOC"];}// 需要根据name移除所注入的scriptMessageHandler来打破循环引用, 否则不会调用到dealloc方法- (void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [self.wkWebView.configuration.userContentController removeScriptMessageHandlerForName:@"messgaeOC"];}- (void)dealloc{NSLog(@"dealloc:溜了溜了");}
WKScriptMessageHandler
WKWebView收到ScriptMessage时回调此方法
// WKWebView收到ScriptMessage时回调此方法- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ if (message.name) { // OC 层面的消息 } // message == messgaeOC --- 青春气息 NSLog(@"消息是:%@ --- %@",message.name,message.body);}
js层级选择框样式_IOS和JS的交互,看这一篇文章就够了相关推荐
- js层级选择框样式_【JavaWeb】85:jQuery的各种选择器
今天是刘小爱自学Java的第85天. 感谢你的观看,谢谢你. 话不多说,开始今天的学习: 选择器的作用是什么? 可以快速准确地定位我们所需要的标签. 刚学CSS的时候,觉得CSS选择器也太多了吧,直到 ...
- 浏览器滚动条css样式设置,看这一篇文章就够了!
一 前言 在CSS 中,如果我们在块级容器上设置了属性: overflow:scroll /* x y 方向都会*/ 或者 overflow-x:scroll /*只是x方向*/ 或者 overflo ...
- input选择框样式修改与自定义
html自带的选择框样式不好看,并且在ios设备上丑的罚款.所以一般都是自定义样式: 原理:将原来默认的input选择框隐藏,然后控制label的:before与:after,配合矢量图标或者图片来实 ...
- 用jquery修改默认的单选框radio或者复选框checkbox选择框样式
默认的radio和checkbox选框很难看.我去看了一下qq注册的页面.发现单选和复选框并没有用<input>,居然是用是A标签.然后用css背景图片展示选择框,用JavaScript控 ...
- mock.js如何使用?简单易懂,一学就会,一篇文章即可出师
1,mock.js是什么? mockjs是生成随机数据的一款前端工具,用来模拟 Ajax 请求,生成并返回模拟数据 2,为什么用mockjs? 当程序员做项目开发时,前端工程师要请求后端做好的数据时, ...
- js如何修改html样式,怎么用js改变css样式?
怎么用js改变css样式?下面本篇文章给大家介绍一下使用JavaScript改变css样式的方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 怎么用js改变css样式? 1.通过 ...
- html input选择框样式修改,关于type=file的input框样式修改小结
关于type="file"的input是啥? 这个是啥我觉得没必要再说了,反正大家都知道,然后在现在有各种手机的时代,还可以通过直接拍照的方式来上传,反正比以前好玩多了. 上传按钮 ...
- 吉他新手防踩雷,告别吉他选择困难症!初学者吉他推荐!看这一篇就够了!
吉他新手扫盲 | 告别吉他选择困难症+初学者吉他推荐!一篇全搞定! 1.考虑预算 2.合板.面单.全单 3.手感弦距 4.音色.音准 5.桶型选择 6.吉他保养 对于吉他的挑选,各位新手小可爱们总是有 ...
- html文本框自动赋值,js给文本框赋值 value与innerHTML
赋值操作: document.getElementById("testId").value="hello"; value与innerHTML的区别 上面的val ...
最新文章
- Java调用ocx控件以及dll
- tesseract-ocr tips
- ----icon moon追加新字体图标----
- apt get php mysql_Ubuntu10用apt-get配置apache+php+mysql(轉)
- 该如何弥补 GitHub 功能缺陷?
- 关于tomcat 中的 tomcat-users.xml 配置不生效原因
- 叶脊网络拓扑(leaf-spine)
- 怎样看oracle有没有监听,Oracle数据库学习_Windows系统查看Oracle数据库监听状态的方法...
- Laravel学习记录--查询构造器
- 如何选择适合你的兴趣爱好(六十一),瓷器
- java的json解析_java中json的使用和解析
- allegro 封装shape焊盘问题 Unable to load shape symbol
- 《论文阅读》Knowledge-Enriched Transformer for Emotion Detection in Textual Conversations
- 数据库操作--已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行
- 51单片机数码管滚动显示学号_单片机数码管显示0到9程序代码
- Linux磁盘挂载问题 ***is apparently in use by the system; will not make a filesystem here!
- 基于LC push的浏览器桌面提醒快速集成方案
- 可视化图形界面编程(Easyx联合c++的通讯录系统)
- 汽车散热器不同造型的注塑件管口密封方案
- SQL注入堆叠注入二次注入
热门文章
- 卡通风格的渲染【Unity Shader入门精要14.1】
- VB.NET 读写HTML 文件,VB.Net读取和写入文本文件
- vbox 虚拟机访问网络,各个虚拟机实现互通
- 数据仓库灵魂30问之数仓有哪几种建模思想?
- Android 6.0: 动态权限管理的解决方案
- 【leetcode】75.颜色分类(多种解法,超详细图文解析)
- 帝国php分页,解决帝国CMS自动分页的问题
- JVM-XX:NewRatio 、-XX:SurvivorRatio 参数的含义
- 第18期基于SpringBoot仓库管理系统
- 四川省、成都市国际、国家、行业标准制定项目申请材料条件及认定奖励补助