[转载]Description Resource Path Location Type Unparsed aapt error(s)! - Jesse的书桌 - 博客频道 - CSDN.NET

mikel阅读(952)

[转载]Description Resource Path Location Type Unparsed aapt error(s)! – Jesse的书桌 – 博客频道 – CSDN.NET.

这个问题时常出现,经常是项目每个文件没有任何错误,但是项目文件夹上有个叉

 

我用下面的方法就解决了,在myeclipse菜单栏的project->clean,选择有问题的项目即可,内容不会丢失

 

PS:如果你的项目内存在错误,请先把错误注释或修改后再使用上面的方法,因为存在错误的话直接clean会丢失R.java文件

只有把错误改掉后重新clean一下

 

如果有闲功夫的,想探究前因后果的,可以参见这个老外的帖子http://forums.pragprog.com/forums/152/topics/8036

 

——————————————————————————————————————————————————————————

补充:如果一不小心在项目有错误的时候clean了  而且项目很大 没法一步步还原,也就是说R文件丢失了

可以参考下面做法

 

 

1。右击你的工程(项目)——>Android Tools——>Fix Project Properties 即可。

2。右击你的工程(项目)——>Properties——>Android ——> 选择相应的target 然后 点击 apply 即可。

 

注意:如果你使用了这两个方法还不行,请检查自己的相关xml文件,以及资源文件,

常见错误:资源文件里新加的图片名称有问题(不能使用大写字母),xml文件内容或名称有问题(名称字母也不能大写)等等

 

我今天就是因为新加的图片名称有误,谨记(2011.5 补充) 

[转载]PHP + Smarty + html5 构建Wap应用 - coder狼 - 博客园

mikel阅读(1187)

[转载]PHP + Smarty + html5 构建Wap应用 – coder狼 – 博客园.

一 简介
Smarty是一个PHP编写的模板引擎(template engine),主要用于构建web应用程序的表示层。Smarty的主页是http://www.smarty.net/download, 目前的新版本是3.1.16。Smarty主页上有详细的开发文档,包括在线阅读版本和可供下载的pdf版本,以及一个guestbook的样例程序,为我们开发人员学习smarty提供了极大的方便。
使用smart编写的模板将被smarty编译成php代码,由于编译过程只在模板文件被修改后发生一次,所以使用smarty模板引擎编写的php代码运行速度几乎没有什么损失。
我曾使用smarty库做Web应用开发,最近发现,smarty库也可以用于构建Wap应用。原理上与Web开发是一样的。本文将利用php+smarty创建一个简单的wap页面,以介绍用php+smarty构建Wap应用的一般方法。

二 下载安装
1.php
php的安装过程可以参考:http://www.php.net/manual/en/install.php,本文不再详细叙述。
2.smarty
首先,下载最新版本的smarty:http://www.smarty.net/download下载后,找到压缩包内的libs目录,将该目录解缩到apache的document root下。
libs目录下对于开发最重要的文件是Smarty.class.php,其中定义了Smarty类。我们将通过继承这个类来配置自己的模板引擎。

三 配置smarty
1. 配置
Smarty的配置是通过继承Smarty类并改写其中的成员变量来完成。
在document root目录下创建mySmarty.class.php文件,输入以下代码:

       require_once("libs/Smarty.class.php");  
       class MySmarty extends Smarty  
         {  
              function MySmarty()  
                {  
                     $this->Smarty();  
                     $this->template_dir = 'template';  
                     $this->compile_dir = 'compile';  
                }  
         }  
           
       $smarty = new MySmarty();  

下面我们来解释上述配置的含义:
template_dir指定模板文件存放的位置。模板文件一般以.tpl作为后缀。使用smarty的display方法显示模板时,smarty会到这个目录中查找指定的模板。
compile_dir:每一个模板都会被smarty编译,编译生成的php代码存放在compile_dir中,需要注意的是,如果在Liunx系统上,要确保php对这一目录具有写权限。
最后一行创建了一个MySmarty对象,这样我们的php代码中只要包含mySmarty.class.php就可以通过$smarty对象操作smarty了。
2.创建相应的目录
在document root下创建相应的template和compile目录。
目录结构如下所示:
www
I—–libs
I—–template
I—–compile
I—–mySmarty.class.php
四 创建wml文件的tpl模板(或创建html5的tpl模板文件)
创建如下的模板:index.tpl

