EXT表单(Ext.form)的各种组件的创建与使用
EXT表单(Ext.form)的各种组件的创建与使用,包含:
datefield(Ext.form.DateField)
timefield(Ext.form.TimeField)
combobox(Ext.form.ComboBox)
radio(Ext.form.Radio)
radiogroup(Ext.form.RadioGroup)
checkbox(Ext.form.Checkbox)
checkboxgroup(Ext.form.CheckboxGroup)
textfield(Ext.form.TextField)
textarea(Ext.form.TextArea)
numberfield(Ext.form.NumberField)
hidden(Ext.form.Hidden)
simplestore(Ext.data.SimpleStore)
jsonstore(Ext.data.JsonStore)
treedode(Ext.tree.TreeNode)
multiselectcombo(Ext.ux.MultiSelectCombo)
fieldset(Ext.form.FieldSet)
formpanel(Ext.form.FormPanel)
// 代码开始
Ext.onReady(function(){
Ext.BLANK_IMAGE_URL = “/widgets/ext-2.2/resources/images/default/s.gif”;
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = “qtip”;
//component
var hiddenField = new Ext.form.Hidden({
name: “hiddenField”,
value: “1″
});
var usernameField = new Ext.form.TextField({
name: “username”,
fieldLabel: “用户名”,
allowBlank: true,
blankText: “请输入用户名!”
});
var pwdField = new Ext.form.TextField({
name: “password”,
fieldLabel: “密码”,
allowBlank: true,
blankText: “请输入密码!”,
inputType: “password”
});
var ageField = new Ext.form.NumberField({
name: “age”,
allowBlank: true,
blankText: “请输入年龄!”,
fieldLabel: “年龄”,
allowDecimals: false,
allowNegative: false,
minValue: 18,
minText: “年龄不能少于18″,
maxValue: 100,
maxText: “年龄不能大于100″
});
var love1 = new Ext.form.Checkbox({
name: “love1″,
boxLabel: “打球”,
inputValue: “1″
});
var love2 = new Ext.form.Checkbox({
name: “love2″,
boxLabel: “游泳”,
inputValue: “2″
});
var love3 = new Ext.form.Checkbox({
name: “love3″,
boxLabel: “登山”,
inputValue: “3″
});
var loveGroup = new Ext.form.CheckboxGroup({
name: “love”,
columns: [80, 80, 1.0],
fieldLabel: “爱好”,
items: [love1, love2, love3]
});
var sex1 = new Ext.form.Radio({
name: “sex1″,
boxLabel: “男”,
inputValue: “1″
});
var sex2 = new Ext.form.Radio({
name: “sex1″,
boxLabel: “女”,
inputValue: “0″
});
var sexGroup = new Ext.form.RadioGroup({
name: “sex”,
columns: [80, 1.0],
fieldLabel: “性别”,
items: [sex1, sex2]
});
//本地数据源的组合框
var store = new Ext.data.SimpleStore({
fields: ["code", "name"],
data: [
["1", "北京"],
["5", "上海"],
["4", "广东"]
]
});
var cmbProvince = new Ext.form.ComboBox({
id: “cmbProvince”,
hiddenName: “province.id”,
fieldLabel: “省份”,
resizable: true,
editable: false,
width: 100,
emptyText: “请选择…”,
store: store,
valueField: “code”,
displayField: “name”,
triggerAction: “all”,
mode: “local”
});
//远程数据源的组合框
var store2 = new Ext.data.SimpleStore({
fields: ["name"],
proxy: new Ext.data.HttpProxy({
url: “../testForm!loadData.action”
})
});
var cmbManager = new Ext.form.ComboBox({
hiddenName: “manager”,
fieldLabel: “经理”,
editable: false,
triggerAction: “all”,
mode: “local”,
maxHeight: 200,
store: new Ext.data.SimpleStore({fields:[],data:[[]]}),
onSelect: Ext.emptyFn,
tpl: “<tpl for=’.'><div id=’tree’></div></tpl>”
});
var root = new Ext.tree.TreeNode({
nodeId: 1,
text: “根节点”,
expanded: true
});
root.appendChild(new Ext.tree.TreeNode({nodeId:2, text:”节点A”, leaf:true}));
root.appendChild(new Ext.tree.TreeNode({nodeId:3, text:”节点B”, leaf:true}));
var tree = new Ext.tree.TreePanel({
root: root,
border: false,
autoHeight: true,
autoScroll: true
});
tree.on(“click”, function(node){
if(!node.isLeaf()) return; //只能选择叶节点
//下拉框的隐藏值
if(cmbManager.hiddenField){
cmbManager.hiddenField.value = node.attributes.nodeId;
}
cmbManager.setRawValue(node.text); //下拉框的显示值
cmbManager.collapse(); //折叠下拉框
});
cmbManager.on(“expand”, function(){
tree.render(“tree”);
});
//分页远程数据源的组合框
var store3 = new Ext.data.JsonStore({
url: “../testForm!loadData3.action”,
totalProperty: “totalNum”,
root: “books”,
fields: ["id", "name"]
});
var cmbBook = new Ext.form.ComboBox({
hiddenName: “books”,
fieldLabel: “书籍”,
store: store3,
valueField: “name”,
displayField: “name”,
triggerAction: “all”,
mode: “remote”,
queryParam: “books”,
loadingText: “正在装载数据…”,
width: 180,
minChars: 1,
editable: false,
listWidth: 250,
pageSize: 3
});
//HTML标准组件
var cmbPass = new Ext.form.ComboBox({
hiddenName: “status”,
fieldLabel: “是否有效”,
triggerAction: “all”,
editable: false,
width: 100,
transform: “isPass”,
lazyRender: true
});
var cmbTimes = new Ext.form.TimeField({
hiddenName: “time”,
fieldLabel: “时间”,
minValue: “09:00″,
minText: “所选时间应大于{0}”,
maxValue: “18:00″,
maxText: “所选时间应小于{0}”,
format: “H时i分”,
increment: 30,
invalidText: “时间格式无效!”,
maxHeight: 200,
width: 100,
value: “09时00分”,
editable: false
});
var cmbMonths = new Ext.ux.MultiSelectCombo({
hiddenName: “months”,
fieldLabel: “月份”,
maxHeight: 200,
editable: false,
store: [["201010","201010"], ["201009","201009"], ["201008","201008"], ["201007","201007"], ["201006","201006"]],
mode: “local”,
width: 180,
maxItemsCount: 3,
maxItemsCountText: “最多只能选择三个选项!”
});
var cmbBirths = new Ext.form.DateField({
name: “births”,
fieldLabel: “出生日期”,
disabledDays: [0,6],
disabledDaysText: “禁止选择周末!”,
width: 100,
readOnly: true,
format: “Y-m-d”,
invalidText: “不是有效的日期值!”
});
var fieldSet1 = new Ext.form.FieldSet({
title: “下拉框”,
checkboxName: “fieldSet1″,
checkboxToggle: true,
autoHeight: true,
layout: “table”,
layoutConfig: {
columns: 3
},
defaults: {
style:”margin-left:8px; margin-top:3px; margin-right:8px; margin-bottom:3px; valign:top”,
layout:”form”,
labelAlign: “right”
},
items: [
{rowspan:1, colspan:1, items:[cmbProvince]},
{rowspan:1, colspan:1, items:[cmbManager]},
{rowspan:1, colspan:1, items:[cmbBook]},
{rowspan:1, colspan:1, items:[cmbPass]},
{rowspan:1, colspan:1, items:[cmbTimes]},
{rowspan:1, colspan:1, items:[cmbMonths]},
{rowspan:1, colspan:1, items:[cmbBirths]}]
});
var remarksField = new Ext.form.TextArea({
name: “remarks”,
fieldLabel: “备注”,
width: 400,
height: 80
});
var form = new Ext.form.FormPanel({
id: “frmAddUser”,
title: “新增用户”,
autoWidth: true,
autoHeight: true,
frame: true,
renderTo: Ext.getBody(),
labelWidth: 70,
tbar: toolbar,
items: [hiddenField, usernameField, pwdField, ageField, loveGroup, sexGroup,
fieldSet1, remarksField],
url: “../testForm!ajaxSubmitForm.action”
});
});
Ext xtype: ‘textfield’, inputType: ‘file’ 的样式和文字的更改方法
正常来说,file类型的样式是没法修改的,不同的操作系统或系统皮肤,这个选择框的样子也随之改变。
对我们前端开发的朋友来说,想要修改他的样式或表现,貌似没有直接的办法修改。
所以,只能放弃直接修改其自身表现的方式,转战自定义个按钮,然后触发file的选择框。
原来这样是可行的。
1、首先添加file类型的输入框:A,将A隐藏。
2、添加一个自定义按钮:B,这个就是你需要表现的选择(浏览)。
3、给B绑定一个点击事件:点击执行A的点击事件,打开文件选择框。【 Ext.get(‘fileinput’).dom.click() 】;
)
OK啦,然后就各自处理各家事了。
网上还有另一种方法:
添加一个自定义按钮,然后把file input 放在按钮的上边,弄成透明的,这样在点按钮时,实际是点击了file input,这样就实现了文件的上传。
Ext中的Ext.get()、Ext.getDom()、Ext.getCmp()、Ext.getBody()、Ext.getDoc()的区别
Ext中的Ext.get()、Ext.getDom()、Ext.getCmp()、Ext.getBody()、Ext.getDoc()的区别
Ext中包含了几个以get开头的方法,这些方法可以用来得到文档中DOM、得到当前文档中的组件、得到Ext元素等,在使用中要注意区别使用。
1、get方法
get方法用来得到一个Ext元素,也就是类型为Ext.Element的对象,Ext.Element类是Ext对DOM的封装,代表DOM的元素,可以为每一个DOM创建一个对应的Element对象,可以通过Element 对象上的方法来实现对DOM指定的操作,比如用hide方法可以隐藏元素、initDD方法可以让指定的DOM具有拖放特性等。get方法其实是 Ext.Element.get的简写形式。
get方法中只有一个参数,这个参数是混合参数,可以是DOM节点的id、也可以是一个Element、或者是一个DOM节点对象等。看下面的示例代码:
Ext.onReady(function(){
var e=new Ext.Element(“hello”);
alert(Ext.get(“hello”));
alert(Ext.get(document.getElementById(“hello”)));
alert(Ext.get(e));
});
Html页面中包含一个id为hello的div,代码如下:
<div id=”hello”>tttt</div>
Ext.get(“hello”)、Ext.get(document.getElementById(“hello”))、Ext.get(e)等三个方法都可以得到一个与DOM节点hello对应的Ext元素。
2、getCmp方法-获得Ext组件。
getCmp方法用来获得一个Ext组件,也就是一个已经在页面中初始化了的Component或其子类的对象,getCmp方法其实是Ext.ComponentMgr.get方法的简写形式。getCmp方法中只有一个参数,也就是组件的id。比如下面的代码:
Ext.onReady(function(){
var h=new Ext.Panel({
id:”h2″,
title:” ”,
renderTo:”hello”,
width:300,
height:200});
Ext.getCmp(“h2″).setTitle(“新的标题”);
});
在代码中,我们使用Ext.getCmp(“h2″).来得到id为h2的组件,并调用其setTitle方法来设置该面板的标题。
3、getDom方法-获得DOM节点
getDom方法能够得到文档中的DOM节点,该方法中包含一个参数,该参数可以是DOM节点的id、DOM节点对象或DOM节点对应的Ext元素(Element)等。比如下面的代码:
Ext.onReady(function(){
var e=new Ext.Element(“hello”);
Ext.getDom(“hello”);
Ext.getDom(e);
Ext.getDom(e.dom);
});
Html:
<div id=”hello”>tttt</div>
在上面的代码中,Ext.getDom(“hello”)、Ext.getDom(e)、Ext.getDom(e.dom)等三个语句返回都是同一个DOM节点对象。
4、getBody方法-得到文档的body节点元素(Element)。
该方法直接得到文档中与document.body这个DOM节点对应的ExtJS元素(Element),实质就是把document.body对象封装成ExtJS元素对象返回,该方法不带任何参数。比如下面的代码把面板h直接渲染到文档的body元素中。
Ext.onReady(function(){
var h=new Ext.Panel({title:”测试”,width:300,height:200});
h.render(Ext.getBody());
});
5、getDoc方法-获得与document对应的Ext元素(Element)
getDoc方法实质上就是把当前html文档对象,也就是把document对象封装成ExtJS的Element对象返回,该方法不带任何参数。
附:定义
getDom : function(el){
if(!el || !DOC){
return null;
}
return el.dom ? el.dom : (Ext.isString(el) ? DOC.getElementById(el) : el);
},
Ext.namespace() Ext.namespace Ext命名空间介绍
Ext.namespace() Ext命名空间介绍
1:支持命名空间
<script type="text/javascript">
//定义一个命名空间
Ext.namespace("Ext.wentao");
//在命名空间上定义一个类
Ext.wentao.helloworld = Ext.emptyFn;
//创建一个类的实例
new Ext.wentao.helloworld();
</script>
其中 Ext.wentao.helloworld = Ext.emptyFn; 等价于 Ext.wentao.helloworld = function(){};
2:支持类实例属性
<script type="text/javascript">
Ext.namespace("Ext.wentao"); //自定义一个命名空间
Ext.wentao.Person = Ext.emptyFn; //在命名空间上自定义一个类
//为自定义的类 增加一个 name 属性,并赋值
Ext.apply(Ext.wentao.Person.prototype, {
name:"刘文涛"
})
var _person = new Ext.wentao.Person();//实例化 自定义类
alert(_person.name);
_person.name = "张三";//修改类name属性
alert(_person.name);
</script>
3:支持类实例方法
<script type="text/javascript">
Ext.namespace("Ext.wentao"); //自定义一个命名空间
Ext.wentao.Person = Ext.emptyFn; //在命名空间上自定义一个类
//演示类实例方法
Ext.apply(Ext.wentao.Person.prototype, {
name:"刘文涛",
sex:"男",
print:function(){
alert(String.format("姓名:{0},性别:{1}",this.name,this.sex));
}
})
var _person = new Ext.wentao.Person();//实例化 自定义类
_person.print();
</script>
4:支持类静态方法
<script type="text/javascript">
Ext.namespace("Ext.wentao"); //自定义一个命名空间
Ext.wentao.Person = Ext.emptyFn; //在命名空间上自定义一个类
//演示类实例方法
Ext.apply(Ext.wentao.Person.prototype, {
name:"刘文涛",
sex:"男",
print:function(){
alert(String.format("姓名:{0},性别:{1}",this.name,this.sex));
}
})
//演示 类静态方法
Ext.wentao.Person.print = function(_name,_sex){
var _person = new Ext.wentao.Person();
_person.name = _name;
_person.sex = _sex;
_person.print(); //此处调用类 实例方法,上面print是类 静态方法
}
Ext.wentao.Person.print("张三","女"); //调用类 静态方法
</script>
5:支持构造方法
<script type="text/javascript">
Ext.namespace("Ext.wentao"); //自定义一个命名空间
//构造方法
Ext.wentao.Person = function(_cfg){
Ext.apply(this,_cfg);
}
//演示类实例方法
Ext.apply(Ext.wentao.Person.prototype, {
print:function(){
alert(String.format("姓名:{0},性别:{1}",this.name,this.sex));
}
})
//演示 类静态方法
Ext.wentao.Person.print = function(_name,_sex){
var _person = new Ext.wentao.Person({name:_name,sex:_sex});
_person.print(); //此处调用类 实例方法,上面print是类 静态方法
}
Ext.wentao.Person.print("张三","女"); //调用类 静态方法
</script>
6:支持类继承
<script type="text/javascript">
Ext.namespace("Ext.wentao"); //自定义一个命名空间
//*******************父类*********************
//构造方法
Ext.wentao.Person = function(_cfg){
Ext.apply(this,_cfg);
}
//演示类实例方法
Ext.apply(Ext.wentao.Person.prototype, {
job:"无",
print:function(){
alert(String.format("姓名:{0},性别:{1},角色:{2}",this.name,this.sex,this.job));
}
})
//*******************子类1*********************
Ext.wentao.Student = function(_cfg){
Ext.apply(this,_cfg);
}
Ext.extend(Ext.wentao.Student,Ext.wentao.Person,{
job:"学生"
})
var _student = new Ext.wentao.Student({name:"张三",sex:"女"});
_student.print(); //调用 父类方法
</script>
7:支持类实例方法重写
<script type="text/javascript">
Ext.namespace("Ext.wentao"); //自定义一个命名空间
//*******************父类*********************
//构造方法
Ext.wentao.Person = function(_cfg){
Ext.apply(this,_cfg);
}
//演示类实例方法
Ext.apply(Ext.wentao.Person.prototype, {
job:"无",
print:function(){
alert(String.format("姓名:{0},性别:{1},角色:{2}",this.name,this.sex,this.job));
}
})
//*******************子类1*********************
Ext.wentao.Student = function(_cfg){
Ext.apply(this,_cfg);
}
//重写父类的 实例 方法
Ext.extend(Ext.wentao.Student,Ext.wentao.Person,{
job:"学生",
print:function(){
alert(String.format("{0}是一位{1}{2}",this.name,this.sex,this.job));
}
})
var _student = new Ext.wentao.Student({name:"张三",sex:"女"});
_student.print(); //调用 父类方法
</script>
8:支持命名空间别名
<script type="text/javascript">
Ext.namespace("Ext.wentao"); //自定义一个命名空间
Wt = Ext.wentao; //命名空间的别名
//*******************父类*********************
//构造方法
Wt.Person = function(_cfg){
Ext.apply(this,_cfg);
}
//演示类实例方法
Ext.apply(Wt.Person.prototype, {
job:"无",
print:function(){
alert(String.format("姓名:{0},性别:{1},角色:{2}",this.name,this.sex,this.job));
}
})
//*******************子类1*********************
Wt.Student = function(_cfg){
Ext.apply(this,_cfg);
}
//重写父类的 实例 方法
Ext.extend(Wt.Student,Ext.wentao.Person,{
job:"学生",
print:function(){
alert(String.format("{0}是一位{1}{2}",this.name,this.sex,this.job));
}
})
var _student = new Wt.Student({name:"张q三",sex:"女"});
_student.print(); //调用 父类方法
</script>
9:支持类别名
<script type="text/javascript">
Ext.namespace("Ext.wentao"); //自定义一个命名空间
Wt = Ext.wentao; //命名空间的别名
//*******************父类*********************
//构造方法
Wt.Person = function(_cfg){
Ext.apply(this,_cfg);
}
PN = Wt.Person; //类别名
//演示类实例方法
Ext.apply(PN.prototype, {
job:"无",
print:function(){
alert(String.format("姓名:{0},性别:{1},角色:{2}",this.name,this.sex,this.job));
}
})
//*******************子类1*********************
Wt.Student = function(_cfg){
Ext.apply(this,_cfg);
}
ST = Wt.Student;
//重写父类的 实例 方法
Ext.extend(ST,PN,{
job:"学生",
print:function(){
alert(String.format("{0}是一位{1}{2}",this.name,this.sex,this.job));
}
})
var _student = new ST({name:"张q三",sex:"女"});
_student.print(); //调用 父类方法
</script>
Ext Form inputType: ‘file’ 上传控件,在给其赋值的时候,会报告一个Security error错误
Ext Form inputType: ‘file’ 上传控件,在给其赋值的时候,会报告一个Security error错误
xtype: ‘textfield’, inputType: ‘file’, fieldLabel: ‘图标本地上传’, name: ‘uploadimg’,
id: ‘txUploadImg’, anchor: ’95%’, buttonCfg: { text: ‘浏览…’ },
程序环境:
1、一个用户资料页面。
2、点击增加用户,增加一个用户资料,包含用户头像。
3、对该用户进行编辑,点击编辑按钮,进入编辑页面,ext的form.load会自动对name为uploadimg的控件进行赋值,那么就会报告一个Security error错误。
原因我没深入研究。。。
解决方法:
1、不对uploadimg进行自动赋值,可以将id为txUploadImg的name值换成其他name,比如将name改成uploadimg123;
2、在保存、更新的时候,后台程序,读取的字段有原来的uploadimg改成uploadimg123。
firefox3.0+ firefox7.0+ 对上传图片预览的file的取值方法:getAsDataURL(),window.URL.createObjectURL(fileobject)
相信很多朋友多知道这断HTML代码:<input type=”flie” id=”uploadFile” >,这里主要记录说火狐对与文件上传控件取值的方式。
firefox3.0+ firefox7.0+ 对上传图片预览的file的取值方法:getAsDataURL(),window.URL.createObjectURL(fileobject)
A、firefox3.0 value的值为文件名称,getAsDataURL()取得绝对路径
B、firefox7.0 value的值为文件名称,window.URL.createObjectURL(fileobject)取得绝对路径
用法:
A、var src= document.getElementById(“uploadFile”).files.item(0).getAsDataURL(); alert(src);
B、var file = document.getElementById(“uploadFile”);
var src= window.URL.createObjectURL(file.files[0]); alert(src);
Ext.EventManager 事件管理器 常用属性onDocumentReady、 onWindowResize和onTextResize
Ext.EventManager
作为事件管理器,Ext.EventManager定义了一系列事件相关的处理函数,其中最常用的当属onDocumentReady、 onWindowResize和onTextResize。其中onDocumentReady就是我们经常见到的Ext.onReady(),它会在页 面文档渲染完毕但图片等还未下载时调用启动函数。
让我们来看一下Ext.onReady()的应用,如下代码所示。
使用Ext.onReady
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>grid</title>
- <link rel="stylesheet" type="text/css" href="../../ resources/css/ext-all.css" />
- <script type="text/javascript" src="../../adapter/ ext/ext-base.js"></script>
- <script type="text/javascript" src="../../ext-all.js"></script>
- <script type="text/javascript">
- Ext.onReady(function(){
- Ext.Msg.alert('信息', Ext.get('test'));
- });
- </script>
- </head>
- <body>
- <button id="test">test</button>
- </body>
- </html>
打开html后,可以在页面上看到一个弹出信息的效果。
无论什么时候,都要使用Ext.onReady()来确保脚本是在HTML元素都加载完成后才执行,这样可以避免很多潜在的问题。
Ext.onWindowResize()的作用是监听浏览器窗口的大小改变,它会提醒我们浏览器窗口的大小在何时发生了改变,以及改变后的大小,如下面的代码所示。
- Ext.EventManager.onWindowResize(function(width, height) {
- alert('width:' + width + ', height:' + height);
- });
不必将它放在Ext.onReady()中,因为它监听的是window对象,这个对象在页面一打开时就存在了。onWindowResize()的监听函数只有两个参数width和height,分别代表当前窗口的宽和高。
Ext.onTextResize()是一个有用的工具函数,它可以监听用户修改浏览器的文字大小,如下面的代码所示。
- Ext.onReady(function() {
- Ext.EventManager.onTextResize(function(oldSize, newSize) {
- alert('oldSize:' + oldSize + ', newSize:' + newSize);
- });
- });
Ext.onTextResize()会在<body>标签中添加一个包含测试文字的div标签,然后监听测试文字的大小。如果测试文字的大小 发生了改变,就执行监听函数,并发送给监听函数两个参数,第一个参数oldSize是改变前文字的大小,第二个参数newSize是改变后文字的大小。
需要注意的是,因为onTextResize()需要操作<body>标签向其中添加测试用的元素,所以它必须包含在Ext.onReady()中,否则会出现错误。
flex AS 与 宿主html中JS(javascript)之间的互相调用通信问题
Flex中As调用Js的方法是:
1、导入包 (import flash.external.ExternalInterface;)
2、使用ExternalInterface.call(“Js函数名称”,参数)进行调用,其返回的值就是Js函数所返回的值
Js调用As的方法是:
1、导入包 (import flash.external.ExternalInterface;)
2、在initApp中使用ExternalInterface.addCallback(“用于Js调用的函数名”,As中的函数名) 进行注册下
3、js中 就可以用document.getElementById(“Flas在Html中的ID”).注册时设置的函数名(参数)进行调用
as和js通信addcallback失效
情况一:flash一旦在浏览器里cache住,如果在as里一开始就addcallback就会失效
情况二:一个js函数上来就调用as的一个函数的时候,页面会报错,提示找不到这个flash对象,或者函数没有定义。Flash8的时代,针对 ExternalInterface这个类,文档里只说明了怎么用,而没有具体说怎么合理的组织和页面的结构,一直到了cs3的时代,帮助里才说明了正确 的函数注册和js调用的过程,具体的见Flash cs3帮助。大概的代码如下:
js部分:
<script>
var jsReady=false;
var swfReady=false;
function isReady(){
return jsReady;
}
function setSwfIsReady(){
swfReady=true;
getSWF(”flashobj”).fun()
}
function pageInit(){
jsReady=true;
}
function getSWF(movieName) {
if (navigator.appName.indexOf(”Microsoft”) != -1) {
return window[movieName+”_ob”];
} else {
return document[movieName+”_em”];
}
}
onload=function(){
pageInit();
}
</script>
注意,在getSWF函数里用了 return window[movieName+”_ob”]和return document[movieName+”_em”],在IE下,如果object标签和embed表现用同样的id,通过js去访问flash对象的时候,IE会认不出,FF是没有问题的
as部分
private function registerJsFun():void{
if(ExternalInterface.available){
try{
var containerReady:Boolean=isContainerReady();
//ExternalInterface.call(”ceshi”,”registerJsFun:”+containerReady);
if(containerReady){
//注册函数
setupCallBacks();
}else{
//检测是否准备好
var readyTimer:Timer=new Timer(100);
readyTimer.addEventListener(TimerEvent.TIMER,timeHandler);
readyTimer.start();
}
}catch(error:Error){
trace(error)
}
}else{
trace(”External interface is not available for this container.”);
}
}
private function timeHandler(event:TimerEvent):void{
var isReady:Boolean=isContainerReady();
if(isReady){
Timer(event.target).stop();
setupCallBacks();
}
}
private function isContainerReady():Boolean{
var result:Boolean=Boolean(ExternalInterface.call(”isReady”));
return result;
}
private function setupCallBacks():void{
ExternalInterface.addCallback(”fun”,fun);
ExternalInterface.call(”setSwfIsReady”);
}
具体我就不解释了,不明白的可以仔细去看下cs3帮助,大概的意思就是页面开始渲染的时候js去调用swf对象,有可能swf对象没有完全load完,所以这个触发器要从flash开始,当flash加载的时候就开始不停的调用页面的一个函数,取一个页面是否加载完毕的标识,当 pageonLoad后,这个标识为true了,说明flash也加载完毕了,这个时候flash再开始注册函数,同时调用页面的js,让js调用 Flash对象。
实例:
html:
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” lang=”zh-CN” xml:lang=”zh-CN”>
<head>
<title>xxx</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<script type=”text/javascript”>
function show_form(msg){
alert(msg)
}
</script>
</head>
<body>
<div id=”flashContent”>
<object classid=”clsid:d27cdb6e-ae6d-11cf-96b8-444553540000″ width=”1000″ height=”600″ id=”123_fla” align=”middle”>
<param name=”movie” value=”123_fla.swf” />
<param name=”quality” value=”high” />
<param name=”bgcolor” value=”#ffffff” />
<param name=”play” value=”true” />
<param name=”loop” value=”true” />
<param name=”wmode” value=”transparent”/>
<param name=”scale” value=”showall” />
<param name=”menu” value=”true” />
<param name=”devicefont” value=”false” />
<param name=”salign” value=”" />
<param name=”allowScriptAccess” value=”sameDomain” />
<!–[if !IE]>–>
<object type=”application/x-shockwave-flash” data=”123_fla.swf” width=”1000″ height=”600″>
<param name=”movie” value=”123_fla.swf” />
<param name=”quality” value=”high” />
<param name=”bgcolor” value=”#ffffff” />
<param name=”play” value=”true” />
<param name=”loop” value=”true” />
<param name=”wmode” value=”transparent”/>
<param name=”scale” value=”showall” />
<param name=”menu” value=”true” />
<param name=”devicefont” value=”false” />
<param name=”salign” value=”" />
<param name=”allowScriptAccess” value=”sameDomain” />
<!–<![endif]–>
<a href=”http://www.adobe.com/go/getflash”> <img src=”http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif” alt=”获得 Adobe Flash Player” /> </a>
<!–[if !IE]>–>
</object>
<!–<![endif]–>
</object>
</div>
</body>
</html>
还有一个值得注意的情况:
最好放到服务器,用域名来测试是否事件被调用执行!
最后说下as2.0于as3.0在调用js中的区别:
as3.0调用JS:
import flash.external.ExternalInterface;
import flash.events.MouseEvent;
btn.addEventListener(MouseEvent.CLICK,clickBTN);
function clickBTN(e:MouseEvent):void {
ExternalInterface.call(“fun”,”参数1″,”参数2″…);
}
as2.0调用JS:
import flash.external.*;
btn.onPress=function(){
ExternalInterface.call(“fun”,”参数1″,”参数2″…);
}
深入理解JavaScript的闭包特性 如何给循环中的对象添加事件
初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件。在事件响应函数中(event handler)获取对应的索引。但每次获取的都是最后一次循环的索引。原因是初学者并未理解JavaScript的闭包特性。
有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4。
- <!DOCTYPE HTML>
- <html>
- <head>
- <meta charset="utf-8" />
- <title>闭包演示</title>
- <style type="text/css">
- p {background:gold;}
- </style>
- <script type="text/javascript">
- function init() {
- var pAry = document.getElementsByTagName("p");
- for( var i=0; i<pAry.length; i++ ) {
- pAry[i].onclick = function() {
- alert(i);
- }
- }
- }
- </script>
- </head>
- <body onload="init();">
- <p>产品 0</p>
- <p>产品 1</p>
- <p>产品 2</p>
- <p>产品 3</p>
- <p>产品 4</p>
- </body>
- </html>
以上场景是初学者经常碰到的。即获取HTML元素集合,循环给元素添加事件。在事件响应函数中(event handler)获取对应的索引。但每次获取的都是最后一次循环的索引。
原因是初学者并未理解JavaScript的闭包特性。通过element.onclick=function(){alert(i);}方式给元 素添加点击事件。响应函数function(){alert(i);}中的 i 并非每次循环时对应的 i(如0,1,2,3,4)而是循环后最后 i 的值5。 或者说循环时响应函数内并未能保存对应的值 i,而是最后一次i++的值5。
了解了原因,下面就由几种方式可与解决:
1、将变量 i 保存给在每个段落对象(p)上
- function init1() {
- var pAry = document.getElementsByTagName("p");
- for( var i=0; i<pAry.length; i++ ) {
- pAry[i].i = i;
- pAry[i].onclick = function() {
- alert(this.i);
- }
- }
- }
2、将变量 i 保存在匿名函数自身
- function init2() {
- var pAry = document.getElementsByTagName("p");
- for( var i=0; i<pAry.length; i++ ) {
- (pAry[i].onclick = function() {
- alert(arguments.callee.i);
- }).i = i;
- }
- }
3、加一层闭包,i 以函数参数形式传递给内层函数
- function init3() {
- var pAry = document.getElementsByTagName("p");
- for( var i=0; i<pAry.length; i++ ) {
- (function(arg){
- pAry[i].onclick = function() {
- alert(arg);
- };
- })(i);//调用时参数
- }
- }
4、加一层闭包,i 以局部变量形式传递给内层函数
- function init4() {
- var pAry = document.getElementsByTagName("p");
- for( var i=0; i<pAry.length; i++ ) {
- (function () {
- var temp = i;//调用时局部变量
- pAry[i].onclick = function() {
- alert(temp);
- }
- })();
- }
- }
5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)
- function init5() {
- var pAry = document.getElementsByTagName("p");
- for( var i=0; i<pAry.length; i++ ) {
- pAry[i].onclick = function(arg) {
- return function() {//返回一个函数
- alert(arg);
- }
- }(i);
- }
- }
6、用Function实现,实际上每产生一个函数实例就会产生一个闭包
- function init6() {
- var pAry = document.getElementsByTagName("p");
- for( var i=0; i<pAry.length; i++ ) {
- pAry[i].onclick = new Function("alert(" + i + ");");//new一次就产生一个函数实例
- }
- }
7、用Function实现,注意与6的区别
- function init7() {
- var pAry = document.getElementsByTagName("p");
- for( var i=0; i<pAry.length; i++ ) {
- pAry[i].onclick = Function('alert('+i+')');
- }
- }
在CSS中,style、id和class的区别及优先级?
id是唯一的,不能重复,id的优先级高于class。
css优先级的四大原则:
原则一: 继承不如指定
如果某样式是继承来的永远不如具体指定的优先级高。
例子1:
CODE:
<style type=”text/css”>
<!–
*{font-size:20px}
.class3{ font-size: 12px; }
–>
</style>
<span>我是多大字号?</span>
运行结果:.class3{ font-size: 12px; }
例子2:
CODE:
<style type=”text/css”>
<!–
#id1 #id2{font-size:20px}
.class3{font-size:12px}
–>
</style>
<div id=”id1″>
<p id=”id2″> <span id=”id3″>我是多大字号?</span> </p>
</div>
运行结果:.class3{ font-size: 12px; }
注意:后面的几大原则都是建立在“指定”的基础上的。
原则二: #ID > .class > 标签选择符
例子:
CODE:
<style type=”text/css”>
<!–
#id3 { font-size: 25px; }
.class3{ font-size: 18px; }
span{font-size:12px}
–>
</style>
<span id=”id3″>我是多大字号?</span>
运行结果:#id3 { font-size: 25px; }
原则三:越具体越强大。
解释:当对某个元素的CSS选择符样式定义的越具体,层级越明确,该定义的优先级就越高。
CODE:
<style type=”text/css”>
<!–
.class1 .class2 .class3{font-size: 25px;}
.class2 .class3{font-size:18px}
.class3 { font-size: 12px; }
–>
</style>
<div>
<p> <span>我是多大字号?</span> </p>
</div>
运行结果:.class1 .class2 .class3{font-size: 25px;}
原则四:标签#id >#id ; 标签.class > .class
上面这条原则大家应该也都知道,看例子
CODE:
<style type=”text/css”>
<!–
span#id3{font-size:18px}
#id3{font-size:12px}
span.class3{font-size:18px}
.class3{font-size:12px}
–>
</style>
<span id=”id3″>我是多大字号?</span>
<span>我是多大字号?</span>
运行结果:span#id3{font-size:18px} | span.class3{font-size:18px}
很多人会有这样的疑问,为什么不把这个原则四归入原则一形成:
【 标签#ID > #ID > 标签.class > .class > 标签选择符 > 通配符 】 呢?或者将 “标签.class” 看作多更为具体的 “.class” 从而归入原则二呢?后面我将解答各位的疑惑,这就涉及到CSS的解析规律———这四大原则间也是有优先级的,是不是有些糊涂了?别急,继续 看。
*四大原则的权重
相信很多人都知道上面的四大原则,不要以为知道了这四大原则就能分辨css中那条代码是起作用的,不信?那你5秒内能肯定的知道下面这段代码,测试中的文字的字号吗?
CODE:
<style type=”text/css”>
<!–
.class1 p#id2 .class3{font-size:25px}
div .class2 span#id3{font-size:18px}
#id1 .class3{font-size:14px}
.class1 #id2 .class3{font-size:12px}
#id1 #id2{font-size:10px}
–>
</style>
<div id=”id1″>
<p id=”id2″> <span id=”id3″>我是多大字号?</span> </p>
</div>
为了大家方便阅读,我去掉了一些代码。
四大原则的权重就是: 原则一 > 原则二 > 原则三 > 原则四
浅谈什么是web标准、可用性、可访问性?
前言:大家不难发现,只要是招聘UED相关的岗位,如前端开发工程师、交互设计师、用户研究员甚至视觉设计师,一般都对web标准、可用性和可访问性的理解有要求。那么到底什么是web标准、可用性、可访问性呢?
一、web标准
简单的说,就是HTML、CSS、JavaScript这三者分离。WEB标准不是某一个标准,而是一系列标准的集合。网页主要由三部分组成:结构(Structure)、表现(Presentation)和行为(Behavior)。对应的标准也分三方面:结构化标准语言主要包括XHTML和XML,表现标准语言主要包括CSS,行为标准主要包括对象模型(如 W3C DOM)、ECMAScript等。
web标准的优点:
- 代码的效率:在HTML文件中使用最精简的代码,而把样式和页面布局信息包含进CSS文件中。则放在服务器上的文件越小,下载文件需要的时间就越短。
- 易于维护:页面的样式和布局信息保存在单独的CSS文件中,如果你想改变站点的外观时,仅需要在单独的CSS文件中做出更改即可。整站统一css则可带来巨大的便利。
- 可访问性:上网用户中那些视力受损的人,通过屏幕阅读器使用键盘命令将网页的内容读给他们听。以语义化的HTML(结构和表现相分离的HTML)编写的网页文件,就可以让此类用户更容易导航,且网页文件中的重要信息也更有可能被这些用户找到。
- 设备兼容性:纯HTML,无附加样式信息,可以针对具有不同特点(如屏幕尺寸等)的设备而被重新格式化,只需要引用一套另外的样式表即可。同时,CSS本身也可以让你为不同的呈现方式和媒体类型(如在屏幕上阅读网页,打印网页,在移动设备上阅读网页等)规定不同的样式表。
- 网络爬虫/搜索引擎:搜索引擎使用“爬虫”,解析你的网页。语义化的HTML能更准确更快速的被解析,从而知道哪些才是重要的内容,那么你的网页在搜索结果中的排名就会大受影响。
二、可用性、可访问性
可访问性就是对所有人一视同仁,无论他们是否有残障。
网站的用户类型:
- 身体健康的用户;
- 盲人或严重视觉障碍者,他们使用屏幕阅读器来听取网站,或者通过点字显示器来感知网页;
- 近视者,需要将字体大小放大到200%;
- 患有运动性残疾,因此无法用手操作鼠标,而用点击棒来操作键盘,或通过视线点击器来操作网站的用户;
- 使用移动设备如常用的手机,或使用跟踪球等不常见的计算机控制设备的用户。
实现可用性、可访问性的方法
- 逐步强化你的网站功能,同时对支持性进行测试。运用“渐进增强”和“平稳退化”原则开发网站。
- 允许用户关闭有问题的增强功能。
- 提供相同内容或功能的替代版本。
- 就客户端需要支持的技术向你的客户提出建议,并举例说明哪些公司的产品支持这些技术。
可访问性良好网页的特征
- HTML语义化、结构化:HTML语义结构提供了网页的整体框架,提示他们在文件层级中所处的位置,还有他们可以如何与各种页面元素进行交互,以及在适当的地方对文本内容进行强调,帮助用户获得大量重要信息。如导航菜单例子:
<ul> <li>Menu Item 1</li> <li>Menu Item 2</li> <li>Menu Item 3</li> </ul>
说明:通过将导航菜单构造为列表,就能很容易地让那些使用屏幕阅读器、同时无法看到列表的人知道这是个列表。因为他们的屏幕阅读器会告诉他们这是一张列表。如果你没有使用列表标记,屏幕阅读器就没办法知道这是列表,因此也就不能告诉使用者了。
- 替代内容:文本可以作为页面内容的通用替代内容,如img标签的alt属性值、a标签的title属性值。
<a href="http://www.alimama.com" title="淘宝联盟大促销"> <img alt="淘宝联盟大促销" src="images/app/sale.jpg"/> </a>
说明:文本内容可以很方便地由屏幕阅读器朗读出来,也可以放大或缩小,还可以方便地改变其对比度,或者进行其他许多变形操作。alt 属性包含了对该图片的简短描述,以便无法准确看到该图片的用户(或搜索引擎)使用,title属性负责对链接地址的详细文本描述。
- HTML定义基本交互:实现tab选项卡搜索功能
<form action="search.html" method="GET"> <fieldset> <legend>Search within:</legend> <ul> <li><label for="dogs">Dogs</label><input id="dogs" type="radio" name="animal" value="dog" checked></li> <li><label for="cats">Cats</label><input id="cats" type="radio" name="animal" value="cat"></li> <li><label for="fish">Fish</label><input id="fish" type="radio" name="animal" value="fish"></li> </ul> </fieldset> <input type="text" id="searchfield" name="search"/> <input type="submit" value="Search"/> </form>
说明:先考虑基本交互(而不是仅仅只加载视觉效果的部分)的话,你就可以简化实现tab搜索效果。现在我们可以只用一个表单来进行所有的搜索,而同时仍然能实现tab选项卡效果(虽然这需要一点样式和脚本)。通过 AJAX 来插入页面内容,那禁用javascript的用户将无法使用。
四个可访问性标准(WCAG 2.0):
- 可感知:人们可以通过适合自己的媒体来获知网页内容。比如应当让盲人得以收听页面内容。例如,图像应该有文本对应体。
- 可操作:人们可以与 web 应用程序或内容进行交互。例如,用户应该可以不用鼠标也能与某个网站进行交互,并且可以通过屏幕阅读器来进行导航。
- 可理解:使用者可以弄懂页面内容和用户界面。例如,正文不应该比它需要的更加复杂,且网站应以可预测的方式来运行。
- 健壮性:所提供的一切服务都应当不受平台或操作系统的限制。这样就可以避免人们提供一些不太完善的服务,这些服务会因为硬件/软件的限制而导致大多数人都无法使用。例如,不同设备上的浏览器能够一起使用网站,且导航应该是一致的。
说明:网站并不是必须满足全部这些要求,要视网站用户类型而定,但为了实现可访问性,网站应当确保其页面可以用一般的屏幕阅读技术读取。
总结:
可访问性是网站开发质量的一个衡量标准。如果你在开发网站的时候(以及开始开发前)顾及你的使用用户的话,你就能创建可用性、可访问性更好、更符合web标准的网页,并且享受它所带来的一切好处。
熊晓鸽 这个世界只有三种人不会嫉妒与他有关的人的成功
今年3月28日,深圳举行的IT领袖峰会论坛上,“如果你当初也做项目,是不是一样会更加成功?”面对记者的提问,熊晓鸽的回答是,“这个世界只有三种人不会嫉妒与他有关的人的成功:他们是中小学教师、 父母、还有风险投资家。只有创业者的成功,才是我们的成功。”
优化CSS/XHTML的编写让JAVASCRIPT更易处理
虽然说同样的一个效果不同的人可能会采用不同的页面实现,但是从拿到页面的程序员来说不同的实现可能会影响到具体实现的逻辑。下面我们取一个TAB效果来分析各种实现方式对脚本实现的影响。

