调用方法:
- var time1 = new Date().Format("yyyy-MM-dd HH:mm:ss");
-
- var time2 = new Date().Format("yyyy-MM-dd");
方法二:
- <mce:script language="javascript" type="text/javascript"><!--
-
- /**
- * 对Date的扩展,将 Date 转化为指定格式的String
- * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q) 可以用 1-2 个占位符
- * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
- * eg:
- * (new Date()).pattern("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
- * (new Date()).pattern("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04
- * (new Date()).pattern("yyyy-MM-dd EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04
- * (new Date()).pattern("yyyy-MM-dd EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04
- * (new Date()).pattern("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
- */
- Date.prototype.pattern=function(fmt) {
- var o = {
- "M+" : this.getMonth()+1, //月份
- "d+" : this.getDate(), //日
- "h+" : this.getHours()%12 == 0 ? 12 : this.getHours()%12, //小时
- "H+" : this.getHours(), //小时
- "m+" : this.getMinutes(), //分
- "s+" : this.getSeconds(), //秒
- "q+" : Math.floor((this.getMonth()+3)/3), //季度
- "S" : this.getMilliseconds() //毫秒
- };
- var week = {
- "0" : "/u65e5",
- "1" : "/u4e00",
- "2" : "/u4e8c",
- "3" : "/u4e09",
- "4" : "/u56db",
- "5" : "/u4e94",
- "6" : "/u516d"
- };
- if(/(y+)/.test(fmt)){
- fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
- }
- if(/(E+)/.test(fmt)){
- fmt=fmt.replace(RegExp.$1, ((RegExp.$1.length>1) ? (RegExp.$1.length>2 ? "/u661f/u671f" : "/u5468") : "")+week[this.getDay()+""]);
- }
- for(var k in o){
- if(new RegExp("("+ k +")").test(fmt)){
- fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
- }
- }
- return fmt;
- }
-
- var date = new Date();
- window.alert(date.pattern("yyyy-MM-dd hh:mm:ss"));
- // --></mce:script>
方法三:
- Date.prototype.format = function(mask) {
-
- var d = this;
-
- var zeroize = function (value, length) {
-
- if (!length) length = 2;
-
- value = String(value);
-
- for (var i = 0, zeros = ''; i < (length - value.length); i++) {
-
- zeros += '0';
-
- }
-
- return zeros + value;
-
- };
-
- return mask.replace(/"[^"]*"|'[^']*'|/b(?:d{1,4}|m{1,4}|yy(?:yy)?|([hHMstT])/1?|[lLZ])/b/g, function($0) {
-
- switch($0) {
-
- case 'd': return d.getDate();
-
- case 'dd': return zeroize(d.getDate());
-
- case 'ddd': return ['Sun','Mon','Tue','Wed','Thr','Fri','Sat'][d.getDay()];
-
- case 'dddd': return ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'][d.getDay()];
-
- case 'M': return d.getMonth() + 1;
-
- case 'MM': return zeroize(d.getMonth() + 1);
-
- case 'MMM': return ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'][d.getMonth()];
-
- case 'MMMM': return ['January','February','March','April','May','June','July','August','September','October','November','December'][d.getMonth()];
-
- case 'yy': return String(d.getFullYear()).substr(2);
-
- case 'yyyy': return d.getFullYear();
-
- case 'h': return d.getHours() % 12 || 12;
-
- case 'hh': return zeroize(d.getHours() % 12 || 12);
-
- case 'H': return d.getHours();
-
- case 'HH': return zeroize(d.getHours());
-
- case 'm': return d.getMinutes();
-
- case 'mm': return zeroize(d.getMinutes());
-
- case 's': return d.getSeconds();
-
- case 'ss': return zeroize(d.getSeconds());
-
- case 'l': return zeroize(d.getMilliseconds(), 3);
-
- case 'L': var m = d.getMilliseconds();
-
- if (m > 99) m = Math.round(m / 10);
-
- return zeroize(m);
-
- case 'tt': return d.getHours() < 12 ? 'am' : 'pm';
-
- case 'TT': return d.getHours() < 12 ? 'AM' : 'PM';
-
- case 'Z': return d.toUTCString().match(/[A-Z]+$/);
-
- // Return quoted strings with the surrounding quotes removed
-
- default: return $0.substr(1, $0.length - 2);
-
- }
-
- });
-
- };
今天关于JavaScript中的“if debug”?和JAVAscript中的数据类型的讲解已经结束,谢谢您的阅读,如果想了解更多关于Firebug Tutorial (Section 3): Script Tab :Javascript Debugging、javascript debug tool --- jsdt (eclipse plug)、JavaScript Debug 之 Console、JavaScript javaScript中的Date 以及对原生javaScript的扩展的相关知识,请在本站搜索。
想了解javascript – 如何改进这个WebGL / GLSL图像下采样着色器的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于图像采样器最小着色速率的相关问题,此外,我们还将为您介绍关于8 个惊艳的 Javascript WebGL 示例、iOS GLSL.有没有办法使用GLSL着色器创建图像直方图?、JavaScript Canvas——“WebGL”的注意要点、JavaScript WebGL 三维相关概念的新知识。
本文目录一览:
javascript – 如何改进这个WebGL / GLSL图像下采样着色器(图像采样器最小着色速率)
我正在使用WebGL在我正在开发的应用程序中快速调整客户端图像的大小.我写了一个GLSL着色器,对我正在缩编的图像执行简单的双线性过滤.
它大部分工作正常,但有很多场合,调整大小是巨大的.从2048×2048图像下降到110×110,以生成缩略图.在这些情况下,质量差,太模糊.
我目前的GLSL着色器如下:
uniform float textureSizeWidth;\
uniform float textureSizeHeight;\
uniform float texelSizeX;\
uniform float texelSizeY;\
varying mediump vec2 texCoord;\
uniform sampler2D texture;\
\
vec4 tex2DBiLinear( sampler2D textureSampler_i,vec2 texCoord_i )\
{\
vec4 p0q0 = texture2D(textureSampler_i,texCoord_i);\
vec4 p1q0 = texture2D(textureSampler_i,texCoord_i + vec2(texelSizeX,0));\
\
vec4 p0q1 = texture2D(textureSampler_i,texCoord_i + vec2(0,texelSizeY));\
vec4 p1q1 = texture2D(textureSampler_i,texelSizeY));\
\
float a = fract( texCoord_i.x * textureSizeWidth );\
\
vec4 pInterp_q0 = mix( p0q0,p1q0,a );\
vec4 pInterp_q1 = mix( p0q1,p1q1,a );\
\
float b = fract( texCoord_i.y * textureSizeHeight );\
return mix( pInterp_q0,pInterp_q1,b );\
}\
void main() { \
\
gl_FragColor = tex2DBiLinear(texture,texCoord);\
}');
TexelsizeX和TexelsizeY简单地(1.0 /纹理宽度)和高度分别…
我想实施一个更高质量的过滤技术,理想的是一个[Lancosz] [1]过滤器,它应该产生更好的结果,但是我似乎不知道如何使用GLSL来实现算法,因为我对WebGL非常新,一般GLSL.
有人可以指出我正确的方向吗?
提前致谢.
解决方法
如果您正在寻找lanczos重采样,以下是我在开源GPUImage库中使用的着色器程序:
顶点着色器:
attribute vec4 position;
attribute vec2 inputTextureCoordinate;
uniform float texelWidthOffset;
uniform float texelHeightOffset;
varying vec2 centerTextureCoordinate;
varying vec2 onestepLeftTextureCoordinate;
varying vec2 twoStepsLeftTextureCoordinate;
varying vec2 threeStepsLeftTextureCoordinate;
varying vec2 fourStepsLeftTextureCoordinate;
varying vec2 onestepRightTextureCoordinate;
varying vec2 twoStepsRightTextureCoordinate;
varying vec2 threeStepsRightTextureCoordinate;
varying vec2 fourStepsRightTextureCoordinate;
void main()
{
gl_Position = position;
vec2 firstOffset = vec2(texelWidthOffset,texelHeightOffset);
vec2 secondOffset = vec2(2.0 * texelWidthOffset,2.0 * texelHeightOffset);
vec2 thirdOffset = vec2(3.0 * texelWidthOffset,3.0 * texelHeightOffset);
vec2 fourthOffset = vec2(4.0 * texelWidthOffset,4.0 * texelHeightOffset);
centerTextureCoordinate = inputTextureCoordinate;
onestepLeftTextureCoordinate = inputTextureCoordinate - firstOffset;
twoStepsLeftTextureCoordinate = inputTextureCoordinate - secondOffset;
threeStepsLeftTextureCoordinate = inputTextureCoordinate - thirdOffset;
fourStepsLeftTextureCoordinate = inputTextureCoordinate - fourthOffset;
onestepRightTextureCoordinate = inputTextureCoordinate + firstOffset;
twoStepsRightTextureCoordinate = inputTextureCoordinate + secondOffset;
threeStepsRightTextureCoordinate = inputTextureCoordinate + thirdOffset;
fourStepsRightTextureCoordinate = inputTextureCoordinate + fourthOffset;
}
片段着色器:
precision highp float;
uniform sampler2D inputimageTexture;
varying vec2 centerTextureCoordinate;
varying vec2 onestepLeftTextureCoordinate;
varying vec2 twoStepsLeftTextureCoordinate;
varying vec2 threeStepsLeftTextureCoordinate;
varying vec2 fourStepsLeftTextureCoordinate;
varying vec2 onestepRightTextureCoordinate;
varying vec2 twoStepsRightTextureCoordinate;
varying vec2 threeStepsRightTextureCoordinate;
varying vec2 fourStepsRightTextureCoordinate;
// sinc(x) * sinc(x/a) = (a * sin(pi * x) * sin(pi * x / a)) / (pi^2 * x^2)
// Assuming a lanczos constant of 2.0,and scaling values to max out at x = +/- 1.5
void main()
{
lowp vec4 fragmentColor = texture2D(inputimageTexture,centerTextureCoordinate) * 0.38026;
fragmentColor += texture2D(inputimageTexture,onestepLeftTextureCoordinate) * 0.27667;
fragmentColor += texture2D(inputimageTexture,onestepRightTextureCoordinate) * 0.27667;
fragmentColor += texture2D(inputimageTexture,twoStepsLeftTextureCoordinate) * 0.08074;
fragmentColor += texture2D(inputimageTexture,twoStepsRightTextureCoordinate) * 0.08074;
fragmentColor += texture2D(inputimageTexture,threeStepsLeftTextureCoordinate) * -0.02612;
fragmentColor += texture2D(inputimageTexture,threeStepsRightTextureCoordinate) * -0.02612;
fragmentColor += texture2D(inputimageTexture,fourStepsLeftTextureCoordinate) * -0.02143;
fragmentColor += texture2D(inputimageTexture,fourStepsRightTextureCoordinate) * -0.02143;
gl_FragColor = fragmentColor;
}
这应用于两次通过,首先执行水平下采样,第二次执行垂直下采样. texelWidthOffset和texelHeightOffset均匀性交替设置为0.0,并且图像中单个像素的宽度分数或高度分数.
我很难计算顶点着色器中的纹理像素偏移量,因为这样可以避免在我针对的移动设备上依赖于纹理读取,从而在那里实现更好的性能.这是一个有点冗长的.
兰培斯重采样的结果:
正常双线性下采样:
最邻近的下采样:

8 个惊艳的 Javascript WebGL 示例
WebGL 是一种 3D 绘图标准,这种绘图技术标准允许把 javascript 和 OpenGL ES 2.0 结合在一起,通过增加 OpenGL ES 2.0 的一个 javascript 绑定,WebGL 可以为 HTML5 Canvas 提供硬件 3D 加速渲染,这样 Web 开发人员就可以借助系统显卡来在浏览器里更流畅地展示 3D 场景和模型了,还能创建复杂的导航和数据视觉化。
显然,WebGL 技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂 3D 结构的网站页面,甚至可以用来设计 3D 网页游戏等等。最酷的事? WebGL 的脚本是用 javascript。糟糕的事情吗?它不能在所有平台。
请务必查看这些实验通过 Chrome9+,火狐和 Safari4 ++ OSX 的 10.6。对不起,没有 IE。
TankWorld

坦克世界是一个坦克射击游戏,你可以使用各种武器打击你的对手。在某些级别,你可以找到一个直升机探索世界…
Clouds

用 javascript 实现的真实云
HelloRacer™ WebGL

高档仿真汽车互动
WebGL Aquarium

将自己沉浸在一个充满了鱼,鲨鱼和珊瑚的水族馆中。此功能演示了 3D 高品质的纹理,场景动画,像素阴影动画,反射,折射和焦散模型。
Fractal Lab

一个 WebGL 的应用程序交互探索和渲染 3D 分形。
Chrysaora

本实验从先前提交的水母实验演变过来。
Visual Random

随机多种级别:体素下降,体素颜色,堆块随机跌落。所有的联合创建一个随机有趣的东西。
Sintel Goes Boom

视频播放的后期处理的一些纹理。
原文地址:http://www.woiweb.net/8-stunning-javascript-webgl-demo.html

iOS GLSL.有没有办法使用GLSL着色器创建图像直方图?
在StackOverflow的其他地方,有人问到有关depthbuffer直方图的问题 –
Create depth buffer histogram texture with GLSL.
我正在编写一个iOS图像处理应用程序,对这个问题感兴趣,但是提供的答案不清楚.那么,是否可以通过GLSL使用GPU创建图像直方图?
解决方法
是的.这不是最好的方法,但它确实是iOS中最好的一种,因为不支持OpenCL.你会失去优雅,你的代码可能不是那么简单,但几乎所有的OpenCL功能都可以通过着色器来实现.
如果有帮助,DirectX11附带了FFT示例,用于计算着色器.请参阅DX11 August SDK发行说明.