<xml version="1.0"?> 
 
<wml> 
       <card title="WAP with smarty"> 
              <p> 
                       {$welcome_message}  
              </p> 
              <p> 
                     <table columns="1"> 
                       {foreach from=$message_list item=message}  
                     <tr><td>{$message}td>tr> 
                       {/foreach}  
                     table> 
              </p> 
</card> 
</wml> 

Smarty模板的结构与一般的XHTML文件非常类似,但是在其中加入了smarty的标签。默认情况下,smarty标签包含在{}里。
如{$welcome_message}表示此处以smarty变量$welcome_message的值代替。
{foreach}标签相当于一个循环语句,在构造表格这类元素时相当的有用。如上述代码表示遍历message_list数组,数组中的每一元素命名为message,表格中每一行显示message_list中的一个元素。
详细的标签列表请参见smarty的开发文档。
由于wml是严格的xml文档,在编写模板时一定要注意符合xml文档的格式。
五 编写php代码
编写如下的php代码index.php

       require_once("mySmarty.class.php");  
         header("Content-type: text/vnd.wap.wml");  
       $smarty->assign("welcome_message", "Welcome smarty!");  
       $list[0] = "Message 1";  
       $list[1] = "Message 2";  
       $list[2] = "Message 3";  
       $smarty->assign("message_list", $list);  
       $smarty->display("index.tpl");  

上述代码中,header(“Content-type: text/vnd.wap.wml”) 一行非常重要,它告诉浏览器这是一个wml文档。assign方法为模板变量赋值。我们看到,模板变量可以是字符串,也可以是数组,事实上,任意类型的php变量都可以赋值给模板。
最后的display方法显示index.tpl模板,模板中的变量将被我们赋于的实际值取代。再次提醒一下的是,smarty将会到template目录中查找index.tpl文件,所以模板文件一定要保存在template目录中。

原文地址:http://wj829.blog.163.com/blog/static/2889363620121142456321/

[转载]SqlServer存储过程传入Table参数 - 世民后人 - 博客园

mikel阅读(1266)

[转载]SqlServer存储过程传入Table参数 – 世民后人 – 博客园.

今天是周日,刚好有空闲时间整理一下这些天工作业务中遇到的问题。

有时候我们有这样一个需求,就是在后台中传过来一个IList<类>的泛型集合数据,该集合是某个类的实例集合体,然后将该集合中的实 例的数据一个个地插入到数据库或者更新到数据库中去。一开始我想到的方法是拼接字符串,然后通过存储过程对接收到的字符串进行截取,再一个个地插入或者更 新到数据库中去,这是最原始的方法,不过过程会比较复杂,想到这就头疼。后来查找发现说SQLServer2008中为存储过程添加了一个新特性,可以传 递表类型的参数,既然可以传递表类型参数,那问题就变得简单啦。以下是开发中写的code.

1.ASP.NET后台:

/// <summary>
        /// Add the PayrollCycle
        /// </summary>
        /// <param name="payrollCycle">payrollCycle</param>
        /// <returns>bool</returns>
        public bool AddPayrollCycle(IList<PayrollCycle> payrollCycles)
        {
            DataTable dataTable=new DataTable();
            dataTable.Columns.Add("Year",typeof(int));
            dataTable.Columns.Add("Month",typeof(int));
            dataTable.Columns.Add("CutoffDate",typeof(int));
            dataTable.Columns.Add("PayrollDate",typeof(int));
            dataTable.Columns.Add("EnterUser",typeof(string));
            dataTable.Columns.Add("EnterDate",typeof(DateTime));
            dataTable.Columns.Add("LastUpdatedUser",typeof(string));
            dataTable.Columns.Add("LastUpdatedDate",typeof(DateTime));
            foreach (PayrollCycle p in payrollCycles)
            {
                DataRow dataRow = dataTable.NewRow();
                dataRow["Year"] = p.Year;
                dataRow["Month"] = p.Month;
                dataRow["CutoffDate"] = p.CutoffDate;
                dataRow["PayrollDate"] = p.PayrollDate;
                dataRow["EnterUser"] = UserSession.LogOnUserAccount;
                dataRow["EnterDate"] = DateTime.Now;
                dataRow["LastUpdatedUser"] = UserSession.LogOnUserAccount;
                dataRow["LastUpdatedDate"] = DateTime.Now;
                dataTable.Rows.Add(dataRow);
            }
            
            SqlParameter[]paras=new SqlParameter[]
                                    {
                                        new SqlParameter("@PayrollCycles",dataTable)
                                    };
            return SqlHelper.ExecuteNonQuery("MCU.USP_AddPayrollCycles", paras) > 0;
        }

