Ubuntu12.04下关闭MongoDB的开机启动

网上什么用sysv-rc-conf配置,什么改S开头为K开头什么的方法通通的不管用,因为10.04开始把MongoDB的启动连接到了/lib/init/upstart-job,而后者是调用了/etc/init/mongodb.conf文件里面关于开机的定义,这是新的框架,所以以前的方法通 通不管用了,你用sysv-rc-conf的时候甚至发现mongodb根本禁止在任何runrevel上启动的,而实际情况是,它每次都很淡定地自动启动了。

 
查看/etc/init/mongodb.conf内容
  1. # Ubuntu upstart file at /etc/init/mongodb.conf  
  2.   
  3. limit nofile 20000 20000  
  4.   
  5. kill timeout 300 # wait 300s between SIGTERM and SIGKILL.  
  6.   
  7. pre-start script  
  8.     mkdir -p /var/lib/mongodb/  
  9.     mkdir -p /var/log/mongodb/  
  10. end script  
  11.   
  12. start on runlevel [2345]  
  13. stop on runlevel [06]  
  14.   
  15. #script  
  16.   ENABLE_MONGODB=“yes”  
  17.   if [ -f /etc/default/mongodb ]; then . /etc/default/mongodb; fi  
  18.   if [ “x$ENABLE_MONGODB” = “xyes” ]; then exec start-stop-daemon –start –quiet –chuid mongodb –exec  /usr/bin/mongod — –config /etc/mongodb.conf; fi  
  19. #end script 

 

修改为
 
  1. # Ubuntu upstart file at /etc/init/mongodb.conf  
  2.   
  3. #limit nofile 20000 20000  
  4.   
  5. #kill timeout 300 # wait 300s between SIGTERM and SIGKILL.  
  6.   
  7. #pre-start script  
  8. #    mkdir -p /var/lib/mongodb/  
  9. #    mkdir -p /var/log/mongodb/  
  10. #end script  
  11.   
  12. #start on runlevel [2345]  
  13. #stop on runlevel [06]  
  14.   
  15. #script  
  16. #  ENABLE_MONGODB=”yes”  
  17. #  if [ -f /etc/default/mongodb ]; then . /etc/default/mongodb; fi  
  18. #  if [ “x$ENABLE_MONGODB” = “xyes” ]; then exec start-stop-daemon –start –quiet –chuid mongodb –exec  /usr/bin/mongod — –config /etc/mongodb.conf; fi  
  19. #end script 

 

Ubuntu开启ip包转发做网关与NAT的设置

基本思想 :开启IP转发,设置好iptables规则。
 
2.1.开启IP转发
两种方式,
临时:echo “1”>/proc/sys/net/ipv4/ip_forward
固定:修改/etc/sysctl.conf,取消这一行的注释:
net.ipv4.ip_forward= 1
然后使之立即生效
sysctl -p
 
2.2.设置iptables规则
临时:iptables -t nat -A POSTROUTING -j MASQUERADE
固定:
或者把上面这个写到一个启动脚本中(比如/etc/rc.local)。这里还有另外一个版本:
iptables -F
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth1 -jMASQUERADE
据说“第一句是清除掉之前所有的iptables规则,第二第三句是允许接收和发送数据包,第四句是在eth1网口上NAT“,只是比上面的多了几句废话,最后指定网卡参数什么,还没试过。iptables的用法还得好好学。
 
3.客户端设置
将缺省网关设置为192.168.0.1,至于IP,192.168.0.*自己随便设。

ubuntu上最新版本mongodb的安装

ubuntu上安装mongodb本可以直接通过sudo apt-get install mongodb 进行安装,只是ubuntu的源上版本比实际mongodb的版本低很多,所以有必要从mongodb的10gen获取最新版本进行安装,安装过程主要需 要将10gen的路径添加到apt-get source list中及key的获取。安装步骤如下:

1、 编辑/etc/apt/sources.list,添加如下内容:

deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen

2、生成GPG key.运行如下命令:

1
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10

3、运行apt-get update,更新源,然后即可安装最新版本的mongodb.

1
2
sudo apt-get update
sudo apt-get install mongodb-10gen

4、安装完毕后,输入mongo即可查看是否服务正常启动了。

Qt Creator系列教程

一、Qt Creator的安装和hello world程序的编写

二、Qt Creator编写多窗口程序

三、Qt Creator登录对话框

四、Qt Creator添加菜单图标

