我为相当新的CSS calc()规则编写了一个故障回退。它工作很好,但我想在生产环境中使用它,并希望得到反馈。请推荐任何关于奇怪/错误代码、可能的优化或减少代码大小的方法。
// CSS calc() replacement
function calcfailback(){
var d = document.createElement('div');
var _body = document.getElementsByTagName('body') [0];
_body.appendChild(d);
d.style.visibility = 'hidden';
d.style.width = "-webkit-calc(10px)";
d.style.width = "-o-calc(10px)";
d.style.width = "-moz-calc(10px)";
d.style.width = "calc(10px)";
var newwidth = d.offsetWidth;
if (newwidth == "10"){}
else{
function resize(){
document.getElementById('content').style.height = window.innerHeight - 40 + 'px';
document.getElementById('content').style.width = window.innerWidth - 300 +'px';
document.getElementById('sidebar').style.height = window.innerHeight - 40 + 'px';
};
resize();
window.onresize = function (){
resize();
}
};
_body.removeChild(d)
};
window.onload = calcfailback;发布于 2012-08-07 01:35:16
我不太熟悉CSS,但我对JS相关部分有几点评论:
我把这叫做calcFailback或calc_failback。
每个作用域只有一个var语句,这是相当标准的做法。这是因为JS在本质上将所有变量声明拉到一个作用域的顶部。
function f() {
var x = 5;
if (x == 5) {
var y = 10;
}
}实际上相当于:
function f() {
var x = 5;
var y;
if (x == 5) {
y = 10;
}
}由于这个原因(或者更重要的是,如果您忘记了它被默默地解释为这一点,可能会导致奇怪的bug),一个相当普遍的做法是,每个作用域只使用一个var声明:
function f() {
var x = 5,
y;
...
}if (newwidth == "10") {}那是毫无意义的。在某些边界情况下,有一个空分支可能很有用,但是对于像这样的琐碎的分支,只需:
if (newwidth != "10") { ... }我会使用下划线或camelCase,这样就有了某种视觉上的词语分离。new_width和newWidth比newwidth更容易阅读和理解。
调用其他函数的
。
var x = function () { f(); };所有这些都是创建一个绑定到x的函数,当调用该函数时,调用f。
除非您特别希望这样做以隐藏调用上下文,否则通常最好将其编写为:
var x = f;在这种情况下,x()仍然调用f,它只是在没有间接层的情况下这样做。
不过,从技术上讲,这是不同的。没有上下文的函数默认为window对象作为上下文(或严格模式下的undefined )。
这意味着f中的this可能是不同的,这取决于x的调用方式。
例如:
function f() {
console.log(this);
}
var x = function() { f(); },
obj = {foo: "bar"};
x.call(obj); //The console.log will output either window or undefined depending on strict mode
//('this' inside of the wrapper function, however, would be obj)与之相比:
function f() {
console.log(this);
}
var x = f,
obj = {foo: "bar"};
x.call(obj); //The console.log will output obj (in other words, 'this' inside of 'f' would be 'obj'当您分配window.onload和window.onresize属性时,您可能需要编写旧的处理程序。
“但这是我页面上唯一的脚本!”你说。
这是目前唯一的剧本。
为了避免将来出现一些奇怪的错误,我可能会使用一个简单的函数来进行堆栈绑定:
function bindEvt(target, evt, func) {
var prev = target[evt];
if (typeof prev !== "function") {
target[evt] = func;
} else {
target[evt] = function() {
prev.apply(this, Array.prototype.slice.call(arguments));
func.apply(this, Array.prototype.slice.call(arguments));
};
}
return target[evt];
}它的用途如下:
function f() { ... };
bindEvt(window, "onresize", f);(注:这实际上应该被用作一个想法而不是一个实际的实现。我完全相信这个函数至少有一个主要问题。)
我可能会写成这样:
// CSS calc() replacement
function calcFailback(){
var d = document.createElement('div'),
_body = document.getElementsByTagName('body')[0],
newWidth;
//functions are actually hoisted too, though in a silenty different way
function resize() {
document.getElementById('content').style.height = window.innerHeight - 40 + 'px';
document.getElementById('content').style.width = window.innerWidth - 300 +'px';
document.getElementById('sidebar').style.height = window.innerHeight - 40 + 'px';
}; //You will not usuaully see a ; here. There's nothing wrong with it though.
_body.appendChild(d);
d.style.visibility = 'hidden';
d.style.width = "-webkit-calc(10px)";
d.style.width = "-o-calc(10px)";
d.style.width = "-moz-calc(10px)";
d.style.width = "calc(10px)";
newWidth = d.offsetWidth;
if (newWidth != "10") { //I might use either !== "10" or !== 10 if you know the type
resize();
window.onresize = resize;
//I might consider inlining the function defition since it's a simple function.
//You could use a structure like:
//window.onresize = function() { ... };
//window.onresize();
//This is not the same thing as a legitimate onresize event happening though, so you'd need to be
//careful to make sure that your handler is capable of handling fake events like this.
//A bit more 'authentic' way might be:
//window.onresize.call(window); since the handler is probably (I'm not sure) called with window as the context
//This would still neglect the parameters though.
} //There was no reason for the ; here
_body.removeChild(d); //This should have a ; here (mainly for styling purposes in this context, but it's a good habit for situations where it does matter)
}关于它的价值,这里有一个使用类似bindEvt函数的(非常)简单的例子:小提琴。
发布于 2012-08-07 01:51:06
泛化您的代码可能是个好主意,这样您就可以以不同的值使用它。我并不是建议您支持完整的calc()语法,但是如果您计划在多个地方使用它,那么至少使其可配置是有用的。
不过,对于您所拥有的代码,我只是有几个建议:
if (newwidth == "10"){} else替换为if (newwidth !== 10) {。与其在真实情况下什么都不做,不如切换比较,跳过其他操作。您还可以直接与数字10进行比较(使用严格相等运算符),而不是进行字符串比较。if语句中,ECMAScript中的函数声明在技术上是不合法的(它们只允许在全局范围内,或者在函数的顶层)。浏览器倾向于将其作为扩展来支持,但是它们的行为不同,并且可能导致问题,所以最好避免这种情况。函数表达式很好,所以我直接给window.onresize分配了一个匿名函数,并通过它调用了它。您还可以将函数赋值给一个变量(将function resize() {...}替换为var resize = function() {...};)。document.getElementById('content'),不如将样式对象存储在变量中并引用它。你将获得一个速度和文件大小的优势。if语句块之后不需要分号。我的结局是:
// CSS calc() replacement
function calcfailback() {
var d = document.createElement('div');
// 1
var body = document.getElementsByTagName('body')[0];
body.appendChild(d);
d.style.visibility = 'hidden';
d.style.width = "-webkit-calc(10px)";
d.style.width = "-o-calc(10px)";
d.style.width = "-moz-calc(10px)";
d.style.width = "calc(10px)";
var newwidth = d.offsetWidth;
// 2
if (newwidth !== 10) {
// 3
window.onresize = function() {
// 4
var contentStyle = document.getElementById('content').style;
contentStyle.height = window.innerHeight - 40 + 'px';
contentStyle.width = window.innerWidth - 300 +'px';
contentStyle.height = window.innerHeight - 40 + 'px';
};
window.onresize();
} // 5
body.removeChild(d);
} // 5
window.onload = calcfailback;发布于 2014-09-10 04:20:14
没有理由检查-o-前缀。Presto引擎下的Opera从来没有对calc()的支持,不管是前缀还是其他。闪烁引擎下的Opera支持它,没有前缀。
https://codereview.stackexchange.com/questions/14392
复制相似问题