为dataTable添加column的时候,必须明确该列的typeof,否则在存储过程当中会把传入的该列当成varchar类型看待,导致某些类型转换失败

2.在SQLServer中先定义一个Table类型的Type:

CREATE TYPE [MCU].[PayrollCycleType] AS TABLE(
    [YEAR] [int] NOT NULL,
    [Month] [int] NOT NULL,
    [CutoffDate] [int] NOT NULL,
    [PayrollDate] [int] NOT NULL,
    [EnterUser] [varchar](20) NULL,
    [EnterDate] [datetime] NULL,
    [LastUpdatedUser] [varchar](20) NULL,
    [LastUpdatedDate] [datetime] NULL
)
GO

接着编写一个传入上步骤中定义的表类型的参数的存储过程,该参数为Readonly(作为表类型参数必须为可读),代码如下:

CREATE PROCEDURE [MCU].[USP_AddPayrollCycles]
(
    @PayrollCycles MCU.PayrollCycleType Readonly 
)
AS
BEGIN
    SET NOCOUNT ON
    BEGIN TRANSACTION
    INSERT INTO MCU.PayrollCycle
            ( 
              [Year] ,
              [Month] ,
              CutoffDate ,
              PayrollDate ,
              EnterUser ,
              EnterDate ,
              LastUpdatedUser ,
              LastUpdatedDate
            )
    SELECT    
              [Year] ,
              [Month] ,
              CutoffDate ,
              PayrollDate ,
              EnterUser ,
              EnterDate ,
              LastUpdatedUser ,
              LastUpdatedDate 
              FROM @PayrollCycles 
    COMMIT TRANSACTION           
END

GO

就这样大功告成,用起来相当方便,就不用通过拼接字符串进行数据的插入,更新操作了。
绿色通道: 好文要顶 关注我 收藏该文与我联系

你连世界都没观过,哪来的世界观

mikel阅读(1269)

世界很大,自己很小

每个人都有机会改变世界,但是很多都在改变自己这一步上乍然而至。

为什么?

自己都改变不了,有脸改变世界吗?

想到就去做,别怀疑,别否定,

做了,才知道自己有多少能量,能干啥!

根本没必要在意别人怎么看你,大家都很忙,没时间关注你!

悟自己道,走自己的路 且行且珍惜 🙂

[转载]Android L试玩Android_L_SDK下载

mikel阅读(878)

转载Android L试玩Android_L_SDK下载.

        6.26谷歌在I/O大会上发布了全新的Android系统。与以往不同,谷歌对于这款全新的Android系统,没有将其命名为Android 5.0,也没有给这套系统起一个像之前版本一样的甜品的名字,只是称之为“Android L”。Alanapi 

 

        今天更新下载了最新的 SDK后,发现以前的老项目报错,找不到 annotations.jar 这个jar文件,去对应的目录(android-sdk-windows\tools\support)发现果然不存在 annotations.jar 文件,看来是在更新 SDK 的时候自动给删除了。好吧,删了就删了吧,在以前的 SDK 版本中 拷贝一个 annotations.jar 到当前 android-sdk-windows\tools\support 一切就OK了。Alanapi 

 

        至于现在最新版本 Android L (API 20)具体把 annotations.jar 文件放在哪儿去了还没有发现,或者以什么方式替代,忘知道的兄弟告诉一声……Alanapi 

 

        更新的SDK有  Android L(API 20, L  preview)、Android 4.4W(API 20)

 

以下是模拟器上面的截图(黑色Android 4.4.2,白色Android L,Android Wear)

 

稍后奉上 SDK 下载地址,正在上传中。。。。

 

 

 

开发工具下载地址:http://pan.baidu.com/s/1hq9UvIW

 


 

百度经常屏蔽地址,如发现分享地址被屏蔽了我会在此更新地址

 

         最新SDK下载地址:   http://pan.baidu.com/s/1pJEzS2v

 

        全部SDK下载地址(包含所以版本):http://pan.baidu.com/s/1jG1cR3o

 


 