方案一
原理:使用不同的选中样式标识,选中时添加相应的选中样式
分析:这种方式CSS开放给了程序若干个接口【理论上有多少种选中样式就需要提供多少个CSS接口】,如范例中的select-0、select-1、select-2等,因此从程序实现的角度来看必须增加逻辑去处理当前选中的TAB项需要增加的样式,同时也必须处理当前项不被选中时需要去除的选中样式,所以会增加额外的逻辑来处理这些差异。另外,如果有不同效果的TAB项增加时,程序还需要在切换中增加新的配置或处理逻辑。再有万一哪天统一了选中的效果呢?!因此这种方式一般不建议应用在实际项目中。
范例:

方案二
原理:用ID标识TAB项,增加统一的选中样式标识选中项,样式中通过TAB ID和选中样式区分不同选中效果
分析:这种方式较第一种方式的一个改进就是CSS开放给程序统一的接口来处理选中效果,如范例中的select样式,程序实现时无需考虑其他因素只需要在选中项时增加选中样式,非选中时去除选中样式。但是因为这种方式使用了ID,因此如果项目中页面和程序是并行开发时,如果程序预先在逻辑种使用其中的ID,当拿到实际页面实现时可能会产生冲突。可能冲突的几率不是很大,因此这种方式看项目具体情况应用即可。
范例:

方案三
原理:既然增加选中样式会有一定的限制,那就采用删除样式来标识当前选中项,因此这种方案预先会设置各个TAB项的选中效果,然后增加一个统一非选中效果的样式,当选中TAB项时把这个非选中效果的样式去掉即可。
分析:这种方式可以很好的解决上面两个方案的限制,需要程序实现时注意的是这里的选中效果是删除样式而不是增加样式,与上面的处理方式刚好相反。因此实际项目中我们建议用这种方式来实现TAB切换的效果。
范例:

手机客户端UI设计之手机平台之争
1. 当前手机平台的争锋
为了占领移动互联网的制高点,当前的几大IT巨头都以手机平台为基础展开争夺。占领移动平台就是占领了用户的移动桌面,也就为自身的移动服务争取到了最佳位置。
微软公司推出windows phone 7, 曝光了windows 8;苹果公司也开了iOS 5的发布会;谷歌的Android 3.0的发布,Android 2.4 的若隐若现等等;大家都在努力提升平台体验。另外,惠普的Web OS、黑莓公司也都在研制和发布新平台,也引起了业内人士的极大关注。
从当前市场占有率和未来的发展趋势看,客户端适配上,主要还是考虑iOS ,Windows,Android三个系统为主,其他的系统在国内还难占据主流,这里不解释。Android手机的增长最快;iOS手机在国内的占有量也增长很快,利好消息也不断,电信、移动都在谈;Windows主要看与Nokia的未来合作,前景不小。
因此,在本文中,简单的介绍一下这三个主流平台的交互特性,以帮助刚从事客户端交互设计的同行们更快地了解它们的基本特性,为能开发出更好体验的客户端提供便利。
2. 各个平台的特点及优势
1)平台的硬件特性
a) 平台的按键
手机按键是系统自带的,平台也会把按键的功能带入到系统的客户端应用中,他也天然地与用户操作相融合。

