iOS web view如何绑定一个自定义的类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS web view如何绑定一个自定义的类相关的知识,希望对你有一定的参考价值。
file:///Users/aoll/Library/Containers/com.tencent.qq/Data/Library/Application%20Support/QQ/Users/1784641826/QQ/Temp.db/D221ACDE-A606-497C-8B73-1D22954E8530.png 在这里写上自定义的类的类名,但是总是会恢复到系统的
用xib写的webView
曾经做过的App也有这样的需求,思路是在UIWebView 的 Request 的 Header 中设置 UserAgent,最后证实这条思路是行不通的,后来由于时间问题,这个功能就放弃了。如今有个App又有这个需求,看到UC浏览器设置中有个UA设置,让我很是羡慕,果然愿意解决问题的人总是幸运的,再网上找到相关文章。了解大概两种思路,第一种是使用私有API,第二种则是iOS SDK内的。第一种这里就放弃不讲了,只能上第二种实现思路。
// 获取 iOS 默认的 UserAgent,可以很巧妙地创建一个空的UIWebView来获取:
NSString *userAgent = [[[UIWebView alloc] init] stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
// 获取App名称,我的App有本地化支持,所以是如下的写法
NSString *appName = NSLocalizedStringFromTable(@"CFBundleDisplayName", @"InfoPlist", nil);
// 如果不需要本地化的App名称,可以使用下面这句
// NSString * appName = [[NSBundle mainBundle] infoDictionary][@"CFBundleDisplayName"];
NSString *version = [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"];
NSString *customUserAgent = [userAgent stringByAppendingFormat:@" %@/%@", appName, version];
[[NSUserDefaults standardUserDefaults] registerDefaults:@@"UserAgent":customUserAgent];
// ---------- 随便写个测试代码,记得设置 delegate哦,这只是测试代码
UIWebView *webView = [[UIWebView alloc] init];
webView.delegate = self;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURLURLWithString:@"http://www.baidu.com/"]]];
- (void)webViewDidFinishLoad:(UIWebView *)webView
NSLog(@"UserAgent = %@", [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"]);
Xcode 5.1.1 iOS 7.1 模拟器下得到的结果是:
Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) 中华浏览器/1.2.2
如何创建从 vue.js 实例到自定义原生 Web 组件的双向绑定?
【中文标题】如何创建从 vue.js 实例到自定义原生 Web 组件的双向绑定?【英文标题】:How to create bidirectional binding from vue.js instance to custom native web component? 【发布时间】:2018-10-07 08:05:43 【问题描述】:以下是自定义 Web 组件 my-input
的示例。我想将自定义输入组件的 value 属性绑定到 vue 实例的 email 属性。 (该示例可能需要 Chrome 支持自定义 Web 组件。)
=>我必须如何调整我的 Web 组件示例才能使绑定正常工作?
如果我将 my-input
替换为普通的 input
标签,则绑定有效。因此,我对 vue.js 部分的语法似乎很好。
https://jsfiddle.net/j5f9edjt/
new Vue(
el: '#app',
template: '#app-template',
data:
//email data is blank initially
email: ''
)
<script type="text/javascript" src="https://unpkg.com/vue@2.2.4"></script>
<script>
class MyInput extends HTMLElement
static get observedAttributes()
return ['value'];
constructor()
super();
this.wrappedInput=undefined;
connectedCallback()
var self=this;
if(!self.wrappedInput)
var wrappedInput = document.createElement('input');
wrappedInput.type='text';
wrappedInput.onchange = ()=>this.wrappedInputChanged();
self.appendChild(wrappedInput);
self.wrappedInput = wrappedInput;
attributeChangedCallback(attr, oldValue, newValue)
if(attr==='value')
console.log('attribute changed ' + newValue);
if(this.wrappedInput)
this.wrappedInput.value= newValue;
wrappedInputChanged()
console.log('wrapepd input changed')
var newValue = this.wrappedInput.value;
this.value = newValue;
get value()
console.log('get value')
return this.getAttribute('value');
set value(newValue)
this.setAttribute('value',newValue);
console.log('set value ' + newValue);
window.customElements.define('my-input', MyInput);
</script>
<div id="app"></div>
<template id="app-template">
<div>
<my-input v-model="email"></my-input>
<h1>
You entered email
</h1>
</div>
</template>
我尝试发送一个额外的输入事件,但没有帮助:
var myInput = new CustomEvent("input",
detail:
message: "Hello World!",
type: 'text',
,
bubbles: true,
cancelable: true
);
this.dispatchEvent(myInput);
我在哪里可以找到 v-model 指令的源代码以了解它的作用?
相关问题:
How to target custom element (native web component) in vue.js?
【问题讨论】:
【参考方案1】:要使v-model
工作,您需要为您的网络组件制作一个包装器组件。包装器将符合requirements for using v-model
with a component。
或者,您可以将v-model
分解为两部分:设置value
属性和处理input
事件。就v-model
而言,Vue 似乎并未将 Web 组件识别为原生元素。
class MyInput extends HTMLElement
static get observedAttributes()
return ['value'];
constructor()
super();
this.wrappedInput = undefined;
connectedCallback()
var self = this;
if (!self.wrappedInput)
var wrappedInput = document.createElement('input');
wrappedInput.type = 'text';
wrappedInput.onchange = () => this.wrappedInputChanged();
self.appendChild(wrappedInput);
self.wrappedInput = wrappedInput;
attributeChangedCallback(attr, oldValue, newValue)
if (attr === 'value')
console.log('attribute changed ' + newValue);
if (this.wrappedInput)
this.wrappedInput.value = newValue;
wrappedInputChanged()
var newValue = this.wrappedInput.value;
this.value = newValue;
get value()
console.log('get value')
return this.getAttribute('value');
set value(newValue)
this.setAttribute('value', newValue);
console.log('set value ' + newValue);
window.customElements.define('my-input', MyInput);
new Vue(
el: '#app',
template: '#app-template',
data:
//email data is blank initially
email: ''
,
methods:
handleInput(event)
this.email = event.target.value;
,
components:
wrappedMyInput:
template: '#wmi-template',
props: ['value'],
methods:
emitInput(event)
this.$emit('input', event.target.value);
)
<script type="text/javascript" src="https://unpkg.com/vue@2.2.4"></script>
<div id="app"></div>
<template id="app-template">
<div>
<my-input :value="email" @input="handleInput"></my-input>
<h1>
You entered email
</h1>
<wrapped-my-input v-model="email"></wrapped-my-input>
<h1>
You entered email
</h1>
</div>
</template>
<template id="wmi-template">
<my-input :value="value" @input="emitInput"></my-input>
</template>
【讨论】:
在 vue 实例中没有额外方法定义的变体是v-model
指令似乎检查标签的类型并单独处理它们:
https://github.com/vuejs/vue/blob/dev/src/platforms/web/compiler/directives/model.js
如果没有额外的包装器,我没有让 v-model
为我的自定义组件工作。 (我放弃了了解我的案例在 model.js 中是如何处理的。)
作为 Roy J 建议的“分解绑定”的替代方法。
<my-input :value="email" @input="email = $event.target.value"></my-input>
我创建了一个自定义指令v-property
。它适用于 my-input
和 input
(在我的原始示例中使用;没有尝试所有可能的情况):
<my-input v-property="email"></my-input>
<input v-property="email"></my-input>
--
Vue.directive('property',
bind: function (el, binding, vnode)
var viewModel = vnode.context;
var propertyName = binding.expression;
el.addEventListener('input', (event)=>
var oldValue = viewModel[propertyName];
var newValue = event.target.value;
if(newValue != oldValue)
viewModel[propertyName] = newValue;
);
viewModel.$watch(propertyName, ()=>
var oldValue = el.value;
var newValue = viewModel[propertyName];
if(newValue != oldValue)
el.value = newValue;
);
);
https://jsfiddle.net/7dqppqo2/
【讨论】:
以上是关于iOS web view如何绑定一个自定义的类的主要内容,如果未能解决你的问题,请参考以下文章
如何:在iOS中使用StackView View从XIB自我调整自定义视图