五、Qt Creator布局管理器的使用

六、Qt Creator实现文本编辑

七、Qt Creator实现文本查找

八、Qt Creator实现状态栏显示

九、Qt Creator中鼠标键盘事件的处理实现自定义鼠标指针

十、Qt Creator中实现定时器和产生随机数

十一、Qt 2D绘图(一)绘制简单图形

十二、Qt 2D绘图(二)渐变填充

十三、Qt 2D绘图(三)绘制文字

十四、Qt 2D绘图(四)绘制路径

十五、Qt 2D绘图(五)显示图片

十六、Qt 2D绘图(六)坐标系统

十七、Qt 2D绘图(七)Qt坐标系统深入

十八、Qt 2D绘图(八)涂鸦板

十九、Qt 2D绘图(九)双缓冲绘图简介

二十、Qt 2D绘图(十)图形视图框架简介

二十一、Qt数据库(一)简介

二十二、Qt数据库(二)添加MySQL数据库驱动插件

二十三、Qt数据库(三)利用QSqlQuery类执行SQL语句(一)

二十四、Qt数据库(四)利用QSqlQuery类执行SQL语句(二)

二十五、Qt数据库(五)QSqlQueryModel

二十六、Qt数据库(六)QSqlTableModel

二十七、Qt数据库(七)QSqlRelationalTableModel

二十八、Qt数据库(八)XML(一)

二十九、Qt数据库(九)XML(二)

三十、Qt数据库(十)XML(三)

三十一、Qt 4.7.0及Qt Creator 2.0 beta版安装全程图解

三十二、第一个Qt Quick程序(QML程序)

三十三、体验QML演示程序

关于QPS和TPS

TPS:Transactions Per Second(每秒传输的事物处理个数),即服务器每秒处理的事务数。TPS包括一条消息入和一条消息出,加上一次用户数据库访问。(业务TPS = CAPS × 每个呼叫平均TPS)

TPS是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。

一般的,评价系统性能均以每秒钟完成的技术交易的数量来衡量。系统整体处理能力取决于处理能力最低模块的TPS值。

QPS:每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系统服务器的机器的性能经常用每秒查询率来衡量。

对应fetches/sec,即每秒的响应请求数,也即是最大吞吐能力。

 

在DBA界,TPS和QPS是衡量数据库性能的2个重要参数。计算方法如下:

TPS(每秒事务处理量)  INNODB 引擎

(com_commit+com_rollback)/uptime

QPS(每秒查询处理量)MyISAM 引擎

Questions/uptime

什么是hash code,到处都是getHashCode()