手机按键一般分为两类,功能键和导航键。功能键被指派为特定的功能,用户按了后,触发对应的功能,一般与屏幕内容关系不大,如拍照键,只是启动拍照,在其他的客户端中基本无效。
另一类是导航键,被赋予了特定的逻辑规则,她的操作与屏幕有一个逻辑映射的关系,但操作与操作对象分离,用户按键后,在屏幕中得到对应的反馈。如【Back】映射为返回前一页,点击【Back】后,屏幕的内容返回到上一页。
功能键能直接启动功能,它本身对交互的影响不是很大。而导航键则是交互设计的重要组成部分。主要应该注意以下几点:
(1) 客户端的交互导航设计应该支持平台的导航按键的操作。不管你是否已经在屏幕中有虚拟按钮代替了按键已有的功能,也应该支持系统按键的导航逻辑。
(2) 客户端用到了平台的功能键对应的功能,应该支持功能键的操作。如,在客户端中需要调节音量,则应该支持系统音量的按键来控制。
(3) 所有客户端对按键的操作都必须保持一致,不要随意互用。
b) 平台的屏幕适配
由于不同平台的开放程度很不一样,不同的平台产品对于屏幕的大小的设计很不一样,有些只有很少的尺寸分布;有些有很多不同的尺寸,这给适配带来了很多问题和麻烦。