或转至 

Android 最新SDK更新,最新SDK下载,最新Android ADT下载,最新Android Studio下载

 


 

下载之后放在对应的 SDK 文件夹中即可

 

QQ截图20140627211705.png

QQ截图20140627211831.pngQQ截图20140627211848.pngQQ截图20140627211908.pngQQ截图20140627212000.pngQQ截图20140627212017.pngQQ截图20140627212111.pngQQ截图20140627212132.pngQQ截图20140627212200.pngQQ截图20140627212211.pngQQ截图20140627212539.pngQQ截图20140627212659.pngQQ截图20140627212825.pngQQ截图20140627212849.pngQQ截图20140627211804.png

[转载]基于ThinkPHP的在线编辑器调用 - Balla_兔子 - 博客园

mikel阅读(1087)

[转载]基于ThinkPHP的在线编辑器调用 – Balla_兔子 – 博客园.

开源的在线编辑器有很多,比如FCKEditor,UEditor,Kindeditor等,调用方式也都大同小异

下面列举UEditor在线编辑器插件在ThinkPHP里面的应用

1、Ueditor下载地址:http://ueditor.baidu.com/website/download.html(注意编码)

2、使用ThinkPHP版本为ThinkPHP3.1.2

 

先下载Ueditor插件解压放置ThinkPHP项目的根目录并将文件夹名称重命名为ueditor

如下图:

编写测试类:

class IndexAction extends Action {
public function index(){
$this-&gt;display();
}

对应映射Html静态页面:


Ueditor
<script src="__ROOT__/ueditor/ueditor.config.js"></script><script src="__ROOT__/ueditor/ueditor.all.js"></script>
<script>// <![CDATA[
function edit(){                 UE.getEditor('content');                 }
// ]]></script>

&nbsp;

<form action="__URL__/edit" method="post">标题:

<input name="info" type="text" />

内容:<textarea id="content" style="width: 700px; height: 300px;" name="content"></textarea>
<input type="submit" value="提交" />

</form>

在静态页面HTML用JavaScript调用,分别引入ueditor.config.js、ueditor.all.js两个JS文件,可直接用UE.getEditor(参数1,{参数2});进行调用

参数1:

需要和下面的TextArea的ID名对应。

参数2:(非必须)

一些初始化参数,比如宽度,高度,各种按钮,样式等。

若不填写此参数,默认下是用TextArea的Style样式的宽高来定义Ueditor

效果如下图:

提交表单:

————————————————————-华丽的分割线 ——————————————————————-

来说下关于参数二,毕竟一般的在线编辑器是不需要那么多功能的,使其简洁。




Ueditor
<script src="__ROOT__/ueditor/ueditor.config.js"></script><script src="__ROOT__/ueditor/ueditor.all.js"></script>
<script>// <![CDATA[
            function edit(){
                UE.getEditor('content',{  
                //这里可以选择自己需要的工具按钮名称,此处仅选择如下五个  
                toolbars:[['FullScreen', 'Source', 'Undo', 'Redo','bold','test']],  
                //focus时自动清空初始化时的内容  
                autoClearinitialContent:true,  
                //关闭字数统计  
                wordCount:false,  
                //关闭elementPath  
                elementPathEnabled:false,  
                //默认的编辑区域高度  
                initialFrameHeight:300  
                //更多其他参数,请参考ueditor.config.js中的配置项  
            });      
        }
        
// ]]></script>

&nbsp;

<form action="__URL__/edit" method="post">标题:

<input name="info" type="text" />

内容:<textarea id="content" style="width: 700px; height: 300px;" name="content"></textarea>
<input type="submit" value="提交" /></form>

关于参数二的toolbars在开发文档ueditor.config.js中有给出:

toolbars: [[
'fullscreen', 'source', '|', 'undo', 'redo', '|',
'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
'directionalityltr', 'directionalityrtl', 'indent', '|',
'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',
'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
'simpleupload', 'insertimage', 'emotion', 'scrawl', 'insertvideo', 'music', 'attachment', 'map', 'gmap', 'insertframe', 'insertcode', 'webapp', 'pagebreak', 'template', 'background', '|',
'horizontal', 'date', 'time', 'spechars', 'snapscreen', 'wordimage', '|',
'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|',
'print', 'preview', 'searchreplace', 'help', 'drafts'
]]
13
toolbars: [[
            'fullscreen', 'source', '|', 'undo', 'redo', '|',
            'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
            'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
            'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
            'directionalityltr', 'directionalityrtl', 'indent', '|',
            'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',
            'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
            'simpleupload', 'insertimage', 'emotion', 'scrawl', 'insertvideo', 'music', 'attachment', 'map', 'gmap', 'insertframe', 'insertcode', 'webapp', 'pagebreak', 'template', 'background', '|',
            'horizontal', 'date', 'time', 'spechars', 'snapscreen', 'wordimage', '|',
            'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|',
            'print', 'preview', 'searchreplace', 'help', 'drafts'
        ]]

按照个人需求填写所需就成

上图代码效果图:

坐在“金矿”边上的可爱“猿”人们

mikel阅读(1027)

昨天Geek众策群里面讨论APP开发的问题,最后谈起大家的APP赚钱了吗?

结果很多人都说自己开发的APP上市场了都不赚钱 。

于是很好奇,

我:那你们为啥要做应用

纸团:“
没想的赚多少钱啊 , 自己很花心思做的  感觉像亲儿子一样 , 比如抄一抄应用  加点广告。就感觉没什么