一个对象的HashCode就是一个简单的Hash算法的实现,虽然它和那些真正的复杂的Hash算法相比还不能叫真正的算法,它如何实现它,不仅仅是程 序员的编程水平问题,而是关系到你的对象在存取是性能的非常重要的关系.有可能,不同的HashCode可能会使你的对象存取产生,成百上千倍的性能差 别。

  我们先来看一下,在JAVA中两个重要的数据结构:HashMap和Hashtable,虽然它们有很大的区别,如继承关系不同,对value的约束 条件(是否允许null)不同,以及线程安全性等有着特定的区别,但从实现原理上来说,它们是一致的.所以,我们只以Hashtable来说明:

  在java中,存取数据的性能,一般来说当然是首推数组,但是在数据量稍大的容器选择中,Hashtable将有比数组性能更高的查询速度.具体原因看下面的内容。

  Hashtable在存储数据时,一般先将作为key的对象的HashCode和0x7FFFFFFF做与操作,因为一个对象的HashCode可以 为负数,这样操作后可以保证它为一个正整数.然后以Hashtable的长度取模,得到值对象在Hashtable中的索引。

  index   =   (o.hashCode()   &   0x7FFFFFFF)%hs.length;这个值对象就会直接放在Hashtable的第index位置,对于写入,这和数组一样,把一个对象放在其 中的第index位置,但如果是查询,经过同样的算法,Hashtable可以直接通过key得到index,从第index取得这个值对象,而数组却要 做循环比较.所以对于数据量稍大时,Hashtable的查询比数据具有更高的性能。

  虽然不同对象有不同的hashcode,但不同的hashCode经过与长度的取余,就很可能产生相同的index。

  极端情况下会有大量的对象产生一个相同的索引.这就是关系Hashtable性能问题的最重要的问题:

  Hash冲突。

  常见的Hash冲突是不同key对象最终产生了相同的索引,而一种非常甚至绝对少见的Hash冲突是,如果一组对象的个数大过了int范围,而 HashCode的长度只能在int范围中,所以肯定要有同一组的元素有相同的HashCode,这样无论如何他们都会有相同的索引.当然这种极端的情况 是极少见的,可以暂不考虑,但是对于同的HashCode经过取模,则会产中相同的索引,或者不同的对象却具有相同的HashCode,当然具有相同的索 引。

  事实上一个设计各好的HashTable,一般来说会比较平均地分布每个元素,因为Hashtable的长度总是比实际元素的个数按一定比例进行自增 (装填因子一般为0.75)左右,这样大多数的索引位置只有一个对象,而很少的位置会有几个元素.所以Hashtable中的每个位置存放的是一个链表, 对于只有一个对象是位置,链表只有一个首节点(Entry),Entry的next为null.然后有hashCode,key,value属性保存了该 位置的对象的HashCode,key和value(对象本身),如果有相同索引的对象进来则会进入链表的下一个节点.如果同一个索引中有多个对象,根据 HashCode和key可以在该链表中找到一个和查询的key相匹配的对象。

  从上面我看可以看到,对于HashMap和Hashtable的存取性能有重大影响的首先是应该使该数据结构中的元素尽量大可能具有不同的 HashCode,虽然这并不能保证不同的HashCode产生不同的index,但相同的HashCode一定产生相同的index,从而影响产生 Hash冲突。

  对于一个象,如果具有很多属性,把所有属性都参与散列,显然是一种笨拙的设计.因为对象的HashCode()方法几乎无所不在地被自动调用,如 equals比较,如果太多的对象参与了散列.那么需要的操作常数时间将会增加很大.所以,挑选哪些属性参与散列绝对是一个编程水平的问题。

  从实现来说,一般的HashCode方法会这样:

  return   Attribute1.HashCode()   +   Attribute1.HashCode()..[+super.HashCode()]。

  我们知道,每次调用这个方法,都要重新对方法内的参与散列的对象重新计算一次它们的HashCode的运算,如果一个对象的属性没有改变,仍然要每次 都进行计算,所以如果设置一个标记来缓存当前的散列码,只要当参与散列的对象改变时才重新计算,否则调用缓存的hashCode,这可以从很大程度上提高 性能。

  默认的实现是将对象内部地址转化为整数作为HashCode,这当然能保证每个对象具有不同的HasCode,因为不同的对象内部地址肯定不同(废 话),但java语言并不能让程序员获取对象内部地址,所以,让每个对象产生不同的HashCode有着很多可研究的技术。

  如果从多个属性中采样出能具有平均分布的hashCode的属性,这是一个性能和多样性相矛盾的地方,如果所有属性都参与散列,当然hashCode 的多样性将大大提高,但牺牲了性能,而如果只能少量的属性采样散列,极端情况会产生大量的散列冲突,如对 “人 “的属性中,如果用性别而不是姓名或出生日期,那将只有两个或几个可选的hashcode值,将产生一半以上的散列冲突.所以如果可能的条件下,专门产生 一个序列用来生成HashCode将是一个好的选择(当然产生序列的性能要比所有属性参与散列的性能高的情况下才行,否则还不如直接用所有属性散列)。

  如何对HashCode的性能和多样性求得一个平衡,可以参考相关算法设计的书,其实并不一定要求非常的优秀,只要能尽最大可能减少散列值的聚集.重要的是我们应该记得HashCode对于我们的程序性能有着生要的影响,在程序设计时应该时时加以注意。

C动态数组

当写下这个题目的时候,笔者心里其实非常犯难。因为从本质上来说,本章想阐述的内容与题目所宣示的概念,其实是不一样的。在编程中,我们常常要处理一段长度未知的数据,而且,运行过程中长度可能会发生变化,现行的C/C++标准没有提供在栈段和数据段内存中的实现,只提供堆中的实现,例如可以象下面代码那样在堆中分配一段内存,以处理一组长度不确定的整数:

 

int *p = ( int* )malloc( n * sizeof( int ) );

 