c) 平台支持的其他硬件:传感器,屏幕特性等
iPhone 推出来后,迅速风靡全球,创造了一个革新的时代(也有人说iPhone本身不是革命,但是他创造了一次革命),除了设计本身外,几个传感器的合理使用也立下了汗马功劳。主要包括,重力加速度传感器、陀螺仪、接近传感器、电子罗盘等。这些传感器在不同的情景下,创造了很多独特的体验,极大的增强了手机的可玩性。
不同的平台或是手机会支持不同的传感器,在界面设计时,也需要考虑它们在不同平台上支持的普及程度,以及不支持的时,能提供的相关代替设计方案。
2)平台的界面特性
a) 应用入口形式
应用程序的启动入口是指用户启动程序的交互界面及操作形式。不同的平台上,对于启动入口操作和界面也有较大的区别,这是展示平台特性的第一印象。同时,不同平台及手机公司为了使品牌形象更加突出也会在这里多做文章。
从交互特性上看,应用程序的启动入口主要有以下几个特征和注意点:

b) 页面基本结构
页面的基本结构布局,决定了手机界面的主要风格,在不同的平台上为了表现出设计的差异和风格,在界面布局上都有所不同。但是,总的来说还是没有与iOS有何本质的不同,主要在形式上略微的不同。
iOS:

Android:

Windows Phone7:

Android 的手机厂商都更改了原生系统的界面,不同Android手机在界面的展示上多有不同。在Android客户端的设计上,本身有不少都是从iOS上直接移植了界面,导致了它的更多不同。但是不管怎么样,界面上操作和导航逻辑要符合平台本身的特征。
在框架的设计上,我是倾向于把最核心的操作放在底部,方便用户的单手操作。iOS的设计把导航按钮方在左上角,远离大拇指的操作区域,就是容易造成用户脱手“甩机”,也影响操作效率。
c) 主要导航特性:
导航作为一个平台的主要交互特性之一,不同平台之间也存在较大的差异。iOS在设计上逻辑严密,所有的应用自成一体、浑然天成;相比之下,Android像是由iOS和android设计师杂交的产物,在不同的应用上导航系统混乱,不太成体系;Windows Phone 7 的导航在界面展示上,标题采用全景图的形式,真是另辟蹊径,自成体系。
在这里主要讲一下不同平台下的导航按键、title和Tab、返回逻辑、退出程序几个小点。

d) 菜单及操作形式
这几个代表当前最高水平的移动平台,都是以手指触摸为基础的直接操作界面。iOS只提供了直接操作的方式;Android和Win Phone 7 还增加了几个硬键按钮配合操作,但总体也是以直接操作为主。几个平台都有菜单操作,但是展示的形式不同,但也在相互的借鉴。