 我:”太可爱了你们

这就是可爱的程序员们

【活跃】河北-Mikel(3379152) 17:16:54
大家研究研究APP赚钱吧,共同讨论学习
【活跃】河北-Mikel(3379152) 17:17:47
思维模式的问题,你们太看不起自己的技术了
【活跃】河北-Mikel(3379152) 17:18:19
大家都一样,觉得做出的东西没啥难度,也感觉不出价值
【活跃】河北-Mikel(3379152) 17:19:20
这个世界就是两个字 买 和卖 
【活跃】河北-Mikel(3379152) 17:19:49
我30岁的时候曾经迷茫过,我要不要做一辈子技术
【活跃】河北-Mikel(3379152) 17:19:56
打一辈子工
【活跃】河北-Mikel(3379152) 17:20:12
感觉打工的日子没头,就想转型
【活跃】河北-Mikel(3379152) 17:20:38
结果发现自己就守着个金矿还不知道
【活跃】河北-Mikel(3379152) 17:21:56
互联网就是金矿,技术就是钥匙,我们程序猿就是要用技术这把钥匙打开互联网这座金矿
 

【活跃】河北-Mikel(3379152) 17:25:11

要转型先要改变自己,于是我就开始建站,学推广,做软件所有的一切的一切都是一个目的就是利用技术挖掘互联网的价值

好了,要写的都在聊天记录中,程序员们不要看不起自己的技术,你们很值钱的!

 

[转载]JavaScript Copy to Clipboard

mikel阅读(1134)

[转载]JavaScript Copy to Clipboard.

Providing your users the ability to copy text to the clipboard can make your website much more convenient and valuable. Unfortunately Flash 10 broke most of the methods for doing so. Luckily a great library named ZeroClipboard exists. ZeroClipboard uses a pinch of Flash and touch of JavaScript to make copying to the clipboard happen.

The Sample HTML

<script src="ZeroClipboard.js"></script>
<textarea id="box-content" cols="70" name="box-content" rows="5">&lt;br /&gt;
	The David Walsh Blog is the best blog around!  MooTools FTW!&lt;br /&gt;
</textarea>

<input id="copy" name="copy" type="button" value="Copy to Clipboard" />

The above HTML features a form element with the ID “box-content” and a button with the ID “copy”. Both of those element IDs will come into play with ZeroClipboard.

The ZeroClipboard JavaScript

//set path
ZeroClipboard.setMoviePath('http://davidwalsh.name/demo/ZeroClipboard.swf');
//create client
var clip = new ZeroClipboard.Client();
//event
clip.addEventListener('mousedown',function() {
clip.setText(document.getElementById('box-content').value);
});
clip.addEventListener('complete',function(client,text) {
alert('copied: ' + text);
});
//glue it to the button
clip.glue('copy');

With the ZeroClipboard object loaded we:

  • Set the path to the SWF file.
  • Create what ZeroClipboard calls a “client”: A client is a single instance of the clipboard library on the page, linked to a particular button or other DOM element.
  • Add a mousedown event listener that places text from inside our textarea into the clipboard.
  • Add an optional complete event where we can add functionality to execute once the text has been successfully added to the clipboard.
  • “Glue” the button to the functionality we’ve added in the steps above.

That’s it! ZeroClipboard is an outstanding utility to allow copy to the clipboard functionality on any website.

[转载]js中几种实用的跨域方法原理详解 - 无双 - 博客园

mikel阅读(1029)

[转载]js中几种实用的跨域方法原理详解 – 无双 – 博客园.

这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。

下表给出了相对http://store.company.com/dir/page.html同源检测的结果:

QQ截图20130613230631

要解决跨域的问题,我们可以使用以下几种方法:

一、通过jsonp跨域

在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。

比如,有个a.html页面,它里面的代码需要利用ajax获取一个不同域上的json数据,假设这个json数据地址是http://example.com/data.php,那么a.html中的代码就可以这样:

QQ截图20130613230631

我们看到获取数据的地址后面还有一个callback参数,按惯例是用这个参数名,但是你用其他的也一样。当然如果获取数据的jsonp地址页面不是你自己能控制的,就得按照提供数据的那一方的规定格式来操作了。

因为是当做一个js文件来引入的,所以http://example.com/data.php返回的必须是一个能执行的js文件,所以这个页面的php代码可能是这样的:

QQ截图20130613230631

最终那个页面输出的结果是:

QQ截图20130613230631

所以通过http://example.com/data.php?callback=dosomething得到的js文件,就是我们之前定义的dosomething函数,并且它的参数就是我们需要的json数据,这样我们就跨域获得了我们需要的数据。

这样jsonp的原理就很清楚了,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。

知道jsonp跨域的原理后我们就可以用js动态生成script标签来进行跨域操作了,而不用特意的手动的书写那些script标签。如果你的页面使用JQuery,那么通过它封装的方法就能很方便的来进行jsonp操作了。

QQ截图20130613230631

原 理是一样的,只不过我们不需要手动的插入script标签以及定义回掉函数。JQuery会自动生成一个全局函数来替换callback=?中的问号,之 后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法; 跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。

 

2、通过修改document.domain来跨子域

浏 览器都有一个同源策略,其限制之一就是第一种方法中我们说的不能通过ajax的方法去请求不同源中的文档。 它的第二个限制是浏览器中不同域的框架之间是不能进行js的交互操作的。有一点需要说明,不同的框架之间(父子或同辈),是能够获取到彼此的window 对象的,但蛋疼的是你却不能使用获取到的window对象的属性和方法(html5中的postMessage方法是一个例外,还有些浏览器比如ie6也 可以使用top、parent等少数几个属性),总之,你可以当做是只能获取到一个几乎无用的window对象。比如,有一个页面,它的地址是http://www.example.com/a.html  , 在这个页面里面有一个iframe,它的src是http://example.com/b.html, 很显然,这个页面与它里面的iframe框架是不同域的,所以我们是无法通过在页面中书写js代码来获取iframe中的东西的:

QQ截图20130613230631

这个时候,document.domain就可以派上用场了,我们只要把http://www.example.com/a.htmlhttp://example.com/b.html这 两个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的设置是有限制的,我们只能把 document.domain设置成自身或更高一级的父域,且主域必须相同。例如:a.b.example.com 中某个文档的document.domain 可以设成a.b.example.com、b.example.com 、example.com中的任意一个,但是不可以设成 c.a.b.example.com,因为这是当前域的子域,也不可以设成baidu.com,因为主域已经不相同了。

在页面 http://www.example.com/a.html 中设置document.domain:

QQ截图20130613230631

在页面 http://example.com/b.html 中也设置document.domain,而且这也是必须的,虽然这个文档的domain就是example.com,但是还是必须显示的设置document.domain的值:

QQ截图20130613230631

这样我们就可以通过js访问到iframe中的各种属性和对象了。

不过如果你想在http://www.example.com/a.html 页面中通过ajax直接请求http://example.com/b.html 页面,即使你设置了相同的document.domain也还是不行的,所以修改document.domain的方法只适用于不同子域的框架间的交互。 如果你想通过ajax的方法去与不同子域的页面交互,除了使用jsonp的方法外,还可以用一个隐藏的iframe来做一个代理。原理就是让这个 iframe载入一个与你想要通过ajax获取数据的目标页面处在相同的域的页面,所以这个iframe中的页面是可以正常使用ajax去获取你要的数据 的,然后就是通过我们刚刚讲得修改document.domain的方法,让我们能通过js完全控制这个iframe,这样我们就可以让iframe去发 送ajax请求,然后收到的数据我们也可以获得了。

 

3、使用window.name来进行跨域

window 对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页 面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。

比如:有一个页面a.html,它里面有这样的代码:

QQ截图20130613230631

再看看b.html页面的代码:

QQ截图20130613230631

a.html页面载入后3秒,跳转到了b.html页面,结果为:

QQ截图20130613230631

我 们看到在b.html页面上成功获取到了它的上一个页面a.html给window.name设置的值。如果在之后所有载入的页面都没对 window.name进行修改的话,那么所有这些页面获取到的window.name的值都是a.html页面设置的那个值。当然,如果有需要,其中的 任何一个页面都可以对window.name的值进行修改。注意,window.name的值只能是字符串的形式,这个字符串的大小最大能允许2M左右甚 至更大的一个容量,具体取决于不同的浏览器,但一般是够用了。

上面的例子中,我们用到的页面a.html和b.html是处于同一个域的,但是即使a.html与b.html处于不同的域中,上述结论同样是适用的,这也正是利用window.name进行跨域的原理。

下面就来看一看具体是怎么样通过window.name来跨域获取数据的。还是举例说明。

比如有一个www.example.com/a.html页面,需要通过a.html页面里的js来获取另一个位于不同域上的页面www.cnblogs.com/data.html里的数据。

data.html页面里的代码很简单,就是给当前的window.name设置一个a.html页面想要得到的数据值。data.html里的代码:

QQ截图20130613230631

那 么在a.html页面中,我们怎么把data.html页面载入进来呢?显然我们不能直接在a.html页面中通过改变window.location来 载入data.html页面,因为我们想要即使a.html页面不跳转也能得到data.html里的数据。答案就是在a.html页面中使用一个隐藏的 iframe来充当一个中间人角色,由iframe去获取data.html的数据,然后a.html再去得到iframe获取到的数据。

充当中间人的iframe想要获取到data.html的通过window.name设置的数据,只需要把这个iframe的src设为www.cnblogs.com/data.html就 行了。然后a.html想要得到iframe所获取到的数据,也就是想要得到iframe的window.name的值,还必须把这个iframe的 src设成跟a.html页面同一个域才行,不然根据前面讲的同源策略,a.html是不能访问到iframe里的window.name属性的。这就是 整个跨域过程。

看下a.html页面的代码:

QQ截图20130613230631

上面的代码只是最简单的原理演示代码,你可以对使用js封装上面的过程,比如动态的创建iframe,动态的注册各种事件等等,当然为了安全,获取完数据后,还可以销毁作为代理的iframe。网上也有很多类似的现成代码,有兴趣的可以去找一下。

通过window.name来进行跨域,就是这样子的。

 

4、使用HTML5中新引进的window.postMessage方法来跨域传送数据

window.postMessage(message,targetOrigin)  方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、 FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。

调用postMessage 方法的window对象是指要接收消息的那一个window对象,该方法的第一个参数message为要发送的消息,类型只能为字符串;第二个参数 targetOrigin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 *  。

需要接收消息的window对象,可是通过监听自身的message事件来获取传过来的消息,消息内容储存在该事件对象的data属性中。

上 面所说的向其他window对象发送消息,其实就是指一个页面有几个框架的那种情况,因为每一个框架都有一个window对象。在讨论第二种方法的时候, 我们说过,不同域的框架间是可以获取到对方的window对象的,而且也可以使用window.postMessage这个方法。下面看一个简单的示例, 有两个页面

QQ截图20130613230631

 

QQ截图20130613230631

我们运行a页面后得到的结果:

QQ截图20130613230631

我们看到b页面成功的收到了消息。

使用postMessage来跨域传送数据还是比较直观和方便的,但是缺点是IE6、IE7不支持,所以用不用还得根据实际需要来决定。

 

结语:

除了以上几种方法外,还有flash、在服务器上设置代理页面等跨域方式,这里就不做介绍了。

以上四种方法,可以根据项目的实际情况来进行选择应用,个人认为window.name的方法既不复杂,也能兼容到几乎所有浏览器,这真是极好的一种跨域方法。

[转载]JavaScript实现复制功能 - bbirdsky - 博客频道 - CSDN.NET

mikel阅读(1046)

[转载]JavaScript实现复制功能 – bbirdsky – 博客频道 – CSDN.NET.

这两天在做Web前端时,遇到需求通过js实现文本复制的功能。

先不考虑浏览器的兼容性,看看各浏览器对复制功能的支持情况:
1、IE浏览器,解决方法有三种,代码如下:
function copy(txtid){
	var txtObj = document.getElementById(txtid);
	if(window.clipboardData){ // 仅IE支持此对象,firefox、chrome不支持
		//1、通过clipboardData对象实现复制
		//window.clipboardData.clearData();
		//window.clipboardData.setData("Text",txtObj.value);
		
		//2、通过document对象实现复制:先选择中文本,再执行复制命令
		//txtObj.select();
		//document.execCommand("Copy");	// 仅IE支持,Firefox报语法错误,chrome执行结果返回false(不支持)
		
		//3、通过TextRange对象实现现复制:可以不用先选中内容
		txtObj.createTextRange().execCommand("Copy");
	}
}
2、Firefox,通过接口的方法实现,火狐是出于安全原因,在17之后版本关闭此接口,17及之前版本可用。代码如下:
var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interface.nsIClipboard);
3、Chrome出于安全,未向用户提供对剪板的操作。由此可见,各浏览器对复制功能的支持并不统一。
Zero Clipboard库
jhuckaby写的Zero Clipboard的js类库,利用Flash完成复制内容到剪贴板。只要浏览器装有Flash插件就可以复制内容,通过ActionScript屏蔽了JavaScript的不足,解决浏览器间复制兼容性问题。