现在我们常常将这段堆内存称为“动态数组”。这正确吗?数组是一个高层概念,是C/C++对象模型及类型系统的重要组成。一个对象欲成为一个数组,引用此对象的表达式或标识符必须具有高层的数组类型,但这段内存没有任何数组类型的引用,只有一个指向它的指针,因此,这段内存不是C/C++高层语义上的数组。虽然p可以使用下标运算符访问内存块中的数据,但其实只不过得益于下标运算符的指针性质(如第四章所述)而已。一个真正的动态数组,不仅长度在运行期内可变,还需要具备数组类型的抽象,这要求语言规则的支持,这些条件是p所不具备的。但是,真正的动态数组的实现也不容易,往往受到效率等多重因素的制约,即使实现了也可能需要付出很大的代价,得不偿失,正因如此,C/C++标准都没有提供对动态数组的支持。不过,这段堆内存被称为“动态数组”多年来已经习惯成自然了,笔者没有为其重新命名的技术能力和资历,也就只有随波逐流,暂且也称之为动态数组吧,重要的是明白两者本质的不同。

 

鉴于动态数组不是真正的受C/C++规则支持的动态数组,因此需要通过指针对数组内部各维地址进行构造,整个数组才能使用下标运算符。这就使动态数组的内部构造分成两部分,一部分叫数据存储区,用来保存真正的数组元素,另一部分叫中间地址缓冲区,保存数组内部各维的中间地址。

 

根据数据存储区的空间连续性,可以将动态数组分成两大类,一类是具有连续存储空间的动态数组,另一类是非连续存储空间的动态数组。笔者分别将它们称为连续动态数组和离散动态数组。

 

离散动态数组是最简单的动态数组,因为无须考虑数据在哪里存储,只需要动态分配就行了,同时中间地址不需要或只需要简单计算就可以得出。例如一个二维离散动态数组可以这样构造:

 

int **p = ( int** )malloc( m * sizeof( int* ) );

for( i = 0; i < m; ++i )

       p[i] = ( int* )malloc( n * sizeof( int ) );

 

上述代码中,p指向中间地址缓冲区,保存第一维各元素的首地址,p[i]指向数据存储区,这个存储区是不连续的。释放空间时需要这样进行:

 

for( i = 0; i < m; ++i )

       free( p[i] );

free( p );

 

离 散动态数组是先构造好中间地址缓冲区,再构造数据存储区,这是造成数据空间不连续的原因,虽然构造过程简单,但非连续性带来很多缺点。一是不利于数组内部 的直接寻址,例如通过数据区首地址计算元素地址;二是当需要对数组长度进行改变时,过程复杂;三是空间的释放需要对中间地址缓冲区重新遍历。但其实,完全 可以先构造数据存储区,再构造中间地址缓冲区,这种方法使连续数据存储空间有了可能,而且,连续动态数组不会带来离散动态数组那些缺点。下面是构造连续动 态数组的示例:

 

int *p = ( int* )malloc( m * n * sizeof( int ) );

int **q = ( int** )malloc( m * sizeof( int* ) );

for( i = 0; i < m; ++i )

       q[i] = p + i * n;

 

首先p分配m*n个int数据的存储区,再由q根据这段空间构造中间地址。现在,不仅可以通过q[m][n]使用这个数组,还可以直接通过p和下标运算符访问数组的元素。释放空间的时候直接释放p和q就行了,需要改变数组长度的话,只须重新分配p指向的空间,再重新构造一下中间地址缓冲区,例如将上述m*n个int元素的数组改为k*j个int元素,可以这样做:

 

int *p = ( int* )realloc( p, k * j * sizeof( int ) );

int **q = ( int** )realloc( q, k * sizeof( int* ) );

for( i = 0; i < k; ++i )

       q[i] = p + i * j;

 

而离散动态数组就必须先动态分配好k*j个int的新空间,然后把旧数据都复制过去,再释放旧空间,整个过程比连续空间麻烦得多。

 

连续动态数组不仅可以使用堆中的空间,还可以在栈段和数据段中构造,只要在栈或数据段的数组对象中重新构造中间地址即可,例如:

 

double a[100];

double **p = ( double** )malloc( 5 * sizeof( double* ) );

for( i = 0; i < 5; ++i )

       p[i] = a + i * 20;

 

这样就把一维double数组a的空间重新在逻辑上改造成了一个二维数组p[5][20],注意重新构造的动态数组的长度不能超出a的空间,否则结果是不确定的,是危险的。

 

上述例子在一个一维数组上构造了一个二维数组,维度发生了变化,这说明连续动态数组不仅可以方便地改变长度,还可以方便地改变维度。当目标维度可变时,中间地址的构造需要使用递归算法。笔者的博客中就提供了一个维度可变的数组ADT的例子。

 