由于手机屏幕较小,一屏内容往往显示一个对象或信息单元,toolbar的操作正是对这个单元进行操作的。如果是对单元内的对象操作,更多的设计都是在界面中直接设置操作对象(如屏幕内的操作按钮)。
e) 信息提示
信息提示方式,各个平台之间也都在相互学习。信息list作为Android系统的最核心的设计优势,现在iOS5也开始应用。同时许多Android手机及锁屏应用在锁屏界面与提示信息间做更多地权衡,使用户能更快地处理信息,提升效率。
各个平台都提供了对话框的形式,只是在叫法上略有不同,如alert,popup,dialog,raw notification等,其主要的交互操作没有区别,都是对话框的基本操作形式。也有一些变异的反馈提示框,如android系统提供的快速消失的反馈提示,做成轻量级的,对用户干扰也减到更少。
Android系统提供的状态栏的消息提示机制,是处理多应用push信息的一个十分创新的设计,可以说是android系统的最佳设计。用户可以在任何界面中,快速的向下拨动状态栏呼出信息list,也可以再向上拨动手指收起提示信息。但是,在最近看到的iOS5上也看到了它的更新特性中,这一点就赫然在列。所以,有好的特性,不同的平台也会相互学习。
iOS上也有它的创新提示,就是在程序图标上来进行新消息数量的提示,这在后面的几个平台上都有应用,只是不同的平台上,表现形式略微不同,就是视觉上微创新。
Windows Phone 7 提供了tile形式的提示信息显示方式,那只是样式上的不同,在设计的本质上,差异不大。
3. 移动应用在多平台适配的原则
一个产品的规划,很少会仅局限于某一个平台,都会进行跨平台的适配。那应该如何进行适配呢?
这里主要有两个观点,以设备为中心来设计还是以应用为中心来设计;以设备为中心的设计师认为,应用界面应该与设备的设计规范保持一致,让用户快速上手,不觉得陌生。以应用为中心的设计师认为,保持所有的平台上的一致性,同时,很多多平台的应用开发工具也是为开发人员提供了多平台界面移植的便利,但是对用户体验是否好,却有待思考。
在多平台适配中遵循如下原则
1) 客户端的设计规范应该以平台规范为基础
2) 在多平台中,应保持统一的品牌标识,包括logo,视觉风格,核心功能点等等。
3) 更多地与平台的特性相融合,运用平台提供的特色功能,来减少用户的输入或者其他体验提升点。如拍照输入,传感器的使用等。
每个平台都需要注意的问题有:
1) 移动的特性决定了手机信号的强弱不均,如何处理在弱信号下的设计?
2) 需要考虑在断网情况下,如何快速恢复中断?
3) 如何设计手机推送的问题?
4) 如何尽量避免手机的固有限制,如屏幕小,输入不方便,电源紧张等?
5) 如何尽量通过手机的特有特性来提升体验,如各类传感器,声音提示等?
从客户端的交互设计上来说,我们要做的是如何发挥平台的特性上的设计优点,把客户端的体验去做好,而不是去改变平台的设计特性。所以,做客户端设计的设计师,需要时刻关注平台特性的更新,这都是你提升客户端体验的契机。
生活简单就迷人,人心简单就幸福
1,人生没有如果,只有后果和结果。2,过去的不再回来,回来的不再完美。3,生活简单就迷人,人心简单就幸福。4,简单一些,快乐一些,幸福一些。5,过去不可忘记,但要放下。6,只要还有明天,今天永远是起跑线。7,学会简单其实不简单。8,简单的生活何尝不是一场华丽的冒险。
DOM元素如何获得焦点
首先让我们看看哪些元素可以直接获得焦点(element..focus()):
- a elements that have an href attribute
- link elements that have an href attribute
- button elements that are not disabled
- input elements whose type attribute are not in the Hidden state and that are not disabled
- select elements that are not disabled
- textarea elements that are not disabled
- command elements that do not have a disabled attribute
- Elements with a draggable attribute set, if that would enable the user agent to allow the user to begin a drag operations for those elements without the use of a pointing device
- Each shape that is generated for an area element
- …
而除上面以外的元素(比如:div,p)一般都无法直接获得焦点,那如何处理呢?
- 给元素添加 contenteditable 属性。
User agents must make editing hosts focusable (which typically means they enter the tab order).
- 给元素添加 tabindex 属性。
// From : http://www.w3.org/TR/2009/WD-html5-20090423/editing.html#attr-tabindex
The tabindex content attribute specifies whether the element is focusable, whether it can be reached using sequential focus navigation, and the relative order of the element for the purposes of sequential focus navigation.
非常推荐使用
tabindex = -1,基本无副作用!!If the value is a negative integer: The user agent must allow the element to be focused, but should not allow the element to be reached using sequential focus navigation.
综述,使无法直接获得焦点的元素获得焦点的最佳实践就是:给元素添加 tabindex = -1 属性。
页面样式重置、css重置(一)
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: ”;
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
你知道么:安全的 CSS hacks 秘籍
你如何搞定 IE 这只难以驯服的怪兽?使用 CSS Hacks 或者条件注释么?恐怕没有什么解决方案是完美的。每个设计师或者前端码农都会有自己打败 IE 行之有效的方法。所有这些技术都各有利弊,让我们一起来看看。
通过条件判断引入样式表
使我们能很容易在 IE 浏览器中通过条件注释语句加载指定样式表,而其他非 IE 内核浏览器则自动忽略这段蹩脚的 HTML 注释。下面是一个例子:
<!–[if IE 8]><link rel=”stylesheet” href=”ie8.css”><![endif]–>
<!–[if IE 7]><link rel=”stylesheet” href=”ie7.css”><![endif]–>
<!–[if IE 6]><link rel=”stylesheet” href=”ie6.css”><![endif]–>这段代码会导致 IE8、IE7、IE6 各自加载对应的样式文件。这事实上是非常牛逼的,条件注释给按浏览器加载各自不同的样式表提供了可能,但同时需要维护多个样式文件。
CSS hacks
这事实上是个龌龊的做法,能解决问题又不符合规范,看着也很头大。大部分人看着它只能束手无策而又逼不得已。之前的《CSS Hacks for IE,IE 也可以很完美》已经谈过 IE 的 CSS hacks 了。现在可以来简单回顾一下常用的几个方法:
_selector{property:value;} //IE6
*selector{property:value;} //IE6 & IE7
selector{property:value\9;} //IE6 & IE7 & IE8这个一般人都知道,就不多说了。但面临的一个现实问题是,\9 这个 hack 不只是针对 IE8 以及更老版本奏效,IE9 最终的发行版依旧会受到这个 hack 的影响。而 IE9 本身在 CSS 上的各种缺陷又是被修复的。如果将来 IE10、IE11 来了,那又怎么办?显然 \9 并不是一个严谨的安全的方案。
另外,采用不同的 X-UA-Compatible 模式也会影响不同版本的 IE 渲染差异。建议设置默认渲染模式如下:
<meta http-equiv=”X-UA-Compatible” content=”IE=Edge”>//标准 IE 模式那咋整呢?咋整咋整咋整?没事,下面还有更绝的。
通过条件判断插入指定类
既然可以用条件判断,那么直接为不同 IE 版本输出单独用于设定样式的钩子类好了。直接上代码:
<!–[if !IE]><html><![endif]–> // 非 IE 浏览器的情况,不添加任何作用类
<!–[if IE 6]><html><![endif]–>
<!–[if IE 7]><html><![endif]–>
<!–[if IE 8]><html><![endif]–>如果要是 IE9、IE10 再想出现什么神奇的行为艺术的话,继续添加指定作用类就行咯。并且你的样式表也会变得异常干净、整洁、美观:
.selector { color: black; }
.ie8 .selector { color: green; } /* IE8 */
.ie7 .selector { color: blue; } /* IE7 */
.ie6 .selector { color: red; } /* IE6 */当然,标准模式的 X-UA-Compatible 声明还是必须的,以防页面被强制按照低版本的 IE 来渲染。
jquery ajax方法:load,get等 在chrome下失效(无效,不显示)的问题
小弟今天碰到一个问题。jquery在chrome 5.0+的版本中,ajax的load、get等方法完失效。 汗,之前一直没发现。
简易代码如下:(test.html页面中有HTML代码)
$(“body”).load(“test.html”,function(data) {alert(data));
}
症状: 其实语句是执行了,但返回的内容就是空值。
百度上找到答案:原来是CHROME 5里面对非针对服务端的AJAX调用做了严格的限制,如果是在SERVER端调用就没有问题了。
欢迎拍砖!
js window.settimeout 传参数、用法小记。
很多时候,我们需要在settimeout的函数中传一些参数,但默认的settimeout函数并不支持直接传参数,那怎么办呢。
(⊙o⊙)…俺是菜鸟,经常都是百度或谷歌出来,然后自己修改成自己想要的东东。那么我就小结一下吧:
setTimeout 定义和用法:
setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。
语法:
setTimeout(code,millisec)
参数:
code (必需):要调用的函数后要执行的 JavaScript 代码串。
millisec(必需):在执行代码前需等待的毫秒数。
提示:
setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。
setTimeOut() 传递参数:
/*
* 先从正常的延时执行说起,以下代码会在2s后弹出true,OK
*/
function st(){
alert(true);
}
setTimeout(st, 2000);
/*
* 下面的代码也会弹出true,但不OK,因为延时没有起作用
*/
function st(arg){
alert(arg);
}
setTimeout(st(true), 2000);
/*
* 解决方法之一,这种方法可以应付参数为字符串型的,对object型就不OK了
*/
function st(arg){
alert(arg);
}
setTimeout(‘st(‘+ true +’)', 2000);
/*
* 解决方法之二,可以利用闭包
*/
function st(arg){
return function(){alert(arg);}
}
var st1 = st(true);
setTimeout(st1, 2000);
/*
* 解决方法之三,可以重载 window.setTimeout 函数,代码转载有修改,这里也有用到闭包的概念
*/
var _st = window.setTimeout;
window.setTimeout = function(fRef, mDelay){
if(typeof fRef == ‘function’){
var argu = Array.prototype.slice.call(arguments,2);
var f = function(){
fRef.apply(null, argu);
};
return _st(f, mDelay);
}
return _st(fRef,mDelay);
}
function st(arg){
alert(arg);
}
setTimeout(st, 2000, true);