现在网上很多朋友在弄网页的视频聊天室
一、加载AnyChat for Web SDK库
首先还是得先加载AnyChat for Web SDK库
<script language="javascript" type="text/javascript" src=/blog_article/"/javascript/anychatsdk.js" charset="GB2312"></script> <script language="javascript" type="text/javascript" src=/blog_article/"/javascript/anychatevent.js" charset="GB2312"></script>
二、全局变量定义
定义全局变量
var mDefaultServerAddr = "demo.anychat.cn"; // 默认服务器地址 var mDefaultServerPort = 8906; // 默认服务器端口号 var mSelfUserId = -1; // 本地用户ID var mTargetUserId = -1; // 目标用户ID(请求了对方的音视频)
三、调用初始化函数
网页加载完成后判断有没有安装插件和插件是否是最新
// 页面加载完成 初始化 function LogicInit() { // 初始化 var NEED_ANYCHAT_APILEVEL = "0"; var errorcode = BRAC_InitSDK(NEED_ANYCHAT_APILEVEL); if (errorcode == GV_ERR_SUCCESS) // 初始化插件成功 document.getElementById("login_div").style.display = "block"; // 显示登录界面 else // 没有安装插件,或是插件版本太旧,显示插件下载界面 document.getElementById("prompt_div").style.display = "block"; // 显示提示层 }
四、调用登录函数
在这里服务器地址和端口都写死,输入用户名就可以登录
登录按钮点击事件:
// 登录系统 function LoginToHall() { BRAC_Connect(mDefaultServerAddr, mDefaultServerPort); // 连接服务器 BRAC_Login(document.getElementById("username").value, "", 0); // 登录系统,密码为空也可登录 }
调用登录函数后首先会触发连接服务器函数
// 客户端连接服务器,bSuccess表示是否连接成功,errorcode表示出错代码 function OnAnyChatConnect(bSuccess, errorcode) { if (errorcode == 0) { } // 连接服务器成功 else alert("连接服务器失败"); //连接失败作提示,此时系统不会触发登录系统函数 }
连接服务器成功后会触发登录系统回调函数
// 客户端登录系统,dwUserId表示自己的用户ID号,errorcode表示登录结果:0 成功,否则为出错代码,参考出错代码定义 function OnAnyChatLoginSystem(dwUserId, errorcode) { if (errorcode == 0) { // 登录成功,显示大厅界面,隐藏登录界面。失败的话什么也不做,维持原状 mSelfUserId = dwUserId; document.getElementById("login_div").style.display = "none"; //隐藏登录界面 document.getElementById("hall_div").style.display = "block"; //显示大厅界面 } }
五、调用进入房间函数
登录成功后显示大厅,大厅里就个输入框和一个 进入房间 按钮
点击 进入房间 按钮 调用函数
// 进入房间 function EnterRoom(){ // 进入自定义房间 BRAC_EnterRoom(parseInt(document.getElementById("customroomid").value), "", 0); //进入房间 }
进入房间触发回调函数
// 客户端进入房间,dwRoomId表示所进入房间的ID号,errorcode表示是否进入房间:0成功进入,否则为出错代码 function OnAnyChatEnterRoom(dwRoomId, errorcode) { if (errorcode == 0) { // 进入房间成功,显示房间界面,隐藏大厅界面;进入房间失败时不作任何动作 document.getElementById("hall_div").style.display = "none"; //隐藏大厅界面 document.getElementById("room_div").style.display = "block"; //显示房间界面 BRAC_UserCameraControl(mSelfUserId, 1); // 打开本地视频 BRAC_UserSpeakControl(mSelfUserId, 1); // 打开本地语音 // 设置本地视频显示位置 BRAC_SetVideoPos(mSelfUserId, document.getElementById("AnyChatLocalVideoDiv"), "ANYCHAT_VIDEO_LOCAL"); // 设置远程视频显示位置(没有关联到用户,只是占位置) BRAC_SetVideoPos(0, document.getElementById("AnyChatRemoteVideoDiv"), "ANYCHAT_VIDEO_REMOTE"); } }
进入房间时,会触发在线用户回调函数
// 收到当前房间的在线用户信息,进入房间后触发一次,dwUserCount表示在线用户数(包含自己),dwRoomId表示房间ID function OnAnyChatRoomOnlineUser(dwUserCount, dwRoomId) { // 判断是否需要关闭之前已请求的用户音视频数据 if (mTargetUserId != -1) { // mTargetUserId 表示 上次视频会话的用户ID 为自定义变量 BRAC_UserCameraControl(mTargetUserId, 0); // 关闭远程视频 BRAC_UserSpeakControl(mTargetUserId, 0); // 关闭远程语音 mTargetUserId = -1; } if (dwUserCount > 1) // 在该函数中判断是否有在线用户,有的话就打开其中一个远程视频 SetTheVideo(); }
有用户退出房间时判断是否远程用户,并作出相应操作
// 用户进入(离开)房间,dwUserId表示用户ID号,bEnterRoom表示该用户是进入(1)或离开(0)房间 function OnAnyChatUserAtRoom(dwUserId, bEnterRoom) {  
浮动元素不占任何正常文档流空间,而浮动元素的定位还是基于正常的文档流,然后从文档流中抽出并尽可能远的移动至左侧或者右侧。文字内容会围绕在浮动元素周围。当一个元素从正常文档流中抽出后,仍然在文档流中的其他元素将忽略该元素并填补他原先的空间。
不过既然浮动元素不占任何正常文档流空间,为什么文字不在DIV下,而是环绕DIV?
这就是浮动的特性。普通的块级元素处在浮动元素下层,但它内部的文字(以及行内元素)会环绕浮动元素。
浮动的概念源自图片的左/右对齐,而图片左/右对齐的目的就是实现文字环绕图片。
所以说,这就是浮动的特性。
left : 文档流向对象的右边
right : 文档流向对象的左边
position
absolute : 将对象从文档流中拖出,使用 left , right , top , bottom 等属性相对于其最接近的一个最有定位设置的父对象进行绝对定位。如果不存在这样的父对象,则依据 body 对象。而其层叠通过 z-index 属性定义
以上引用CSS2.0手册。
关于文档流这个概念,其实一直没有一个很明确的定义,比较一致的看法就是指文档自上而下的书写顺序。
对于拖出文档流的元素有很多不同的解释,我的观点就是这类元素不会对其周围元素位置产生影响。
http://jmedia.cn/
在一个完美的世界,我们不需要知道hasLayout属性是什么东西。它是Windows Internet Explorer渲染引擎的一个内部组成部分。但是它的作用不可小觑,他对元素的外观和行为有很大影响,主要针对元素内容的约束和与邻接元素的相互作用。
这篇文章完全针对Windows的Internet Explorer。
hasLayout属性是什么?
在Internet Explorer中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容。
为了调节这两个不同的概念,渲染引擎采用了所谓的hasLayout的属性,属性值可以为true或false。当一个元素的hasLayout属性值为true时,我们说这个元素有一个布局(layout)。
当一个元素有一个布局时,它负责对自己和可能的子孙元素进行尺寸计算和定位。简单来说,这意味着这个元素需要花更多的代价来维护自身和里面的内容,而不是依赖于祖先元素来完成这些工作。因此,一些元素默认会有一个布局,尽管大多数都没有。
负责组织自身内容的元素将默认有一个布局,主要包括以下元素(不完全列表):
- body and html (in standards mode)
- table, tr, th, td
- img
- hr
- input, button, file, select, textarea, fieldset
- marquee
- frameset, frame, iframe
- objects, applets, embed
对于并非所有的元素都默认有布局,微软给出的主要原因是“性能和简洁”。如果所有的元素都默认有布局,会对性能和内存使用上产生有害的影响。
那么,我们为什么要关心这个hasLayout属性呢?原因是,许多Internet Explorer的显示不一致问题,都可以归因于这个属性。
在大多数情况下,有与元素缺少布局而导致的问题很容易发现:内容往往错位了或者完全不见了。例如,当一个元素(如div,它默认情况下是没有布局的)内含浮动或绝对定位的内容时,它通常会表现出奇怪和错误的行为。这类可能产生的奇怪行为是多种多样的,包括内容缺失或者错位,或者当浏览器窗口移动或者滚动时元素重绘失败。3
如果你发现一块内容有的显示有点不显示,部分网页只显示了部分内容,这些迹象都表明很可能某个元素需要一个布局。当关键元素有了布局以后,这个问题就会奇迹般地消失了。事实上,在日常开发中所遇到的99%的Internet Explorer CSS的bug都可以用设置hasLayout的方法来修正。修正hasLayout具体无非声明一个CSS属性来使这个因素获得布局,如果这个元素默认没有布局的话。
为一个元素设置布局最简单的方法是,设置一个CSS尺寸属性(例如,宽度width或高度height)。然而,有些情况下你可能不希望对元素设置具体的宽度或高度,还有其他一些的CSS属性也可以达到相同的效果。
这些其他属性是:
- display: inline-block
- height: (任何值除了auto)
- float: (left 或 right)
- position: absolute
- width: (任何值除了auto)
- writing-mode: tb-rl
- zoom: (任何值除了normal)4
Internet Explorer 7还有一些额外的属性(不完全列表) :
- min-height: (任何值)
- max-height: (任何值除了none)
- min-width: (任何值)
- max-width: (任何值除了none)
- overflow: (任何值除了visible)
- overflow-x: (任何值除了visible)
- overflow-y: (任何值除了visible)5
- position: fixed
声明任何这些CSS属性都会让元素得到布局,当然前提是这个属性对这个元素是有效的。例如,我们不能对内嵌(inline)元素设置高度,除非文档运行于quirks mode。
让所有的元素都有布局并不明智——不仅是因为前面提到的对性能和内存的问题,还因为许多其他不必要的CSS副作用会发生。例如:
- 绝对定位或者浮动元素的子孙元素有布局时,就不会收缩环绕其中的内容。
- 浮动元素旁的静态定位内容不会环绕浮动元素,而是形成一个矩形块并列在浮动元素旁。 更多的例子可以在MSDN网站上找到。
做管理系统的时候,打印一直是个棘手的问题,做B/S的系统这个问题就更加突出了!下面举出几种常用的web打印处理方式
1、利用word或者excel来实现web打印(如果不修改ie设置,可以在web服务器端生成xls文件,然后通过xlBook = xls.Workbooks.Open(remotePath) 获取对象打印)
实现过程:先将需要打印的数据导入到word或者excel中,再利用word或者excel的打印功能来实现web打印。
下面以excel为例实现如何打印的过程
将网页中数据导入excel中的方法有很多,这里先介绍一种,利用ActiveX控件的方式,即 Excel.Application, 这个控件是MS为excel提供的编程接口,在很多种编程语言种都可以通过该接口来操纵excel表格。
下面用javascript脚本来实现一个简单的例子。
function ExcelPrint(){
var excelApp;//存放Excel对象
var excelBook;//存放Excel工件簿文件
var excelSheet;//存放Excel活动工作表
try{
excelApp = new ActiveXObject("Excel. Application");//创建Excel对象}
catch(e){
alert("请启用ActiveX控件设置!");
return;}
excelBook = excelApp.Workbooks.Add();//创建Excel工作簿文件
excelSheet = excelBook.ActiveSheet;//激活Excel工作表
var rowLen = printTable.rows.length;//table对象的行数
for (var i=0;i< rowLen;i++){
var colLen = printTable.rows(i).cells.length;//table对象的列数
for (var j=0;j< colLen;j++)//为Excel表的单元格赋值
excelSheet.Cells(i+1,j+1).value = printTable.rows(i).cells(j).innerText;} //将表格中的每个单元格的innerText导入到excel的单元格中
excelApp.Visible = true;//设置Excel对象可见}
excelSheet.PrintOut(); //打印工作表
excelBook.Close(true); //关闭文档
excelApp.Quit(); //结束excel对象
excelApp=null; //释放excel对象
< /script>
注意:
运行该程序的前提是 IE要允许对没有标记为安全的Activex控件进行初始化和脚本运行。设置方法如下:
打开控制面板→Internet选项→安全性→自定义级别→对没有标记为安全的ActiveX控件进行初始化和脚本运行→选中启用,这样我们的程序就可以运行了。如果没有启用该ActiveX控件设置,那么程序在执行创建Excel对象时会抛出一个异常,这时可以通过catch()语句来捕获这个异常,并且做出相应的处理。
运行该程序必须客户端安装了MS EXCEL,否则Activex驱动不了。
2、利用浏览器自带的打印控件来实现web打印
实现过程:直接调用IE的打印功能或者在程序中调用window.print()来实现web打印,页眉和页脚会有网页标题、页码、网址,日期等信息,这些打印时如果不需要,怎样能去掉呢。做法其实很简单,只有在IE的文件菜单中打开页码设置对话框,去掉页眉页脚中设置的哪些信息,就可以了。但是这需要每个客户端都去手动设置一次。如果不想让每个客户端都手动去设置一次,也可以用代码通过修改注册表的键值来实现。
下面是用VBScript来实现的修改注册表的过程:
dim path, reg
'path存放IE打印设置的注册表地址, reg存放WScript.Shell组件的对象
path = "HKEY_CURRENT_USER\Software\Micro-soft\Internet Explorer\PageSetup"
'通过注册表修改打印设置,只修改页眉、页脚和各边界的值
'参数说明:header--页眉,footer--页脚,margin_left--左边界
'margin_top--上边界,margin_right--右边界,margin_bottom--下边界
'页边距的设置中 1对应25.4mm,即margin_left=1表示实际值的25.4mm
function pagesetup(header, footer, margin_left, margin_top, margin_right, margin_bottom)
On Error Resume Next
Set reg = CreateObject("WScript.Shell")
if err.Number>0 then
MsgBox "不能创建WScript.Shell对象!"
exit function
end if
reg.RegWrite path+"\header", header'设置页眉
reg.RegWrite path+"\footer", footer '设置页脚
reg.RegWrite path+"\margin_left", margin_left'设置左边界
reg.RegWrite path+"\margin_top", margin_top'设置上边界
reg.RegWrite path+"\margin_right", margin_right'设置右边界
reg.RegWrite path+"\margin_bottom", margin_bottom'设置下边界
end function
< /script>
还有一点需要注意的是,利用window.print()这样的方法来打印,是直接弹出打印对话框,而不是打印预览的窗口。一般来说用户希望先打印预览一下,然后再打印。或者有的格式固定的,每次都是一样的格式,就希望不弹出打印对话框,直接就打印出来。
还有的用户希望每个打印都是直接和一种纸张绑定好,打印时候直接就调用那种类型的纸张来打印,这样window.print()显然远远不够。
3、利用第三方的控件或者报表软件来实现web打印
实现过程:第三方控件将打印的参数和方法封装成对象,在页面中可以方便的直接调用,例如ScriptX.cab,eprint.cab 都是这种类型的控件。可以直接用代码实现web打印页眉页脚的设置,web打印纸张的绑定,web打印边距的设置,web打印预览,直接web打印。
web打印格式设置,web打印分页,web打印换页重新打印某些信息,某些信息只能第一页打印,某些信息只能最后一页打印等等这些,也都解决方案。Scriptx没有处理这些的方案,webprint有webgrid和eprint两种解决方案,行列规则的表格式的可以简单webgrid来处理,复杂格式的可以用eprint来设计格式。
一般这种类型的打印控件都是需要收费的,用户可以从经济的角度来考虑。
一、 浏览器的打印功能菜单
这种方案的优势是不需要对浏览器作任何扩充,是最简单的办法,但问题也最多,如:
浏览器一般是根据用户设置的页面大小,web页面的内容多少,来自行决定分页位置,程序员很难控制。会有页脚页眉干扰。
比如,不是仅打印一张票据,而是连续一次打印若干个票据。