JavaScript Canvas——“WebGL”的注意要点
OpenGl:www.opengl.org
WebGL:www.learningwebgl.com
WebGL是针对Canvas的3D上下文;OpenGL等是3D图形语言;
类型化数组
类型化数组也是数组,只不过其元素被设置为特定类型的值。
数组缓冲器ArrayBuffer
类型和byteLength
属性
类型化数组的核心就是一个名为
如:
var buffer = new ArrayBuffer(20); //在内存中分配20B
属性
如:
var buffer = new ArrayBuffer(20);
console.log(buffer.byteLength); //20
数组缓冲器视图
DataView
数组缓冲器视图
使用ArrayBuffer(数组缓冲器类型)的一种特别的方式就是用它来创建数组缓冲器视图。其中,最常见的视图是
如:
var view = new DataView(buffer); //新的视图
var view = new DataView(buffer, 6); //开始于字节6的新视图
var view = new DataView(buffer, 6, 9); //开始于字节6,结束于字节9的新视图
DataView
的属性byteOffset
和byteLength
DataView对象会把字节偏移量以及字符长度信息保存在
两个属性中:
var view = new DataView(buffer, 6, 9); //开始于字节6,结束于字节9的新视图
console.log(view.byteOffset); //6 字节偏移量为6
console.log(view.byteLength); //9 字节长度为9
buffer属性也可以取得数组缓冲器;
getter
和setter
读写方法
读取和写入DataView的时候,要根据实际操作的数据类型,选择相应的
如下,列出了DataView支持的数据类型以及相应的读写方法:
getter:
getInt8(byteOffset)
方法: 在相对于视图开始处的指定字节偏移量位置处获取 Int8 值。
getUint8(byteOffset)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处获取 Uint8 值。
getInt16(byteOffset,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处获取 Int16 值。
getUint16(byteOffset,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处获取 Uint16 值。
getInt32(byteOffset,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处获取 Int32 值。
getUint32(byteOffset,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处获取 Uint32 值。
getFloat32(byteOffset,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处获取 Float32 值。
getFloat64(byteOffset,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处获取 Float64 值。
setter:
setInt8(byteOffset,value)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处存储 Int8 值。
setUint8(byteOffset,value)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处存储 Uint8 值。
setInt16(byteOffset,value,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处存储 Int16 值。
setUint16(byteOffset,value,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处存储 Uint16 值。
setInt32(byteOffset,value,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处存储 Int32 值。
setUint32(byteOffset,value,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处存储 Uint32 值。
setFloat32(byteOffset,value,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处存储 Float32 值。
setFloat64(byteOffset,value,littleEndian)
方法 (DataView): 在相对于视图开始处的指定字节偏移量位置处存储 Float64 值。
如:
var buffer = new ArrayBuffer(20);
var view = new DataView(buffer);
view.setUint16(0,25); //0000000000001001
var value = view.getUint8(0); //00000000
console.log(value); //0
类型化视图在读写数组缓冲器中更加便利:
类型化视图(类型化数组)
类型化视图一般也被称为类型化数组,因为它们除了元素必须是某种特定的数据类型外,与常规的数组无异。类型化视图也分几种,而且它们都继承了DataView。
需要三个参数,只有第一个是必须的:ArrayBuffer对象、字节偏移量、要包含的字节数,如:
var buffer = new ArrayBuffer(20);
var int8s = new Int8Array(buffer);
注意:20B的ArrayBuffer可以保存20个Int8Array或Uint8Array,或者10个Int16Array或Uint16Array,或者5个Int32Array或Uint32Array或Float32Array,或者2个Float64Array。
var buffer = new ArrayBuffer(20);
var int8s = new Int8Array(buffer); //创建一个新数组,使用整个缓冲器
var int16s = new Int16Array(buffer, 9); //只使用从字节9开始的缓冲器
var uint16s = new Uint16Array(buffer, 9, 10); //只使用从字节9到字节10的缓冲器
能够指定缓冲器中可用的字节段,意味着能在同一个缓冲器中保存不同类型的数值,如下面的代码就是在缓冲器的开头保存8位整数,而在其他字节中保存16位整数:
var buffer = new ArrayBuffer(30); //缓冲器中有30个字节
var int8s = new Int8Array(buffer, 0, 10); //前面10个字节存储10个8位整数
var int16s = new Int16Array(buffer, 10, 10); //后面还有20个字节,2个字节存储1个16位整数,所以只能存储10个
另外,每个视图构造函数都有一个名为
表示类型化数组的每个元素需要多少字节:
console.log(Float64Array.BYTES_PER_ELEMENT) //8
这样就可以利用这个属性来辅助初始化:
var buffer = new ArrayBuffer(20);
var int8s = new Int8Array(buffer, 0, 10 * Int8Array.BYTES_PER_ELEMENT);
var int16s = new Int16Array(buffer, int8s.byteOffset + int8s.byteLength, (10 / Int16Array.BYTES_PER_ELEMENT));
另外,还可以不用首先创建ArrayBuffer对象,只要传入希望数组保存的元素数,相应的构造函数就可以自动创建一个包含足够字节数的ArrayBuffer对象:
var int16s = new Int16Array(10); //创建一个数组保存10个16位整数(10字节)
var int32s = new Int32Array(1); //创建一个数组保存1个32位整数(4字节)
另外还可以把常规数组转换为类型化视图:
var int8s = new Int8Array([1,2,3,4]);
var view = new DataView(int8s.buffer);
console.log(int8s.toString()); //1234
console.log(view.byteLength); //4
对类型化视图的迭代:
for (var i = 0; i < int8s.length; i++) {
console.log(int8s[i]);
};
也可以使用方括号语法为类型化视图的元素赋值:
var uint16s = new Uint16Array(10);
uint16s[0] = 65537;
console.log(uint16s[0]); //1
另外可以通过
如:
var uint16s = new Uint16Array(10),
sub = uint16s.subarray(2, 5);
WebGL上下文
目前,在支持的浏览器中,WebGL的名字叫做“experimental-webgl”,这是因为WebGL规范仍然未制定完成。制定完成后,这个上下文的名字就会变成简单的“webgl”。如果浏览器不支持WebGL,那么取得该上下文时会返回null。
var drawing = document.getElementById("drawing");
if (drawing.getContext) {
var gl = drawing.getContext("experimental-webgl");
if (gl) {
//[...]
}
}
通过给getContext()传递第二个参数,可以为WebGL上下文设置一些选项。这个参数本身是一个对象,可以包含下列属性:
* `alpha`:值为true,表示为上下文创建一个Alpha通道缓冲区;默认值为true;
* `depth`:值为true,表示可以使用16位深缓冲区;默认值为true;
* `stencil`:值为true,表示可以使用8位模板缓冲区;默认值为false;
* `antialias`:值为true,表示将使用默认机制执行抗锯齿操作;默认值为true。
* `premultipliedAlpha`:值为true,表示绘图缓冲区有预乘Alpha值;默认为true;
* `preserveDrawingBuffer`:值为true;表示在绘图完成后保留绘图缓冲区;默认值为false。
传递这个选项对象的方式如下:
var drawing = document.getElementById("drawing");
if (drawing.getContext) {
var gl = drawing.getContext("experimental-webgl", {
alpha: false
});
if (gl) {
//[...]
}
}
大多数情况下不用开启,因为可能影响到性能,而且默认值一般都能满足我们需求。
如果getContext()无法创建WebGL上下文,浏览器可能会报错。所以应该把它封装到try-catch块中:
var drawing = document.getElementById("drawing");
if (drawing.getContext) {
try {
var gl = drawing.getContext("experimental-webgl");
} catch (e) {}
if (gl) {
//[...]
}
}
常量
在WebGL中,保存在上下文对象中的这些常量都没有GL_前缀。
方法命名
方法名的后缀会包含参数个数(1到4),和接收的数据类型(f为浮点数,i为整数),如:gl.uniform4f()意味着要接收4个浮点数;另外还有很多方法接收数组参数而非一个个单独的参数,这样的方法中名字包含字母v,如:gl.uniform3iv()可以接收一个包含3个值的整数数组。
准备绘图
在实际操作WebGL上下文之前,一般都要使用某种实色清除canvas元素,为绘图做好准备。为此,首先必须使用:
如:
var drawing = document.getElementById("drawing");
if (drawing.getContext) {
try {
var gl = drawing.getContext("experimental-webgl");
} catch (e) {}
if (gl) {
gl.clearColor(0,0,0,1); //把清理缓冲区的值设置为黑色
gl.clear(gl.COLOR_BUFFER_BIT); //调用clear方法,传入参数gl.COLOR_BUFFER_BIT告诉WebGL使用之前定义的颜色来填充相应区域。
}
}
视口与坐标
开始绘图之前,通常要先定义WebGL的视口(viewport)。默认情况下,视口可以使用整个canavs区域。要改变视口大小,可以调用
视口坐标的原点(0,0)在canvas元素的左下角,x轴和y轴的正方向分别是向右和向上,可以定义为(width-1,height-1)。
如:
var drawing = document.getElementById("drawing");
if (drawing.getContext) {
try {
var gl = drawing.getContext("experimental-webgl");
} catch (e) {}
if (gl) {
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.viewport(0, 0, drawing.width / 2, drawing.height / 2); //视口在画布的左下角四分之一区域
gl.viewport(drawing.width / 2, 0, drawing.width / 2, drawing.height / 2); //视口在画布的右下角四分之一区域
}
}
视口内部的坐标系与定义视口的坐标系也不一样。在视口内部,坐标原点(0,0)是视口的中心点,因此视口左下角坐标为(-1,-1),而右上角坐标为(1,1)。
缓冲区
顶点信息保存在JavaScript的类型化数组中,使用之前必须转换到WebGL的缓冲区。要创建缓冲区,可以调用
如:
var drawing = document.getElementById("drawing");
if (drawing.getContext) {
try {
var gl = drawing.getContext("experimental-webgl");
} catch (e) {}
if (gl) {
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(drawing.width / 2, 0, drawing.width / 2, drawing.height / 2);
var buffer = gl.createBuffer(); //创建缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); //绑定到上下文
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0.5, 1]), gl.STATIC_DRAW); //使用Float32Array中的数据初始化buffer
}
}
最后一个参数主要有:
gl.STATIC_DRAW
:数据只加载一次,在多次绘图中使用;
gl.STREAM_DRAW
:数据只加载一次,在几次绘图中使用;
gl.DYNAMIC_DRAW
:数据动态改变,在多次绘图中使用;
一般来说gl.STATIC_DRAW
够用了;
在包含缓冲区的页面重载之前,缓冲区始终保留在内存中。如果你不想要某个缓冲区了,可以直接调用
错误
JavaScript与WebGL之间的一个最大区别在于,WebGL操作一般不会抛出错误。为了知道是否有错误发生,必须在调用某个可能出错的方法后,手工调用
可能的错误常量如下:
gl.NO_ERROR
:上一次操作没有发生错误(值为0)。
gl.INVALID_ENUM
:应该给方法传入WebGL常量,但却传错了参数。
gl.INVALID_VALUE
:在需要无符号数的地方传入了负值。
gl.INVALID_OPERATION
:在当前状态下不能完成操作。
gl.OUT_OF_MEMORY
:没有足够的内存完成操作。
gl.CONTEXT_LOST_WEBGL
:由于外部事件(如设备断电)干扰丢失了当前WebGL的上下文。
如果发生了多个错误,需要反复调用gl.getError()直到返回gl.NO_ERROR:
var errorCode = gl.getError();
while (errorCode) {
console.log(errorCode);
errorCode = gl.getError();
}
着色器
着色器(shader)是OpenGL 中的另一个概念。WebGL中有两种着色器:定点着色器和片段(或像素)着色器。顶点着色器用于将3D顶点转换为需要渲染的2D点。片段着色器用于准确计算要绘制的每个像素的颜色。WebGL的着色器是使用GLSL(OpenGL Shading Language,OpenGL着色器)写的,GLSL是一种与C和JavaScript完全不同的语言。
编写着色器
GLSL是一种类C语言,专门用于编写OpenGL着色器。因为WebGL是OpenGL ES 2.0的实现,所以OpenGL中使用的着色器可以直接在WebGL中使用。
每个着色器都有一个
为着色器传递数据的方式有两种:
Attribute和Uniform在main()方法外部定义,分别使用关键字attribute和uniform。
如Attribute顶点着色器:
void main() {
gl_Position = vec4(aVertexPosition, 0.0, 1.0);
}
又如Uniform片段着色器:
void main() {
gl_FragColor = uColor;
}
编写着色器程序
浏览器不能理解GLSL程序,因此必须准备好字符串形式的GLSL程序,以便编译并链接到着色器程序。
为着色器传入值
前面定义的着色器必须接收一个值才能工作。为了给着色器传入这个值,必须先找到要接收这个值的变量。
调试着色器和程序
与着色器的其他操作一样,着色器操作也可能会失败,而且也是静默失败。如果你想找到着色器或程序执行中是否发生了错误,必须亲自询问WebGL上下文。
绘图
WebGL只能绘制三种形状:点、线和三角。其他所有形状都是由这三种基本形状合成之后,再绘制到三维空间中的。执行绘图操作要调用gl.drawArrays()或gl.drawElements()方法,前者用于数组缓冲区,后置用于元素数组缓冲区。
纹理
WebGL的纹理可以使用DOM中的图像。要创建一个新纹理,可以调用gl.createTexture(),然后再将一副图像绑定到该纹理。如果图像尚未加载到内存中,可能需要创建一个Image对象的实例,以便动态加载图像。图像加载完成之前,纹理不会初始化,因此,必须在load事件触发后才能设置纹理。
读取像素
与2D上下文类似,通过WebGL上下文也能读取像素值。读取像素值的方法readPixels()与OpenGL中的同名方法只有一点不同,即最后一个参数必须是类型化数组。像素信息是从帧缓冲区读取的,然后保存在类型化数组中。readPixels()方法的参数有:x、y、宽度、高度、图像格式、数据类型和类型化数组。前4个参数指定读取哪个区域中的像素。图像格式参数几乎总是gl.RGBA。数据类型用于指定保存在类型化数组中的数据类型,但有以下限制。
15.3.3 支持
Firefox4+和Chrome都实现了WebGL API。Safari5.1也实现了WebGL,但默认是禁用的。

JavaScript WebGL 三维相关概念
引子
在 JavaScript WebGL 矩阵之后,发现在实现三维效果之前还有一些概念需要理解,就去查了下资料,按照自己的习惯整合了一下。
齐次坐标
三维坐标理论上三个分量就够了,但在看相关程序的时候,发现会出现 4 个分量,这种表示方式称为齐次坐标,它将一个原本 n 维向量用一个 n+1 维向量表示。比如向量 (x, y, z) 的齐次坐标可表示为 (x, y, z, w)。这样表示有利于使用矩阵运算将一个点集从一个坐标系转换到另一个坐标系。齐次坐标 (x, y, z, w) 等价于三维坐标 (x/w, y/w, z/w) 。更详细介绍见这里。
空间转换
WeGL 没有现成 API 可以直接绘制出三维效果,需要进行一系列空间转换,最终在二维空间(比如电脑屏幕)显示,从视觉上看上去是三维立体效果。下面看看几个主要转换过程。
模型空间
模型空间是描述三维物体自身的空间,拥有自己的坐标系和对应原点。这里点坐标可以按照 WebGL 中可见范围 [-1, +1] 约束进行描述,也可以不按照这个约束。自定义描述规则后面需要转换一下。
世界空间
物体模型创建好后,放在具体环境当中,才会达到想要的效果,除此之外,还可能会进行位移、缩放和旋转,进行这些变化都需要一个新参考坐标系,这个所处环境就是世界空间。有了世界坐标系,相互独立的物体才会有相对位置的描述。
从模型空间转换到世界空间,需要用到模型矩阵(Model Matrix)。
三维模型矩阵跟 JavaScript WebGL 矩阵中介绍的二维变换矩阵类似,主要变化是行列增加和旋转。
const m4 = {
translation: (x, y, z) => {
return [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, z, 1,
];
},
// 缩放矩阵
scaling: (x, y, z) => {
return [
x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, 0,
0, 0, 0, 1,
];
},
// 旋转矩阵
xRotation: (angle) => {
const c = Math.cos(angle);
const s = Math.sin(angle);
return [
1, 0, 0, 0,
0, c, s, 0,
0, -s, c, 0,
0, 0, 0, 1,
];
},
yRotation: (angle) => {
const c = Math.cos(angle);
const s = Math.sin(angle);
return [
c, 0, s, 0,
0, 1, 0, 0,
-s, 0, c, 0,
0, 0, 0, 1,
];
},
zRotation: (angle) => {
const c = Math.cos(angle);
const s = Math.sin(angle);
return [
c, s, 0, 0,
-s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
];
},
}
视图空间
人眼在观察一个立方体时,从远处看和从近处看会有大小的差别,从左边看和从右边看会看到不同的面,在 WebGL 中绘制三维物体时,需要根据观察者的位置和方向,将物体放到正确的位置,观察者所处的空间就是视图空间。
从世界空间转换到视图空间,需要用到视图矩阵(View Matrix)。
为了描述观察者的状态,需要下面一些信息:
- 视点:观察者所在空间的位置,从这个位置沿着观察方向的射线为视线。
- 观察目标点:被观察目标所在的点,视点和观察目标点共同决定了视线的方向。
- 上方向:最终绘制在屏幕上影像向上的方向,因为观察者是可以围绕视线进行旋转,所以需要一个具体的参考方向。
上面的三种信息共同构成视图矩阵,WebGL 中观察者的默认状态为:
- 视点:位于坐标系统原点 (0, 0, 0)
- 观察目标点:视线是 z 轴负方向,观察点为 (0, 0, -1)
- 上方向:y 轴正方向,(0, 1, 0)
生成视图矩阵一种方法:
function setLookAt(eye, target, up) {
const [eyeX, eyeY, eyeZ] = eye;
const [targetX, targetY, targetZ] = target;
const [upX, upY, upZ] = up;
let fx, fy, fz, sx, sy, sz, ux, uy, uz;
fx = targetX - eyeX;
fy = targetY - eyeY;
fz = targetZ - eyeZ;
// 单位化
const rlf = 1 / Math.sqrt(fx * fx + fy * fy + fz * fz);
fx *= rlf;
fy *= rlf;
fz *= rlf;
// f 与上向量的叉乘
sx = fy * upZ - fz * upY;
sy = fz * upX - fx * upZ;
sz = fx * upY - fy * upX;
// 单位化
const rls = 1 / Math.sqrt(sx * sx + sy * sy + sz * sz);
sx *= rls;
sy *= rls;
sz *= rls;
// s 和 f 的叉乘
ux = sy * fz - sz * fy;
uy = sz * fx - sx * fz;
uz = sx * fy - sy * fx;
const m12 = sx * -eyeX + sy * -eyeY + sz * -eyeZ;
const m13 = ux * -eyeX + uy * -eyeY + uz * -eyeZ;
const m14 = -fx * -eyeX + -fy * -eyeY + -fz * -eyeZ;
return [
sx, ux, -fx, 0,
sy, uy, -fy, 0,
sz, uz, -fz, 0,
m12,m13, m14, 1,
];
}
这里用到了叉乘,通过两个向量的叉乘,可以生成垂直于这两个向量的法向量,从而构建一个坐标系,也就是观察者所在的空间。
下面是三维有无自定义观察者的示例:
裁剪空间
基于上面的示例,旋转一下就会发现有部分角消失的现象,这是因为超出了 WebGL 的可视范围。
在 WebGL 程序中,顶点着色器会将点转换到一个称为裁剪空间的特殊坐标系上。延展到裁剪空间之外的任何数据都会被剪裁并且不会被渲染。
从视图空间转换到裁剪空间,需要用到投影矩阵(Projection Matrix)。
可视域
人眼的观察范围是有限的,WebGL 类似的限制了水平视角、垂直视角和可视深度,这些共同决定了可视域(View Volume)。
有两类常见的可视域:
- 长方体/盒状可视域,由正射投影产生。
- 四棱锥/金字塔可视域,由透视投影产生。
正射投影可以方便的比较场景中物体的大小,因为物体看上去的大小与所在位置没有关系,在建筑平面等技术绘图相关场合,应当使用这种投影。透视投影让产生的场景看上去更有深度,更加自然。
正射投影
正射投影的可视域由前后两个矩形表面确定,分别称为近裁剪面和远裁剪面,近裁剪面和远裁剪面之间的空间就是可视域,只有在这个空间内的物体会被显示出来。正射投影下,近裁剪面和远裁剪面的尺寸是一样的。

正射投影矩阵实现的一种方式:
function setOrthographicProjection(config) {
const [left, right, bottom, top, near, far] = config;
if (left === right || bottom === top || near === far) {
throw "Invalid Projection";
}
const rw = 1 / (right - left);
const rh = 1 / (top - bottom);
const rd = 1 / (far - near);
const m0 = 2 * rw;
const m5 = 2 * rh;
const m10 = -2 * rd;
const m12 = -(right + left) * rw;
const m13 = -(top + bottom) * rh;
const m14 = -(far + near) * rd;
return [
m0, 0, 0, 0,
0, m5, 0, 0,
0, 0, m10, 0,
m12, m13, m14, 1,
];
}
这是示例,通过改变各个边界感受可视范围变化。更加详细的原理解释见这里。
Canvas 上显示的就是物体在近裁剪面上的投影。如果裁剪面的宽高比和 Canvas 的不一样,画面就会按照 Canvas 的宽高比进行压缩,物体会被扭曲。
透视投影
透视投影的可视域产生跟正射投影的类似,比较明显的区别就是近裁剪面和远裁剪面尺寸不一样。

透视投影矩阵实现的一种方式:
/**
* 透视投影
* @param {*} config 顺序 fovy, aspect, near, far
* fovy - 垂直视角,可是空间顶面和底面的夹角,必须大于 0
* aspect - 近裁剪面的宽高比(宽/高)
* near - 近裁剪面的位置,必须大于 0
* far - 远裁剪面的位置,必须大于 0
*/
function setPerspectiveProjection(config) {
let [fovy, aspect, near, far] = config;
if (near === far || aspect === 0) {
throw "null frustum";
}
if (near <= 0) {
throw "near <= 0";
}
if (far <= 0) {
throw "far <= 0";
}
fovy = (Math.PI * fovy) / 180 / 2;
const s = Math.sin(fovy);
if (s === 0) {
throw "null frustum";
}
const rd = 1 / (far - near);
const ct = Math.cos(fovy) / s;
const m0 = ct / aspect;
const m5 = ct;
const m10 = -(far + near) * rd;
const m14 = -2 * near * far * rd;
return [
m0, 0, 0, 0,
0, m5, 0, 0,
0, 0, m10,-1,
0, 0, m14, 0,
];
}
这是模拟街道两边视角示例,更加详细的原理解释见这里。
参考资料
- WebGL编程指南在线版
- WebGL model view projection
- WebGL摄像机详解之一:模型、视图和投影矩阵变换的含义
- 坐标系统
我们今天的关于javascript – 如何改进这个WebGL / GLSL图像下采样着色器和图像采样器最小着色速率的分享就到这里,谢谢您的阅读,如果想了解更多关于8 个惊艳的 Javascript WebGL 示例、iOS GLSL.有没有办法使用GLSL着色器创建图像直方图?、JavaScript Canvas——“WebGL”的注意要点、JavaScript WebGL 三维相关概念的相关信息,可以在本站进行搜索。
本文将分享我如何使用Firebug告诉我什么是JavaScript被解雇?的详细内容,并且还将对javascript被阻止怎么办进行详尽解释,此外,我们还将为大家带来关于Firebug Tutorial (Section 3): Script Tab :Javascript Debugging、Firebug不显示我的javascript?找不到错误、Firebug入门指南(Firefox浏览器)_javascript技巧、Firebug没有显示JavaScript的相关知识,希望对你有所帮助。
本文目录一览:
我如何使用Firebug告诉我什么是JavaScript被解雇?(javascript被阻止怎么办)
我正在尝试对一些
JavaScript进行逆向工程,而且令人讨厌的是,JS并不是非常清晰或有充分记录.我有一系列事件被触发(使用JQuery),我需要找到函数所在的位置.
有没有办法配置Firebug(或Opera / IE控制台 – 而不是Chrome / Safari),以便我可以看到单击按钮时会触发哪些事件?
谢谢
解决方法
在firebug中,选择控制台选项卡.点击个人资料,在页面上进行您的活动,再次点击个人资料…被叫功能列表将在下面的firebug面板中列出.

Firebug Tutorial (Section 3): Script Tab :Javascript Debugging
Firebug Tutorial – Script Tab : Javascript Debugging
September 30, 2007
Firebug Tutorial
Section 3: Script Tab : Javascript Debugging
I’m going to show you how to debug the Javascript code with Firebug in this tutorial. If you are an Ajax developer, the tutorial will help you in many ways to boost your production in your RIA (Rich Internet Application) development.
The following topics will be covered in this tutorial.
- Overview of Script Tab
- Debugging Javascript with Firebug
- Javascript File Selector
- Conditional breakpoint
- Using Commandline API while debugging
- debug(fn) and undebug(fu) <CommandLine API>
Download : Sample File
Note : Please refresh your web page if something goes wrong in Firebug console while you are debugging. As I’m using Firebug for my web project over 1 year, I know that this tool is very useful too. However, there are a few issues and limitations with this tool. So, please don’t mind about that. If you found any bug, you can report here. OR, you can search the existing issue in issue list.
#1. Overview of Script Tab
The Script tab is the fourth tab of Firebug that allows you to debug the Javascript code on the browser. There are two subpanels in script panel. The panel on the left is the Javascript editor for debugging the javascript code. The subpanel on the right includes two sub panels called “Watch” and “breakpoint”. Please take a look the picture and description in below for more details.

- JS Editor : This is the Javascript editor where you can debug the Javascript. There is one option called “Break on All Errors” in this editor. If you check this option, the script exection will be paused if the errors occurs in your script.
- JS File Selector : If you click on it, you will see the list of all Javascript files that are included in your page. (Please check “#3. Javascript File Selector” section for more details.)
- Line of Code & breakpoint : This is a place where you can set the breakpoint for debugging.
- Watch Window: It displays the value of variables as a list in that window. If you have some experiences in using Microsoft Visual Studio, you already have some idea about how to use Watch window. There is only one difference between the Watch window from Firebug and the one from Visual Studio. In Visual Studio, the “Watch” window displays the value of selected variables. But the “Watch” window of Firebug will display all values of variables within the current scope.
- list of breakpoints : The list of breakpoints that you set in Javascript Editor will be shown in that panel. You can also remove all breakpoints from that panel.
#2. Debugging Javascript with Firebug
Debugging javascript is very straightforward process with Mozilla Firefox and Firebug. If you are Visual Studio developer then you won’t feel any differences while you are debugging the Javascript code with Firebug excepts the debugger runs as the part of browser. Let’s follow the steps to take a look how to debug the JS code.
Steps to debug Javascript with Firebug
- Copy the code below and paste them in notepad and save as a htm file. ( or If you already downloaded the sourcecode of this article, you can find the html file called JS-Example1.htm in zip file. )
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Javascript Debugging with Firebug</title>
<script type="text/javascript">
function doSomething(){
var lbl = document.getElementById(''messageLabel'');
lbl.innerHTML = "I just did something.";
}
</script>
</head>
<body>
<div>
<div id="messageLabel"></div>
<input type="button" value="Click Me!" onclick="doSomething();" />
</div>
</body>
</html>
Example 1.0
- Open your HTML file in Firefox browser.
- Launch the Firebug console and go to “Script” tab.
- Set the breakpoint on line 7 (as shown in pic below)

- Take a look at “Breakpoint” window at the right panel. (One line is added in “Breakpoints” windows as shown in pic.)

- Click “Click Me!” button on your page. (The Javascript execution will stop at the breakpoint that you set on line 7. )

- You can step thought the code by using one of those buttons (Continue, Step Over, Step Into and Step Out ) on the toolbar of Firebug.

(From left to right)
- Continue (F8) : allow you to resume the script execution once it has been stopped via breakpoint
- Step Over (F10) : allow you to step over the function call.
- Step Into (F11) : allow you to step into the body of the another function.
- Step Out : allow you to resume the script execution and will stop at next breakpoint.
- So, click “Step Over” icon to go to the next line (line 8). (then, please take a look at “Watch” window. The values of variable called “lbl” will be displayed on “Watch” window. )

- then, Click “Step Over” icon to go to the next line. As there is no next line in our script, the execution will be stopped.
Yeah. That’s all about simple Javascript debugging with Firebug. I will explain about more advanced features such as “using conditional breakpoint” and “using commandline API while debugging” in next example.
Note about “Watch”window : Even though the value of the most variables are shown in “Watch” window, there might be some cases that you can’t find the variable you want in “Watch” window. In that case, the Commandline API are very helpful for you.
#3. Javascript File Selector
Using firebug console, you can easily find out how many script files are included in your page. (Please check-out the picture below. ) And also, you can change the script file that you wanna to debug.

#4. Conditional breakpoint
The conditional breakpoint is very helpful when you don’t want to debug line-by-line. For example, there is one for-loop that loops 50 times in your code. If you set the normal breakpoint, the execution will be paused each time you enter in that loop. But if you are using conditional breakpoint, you can put the condition on your breakpoint so that the script execution won’t be paused every time you enter in that loop.
In order to show you how to use the conditional breakpoint, I will change the Javascript code as below from the previous example (e.g: 1.0). (If you already downloaded the sourcecode of this tutorial, please take a look the html file called “JS-Example2.htm” in zip file.)
function Dwarf(name){
this.Name = name;
}
function DwarfFactory(){
var dwarfs = new Array();
this.AddDwarfs = function(){
dwarfs[0] = new Dwarf(''Bashful'');
dwarfs[1] = new Dwarf(''Doc'');
dwarfs[2] = new Dwarf(''Dopey'');
dwarfs[3] = new Dwarf(''Grumpy'');
dwarfs[4] = new Dwarf(''Happy'');
dwarfs[5] = new Dwarf(''Sleepy'');
dwarfs[6] = new Dwarf(''Sneezy'');
}
this.ShowDwarfs = function(){
for(var idx in dwarfs){
console.log(dwarfs[idx].Name);
}
}
this.ToString = function(){
var names = '''';
for(var idx in dwarfs){
names += dwarfs[idx].Name + '' '';
}
return names; //dwarfs.join('' '');
}
}
function doSomething(){
var objDwarfFactory = new DwarfFactory();
objDwarfFactory.AddDwarfs();
objDwarfFactory.ShowDwarfs();
var lbl = document.getElementById(''messageLabel'');
lbl.innerHTML = objDwarfFactory.ToString();
}
Example : 1.1
In our example, there is one for-loop in “ShowDwarfs()” function. We will set the conditional breatpoint in that loop. We wanna pause the script execution only when the name of dwarfs object is “Happy”. So, right-click on Javascript editor and put the condition “dwarfs[idx].Name == ‘Happy’” in the properties of breakpoint as shown in screenshot below. Then, press “Enter” key.

then, click the button on your webpage. The script execution will be paused when the condition that we put is true. We can also use the commandline API while debugging.
#5. Using Commandline API while debugging
If you have no idea about Firebug’s commandline API, I suggest you to read this tutorial first. Like we used to use “Immediate” window while we are debugging the code in Visual Studio, you can use Console panel with Commandline APIs while debugging Javascript with Firebug.
Let’s continue the previous example. The execution is paused when the condition is true. Then, you can go to Console panel and type any commandline API to find out more about current dwarf object. Let’s say we typed “console.dir(dwarfs[idx])” in one-line commandline. then, You will get the result “Name “Happy”" in console panel as pic below.

#6. Using debug(fn) and undebug(fu) API
As I said in my Commandline API article, I will explain about debug() and undebug() API here.
#11. debug(fn) and undebug(fu)
Adds or removes a breakpoint on the first line of a function.
Note: I’m not going to cover about this API in this tutorial. Please read more about this in next section.
Basically, debug(fn) and undebug(fn) APIs allows you to set/remove the breakpoint based on the function name from commandline or Javascript code instead of setting the breakpoint in script panel.
Example
- Open the “JS-Example2.htm” from zip file
- Remove all breakpoints that you set earlier. (Script panel>Breakpoint panel>Options>Remove all breakpoints)
- Go to the Console panel.
- Type “debug(doSomething)”
- then, click “Click Me!” button. (Observe: The script execution will be paused at the first line of doSomething() function. )
- If you want to remove the breakpoint that you set, type “undebug(doSomething)” in commandline.
So, keep in mind that there are three ways to set the breakpoint in Firebug.
- Static Breakpoint : It can be set based on line number. You need to set this kinda breakpoint by clicking the line of code bar in Script panel.
- Conditional breakpoint : It can be set based on the condition. You need to set this kinda breakpoint by clicking the line of code bar in Script panel.
- Dynamic breakpoint : It can be set based on the name of Javascript function. You can set this from commandline or Javascript code by using debug(fn) and undebug(fn).
If you wanna try to debug Ajax application, there is one sample file called AjaxExample folder. So, feel free to try debugging this sample if you want.
Okay. that is all about debugging Javascript with Firebug. I hope you will help it useful. Sorry for taking so long to post this tutorial because there are a lot of problems in my country (Myanmar) so I have no mood to blog. :( Anyway, I have tried to cover as much as I can in this tutorial. Feel free to let me know if you have any comment or suggestion. Thanks for reading..
Firebug Tutorial – Script Tab : Javascript Debugging
tags: Ajax debugging, Firebug, Firefox Addon, Firefox Extension, Javascript debugging
posted in Firebug, Firefox by Michael Sync

Firebug不显示我的javascript?找不到错误
好吧我想用Firebug调试一些脚本,(因为我在浏览器窗口中看不到任何内容)但是当我点击Firefox中的脚本选项卡时它会给我错误信息:
如果标签具有“type”属性,则它应该等于“text / javascript”或“application / javascript”.脚本也必须是可解析的(语法正确).
我究竟做错了什么?
这是我的代码:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script src="jquery-1.7.1.js"></script>
<script type="text/javascript">
$(function() {
/* fix: “close” the value of i inside createFunction,so it won't change */
var createFunction = function(i) {
return function() { alert(i); };
};
for (var i=0; i<5; i++) {
$('p').appendTo('body').on("click",createFunction(i));
}
})();
</script>
</body>
</html>
解决方法
你必须省略最后一个括号,我想代码应该在dom上运行吗?
<script type="text/javascript">
$(function() {
/* fix: “close” the value of i inside createFunction,so it won't change */
var createFunction = function(i) {
return function() { alert(i); };
};
for (var i=0; i<5; i++) {
$('<p>').appendTo('body').on("click",createFunction(i));
}
});
</script>
See here如何使用jquery在dom load上运行代码.

Firebug入门指南(Firefox浏览器)_javascript技巧
我最近就在学习怎么使用Firebug,网上找到一篇针对初学者的教程,感觉比较有用,就翻译了出来。
作者:Estelle Weyl
原文网址:http://www.evotech.net/blog/2007/06/introduction-to-firebug/
译者:阮一峰
本文是Firebug的一个概览,并不对它的所有特性进行详尽解释。不过,本文的内容对一个新手来说,应该是足够了。
目录
一、安装Firebug
二、打开和关闭Firebug
三、Firebug窗口概览
四、随时编辑页面
五、用Firebug处理CSS
六、盒状模型
七、评估下载速度
八、DOM
九、Javascript调试
十、AJAX
十一、附注
一、安装Firebug
Firebug在Firefox浏览器中运行。另外有一个Firebug lite版本,可以通过javascript调用,包含在页面中,从而在其他非Firefox浏览器中使用。本文不涉及这个版本。
安装Firebug,请访问Firebug下载页面。点击该页面右边栏中部巨大的橙黄色按钮即可。你也可以在Mozilla的FireFox Add-ons站点下载它。安装后只要重新启动FireFox,就可以使用了。
如果你已经安装过了,那么请检查是否更新到了最新版本。打开Firefox的“Tools”菜单,选择“Add-ons”命令,然后在弹出窗口中点击左下角的“Find Updates”按钮。
二、打开和关闭Firebug
在Firebug网站上,可以找到它的快捷键设置。我最常使用以下三种方法:
* 打开Firebug:按F12,或者点击浏览器状态栏右边的
绿色标志。
* 关闭Firebug:按F12,或者点击浏览器状态栏右边的
绿色标志,或者点击Firebug窗口右上角的
红色关闭标志。
* 在单独窗口中打开Firebug:点击firebug窗口右上角的
红色箭头标识,或者使用Ctrl+F12/⌘+F12按钮。
Firebug的相关设置:
* 固定Firebug在新窗口打开:先打开firebug,点击左上角的bug标志,选择options菜单中的“Always Open in New Window”设置。
* 增加/缩小字体大小:先打开firebug,点击左上角的bug标志,选择“Text Size”命令。每次字体变化的幅度非常小,你可能需要使用多次。

* 限制只对某些站点使用Firebug:先右击浏览器状态上的green check mark标志,选择“disable Firebug”命令。然后,再右击这个已经变灰的标志,选择“Allowed Sites...”命令,增加允许Firebug生效的域名。

三、Firebug窗口概览
* Console标签: 主要使用javascript命令行操作,显示javascript错误信息,在底部的>>>提示符后,你可以自己键入javascript命令。
* HTML标签: 显示HTML源码,并且像DOM等级结构那样,每行之前有缩进。你可以选择显示或不显示某个子节点。
* CSS标签:浏览所有已经装入的样式表,可以当场对其修改。在Firebug窗口上部,“edit”命令的旁边,有一个本页面中所有样式表的下拉列表,你可以选择一个样式表进行浏览。

* Script标签: 显示javascript文件及其所在页面。在Firebug窗口上部,“inspect”命令的旁边,有一个本页面中所有Javascript文件的下拉列表,你可以选择一个进行浏览。你可以在javascript命令中,设置断点(breakpoint)及其出现的条件。
* DOM标签: 显示所有的页面对象和window物体的属性。因为在javascript中,所有变量都是window物体的属性,所以Firebug会显示所有变量和它们的值。
* Net标签:显示本页面涉及的所有下载,以及它们各自花费的时间,各自的HTTP请求头信息和服务器响应的头信息。XHR标签对AJAX调试很有用。
四、随时编辑页面
在HTML标签中,点击窗口上方的“inspect”命令,然后再选择页面中的文本节点,你可以对其进行修改,修改结果会马上反应在页面中。

Firebug同时是源码浏览器和编辑器。所有HTML、CSS和Javascript文件中的对象,都可以用单击或双击进行编辑。当你输入完毕,浏览器中的页面立刻会发生相应变化,你可以得到瞬时反馈。DOM浏览器允许你对文档结构进行彻底的编辑,不局限于文本节点。在HTML标签中,点击窗口上部“inspect”命令旁边的“edit”命令,下方的窗口就会立刻变成一个黑白的文本编辑窗口,你可以对HTML源代码进行任意编辑。在CSS标签中,Firebug会自动补全你的输入。在DOM标签中,当你按Tab键时,Firebug会自动补全属性名。
五、用Firebug处理CSS
在DOM标签中,每个HTML元素的style属性揭示了该元素的所有CSS设置。你可以双击对这些设置进行编辑。

对于那些Firefox不支持的CSS规则,Firebug会自动隐藏。比如,Firebug会隐藏针对某些浏览器的CSS特定设置,以及一些它不支持的CSS3规则。所以,它会隐藏_height:25px;(下划线是一个针对IE6的设置)和p:first-of-type {color: #ff0000;} (:first-of-type是一个CSS3规定的伪类,目前只有Safari 3支持)。但是,这也意味着,如果你恰巧发生了打字错误,导致某些规则无法显示,那么你只有使用其他编辑器显示全部CSS内容,找到你的错误。
Firebug允许你关闭CSS中的某些语句,页面会立刻反映相应变化,你可以立刻查看效果。“关闭”一条语句的方法是,在该语句的左边点击,会出现一个红色的
禁止标志。该语句就会变灰。再次点击,该语句就会恢复。
Firebug允许你编辑CSS的属性和属性值。你只要对它们点击,就能编辑。修改后的效果会立刻在浏览器窗口中显示出来。这个特性最好的运用,是在确定准确定位的padding和margin时,firebug允许你用方向键逐单位的增加。
Firebug允许你增加新的属性和属性值。增加方法是双击现有的selector,然后就会出现一个空白的属性名输入框,完成输入后则会出现一个空白的属性值。
六、盒状模型
当你在HTML标签中,点击一个元素时,左面窗口显示HTML代码,右面窗口显示该元素的CSS。在CSS窗口上方,有一个layout按钮,点击后会展示与该元素相关的方块模型,包括padding、margin和border的值。要查看每一个元素的这三项值,只需点击“inspect”按钮,然后用鼠标悬停在页面中该元素的上方。

七、评估下载速度
Net标签中图形化了页面中所有http请求所用的时间。使用这个功能,必须打开Network monitoring,默认设置就是打开,但是你可以在“options”下拉菜单中关闭这个选项。你可以用这项功能评估javascript文件下载,占用整个页面显示的时间。

在每个HTTP请求的左面点击,会显示该次请求的头信息。
在1.0.5版以后,你可以单独查看HTML文件、CSS文件、图像文件等各自下载的时间。
八、DOM
DOM标签提供页面上所有物体的所有属性的信息。Firebug最酷的功能之一是,它可以动态修改页面,反映在浏览器窗口,但是如果使用浏览器自带的查看源码功能,你会发现源码并没有改变。
九、Javascript调试
JavaScript profiler可以报告你的Javascript函数执行所花的时间,因此你可以查看不同函数对速度的影响。使用这个功能的方法是,打开console标签,然后点击上面的Profile按钮(上部的按钮顺序是“Inspect |Clear | Profile”)。Firebug列出调用的所有函数,及其所花的时间。你可以针对要测试的某个函数,在其前部加上console.profile([title]),在其后部加上console.profileEnd()。
console标签的底部是命令行输入,它以“>>>”开头。如果命令行输入有结果输出,那么它会展示在上部的窗口。有一个详细的命令行输入API值得看一下。Firebug内置console对象有几种有用的方法可供调用,包括console.debug、console.info、console.warning、console.error等。如果这些方法产生了输出结果,Firebug会提供一个链接,让你查看相应的代码。
调试的另一个方法是设置断点。Script标签允许你在任意行暂停执行。单击行号,就会设置一个断点。右击行号,就可以设置一个断点出现的条件,只有当条件为真时,程序才会暂停执行。右面还有一个watch窗口,可以查看当前变量的值。

十、AJAX
前面已经提到,Firebug可以捕捉页面的动态内容和其他DOM变化。如果你打开这个示例文件,点击页面上的链接后,在浏览器中查看源码,你会发现什么也没有改变,源码中依然包含那个链接。但是,如果你在Firebug中查看源码,你会发现DOM已经发生了变化,“Hello World”已经被包括在内了。这就是Firebug的核心功能之一,没有它,AJAX的请求和回应就是不可见的。有了它,你可以看到送出的和收到的文本,已经相应的头信息。在Net标签中,你还能监控每个请求/回应各自所花费的时间。

Net标签中的XHR功能,对查看AJAX操作特别有用。如果你点击每个服务器端回应前的加号,你就会看到服务器端回应的头信息和内容。
当通过XMLHttpRequest对象向服务器端发出一个请求时,Firebug会记录请求的POST或GET内容,以及回应的头信息和内容。使用Net标签中的XHR功能,就可以看到这些内容。它会列出所有服务器的回应,以及所花费的时间。点击前面的+号,如果是GET请求,会显示三个标签;如果是POST请求,会显示4个标签:
Params: 显示请求URL中所包含的name/value对。
Headers: 显示请求和回应的头信息。
Response: 显示实际从服务器收到的信息。
Post:显示从通过POST请求,送到服务器的信息。(此项GET请求不包括。)
这四个标签对编写和调试程序很有用。检查POST和Params标签,确定你的请求被正确地发出了。检查Response标签查看返回的格式,确定相应的Javascript处理函数应该如何编写。
十一、附注
* Firebug 1.05 及以前版本,与Firefox 3.0不兼容。
* Firebug的作者Joe Hewitt免费提供了这个软件,为了显示我们对他的爱,你可以考虑对他进行捐助。
* Firebug的一些高级应用,请看Joe Hewitt的这段演示视频(http://video.yahoo.com/watch/111597)。
(完)

Firebug没有显示JavaScript
我有最新版本的Firefox(50.0.2)和Firebug(2.0.18).我想调试我的
JavaScript代码,但Firebug告诉我:此页面上没有JavaScript.
我清除了我的活动列表,因为它在这个帖子中被告知:
Firebug says “No Javascript on this page”,even though JavaScript does exist on the page
但没有改变.正如Firebug的常见问题解答告诉我,JavaScript源代码中可能存在一些错误,我尝试了其他页面.但即使在google或facebook等网页上,我仍会收到相同的消息.
我能做些什么让Firebug再次工作?
最好的祝福
马尔科
解决方法
这不仅仅是你的问题.新的Firefox不想像几天前那样与Firebug合作.
我们今天的关于我如何使用Firebug告诉我什么是JavaScript被解雇?和javascript被阻止怎么办的分享已经告一段落,感谢您的关注,如果您想了解更多关于Firebug Tutorial (Section 3): Script Tab :Javascript Debugging、Firebug不显示我的javascript?找不到错误、Firebug入门指南(Firefox浏览器)_javascript技巧、Firebug没有显示JavaScript的相关信息,请在本站查询。
针对关于JavaScript,WebSockets,WebGL的问题和websocket javascript这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Cocos2d-x-javaScript 的webSocket的代码、HTML5 websockets与PHP websockets vs node.js websockets?、HTML5之WebSocket入门3 -通信模型socket.io_javascript技巧、javascript - php和websocket怎么建立连接等相关知识,希望可以帮助到你。
本文目录一览:
关于JavaScript,WebSockets,WebGL的问题(websocket javascript)
我已经看到很多关于其他客户端脚本语言的stackoverflow问题
互联网正在成为一个内容丰富且充满活力的地方. HTML和CSS规范正试图将Web提升到一个新的水平 – 我们正在获得WebSockets支持,这对于全双工客户端 – 服务器通信非常有用,可以实现一些引人入胜的设计模式.此外,我们在JavaScript中有一个WebGL的工作实现,到目前为止我已经有了很多乐趣.
但这引起了一些担忧,至少对我而言.我是桌面程序员,C/C++ / Objective-C – 取决于平台.具体来说,是渲染架构师. JavaScript为我们所有人提供了极好的服务,不是吗?我们使用它来获取与2D线性网站的基本用户交互,响应简单事件并将所有这些与HTML和CSS相结合.
鉴于实时通信和GPU驱动可视化的大门已经向网络开放,这对JavaScript有什么影响吗?我已经看到了对Dart的反应和其他推动JavaScript的尝试. JavaScript是弱类型的,它对我来说听起来像是各种各样的警报(考虑到速度很快的数学库,不必要的运行时检查不是一个有趣的时间).
我已经将很多代码转移到了GPU上,但即使这样,我的内部渲染器也只是cpu限制(HD6990不是问题,更不用说为桌面/嵌入式引擎提供动力的代码了).
所以,这是在前面:
>由于翻译设计,代码是赤裸裸的.渲染技术和解决方案非常值钱.这是我公司的唯一基础并支付账单.混淆不会削减它(如果我错了,请纠正我).我一直在想,为什么没有一个可以由VM处理的字节码形式的中间编译过程?
>它是弱类型的.杂耍矩阵,向量,四元数,数组以及高度交互式应用程序常用的所有其他类型的数据只会通过运行时检查进行处理.即使它最终进入GPU方面,你仍然需要在cpu方面做相当多的工作,这是由JavaScript陷入困境.
>基于原型的范例将抑制从可以推动采用WebGL / WebSockets的主要参与者移植代码的努力. (请记住,很多都是由cpu驱动的).随着越来越多的用户开始要求高保真的2D / 3D内容,基于原型的范例是否会持续存在?
> WebSockets已经被证明是网络游戏(browserQuest)的一个美丽的新增功能,更不用说动态网站了,将来会有很多人开发以开发出令人敬畏的内容(我的公司正在运行一个实施的小项目)由WebSockets驱动的3D环境中的小型MMO).
那么,我的担忧是否有任何实际依据?
这些问题有没有新动向?
如果您对该主题提供任何答案,您是否还可以添加一小段个人意见?我知道这不是“Stackexchange的方式”,但它没有坏处,因为所有其他问题都是合法的,答案可以基于事实.
解决方法
您的担忧是基于对Javascript运行时间如何工作的误解,而且实际上没有任何依据.
>现在所有的Javascript代码都是JIT的 – 不需要中间字节码语言,并且在可能的情况下可能会阻碍可移植性,这是Web的最大优点.像Python,Ruby,PHP等编程语言这样的现代脚本即使应用程序不是作为字节码分发也能很好地工作.不需要字节码步骤,因为无论如何代码最终都是JIT.您可以为JIT提供更多的材料,更好.事实上,对于Java,他们在现代版本中禁用了字节码优化,因为它使JIT编译器感到困惑.
> JIT编译可以优化动态类型问题,但它们永远不会提供静态类型的性能,但最有可能提供足够好的性能.虽然http://www.scirra.com/blog/76/how-to-write-low-garbage-real-time-javascript有一些问题,但Javascript实现正在变得更好地解决这些问题.例如,Mozilla Audio团队(似乎更像是演示团队……)正在开发3D演示,只是为了获得优化其Javascript运行时的材料.
>我不明白为什么基于原型的方法与高保真度有任何联系,它们是两个完全不同的东西
>目前像谷歌NaCL这样的替代方法没有得到其他浏览器供应商的认可,而且很可能永远不会,因为微软和苹果不会采用仅谷歌技术而且Mozilla认为NaCL是开放网络的威胁
有关现代JIT编译工作的见解,请参阅PyPy博客http://morepypy.blogspot.com/(虽然不是特定于Javascript).他们详细解释了现代计算机科学对代码应用何种JIT优化.
对于“类似于网络的设计模式可以在3D中实现”,请参阅tQuery,它是jQuery,类似于3D内容https://github.com/jeromeetienne/tquery的框架
干杯,米科

Cocos2d-x-javaScript 的webSocket的代码
var WebSocket = WebSocket || window.WebSocket || window.MozWebSocket;
var WebSocketManager = cc.Class.extend({
_wsObj:null,
_wsReConnectTimes:0,
_reConnectMax:3,
_connectTimeout:5,
_reConnectFlag:false,
_msg:null,
_msgKey:null,
_msgSendStatus:''nothing'',
_msgTimeout:5,
_msgTimeoutTimes:0,
_msgGet:'''',
_target:null,
_callback:null,
ctor:function () {
NC.addObserver(this,this.connectTimeoutHandle, ''ws_connect_timeout'');
NC.addObserver(this,this.sendTimeoutHandle, ''ws_timeout'');
},
//打开连接
openConnect:function () {
if(this._wsObj){
this._wsObj.close();
return;
}
this._wsObj = null;
var self = this;
this._wsObj = new WebSocket(CFG_SER.ws_ser);
cc.log("WS CONNECTING." + CFG_SER.ws_ser);
//连接超时推断
director.getScheduler().scheduleCallbackForTarget(this,this.connectTimeoutCheck,0, 0, this._connectTimeout);
this._wsObj.onopen = function (evt) {
self.openGet(evt);
};
this._wsObj.onmessage = function (evt) {
self.messageGet(evt);
};
this._wsObj.onerror = function (evt) {
self.errorGet(evt);
};
this._wsObj.onclose = function (evt) {
self.closeGet(evt);
};
},
//连接超时推断
connectTimeoutCheck:function(){
if(CFG_SER.is_websock && this._wsObj && this._wsObj.readyState == WebSocket.CONNECTING){
//重连次数
if(this._wsReConnectTimes >this._reConnectMax){
//重试过多后。应该提示玩家眼下网络不稳定
GY_ti_shi_popup.getInstance().show(L(''gy:ws_wang_luo_bu_wen''));
}else{
this._wsReConnectTimes++;
GY_ti_shi_popup.getInstance().show(L(''gy:ws_timeout''),''ws_connect_timeout'');
}
}else{
this.connectTimeoutHandle();
}
},
//超时后又一次连接
connectTimeoutHandle:function(){
//又一次打开连接
this.closeConnect();
},
//关闭连接
closeConnect:function () {
cc.log("WS CLOSING.");
if(this._wsObj){
this._wsObj.close();
}
},
//连接后处理
openGet:function (evt) {
cc.log("WS was opened.");
//获得连接的消息后,去掉超时推断
director.getScheduler().unscheduleCallbackForTarget(this,this.connectTimeoutCheck);
//清除重连次数
this._wsReConnectTimes = 0;
//是否有未发送的消息又一次发送
if (this._msgSendStatus ==''msgReady'' && this._msg) {
this.sendRequest();
}
},
//获得消息
messageGet:function (evt) {
this._msgGet = evt.data;
try{
if (this._msgGet.length <10000)
cc.log(''response:'' +this._msgGet);
else
cc.log(''content too long to display.'');
}catch(e){
cc.log(''too large'');
}
try{
var resObj = JSON.parse(this._msgGet);
}catch (e){
GY_msg_popup.getInstance().show(L(''gy:request_err''));
}
if (resObj._st == 1) {
GY_tools.fan_yi_http_body(resObj._body);
//推断是什么消息
if(this._msgSendStatus ==''msgSend'' && resObj._body.func == this._msgKey){
this.requestResponse(resObj);
}else{
switch (resObj._body.func){
case ''chong_zhi''://这里做一些自己的处理逻辑
break;
}
}
}else{
cc.log(''request data err'');
GY_msg_popup.getInstance().show(L(''gy:request_data_err''));
}
},
//获取错误
errorGet:function (evt) {
cc.log("WS Error");
this.closeConnect();
},
//连接关闭处理
closeGet:function (evt) {
cc.log("websocket instance closed.");
this._wsObj = null;
//连接关闭立即进行重试
this.openConnect();
},
/**
* 给服务器发送消息
* @param act
* @param params
* @param callback
* @param target
*/
sendGetRequest:function (act, params, callback, target) {
this.beforeRequestSend(act, params, callback, target);
//推断当前连接
if (this.isOpen()) {
this.sendRequest();
}
else {
this.openConnect();
}
},
//准备消息
beforeRequestSend:function (act, params, callback, target) {
//弹出loading
GY_loading_popup.getInstance().show();
//消息拼接
this._msg = {''pathname'':'''', ''query'':''''};
this._msg.pathname = ''/'' + act;
G.js_jiao_se ? params.id_jiao_se = G.js_jiao_se.id_jiao_se :null;
//由于之前是HTTP的请求,须要将參数变成字符串的
var p = {};
for (key in params) {
p[key] ='''' + params[key];
}
this._msg.query = p;
//注冊消息,回调
this._msgKey = this._msg.pathname;
this._target = target;
this._callback = callback;
this._msgSendStatus = ''msgReady'';
},
//发送消息
sendRequest:function () {
cc.log(''send request :'');
cc.log(JSON.stringify(this._msg));
this._wsObj.send(JSON.stringify(this._msg));
this._msgSendStatus = ''msgSend'';
//设置超时时间
director.getScheduler().scheduleCallbackForTarget(this,this.sendTimeoutCheck,0, 0, this._msgTimeout);
},
//消息被响应了
requestResponse:function (resObj) {
//获得响应的消息后,去掉loading遮罩
director.getScheduler().unscheduleCallbackForTarget(this,this.sendTimeoutCheck);
this._msg = null;
this._msgSendStatus = ''nothing'';
GY_loading_popup.getInstance().hide();
this._callback.call(this._target, resObj._body);
},
//发送消息超时推断
sendTimeoutCheck:function(){
if(this._msgSendStatus ==''msgSend''){
//消息没有被响应。去掉loading遮罩
GY_loading_popup.getInstance().hide();
GY_ti_shi_popup.getInstance().show(L(''gy:ws_timeout''),''ws_timeout'');
}
},
//超时后又一次获取玩家信息 并刷新当前页面
sendTimeoutHandle:function(){
var act =''gc/jiao_se/deng_lu'';
var param = {};
param.gc_token = LS.getItem(''gc_token'');
param.id_yong_hu = LS.getItem(''id_yong_hu'');
param.zhouqi = LS.getItem(''uc_zhouqi'');
HttpManager.create().sendGetRequest(act, param,this.callbackTimeoutHandle, this);
},
//超时消息处理
callbackTimeoutHandle:function(resObj){
if (resObj.st_code == 1) {
if (G.js_jiao_se.zt_jiao_se == 1) {
SM.goto_page(''DL_chuang_ming_page'');
}else if (G.js_jiao_se.zt_jiao_se ==2) {
SM.goto_page(''YD_yin_dao_'' + G.js_jiao_se.xin_shou_jin_du +''_page'');
}else if (G.js_jiao_se.zt_jiao_se ==3) {
//SM.goto_page(''SY_shou_ye_page'');
//试试看直接刷新页面的效果吧
SM.flush_page();
}
}
},
//推断ws是否已经连接
isOpen:function(){
return (this._wsObj &&this._wsObj.readyState == WebSocket.OPEN);
},
purge:function () {
NC.removeObserver(this,''ws_timeout'');
NC.removeObserver(this,''ws_connect_timeout'');
this.closeConnect();
this._instance = null;
}
});
WebSocketManager._instance =null;
WebSocketManager.getInstance =function () {
if (!this._instance) {
this._instance = new WebSocketManager();
}
return this._instance;
};

HTML5 websockets与PHP websockets vs node.js websockets?
我决定使用WebSockets作为我的网站聊天应用程序,我刚开始学习websockets,但我有三个不同的选项,node.js,PHP或HTML5.
我想知道的是三者之间有什么区别,我的意思是我不想学习所有这三者,如果有的话比其他人好.
解决方法
Web套接字是一种定义双方如何通信的协议.这是语言不可知的;任何语言都可以提供适配器与另一个Web套接字通信.你提到的三件事是这个适配器的三种不同的实现.对于聊天应用程序,您可能至少需要其中两个:一个服务器,一个客户端.选择您要编写服务器的语言(PHP或Node.js),并使用浏览器中的HTML 5 Web套接字功能与服务器通信.

HTML5之WebSocket入门3 -通信模型socket.io_javascript技巧
socket.io为什么会诞生呢?请看下面文字说明。
为什么需要socket.io?
node.js提供了高效的服务端运行环境,但是由于浏览器端对HTML5的支持不一,为了兼容所有浏览器,提供卓越的实时的用户体验,并且为程序员提供客户端与服务端一致的编程体验,于是socket.io诞生。
socket.io设计的目标是支持任何的浏览器,任何Mobile设备。目前支持主流的PC浏览器(IE,Safari,Chrome,Firefox,Opera等),Mobile浏览器(iphone Safari/ipad Safari/android WebKit/WebOS WebKit等)。
socket.io基于node.js并简化了WebSocket API,统一了各种通信API。它支持:WebSocket, Flash Socket, AJAX long-polling, AJAX multipart streaming, Forever IFrame, JSONP polling。
socket.io解决了实时的通信问题,并统一了服务端与客户端的编程方式。启动了socket以后,就像建立了一条客户端与服务端的管道,两边可以互通有无。
安装
在命令行中执行:npm install socket.io 即可安装。
服务端编程模型
服务端编程还是与普通服务器一样,启动服务器,提供服务,处理事件。
立即学习“Java免费学习笔记(深入)”;
比如下面的server.js:
var http = require(''http'')
, url = require(''url'')
, fs = require(''fs'')
, server;
server = http.createServer(function(req, res){
// your normal server code
var path = url.parse(req.url).pathname;
switch (path){
case ''/'':
res.writeHead(200, {''Content-Type'': ''text/html''});
res.write(''<h1>Hello! Try the <a href="/index.html">Socket.io Test</a></h1>'');
res.end();
break;
case ''/index.html'':
fs.readFile(__dirname + path, function(err, data){
if (err) return send404(res);
res.writeHead(200, {''Content-Type'': path == ''json.js'' ? ''text/javascript'' : ''text/html''})
res.write(data, ''utf8'');
res.end();
});
break;
default: send404(res);
}
}),
send404 = function(res){
res.writeHead(404);
res.write(''404'');
res.end();
};
server.listen(8080);
var io = require(''socket.io'').listen(server);
io.sockets.on(''connection'', function(socket){
console.log("Connection " + socket.id + " accepted.");
socket.on(''message'', function(message){
console.log("Received message: " + message + " - from client " + socket.id);
});
socket.on(''disconnect'', function(){
console.log("Connection " + socket.id + " terminated.");
});
});
登录后复制
客户端编程模型
客户端编程也是相似的处理方式,连接服务器,交互信息。
比如下面的index.html页面:
<!doctype html>
<html>
<head>
<title>Socket.io Test</title>
<script src="/json.js"></script> <!-- for ie -->
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<script>
var socket;
var firstconnect = true;
function connect() {
if(firstconnect) {
socket = io.connect(null);
socket.on(''message'', function(data){ message(data); });
socket.on(''connect'', function(){ status_update("Connected to Server"); });
socket.on(''disconnect'', function(){ status_update("Disconnected from Server"); });
socket.on(''reconnect'', function(){ status_update("Reconnected to Server"); });
socket.on(''reconnecting'', function( nextRetry ){ status_update("Reconnecting in "
+ nextRetry + " seconds"); });
socket.on(''reconnect_failed'', function(){ message("Reconnect Failed"); });
firstconnect = false;
}
else {
socket.socket.reconnect();
}
}
function disconnect() {
socket.disconnect();
}
function message(data) {
document.getElementById(''message'').innerHTML = "Server says: " + data;
}
function status_update(txt){
document.getElementById(''status'').innerHTML = txt;
}
function esc(msg){
return msg.replace(/</g, ''<'').replace(/>/g, ''>'');
}
function send() {
socket.send("Hello Server!");
};
</script>
<h1>Socket.io Test</h1>
<div><p id="status">Waiting for input</p></div>
<div><p id="message"></p></div>
<button id="connect" onClick=''connect()''/>Connect</button>
<button id="disconnect" onClick=''disconnect()''>Disconnect</button>
<button id="send" onClick=''send()''/>Send Message</button>
</body>
</html>
登录后复制
注意事项
1. 启动服务器还是交给node,打开命令行窗口,定位到server.js所在文件夹,输入node server.js启动服务器。
在上面的index.html中,注意这行:。如果不想使用本地的socket.io脚本,可
以直接使用下面这个公开的脚本:
<script src="http://cdn.socket.io/stable/socket.io.js"></script>
登录后复制
此外需要注意这行:socket = io.connect(null)。
这里的null代表连接本地服务,可以换成"localhost",效果也是一样的。
2. 可以使用socket.io直接启动http服务。
例如:
var io = require(''socket.io'').listen(80);
io.sockets.on(''connection'', function (socket) {
io.sockets.emit(''this'', { will: ''be received by everyone''});
});
登录后复制
3. socket.io可以直接通过send方法发送消息,使用message事件接收消息,例如:
//server.js
var io = require(''socket.io'').listen(80);
io.sockets.on(''connection'', function (socket) {
socket.on(''message'', function () { });
});
//index.html
<script>
var socket = io.connect(''http://localhost/'');
socket.on(''connect'', function () {
socket.send(''hi'');
socket.on(''message'', function (msg) {
// my msg
});
});
</script>
登录后复制
4. 发送和处理数据
两端可以互发事件,互发数据,相互通信。发送事件的代码为:socket.emit(action, data, function),其中action为事件的名称,data为数据,function为回调函数;处理事件代码为:socket.on(action,function),如果emit发送的时候有数据data,则function中参数包含了这个数据。socket.io除了发送和处理内置事件,如connect, disconnect, message。还允许发送和处理自定义事件,例如:
//服务端:
io.sockets.on(''connection'', function (socket) {
socket.emit(''news'', { hello: ''world'' });
socket.on(''my other event'', function (data) {
console.log(data);
});
});
登录后复制
//客户端:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect(''http://localhost'');
socket.on(''news'', function (data) {
console.log(data);
socket.emit(''my other event'', { my: ''data'' });
});
</script>
登录后复制
5. 从上面可以看出来,发送数据的时候,send和emit是都可以使用的。只不过emit更是强化了自定义事件的处理。
6. 可以在服务端使用socket的get/set方法存储客服端的相关数据,例如:
//服务端
var io = require(''socket.io'').listen(80);
io.sockets.on(''connection'', function (socket) {
socket.on(''set nickname'', function (name) {
socket.set(''nickname'', name, function () { socket.emit(''ready''); });
});
socket.on(''msg'', function () {
socket.get(''nickname'', function (err, name) {
console.log(''Chat message by '', name);
});
});
});
登录后复制
//客户端
<script>
var socket = io.connect(''http://localhost'');
socket.on(''connect'', function () {
socket.emit(''set nickname'', confirm(''What is your nickname?''));
socket.on(''ready'', function () {
console.log(''Connected !'');
socket.emit(''msg'', confirm(''What is your message?''));
});
});
</script>
登录后复制
7. 可以广播消息,比如聊天室中给除了当前socket连接外的所有人发消息。
var io = require(''socket.io'').listen(80);
io.sockets.on(''connection'', function (socket) {
socket.broadcast.emit(''user connected'');
});
登录后复制
8. 可以在同一次链接中,建立多个互相独立的通道,而不是建立多次链接。这个官方叫法是“多个namespace”,比如官方的例子:
var io = require(''socket.io'').listen(80);
//Server
var chat = io
.of(''/chat'')
.on(''connection'', function (socket) {
socket.emit(''a message'', {
that: ''only''
, ''/chat'': ''will get''
});
chat.emit(''a message'', {
everyone: ''in''
, ''/chat'': ''will get''
});
});
var news = io
.of(''/news'')
.on(''connection'', function (socket) {
socket.emit(''item'', { news: ''item'' });
});
//Client
<script>
var chat = io.connect(''http://localhost/chat'')
, news = io.connect(''http://localhost/news'');
chat.on(''connect'', function () {
chat.emit(''hi!'');
});
news.on(''news'', function () {
news.emit(''woot'');
});
</script>
登录后复制
socket.io的配置
socket.io的配置很简单,如果配置过express的话,你会发现它们几乎是使用差不多的方式。先看个小例子:
var io = require(''socket.io'').listen(80);
io.configure(''production'', function(){
io.enable(''browser client etag'');
io.set(''log level'', 1);
io.set(''transports'', [
''websocket''
, ''flashsocket''
, ''htmlfile''
, ''xhr-polling''
, ''jsonp-polling''
]);
});
io.configure(''development'', function(){
io.set(''transports'', [''websocket'']);
});
登录后复制
可以看到,socket.io使用configure, set, enable, disable进行配置。
1. 使用configure方法配置不同的运行环境下的行为;就是说在不同的环境下,启用不同的配置选项。configure的第一个参数是运行环境,第二个参数是进行配置的function。运行环境典型的如production或者是development,当然这里可以使任意的字符串。如果configure的第一个参数省略的话,说明后面的配置是公用的,不管是什么环境下,都有效。
2. 配置好各种运行环境了,那么如何设置当前运行在那个环境下呢?这个是通过在命令行中修改环境变量NODE_ENV的值实现的。
3. 在configure的配置函数中,我们可以使用set, enable, disable设置相关选项。
4. 具体可以配置的项参考:https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO
实用参考
socket.io介绍:http://davidchambersdesign.com/getting-started-with-socket.io/
socket.io安装和使用说明:http://socket.io/
socket.io Wiki:https://github.com/LearnBoost/Socket.IO/wiki

javascript - php和websocket怎么建立连接
h5的websocket 怎么和服务端建立连接,网上找了几个例子都不好使,具体应该怎么做
回复内容:
h5的websocket 怎么和服务端建立连接,网上找了几个例子都不好使,具体应该怎么做
个人理解的是
1、了解websocket的协议和请求规范;
2、使用PHP的socket函数库来处理websocket的请求;
3、处理websocket的数据帧。
下面是我写的一个小例子,里面的注释我觉得也挺详细的了,对帧的处理我没有完善,处理41字节以上的内容,要了解各种字处理。。。待补。
https://github.com/zhenbianshu/websocket
弄明白这些基本的应该能简单的应用了,但是要是用在项目中,还是建议用已经成熟的扩展类workerman或swoole。
使用的话,这要看你的服务器配置了,
服务器端:$ws=new WebSocket("127.0.0.1","8080");
客户端:var ws = new WebSocket("ws://127.0.0.1:8080");
照这么看的话,放在哪里都是无所谓的。。。运行时先用一个窗口运行服务器端,保持监听,然后用另一个窗口运行客户端连接。
我这个是简单版,消息推送弄得跟HTTP响应一样。。。应答没有再次转发,直接服务器返回的,但原理都是一样的。
你需要一个websocket 的服务,可以使用 workman 或者swoole作为websocket服务。
立即学习“PHP免费学习笔记(深入)”;
用传统lnmp实现socket不现实。
我都是用node做服务
我们今天的关于关于JavaScript,WebSockets,WebGL的问题和websocket javascript的分享已经告一段落,感谢您的关注,如果您想了解更多关于Cocos2d-x-javaScript 的webSocket的代码、HTML5 websockets与PHP websockets vs node.js websockets?、HTML5之WebSocket入门3 -通信模型socket.io_javascript技巧、javascript - php和websocket怎么建立连接的相关信息,请在本站查询。
在本文中,您将会了解到关于javascript – Android webview性能缓慢的新资讯,同时我们还将为您解释android webview性能优化的相关在本文中,我们将带你探索javascript – Android webview性能缓慢的奥秘,分析android webview性能优化的特点,并给出一些关于Android API 23. WebView如何忽略javascript错误、Android Javascript WebView、Android JavaScript自动完成表单WebView、Android Webview HTML加载Javascript问题的实用技巧。
本文目录一览:
javascript – Android webview性能缓慢(android webview性能优化)
我正在用
javascript编写游戏.这个应用程序在我的浏览器上运行良好(快速),
但是用android webview运行它有点麻烦.
>启动应用程序的时间需要5秒或更长时间(我认为这有点慢,但也许这是正常的?)
>在游戏菜单中,我有一个方法:
this.showCredits = function() {
document.getElementById('core-credits-layer').style.display = 'block';
document.getElementById('core-credits').style.display = 'block';
var parent = this;
$.ajax({
url: 'content/credits.html',dataType: 'html',success: function(data,status,response) {
var Now = new Date();
var s = Now.getSeconds()-parent.test.getSeconds();
console.log('success ajax: '+s);
document.getElementById('core-credits').scrollTop = 0;
document.getElementById('core-credits').innerHTML = response.responseText;
console.log('finished');
},error: function() {
console.error('Failed fetch credits');
}
});
}
因此,在单击“信用”菜单后立即出现控制台日志(“已完成”,成功的最后一行()).但是在我看到div #core-credits之前,它可能需要6s(或多或少).
在我的浏览器中,我点击后立即看到#core-credits.
但第二次点击该菜单点我在1-2s之后得到了div.
我现在不知道那是什么,我不这么认为,这是一个缓存的事情,因为我很快就进入了success()回调.
Java方面:
public void onCreate(Bundle savedInstanceState)
{
requestwindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Context context = this.getApplicationContext();
SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
boolean isFirstRun = wmbPreference.getBoolean("FirsTRUN",true);
if(isFirstRun) {
this.copyAudioFiles(context);
}
WebView mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.getSettings().setJavaScriptCanopenWindowsAutomatically(true);
String data = context.getFilesDir().getPath();
mWebView.getSettings().setDatabasePath(data+"data/"+this.getPackageName()+"/databases/");
mWebView.getSettings().setAllowFileAccess(true);
mWebView.setWebChromeClient(new WebChromeClient());
String data_root = Environment.getExternalStorageDirectory()+"/"
+this.getPackageName();
mWebView.loadUrl("file:///android_asset/www/index.html?system=android&" +
"data_root="+data_root);
}
我在Eclipse中的虚拟平板设备上以及我真正的华硕平板电脑上都存在性能问题.
动画(jquery show(‘slow’))有时真的很慢或很破碎.例如(这是纸牌游戏),玩家变成9张带有节目(‘慢’)动画的牌,每2或3次我得到3或8张牌而不是9 ^^.
以上所有这些都适用于Chrome或firefox等浏览器.
我正在使用Android 4.1.
激活硬件加速没有帮助.关于webview的渲染问题有各种各样的帖子,但只有硬件加速解决方案,这没有帮助.
解决方法
在这种情况下忘记硬件加速 –
it’s a false friend.在大多数情况下,它甚至比软件渲染慢.
但是你可以优化很多小东西:
写更快的javascript
>在适用的情况下,始终使用选择器缓存(在代码中只应出现一次document.getElementById(‘core-credits’)
>分组/解耦(参见下一点或直接使用setTimeout)代码执行和DOM操作(总是触发单个元素的重绘或 – 更糟糕的是 – 文档的重排)
>在某些应用程序中,我看到使用requestAnimationFrame Polyfill进行dom操作的良好结果 – 不一定会导致更高的帧速率,但在我的情况下,它允许我正确地“抛弃”openlayers地图(而不是设备只是没有对touchmove)
对Android友好
>就像intel appframework(以前的jqmobi ui)那样,大量使用css3转换而不是尝试jquery风格的“tick”动画
>删除border-radius,而是使用透明的png方法
> Android上其他昂贵的效果图应该是:(-webkit-)box-shadow
,文本阴影和各种渐变(再次可以用于交换旧学校的png)
希望这有所帮助 – 将尝试详细说明,分别说明.纠正信息,因为我现在继续在我自己的应用程序中对抗web webview缓慢.

Android API 23. WebView如何忽略javascript错误
我使用WebView将第三方网站嵌入到应用程序中.
mWebView = (WebView) findViewById(R.id.activity_main_webview);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient());
mWebView.loadUrl("http://someurl.com/");
问题是WebView在发现javascript错误时冻结:
I/chromium﹕ [INFO:CONSOLE(7178)] “Uncaught TypeError: Cannot read property ‘getItem’ of null”
但是以某种方式在浏览器(Android)中可以完美加载.
解决方法:
尝试使用setDomStorageEnabled(true)
WebSettings settings = webView.getSettings();
settings.setDomStorageEnabled(true);

Android Javascript WebView
我有一个应用程序,我的最小API是16,我想在网页视图上评估一些
JavaScript,当我有
mWebView.evaluateJavascript("(function()...)");
我得到一个编译错误,说这只在API 19及更高版本中可用,所以如何在Web视图中为19以下的API评估javascript,我在API 19及更高版本的if语句中有以上代码,但怎么能我在19以下的API中这样做?
谢谢您的帮助
解决方法
在API 19之前,您必须使用
WebView.loadUrl()
和javaScript协议来评估当前加载页面中的JavaScript:
String javaScript = // Some JavaScript code here
if (Build.VERSION.SDK_INT >= 19) {
mWebView.evaluateJavascript(javaScript,null);
} else {
mWebView.loadUrl("javascript:" + javaScript);
}

Android JavaScript自动完成表单WebView
使用此代码,我可以轻松地将用户名和密码自动粘贴到facebook.com上
目的是为用户选择的每个站点自动粘贴用户名和密码.许多应用程序都可以这样做,但我还没有找到方法.谢谢你的帮助
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
String user = "user";
String pwd = "pass";
view.loadUrl("javascript:(function(){document.getElementsByName('email')[0].value='"
+ user
+ "';document.getElementsByName('pass')[0].value='"
+ pwd + "';document.getElementsByTagName('form')[0];})()");
}
解决方法:
就像Speditz所说的,并不是每个登录页面都使用相同的name / id元素.
通常,大多数网站都使用type =“ email”或type =“ text”作为用户名,使用type =“ password”进行密码登录,并且您可以进行某些字段存在检查并在加载网页后执行注入
view.loadUrl(
"javascript:window.onload= (function(){"
+ "var selectElementName = document.querySelector('input[type=\"email\"]');"
+"if(selectElementName){selectElementName.value = \"" + user + "\";}"
+"var selectElementName = document.querySelector('input[type=\"text\"]');"
+"if(selectElementName){selectElementName.value = \"" + user + "\";}"
+"var selectElementpassword = document.querySelector('input[type=\"password\"]');"
+"if(selectElementpassword){selectElementpassword.value = \"" + pwd + "\";}"
+"})();"
);
这是JavaScript之上的纯文本格式,更易于理解:
window.onload= function(){
var selectElementName = document.querySelector('input[type="email"]');
if(selectElementName){selectElementName.value = "username";}
var selectElementName = document.querySelector('input[type="text"]');
if(selectElementName){selectElementName.value = "username";}
var selectElementpassword = document.querySelector('input[type="password"]');
if(selectElementpassword){selectElementpassword.value = "password";}
};

Android Webview HTML加载Javascript问题
我一直在与这个问题进行斗争超过48小时,我无法在网上任何地方找到答案.这是设置:
我的Android应用程序在首次运行时下载内容(内容超过20MB),文件解压缩到用户的SD卡/ mnt / sdcard / {my package} /文件夹中.内容包括HTML文件,CSS文件,JS文件和图像.这是写入SD卡的完整结构(其中/ = / mnt / sdcard / {my package} / folder /):
/内容/
a.html
b.html
images/
image1.jpg
/ CSS /
c.css
d.css
/ JS /
e.js
f.js
这是我从SD卡加载html文件的代码:
webView = (WebView) findViewById(R.id.pagebrowser);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new LinkHandlerInterface(),"Android");
webView.setWebViewClient(new PageWebViewClient());
// contentLocation + url is equal to the full path to the html file
webView.loadUrl("file://" + contentLocation + url);
此代码成功加载HTML页面.没有问题.每个页面都有以下标题:
<link rel="stylesheet" type="text/css" href="../css/screen.css" media="all" />
<link rel="stylesheet" type="text/css" href="../css/inPractice.css" media="all" />
<link rel="stylesheet" type="text/css" href="../css/inPracticeScheme.css" media="all" />
<link rel="stylesheet" type="text/css" href="../css/mobile/iPad.css" media="all" />
<script type="text/javascript" src="../js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="../js/inPractice-utilities.js"></script>
<script type="text/javascript" src="../js/inPractice.js"></script>
<script type="text/javascript" src="../js/mobile/inpractice.ipad.js"></script>
这就是问题所在.我的WebView渲染HTML就好了.它甚至可以完美地加载和应用CSS.但是,它拒绝加载和执行Javascript.如果从上面记得,js文件夹实际上是从html文件中提取的,所以它指向正确的位置.
这是我所知道的清单:
>我正在使用的CSS正在应用,所以我知道问题不在于文件位置.
>之前我使用过相同的代码,但是从我的应用程序的资源文件夹(文件:/// android_assets / …)加载文件,它运行得很好.由于内容太大,我无法将其与我的应用程序捆绑在一起,因此转移到SD卡.
>如果我更改HTML文件的方式是在脚本标记内列出所有Javascript方法,那么它可以正常工作.我无法控制HTML,因此我无法永久应用此更改.这告诉我WebView执行Javascript没有问题.
>图像加载正常.
我现在的想法很新鲜.有没有人知道为什么我的WebView无法加载我的Javascript文件?谁看过这个吗?
编辑:这里是我试图使用的JS文件可以在这里查看:
http://www.automatastudios.com/clients/cco/inpractice/css/inPractice.css
http://www.automatastudios.com/clients/cco/inpractice/css/inPracticeScheme.css
http://www.automatastudios.com/clients/cco/inpractice/css/screen.css
http://www.automatastudios.com/clients/cco/inpractice/css/mobile/iPad.css
>注意:这些CSS文件不是由我创作的.
解决方法
从来没有能够找到解决方案.
我最后只是编辑HTML文件,这样就将Javascript源文件更改为内联Javascript.这有效(正如我预期的那样).
今天关于javascript – Android webview性能缓慢和android webview性能优化的讲解已经结束,谢谢您的阅读,如果想了解更多关于Android API 23. WebView如何忽略javascript错误、Android Javascript WebView、Android JavaScript自动完成表单WebView、Android Webview HTML加载Javascript问题的相关知识,请在本站搜索。
本篇文章给大家谈谈json – 无法从Facebook API获得age_range,以及json文件无法读取的知识点,同时本文还将给你拓展Android me / invitable_friends facebook api获取短ID、android – Facebook登录CallbackManager FacebookCallback每次调用onCancel()、android – 使用Facebook API获取封面照片、android – 如何通过弃用的api从facebook获得可邀请的朋友?等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
json – 无法从Facebook API获得age_range(json文件无法读取)
根据Facebook文档,age_range是请求用户数据时的默认属性:
https://developers.facebook.com/docs/facebook-login/permissions#reference-basic-info
当我使用“me”作为具有正确令牌的用户ID时,这确实有效:
07001 for required user]
{
"id": "FACEBOOKID","name": "testuser","email": "testuser\u0040test.net","first_name": "testuser","last_name": "testuser","gender": "male","age_range": {
"min": 21
},"picture": {
"data": {
"url": "https://...","is_silhouette": false
}
}
}
但是当我使用用户ID时,data_range为空:
07002*
给我回复:
{
"id": "FACEBOOKID","first_name": "tftestuser","last_name": "tftestuser","picture": {
"data": {
"url": "http://....","is_silhouette": true
}
}
}
知道为什么吗?我在这里错过了什么?
先感谢您!
解决方法
我在这里找到了一个使用API的答案:
no age_range in facebook response (javascript sdk)
api调用“/ me”返回默认信息,该信息并不总是包含age_range.
但是你可以通过api调用请求age_range:“/我吗?田= AGE_RANGE”

Android me / invitable_friends facebook api获取短ID
我收到了invitable_friends列表,得到的数据如下
{
"id": "AVnRyTe6jbT3TdDNmQQJx1vYFRWt2GPx7zRxNsBiyOOaqVYQhU--1sNQ4gaIy_uDNg8e44-dXTVoSeUakW4lremIeDzLU5O0FRTtoZ7tkZo3cA",
"name": "Marianne Abinguna",
"picture": {
"data": {
"is_silhouette": false,
"url": "..."
}
}
但是我想获得像100009555113xxx这样的简短Facebook ID.任何帮助表示赞赏.
解决方法:
您无法通过invitable_friends获得(应用程序范围内)用户ID.获取用户ID的唯一方法是使用/ me / friends.当然,您只会得到授权您的应用程序的朋友.
无论如何,获取用户ID是没有意义的,因为只允许您使用invitable_friends邀请朋友(参加具有Canvas实现的游戏).您可以仅使用邀请令牌.

android – Facebook登录CallbackManager FacebookCallback每次调用onCancel()
我正在通过facebook实现登录并使用SDK 4.1.0获取用户电子邮件ID,如
facebook documentation所示,但问题是每次在onActivityResult之后调用registerCallback时,调用而不是onSuccess onCancel.
package com.dexterous.hellologin;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBaractivity;
import android.util.Log;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
public class MainActivity2 extends ActionBaractivity {
CallbackManager callbackManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
setContentView(R.layout.activity_main_activity2);
LoginButton loginButton = (LoginButton) findViewById(R.id.login_button);
loginButton.setReadPermissions("email");
// If using in a fragment
// loginButton.setFragment(this);
// Other app specific specialization
// Callback registration
loginButton.registerCallback(callbackManager,new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
// App code
Log.e("TAG","success");
}
@Override
public void onCancel() {
// App code
Log.e("TAG","onCancel");
}
@Override
public void onError(FacebookException exception) {
// App code
Log.e("TAG","error");
}
});
}
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data) {
super.onActivityResult(requestCode,resultCode,data);
callbackManager.onActivityResult(requestCode,data);
Log.e("TAG","onActivityResult");
}
}
每次我得到输出
onActivityResult
onCancel
我没有得到包含按钮取消和登录的facebook登录屏幕.
卸载Facebook应用程序从移动设备错误更改为无效的应用程序ID
这是堆栈跟踪
06-04 10:55:16.631 19864-19864/com.dexterous.hellologin I/WebViewFactory﹕ Loading com.google.android.webview version 42.0.2311.138 (code 2311138)
06-04 10:55:16.706 19864-19864/com.dexterous.hellologin I/LibraryLoader﹕ Time to load native libraries: 4 ms (timestamps 8772-8776)
06-04 10:55:16.706 19864-19864/com.dexterous.hellologin I/LibraryLoader﹕ Expected native library version number “”,actual native library version number “”
06-04 10:55:16.717 19864-19864/com.dexterous.hellologin W/art﹕ Attempt to remove local handle scope entry from IRT,ignoring
06-04 10:55:16.816 19864-19864/com.dexterous.hellologin V/WebViewChromiumFactoryProvider﹕ Binding Chromium to main looper Looper (main,tid 1) {28a6fbd9}
06-04 10:55:16.816 19864-19864/com.dexterous.hellologin I/LibraryLoader﹕ Expected native library version number “”,actual native library version number “”
06-04 10:55:16.819 19864-19864/com.dexterous.hellologin I/chromium﹕ [INFO:library_loader_hooks.cc(112)] Chromium logging enabled: level = 0,default verbosity = 0
06-04 10:55:16.834 19864-19864/com.dexterous.hellologin I/browserStartupController﹕ Initializing chromium process,singleProcess=true
06-04 10:55:16.838 19864-19864/com.dexterous.hellologin W/art﹕ Attempt to remove local handle scope entry from IRT,ignoring
06-04 10:55:16.841 19864-19864/com.dexterous.hellologin E/SysUtils﹕ ApplicationContext is null in ApplicationStatus
06-04 10:55:16.869 19864-19864/com.dexterous.hellologin W/chromium﹕ [WARNING:resource_bundle.cc(286)] locale_file_path.empty()
06-04 10:55:16.870 19864-19864/com.dexterous.hellologin I/chromium﹕ [INFO:aw_browser_main_parts.cc(63)] Load from apk succesful,fd=63 off=46992 len=3337
06-04 10:55:16.871 19864-19864/com.dexterous.hellologin I/chromium﹕ [INFO:aw_browser_main_parts.cc(76)] Loading webviewchromium.pak from,fd:64 off:7953032 len:1161174
06-04 10:55:17.024 19864-19953/com.dexterous.hellologin W/chromium﹕ [WARNING:data_reduction_proxy_config.cc(150)] SPDY proxy OFF at startup
06-04 10:55:17.047 19864-19864/com.dexterous.hellologin W/art﹕ Attempt to remove local handle scope entry from IRT,ignoring
06-04 10:55:17.060 19864-19864/com.dexterous.hellologin W/AwContents﹕ onDetachedFromWindow called when already detached. Ignoring
06-04 10:55:24.893 19864-19864/com.dexterous.hellologin W/BindingManager﹕ Cannot call determinedVisibility() – never saw a connection for the pid: 19864
06-04 10:55:26.140 19864-20020/com.dexterous.hellologin E/Adreno-ES20﹕ : Invalid texture format! Returning error!
06-04 10:55:26.140 19864-20020/com.dexterous.hellologin E/Adreno-ES20﹕ : Framebuffer color attachment incomplete. Returning GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT!
06-04 10:55:26.198 19864-19912/com.dexterous.hellologin E/Adreno-ES20﹕ : Invalid texture format! Returning error!
06-04 10:55:26.198 19864-19912/com.dexterous.hellologin E/Adreno-ES20﹕ : Framebuffer color attachment incomplete. Returning GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT!
06-04 10:58:32.287 19864-19864/com.dexterous.hellologin E/TAG﹕ onCancel
06-04 10:58:32.287 19864-19864/com.dexterous.hellologin E/TAG﹕ onActivityResult
06-04 10:59:25.498 19864-19864/com.dexterous.hellologin I/art﹕ Explicit concurrent mark sweep GC freed 16056(1325KB) AllocSpace objects,0(0B) LOS objects,39% free,9MB/16MB,paused 856us total 79.028ms
表现
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUetoOTH"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.dexterous.hellologin.MainActivity2"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main_activity2" >
</activity>
<Meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="1437829111203883" />
</application>
</manifest>
解决方法
Problem is here that you are using Facebook APPId directly and You should use Like this
<Meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/app_id" />
In sting xml
<string name="app_id">1437829111203883 </string>

android – 使用Facebook API获取封面照片
在我的
Android应用程序中,我试图从他的Facebook帐户获取用户的封面照片.
我可以使用下面的代码获取个人资料图片.
profilePicUrl = new URL("http://graph.facebook.com/" + userId + "/picture?type=large");
profilePicBmp = BitmapFactory.decodeStream(profilePicUrl.openConnection().getInputStream());
documentation指定了以下用于检索封面照片.
The user’s cover photo (must be explicitly requested using
fields=cover parameter)
Requires access_token
Returns : array of fields id,source,and
offset_y
因此,JSON响应的结构将是这样的.
{
"cover": {
"cover_id": "10151008748223553","source": "http://sphotos-a.ak.fbcdn.net/hphotos-ak-ash4/s720x720/391237_10151008748223553_422785532_n.jpg","offset_y": 0
},"id": "19292868552"
}
我对Facebook Graph API很新,因此对如何解决这个问题知之甚少.
我试过这个coverPicUrl =新的URL(“http://graph.facebook.com/”userId“/ cover?type = large”);
还有这个coverPicUrl =新的URL(“http://graph.facebook.com/”userId“/ fields = cover”);
但我无法获得用户个人资料的封面图片.
在线搜索也没有产生任何丰硕的成果.
任何帮助确实会受到赞赏.
谢谢!
解决方法
“source”标记(JSONObject)嵌套在另一个JSONObject(“cover”标记)中.要解析此结果,您必须使用以下内容:
JSONObject JOSource = JOCover.optJSONObject("cover");
String coverPhoto = JOSource.getString("source");
示例中使用的JOCover假定您已经有一个JSONOBject(JOCover)来解析根.您可以在自己的位置替换自己的JSONObject.
无法直接访问“source”标记,因为它嵌套在“cover”标记中.你将不得不使用“.optJSONObject(”cover“)”.我见过人们使用.getString而不是.optJSONObject,但我从未使用它.选择适合你的方式.
编辑
根据您对使用Graph API的解决方案的要求,我正在编辑早期的解决方案并将其替换为Graph API解决方案.
最好在AsyncTask中,在doInBackground中使用此代码:
String URL = "https://graph.facebook.com/" + THE_USER_ID + "?fields=cover&access_token=" + Utility.mFacebook.getAccesstoken();
String finalCoverPhoto;
try {
HttpClient hc = new DefaultHttpClient();
HttpGet get = new HttpGet(URL);
HttpResponse rp = hc.execute(get);
if (rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String result = EntityUtils.toString(rp.getEntity());
JSONObject JODetails = new JSONObject(result);
if (JODetails.has("cover")) {
String getinitialCover = JODetails.getString("cover");
if (getinitialCover.equals("null")) {
finalCoverPhoto = null;
} else {
JSONObject JOCover = JODetails.optJSONObject("cover");
if (JOCover.has("source")) {
finalCoverPhoto = JOCover.getString("source");
} else {
finalCoverPhoto = null;
}
}
} else {
finalCoverPhoto = null;
}
} catch (Exception e) {
// Todo: handle exception
}
我已经测试了这个解决方案并且运行得很您必须向活动所需的基本URL添加任何添加字段.为了测试,我只使用fields = cover
在onPostExecute中,做你的事情来显示封面图片.希望这可以帮助.

android – 如何通过弃用的api从facebook获得可邀请的朋友?
我正在为
Android编写一款游戏,它使用Facebook来跟踪用户在云端保存他的游戏状态.我们希望允许用户从Facebook邀请他的朋友.然而facebook图表api不再支持获得邀请的朋友(自4月4日
https://developers.facebook.com/docs/graph-api/reference/user/invitable_friends/)
我无法在页面中找到有关如何解决它的任何信息.是吗?没有其他方式邀请朋友?
解决方法
我们写了一篇关于这个主题的文章,read here.
如果您有游戏应用程序,您仍然可以使用GameRequest对话框. Facebook App invites was also deprecated back in Feb.但是,我们的数据显示,与WhatsApp等其他渠道相比,通过Facebook进行的有机安装仅为1%(见study by Sega and GetSocial).
免责声明:我是GetSocial的创始人
关于json – 无法从Facebook API获得age_range和json文件无法读取的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Android me / invitable_friends facebook api获取短ID、android – Facebook登录CallbackManager FacebookCallback每次调用onCancel()、android – 使用Facebook API获取封面照片、android – 如何通过弃用的api从facebook获得可邀请的朋友?的相关知识,请在本站寻找。
本文将分享javascript – Ember.js如何引用Grunt.js预编译的Handlebars模板?的详细内容,并且还将对在js文件中如何引用模块进行详尽解释,此外,我们还将为大家带来关于ember.js – Handlebars助手和Ember Handlebars助手有什么区别?、ember.js – 使用Handlebars Runtime进行预编译的ember-i18n、gruntjs – 带有grunt-contrib-watch,browserify和hbsfy(handlebars)的Gruntfile – 自动转换、gulp – 模板是使用旧版本的Handlebars预编译的,而不是当前运行时的相关知识,希望对你有所帮助。
本文目录一览:
javascript – Ember.js如何引用Grunt.js预编译的Handlebars模板?(在js文件中如何引用模块)
我一直在探索Ember.js,以及Grunt.js,但是我不明白Ember.js如何能够找到并使用预编译的Handlebars模板.现在我的Gruntfile.js看起来像这样:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),handlebars: {
compile: {
files: {
"js/templates.js": "templates/*.hbs",}
}
}
});
// Load the plugin that handles the handlebars compiling
grunt.loadNpmtasks('grunt-contrib-handlebars');
// Default task(s).
grunt.registerTask('default',['handlebars']);
};
而我的app.js Ember视图被这样声明(路由和控制器被忽略):
App.logoView = Ember.View.extend({
templateName: 'logo',classNames: ['logo']
});
App.TabsView = Ember.View.extend({
templateName: 'tabs',classNames: ['tabs']
});
App.TabView = Ember.View.extend({
classNames: ['content'],tabPositions: {
tab1: {
width: '90px',left: '82px'
},tab2: {
width: '180px',left: '172px'
},tab3: {
width: '271px',left: '263px'
}
},animateTab: function() {
var left,tab,width;
tab = this.get('templateName');
width = this.get('tabPositions.' + tab + '.width');
left = this.get('tabPositions.' + tab + '.left');
Ember.run.next(function() {
$('div.tabs').removeClass('tab1 tab2 tab3');
$('div.tabs').addClass(tab);
$('div.slider div.foreground').stop().animate({
'width': width
},1000);
$('div.slider div.handle').stop().animate({
'left': left
},1000);
});
},didInsertElement: function() {
this.animateTab();
}
});
App.SliderView = Ember.View.extend({
templateName: 'slider',classNames: ['slider']
});
App.Tab1View = App.TabView.extend({
templateName: 'tab1'
});
App.Tab2View = App.TabView.extend({
templateName: 'tab2'
});
App.Tab3View = App.TabView.extend({
templateName: 'tab3'
});
这是我的文件结构:
--/
|--js/
|--app.js
|--ember.js
|--handlebars.js
|--jquery.js
|--templates.js
|--templates/
|--application.hbs
|--logo.hbs
|--slider.hbs
|--tab1.js
|--tab2.js
|--tab3.js
|--tabs.js
|--Gruntfile.js
|--index.html
|--package.json
|--server.js
所以我使用< script type =“text / x-handlebars”data-template-name =“slider”>我的index.html文件中的语法通过名称引用模板,并且工作正常.我不明白的是,Ember.js应该如何使用预编译的模板.
现在,我使用Grunt.js来编译它们,并将它们输出到templates.js.根据Ember文档,当应用程序加载时,它将查找应用程序模板.与index.html以及通过更改模板的文件名一起使用的是更改模板的名称吗?有人指出Ember.js使用预编译模板的方向正确吗?谢谢!
解决方法
What I don’t understand,is how Ember.js is supposed to use the precompiled templates.
Ember希望将编译的模板添加到Ember.TEMPLATES属性中.当加载了一个ember应用程序时,它会检查任何句柄脚本标签并进行编译.然后,使用指定的data-template-name属性作为关键字,将每个模板添加到Ember.TEMPLATES.如果没有提供数据模板名称,则将其密钥设置为应用程序.
除了那个余烬不在乎Ember.TEMPLATES如何进行.您可以手动添加/删除模板.例如,https://stackoverflow.com/a/10282231/983357演示了如何可以内联编译模板:
Ember.TEMPLATES['myFunkyTemplate'] = Ember.Handlebars.compile('Hello {{personName}}');
现在显然你不想以这种方式写你的模板,你想咕噜为你做,但是你可以看到没有任何魔法.
According to the Ember docs when an application loads,it will look for the application template. How does that work with index.html and by changing the file name of the template,is that changing the template’s name?
Ember不关心模板的文件名,它只是关心Ember.TEMPLATES [‘key / goes / here]中使用什么字符串作为关键字.也就是说,使用filename作为模板的关键是非常有意义的.
Could someone point me in the right direction as to how Ember.js uses precompiled templates?
我想你的项目缺少的可能是编译的模板没有被添加到Ember.TEMPLATES. AFAIK的grunt-contrib-handlebars插件不这样做.考虑使用grunt-ember-templates.

ember.js – Handlebars助手和Ember Handlebars助手有什么区别?
我无法赶上所有对普通手把和修改的Ember Handlebars助手所做的所有修改.如果我记得正确,可以使用以下方法注册一个助手
> Ember.Handlebars.helper
> Ember.Handlebars.registerHelper
> Ember.Handlebars.registerBoundHelper
> Handlebars.registerHelper
对我来说太多了你能解释一下它有什么区别吗?
解决方法
Ember.Handlebars.registerHelper是一个基本的帮助器,不会将参数字符串绑定到属性.例如,考虑使用registerHelper创建的一个hello帮助器,它只返回一个问候消息.
Ember.Handlebars.registerHelper('hello',function(name) {
return 'Hello ' + name;
});
当您在模板中使用它时,
{{hello name}}
您将获得显示文本为“Hello”名称. name属性的值不被查找.
要获取你需要的帮助器的name属性的值,registerBoundHelper.顾名思义,它创建一个绑定到名称属性之间.随着名字的更改,帮助者再次被呼叫重新投递.实施方式类似,
Ember.Handlebars.registerBoundHelper('hello',function(name) {
return 'Hello ' + name;
});
Ember.Handlebars.helper与registerBoundHelper相同,还有一些额外的检查功能,可以自动检测你想要什么样的帮手.
香草Handlebars.registerHelper不在Ember中使用.它将为不使用Ember的项目创建类似的帮助.

ember.js – 使用Handlebars Runtime进行预编译的ember-i18n
ember-i18n readme file说:
if you haven’t precompiled your translations,you’ll need to include
the full Handlebars,not just handlebars-runtime.js in your
application.
问题是即使使用预编译模板,一旦我们使用如下的函数Em.I18n.t,它仍然会调用Handlebars编译功能,需要完整的Handlebars.
有人知道解决方案吗?即使是函数调用,也许有预编译的最佳实践?
解决方法
好吧,因为我对这个案子有紧迫感,这就是我修复它的方式:
/* Customized version of translation compiler */
Em.I18n.compile = function(template) {
// Full Handlebars completely disabled
//if (typeof window.Handlebars.compile === 'function')
// return window.Handlebars.compile(template);
return function(context,options){
var ret = template;
if (context !== undefined) {
$.each(context,function(key,value){
ret = ret.replace("{{"+key+"}}",value);
});
}
return ret;
}
}
这非常有效,但我并非百分之百地确信它涵盖了所有可能的情况.

gruntjs – 带有grunt-contrib-watch,browserify和hbsfy(handlebars)的Gruntfile – 自动转换
我对大多数所有这些工具都很陌生(grunt,browserify,handlebars).我设置gruntfile.js来监视几个.js文件的保存,然后自动运行默认的browserify bundle命令.这是我目前的gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('node_modules/grunt/package.json'),watch: {
js: {
files: ['tvguide.js','responsive-tables.js'],tasks: ['browserify']
}
},browserify: {
js: {
src: ['responsive-tables.js','tvguide.js'],dest: 'bundle.js'
}
}
});
grunt.loadNpmtasks('grunt-contrib-watch');
grunt.loadNpmtasks('grunt-contrib-handlebars');
grunt.loadNpmtasks('grunt-browserify');
grunt.registerTask('default',['watch','browserify']);
};
这很好 – 虽然文件和src可能是多余的.然而,我已经到了充实我的应用程序的地步,我想使用把手进行模板化,许多谷歌搜索带有把手的浏览器导致我进入这个npm包hbsfy.说明说我会运行browserify -t hbsfy myscriptusingatemplate.js > bundle.jsI我希望在保存特定的.js文件时自动运行此命令,但我不确定如何在相同或不同的文件上同时使用-o和-t.
我做了一些使用选项对象的尝试,但没有任何结果.任何帮助/建议将不胜感激.
解决方法
如果你想使用Grunt中的hbsfy,请使用以下配置:
browserify: {
js: {
src: ['responsive-tables.js','tvguide.js','tmpl/**/*.handlebars'],dest: 'bundle.js'
},options: {
transform: ['hbsfy']
}
}
这样,您根本不需要使用grunt-contrib-handlebars.
另外,我建议不要使用grunt-contrib-watch,而是将’watch’选项设置为browserify为true.

gulp – 模板是使用旧版本的Handlebars预编译的,而不是当前运行时
我有这个错误,但
this question和我的问题之间的不同之处在于我正在使用gulp而不是grunt.
首先,我的车把运行时是把手v4.0.5(js文件).
车把-v的输出为4.0.5
这是我的gulpfile.js:
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var handlebars = require('gulp-handlebars');
var wrap = require('gulp-wrap');
var declare = require('gulp-declare');
var concat = require('gulp-concat');
gulp.task('default',['templates','scripts'],function () {
});
gulp.task('templates',function () {
gulp.src('templates/*.hbs')
.pipe(handlebars())
.pipe(wrap('Handlebars.template(<%= contents %>)'))
.pipe(declare({
namespace: 'MyApp.templates',noredeclare: true,// Avoid duplicate declarations
}))
.pipe(concat('templates.js'))
.pipe(gulp.dest('js/dist'));
});
gulp.task('scripts',function () {
return gulp.src([
'bower_components/handlebars/handlebars.runtime.js','bower_components/jquery/dist/jquery.js','bower_components/bootstrap/dist/bootstrap.js','js/dist/templates.js','js/main.js'])
.pipe(concat('bundle.js'))
.pipe(uglify())
.pipe(gulp.dest('js/dist/'));
});
Main.js
"use strict";
var data = { title: 'This Form',name: 'Joey' };
var html = MyApp.templates.hellotemplate(data);
// console.log(html);
$(document).ready(function () {
$('#dynamic-content').html(html);
});
哪里可以成为我的问题?
错误:
Uncaught Error: Template was precompiled with an older version of
Handlebars than the current runtime. Please update your precompiler to
a newer version (>= 4.0.0) or downgrade your runtime to an older
version (>= 2.0.0-beta.1).
我使用gulp命令预编译了模板.
非常感谢!!
解决方法
有一种更好的方法来使用README:
https://github.com/lazd/gulp-handlebars#compiling-using-a-specific-handlebars-version中介绍的特定版本的把手来编译模板
确保您已在应用的package.json文件中指定了把手版本:
{
"devDependencies": {
"handlebars": "^4.0.5"
}
}
然后通过将其作为gulp文件中的gulp-handlebars选项传递来要求把手:
gulp.task('templates',function () {
gulp.src('templates/*.hbs')
.pipe(handlebars({
handlebars: require('handlebars')
}))
.pipe(wrap('Handlebars.template(<%= contents %>)'))
.pipe(declare({
namespace: 'MyApp.templates',// Avoid duplicate declarations
}))
.pipe(concat('templates.js'))
.pipe(gulp.dest('js/dist'));
});
今天关于javascript – Ember.js如何引用Grunt.js预编译的Handlebars模板?和在js文件中如何引用模块的讲解已经结束,谢谢您的阅读,如果想了解更多关于ember.js – Handlebars助手和Ember Handlebars助手有什么区别?、ember.js – 使用Handlebars Runtime进行预编译的ember-i18n、gruntjs – 带有grunt-contrib-watch,browserify和hbsfy(handlebars)的Gruntfile – 自动转换、gulp – 模板是使用旧版本的Handlebars预编译的,而不是当前运行时的相关知识,请在本站搜索。
在这篇文章中,我们将带领您了解javascript – Web Audio API:noteOn后noteOff不工作?的全貌,同时,我们还将为您介绍有关ASP.NET WebApi DateTimeOffset序列化为Json / JavaScript(angular2)、Float32到Int16 – Javascript(Web Audio API)、html5 – Firefox 25和AudioContext createJavaScriptNote不是一个函数、html5 – 在Javascript中使用Web Audio API的本地文件的知识,以帮助您更好地理解这个主题。
本文目录一览:
javascript – Web Audio API:noteOn后noteOff不工作?
我使用Web Audio API编写了一个简单的Web应用程序,但是我注意到当我向给定的源发出noteOn(0)命令,然后是noteOff(0),然后是另一个noteOn(0)命令,声音将打开,关闭(如预期的那样),但随后不会打开第三个命令.
有什么我做错了吗?就这么简单,我可以向你展示代码,但我觉得它是多余的.也许我需要在noteOff之后将缓冲区重新分配给源代码,但我无法想象它是如何使用的.
解决方法
AudioBufferSourceNode只能播放一次.
http://youtu.be/hFsCG7v9Y4c?t=18m22s

ASP.NET WebApi DateTimeOffset序列化为Json / JavaScript(angular2)
我找不到将DateTimeOffset值获取到JavaScript(angular2)的好方法.
我正在使用WebApi(5.2.3)和angular2.在电线上,我看到的日期如下:
RecordModifiedAt : "2016-03-08T17:27:11.9975483+01:00"
JavaScript / angular2无法将此识别为有效的datetime值.
我确实有选择,但是我应该去哪个方向:
>服务器端:Newtonsoft.Json,…
>客户端:angular2,…
>其他?
非常感谢您的帮助!
解决方法:
感谢我对PierreDuc的反馈,我得出以下结论:
由于JSON不支持Date数据类型,因此我认为必须在客户端进行转换.我使用以下“模式”(请参见http://codegur.com/36681078/angular-2-date-deserialization):
getTags() {
return this.http.get(''/api/tag/getAll'')
.map((response: Response) => this.convertData(response));
}
private convertData(response: Response) {
var data = response.json() || [];
data.forEach((d) => {
// Convert to a Date datatype
d.RecordModifiedAt = new Date(d.RecordModifiedAt);
});
return data;
}
总结
以上是小编为你收集整理的ASP.NET WebApi DateTimeOffset序列化为Json / JavaScript(angular2)全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
原文地址:https://codeday.me/bug/20191027/1941791.html

Float32到Int16 – Javascript(Web Audio API)
我想将Float32转换为Int16.但到目前为止,效果不佳.因为输出音频会产生大量剪辑(因此,音频输出非常差).我正在使用这个功能:
function convertoFloat32ToInt16(buffer) {
var l = buffer.length; //Buffer
var buf = new Int16Array(l/3);
while (l--) {
if (l==-1) break;
if (buffer[l]*0xFFFF > 32767)
buf[l] = 32767;
elseif (buffer[l]*0xFFFF < -32768)
buf[l] = -32768;
else
buf[l] = buffer[l]*0xFFFF;
}
return buf.buffer;
}
如果我之前实现了gainNode(),则剪切效果不易察觉.但这不是一种理想的方式,因为目的是在每个麦克风中都有效.在这个Matlab图中可以看到剪切效果:
解决方法
取而代之的是解决方案:
while (l--) {
s = Math.max(-1,Math.min(1,samples[l]));
buf[l] = s < 0 ? s * 0x8000 : s * 0x7FFF;
//buf[l] = buffer[l]*0xFFFF; //old //convert to 16 bit
}
}
现在,这些记录听起来很完美,Matlab也是如此.

html5 – Firefox 25和AudioContext createJavaScriptNote不是一个函数
Firefox 25说要带来Web Audio,但似乎缺少一些重要的功能 – createJavaScriptNode.
我正在尝试构建一个分析器但是我在控制台中得到错误,createJavaScriptNode不是一个函数.
演示 – http://jsbin.com/olugOri/3/edit
解决方法
您可以尝试使用createscriptprocessor. Firefox仍未获得正确的值,但至少该错误不再存在.
演示 – http://jsbin.com/olugOri/4/edit
编辑:(评论中重要讨论的更多可见性)
如果媒体遵守Same-Origin Policy,Firefox确实支持MediaElementSource,但是当尝试使用来自远程源的媒体时,Firefox不会产生错误.
规范并不是真正具体(双关语),但我被告知这是一个预期的行为,问题实际上是Chrome …这是Blink实现(Chrome,Opera)need to be updated to require CORS.
MediaElementSource Node and Cross-Origin Media Resources:
From: Robert O'Callahan <robert@ocallahan.org>
Date: Tue,23 Jul 2013 16:30:00 +1200
To: "public-audio@w3.org" <public-audio@w3.org>
HTML media elements can play media resources from any origin. When an
element plays a media resource from an origin different from the page’s
origin,we must prevent page script from being able to read the contents of
the media (e.g. extract video frames or audio samples). In particular we
should prevent scriptprocessorNodes from getting access to the media’s
audio samples. We should also information about samples leaking in other
ways (e.g. timing channel attacks). Currently the Web Audio spec says
nothing about this.
I think we should solve this by preventing any non-same-origin data from
entering Web Audio. That will minimize the attack surface and the impact on
Web Audio.
My proposal is to make MediaElementAudioSourceNode convert data coming from
a non-same origin stream to silence.
如果这个提议符合规范,那么开发人员几乎不可能意识到他的MediaElementSource无法正常工作的原因.就像现在一样,在< audio>上调用createMediaElementSource(). Firefox 26 actually stops the <audio>
controls from working at all中的元素并且不会抛出任何错误.
使用来自远程原点的音频/视频数据可以做些什么危险的事情?一般的想法是,如果不将同源策略应用于MediaElementSource节点,一些恶意javascript可以访问只有用户应该访问的媒体(会话,VPN,本地服务器,网络驱动器)并发送其内容 – 或一些表示它 – 对攻击者.
默认情况下,HTML5媒体元素没有这些限制.您可以使用< audio>,< img>或< video>在所有浏览器中添加远程媒体.元素.只有当您想要从这些远程资源中操作或提取数据时,才会发起同源策略.
[It’s] for the same reason that you cannot dump image data cross-origin via <canvas>
: media may contain sensitive information and therefore allowing rogue sites to dump and re-route content is a security issue. – 07005

html5 – 在Javascript中使用Web Audio API的本地文件
我正在使用Web Audio API在iPhone游戏上获得声音。问题是这个程序完全是客户端。我想将我的mp3存储在本地文件夹中(而不是用户输入驱动),所以我不能使用XMLHttpRequest来读取数据。我正在研究使用FileSystem,但Safari不支持它。
有什么办法吗?
编辑:感谢以下回复。不幸的是,Audio API对于游戏来说是非常慢的。我有这个工作,延迟只会使用户体验不可接受。为了澄清,我需要的是如此 –
var request = new XMLHttpRequest();
request.open('GET','file:///./../sounds/beep-1.mp3',true);
request.responseType = 'arraybuffer';
request.onload = function() {
context.decodeAudioData(request.response,function(buffer) {
dogBarkingBuffer = buffer;
},onError);
}
request.send();
但这给我的错误 –
XMLHttpRequest无法加载文件:///sounds/beep-1.mp3。只有HTTP支持交叉原始请求。
未捕获错误:NETWORK_ERR:XMLHttpRequest异常101
通过阅读本地文件了解安全风险,但是在您自己的域内肯定可以吗?
解决方法
我有同样的问题。我发现这个非常简单的解决方案。
JS:
audio_file.onchange = function(){
var files = this.files;
var file = URL.createObjectURL(files[0]);
audio_player.src = file;
audio_player.play();
};
HTML:
<input id="audio_file" type="file" accept="audio/*" />
<audio id="audio_player" />
你可以在这里测试:
http://jsfiddle.net/Tv8Cm/
今天的关于javascript – Web Audio API:noteOn后noteOff不工作?的分享已经结束,谢谢您的关注,如果想了解更多关于ASP.NET WebApi DateTimeOffset序列化为Json / JavaScript(angular2)、Float32到Int16 – Javascript(Web Audio API)、html5 – Firefox 25和AudioContext createJavaScriptNote不是一个函数、html5 – 在Javascript中使用Web Audio API的本地文件的相关知识,请在本站进行查询。