Zero Clipboard的实现原理:Zero Clipboard首先生成Flash对象标签,让透明的Flash漂浮在复制按钮之上,其实点击的不是按钮而是Flash,这样将需要的内容传入Flash,再通过Flash的复制到系统剪贴板。

Zero Clipboard的使用方法

注意:由于是基于Flash实现,Flash出于安全,需要在Web容器(例 如Apache、Tomcat)中才能运行,直接打开Flash将不会被加载,按钮类似假死现象,网上说右键Flash设置将 ZeroClipboard.swf添加到受信任位置,感觉应该是行的,我试了,仍然不行,也可能是我本地浏览器的问题。

1>下载Zero Clipboard的压缩包,解压后把文件夹中两个文件:ZeroClipboard.js和ZeroClipboard.swf放入到你的项目中;

2>引入Zero Clipboard.js文件,如下代码:<script type=”text/JavaScript” src=”ZeroClipboard.js”></script>;

    注意:ZeroClipboard.js与ZeroClipboard.swf需要放在同一路径下,如果不在同一路径,可使用ZeroClipboard.setMoviePath()来设置。

3>简单复制代码如下:

var clip = new ZeroClipboard.Client();  // 新建一个clip对象
clip.setHandCursor( true );                 // 设置鼠标为手型
clip.setText("hello,world");                  // 设置要复制的文本,可以为文本框的值
clip.glue("copy-botton");  // 为clip注册一个按钮,参数为按钮元素的id,点击按钮就可以实现复制

4>Zero Clipboard常用方法,建议直接查看源码:

    reposition():防止当页面大小发生变化时,Flash按钮可能会错位问题

    hide()  :隐藏Flash按钮

    show()    :显示Flash按钮

    setCSSEffects():解决Flash遮挡按钮样式失效问题(将:hover修改为.hover)。

5>Zero Clipboard 常用事件,事件处理函数为addEventListener():

    load :Flash按钮加载完事件
mouSEOver:鼠标移上事件
mouSEOut: 鼠标移出事件
mouseDown:鼠标按下事件
mouseUp:鼠标松开事件
complete:复制成功事件

JQuery.zclip库

由于ZeroClipboard是基于原生JavaScript实现,JQuery.zclip使用jQuery对Zero Clipboard进行封装,如果项目中已经使用jQuery,建议使用它,jquery.zclip体积较小。

jquery.zclip下载地址:http://www.steamdev.com/zclip/

Zero Clipboard下载地址:https://github.com/zeroclipboard/ZeroClipboard/releases

示例下载:

为了方便测试,我将jquery.zclip和Zero Clipboard写好的例子上传到csdn,示例必须在web容器里运行。

下载地址:http://download.csdn.net/detail/bbirdsky/5776583