要注意的是,动态数组的中间地址不具数组类型。例如上述动态数组q[m][n]的第一维q[m]类型依然是int*,而一个数组对象int a[m][n]的第一维a[m]的类型是数组类型int[n]。

 

综合来看,由于连续动态数组的优点比离散动态数组多得多,在编程实践中应优先使用连续动态数组。

C99可变长数组VLA详解

C90及C++的数组对象定义是静态联编的,在编译期就必须给定对象的完整信息。但在程序设计过程中,我们常常遇到需要根据上下文环境来定义数组的情况,在运行期才能确知数组的长度。对于这种情况,C90及C++没有什么很好的办法去解决(STL的方法除外),只能在堆中创建一个内存映像与需求数组一样的替代品,这种替代品不具有数组类型,这是一个遗憾。C99的可变长数组为这个问题提供了一个部分解决方案。

 

可变长数组(variable length array,简称VLA)中的可变长指的是编译期可变,数组定义时其长度可为整数类型的表达式,不再象C90/C++那样必须是整数常量表达式。在C99中可如下定义数组:

 

int n = 10, m = 20;

char a[n];

int b[m][n];

 

a的类型为char[n],等效指针类型是char*,b的类型为int[m][n],等效指针类型是int(*)[n]。int(*)[n]是一个指向VLA的指针,是由int[n]派生而来的指针类型。

 

由此,C99引入了一个新概念:可变改类型(variably modified type,简称VM)。一个含有源自VLA派生的完整声明器被称为可变改的。VM包含了VLA和指向VLA的指针,注意VM类型并没有创建新的类型种类,VLA和指向VLA的指针仍然属于数组类型和指针类型,是数组类型和指针类型的扩展。

 

一个VM实体的声明或定义,必须符合如下三个条件:

 

1。代表该对象的标识符属于普通标识符(ordinary identifier);

2。具有代码块作用域或函数原型作用域;

3。无链接性。

 

Ordinary identifier指的是除下列三种情况之外的标识符:

 

1。标签(label);

2。结构、联合和枚举标记(struct tag、uion tag、enum tag);

3。结构、联合成员标识符。

 

这意味着VM类型的实体不能作为结构、联合的成员。第二个条件限制了VM不能具有文件作用域,存储连续性只能为auto,这是因为编译器通常把全局对象存放于数据段,对象的完整信息必须在编译期内确定。

 

VLA不能具有静态存储周期,但指向VLA的指针可以。

 

两个VLA数组的相容性,除了满足要具有相容的元素类型外,决定两个数组大小的表达式的值也要相等,否则行为是未定义的。

 

下面举些实例来对数种VM类型的合法性进行说明:

 

#include <stdio.h>

 

int n = 10;

int a[n];        /*非法,VM类型不能具有文件作用域*/

int (*p)[n];      /*非法,VM类型不能具有文件作用域*/

struct test

{

       int k;

       int a[n];     /*非法,a不是普通标识符*/

       int (*p)[n];   /*非法,p不是普通标识符*/

};

 

int main( void )

{

       int m = 20;

       struct test1

       {

              int k;

              int a[n];         /*非法,a不是普通标识符*/

              int (*p)[n];       /*非法,a不是普通标识符*/

       };

       extern int a[n];       /*非法,VLA不能具有链接性*/

       static int b[n];        /*非法,VLA不能具有静态存储周期*/

       int c[n];             /*合法,自动VLA*/

       int d[m][n];          /*合法,自动VLA*/

       static int (*p1)[n] = d; /*合法,静态VM指针*/

       n = 20;

       static int (*p2)[n] = d; /*未定义行为*/

       return 0;

}

 

一个VLA对象的大小在其生存期内不可改变,即使决定其大小的表达式的值在对象定义之后发生了改变。有些人看见可变长几个字就联想到VLA数组在生存期内可自由改变大小,这是误解。VLA只是编译期可变,一旦定义就不能改变,不是运行期可变,运行期可变的数组叫动态数组,动态数组在理论上是可以实现的,但付出的代价可能太大,得不偿失。考虑如下代码:

 

#include <stdio.h>

 

int main( void )

{

       int n = 10, m = 20;

       char a[m][n];

       char (*p)[n] = a;

       printf( “%u %u”, sizeof( a ), sizeof( *p ) );

       n = 20;

       m = 30;

       printf( “/n” );

       printf( “%u %u”, sizeof( a ), sizeof( *p ) );

       return 0;

}

 

虽然n和m的值在随后的代码中被改变,但a和p所指向对象的大小不会发生变化。

 

上述代码使用了运算符sizeof,在C90/C++中,sizeof从操作数的类型去推演结果,不对操作数进行实际的计算,运算符的结果为整数常量。当sizeof的操作数是VLA时,情形就不同了。sizeof必须对VLA进行计算才能得出VLA的大小,运算结果为整数,不是整数常量。

 

VM除了可以作为自动对象外,还可以作为函数的形参。作为形参的VLA,与非VLA数组一样,会调整为与之等效的指针,例如:

 

void func( int a[m][n] ); 等效于void func( int (*a)[n] );

 

在函数原型声明中,VLA形参可以使用*标记,*用于[]中,表示此处声明的是一个VLA对象。如果函数原型声明中的VLA使用的是长度表达式,该表达式会被忽略,就像使用了*标记一样,下面几个函数原型声明是一样的:

 

void func( int a[m][n] );

void func( int a[*][n] );

void func( int a[ ][n] );

void func( int a[*][*] );

void func( int a[ ][*] );

void func( int (*a)[*] );

 

*标记只能用在函数原型声明中。再举个例:

 

#include<stdio.h>

 

void func( int, int, int a[*][*] );

 

int main(void)

{

       int m = 10, n = 20;

       int a[m][n];

       int b[m][m*n];

       func( m, n, a );     /*未定义行为*/

       func( m, n, b );    

    return 0;

}

 

void func( int m, int n, int a[m][m*n] )

{

       printf( “%u/n”, sizeof( *a ) );

}

 

除了*标记外,形参中的数组还可以使用类型限定词const、volatile、restrict和static关键字。由于形参中的VLA被自动调整为等效的指针,因此这些类型限定词实际上限定的是一个指针,例如:

 

void func( int, int, int a[const][*] );

 

等效于

 

void func( int, int, int ( *const a )[*] );

 

它指出a是一个const对象,不能在func内部直接通过a修改其代表的对象。例如:

 

void func( int, int, int a[const][*] );

……..

void func( int m, int n, int a[const m][n] )

{

       int b[m][n];

       a = b;        /*错误,不能通过a修改其代表的对象*/

}

 

       static表示传入的实参的值至少要跟其所修饰的长度表达式的值一样大。例如:

 

void func( int, int, int a[const static 20][*] );

……

int m = 20, n = 10;

int a[m][n];

int b[n][m];

func( m, n, a );

func( m, n, b );     /*错误,b的第一维长度小于static 20*/

 

       类型限定词和static关键字只能用于具有数组类型的函数形参的第一维中。这里的用词是数组类型,意味着它们不仅能用于VLA,也能用于一般数组形参。

 

       总的来说,VLA虽然定义时长度可变,但还不是动态数组,在运行期内不能再改变,受制于其它因素,它只是提供了一个部分解决方案。

jQuery取得iframe元素的方法

收集利用Jquery取得iframe中元素的几种方法 :

 

Js代码  
  1. $(document.getElementById(‘iframeId’).contentWindow.document.body).htm()  

 

 显示iframe中body元素的内容。

 

Js代码  
  1. $(“#testId”, document.frames(“iframename”).document).html();  

 根据iframename取得其中ID为”testId”元素

 

Js代码  
  1. $(window.frames[“iframeName”].document).find(“#testId”).html()  

 作用同上

 

 

收集网上的一些示例:

用jQuery在IFRAME里取得父窗口的某个元素的值

只好用DOM方法与jquery方法结合的方式实现了

1.在父窗口中操作 选中IFRAME中的所有单选钮
$(window.frames[“iframe1”].document).find(“input[@type=’radio’]”).attr(“checked”,”true”);

2.在IFRAME中操作 选中父窗口中的所有单选钮
$(window.parent.document).find(“input[@type=’radio’]”).attr(“checked”,”true”);

iframe框架的:<iframe src=”test.html” id=”iframe1″ width=”700″ height=”300″ frameborder=”0″ scrolling=”auto”></iframe>

IE7中测试通过

getID3()

getID3() is a PHP script that extracts useful information from MP3s & other multimedia file formats
 
 

http://www.getid3.org/