Actually,simplicity is not simple

在页面中加载jQuery

又是N久没更新过了,懒啊!

常要测试些代码,又或者要对页面中做些操作,但发现页面中没有引入jQuery,今天写了个简单的东西让页面方便快速的加载jQuery

方法很简单将下面的链接拖到你的收藏夹中就可以了,以后想要在当前页面加载jQuery,直接按一下就可以了,如果页面中已经加载了jquery则不会去加载并且显示当前jQuery的版本。

灵感来源由Firefox的一个插件fireQuery,但它只能在FF下使用。

代码也没什么,放这了,别见笑:

(function(window, document, undefined){
    var div = document.createElement('div')
        , body = document.getElementsByTagName('body')[0];
    if(window.jQuery === undefined){
        var ga=document.createElement('script');
        ga.type='text/javascript';
        ga.async=true;
        ga.src='https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js';
        body.insertBefore(ga, body.firstChild);
        if (ga.addEventListener) {
            ga.addEventListener('load', callback, false);
        } else { // for IE6-8
            ga.attachEvent('onreadystatechange', function() {
                var rs = ga.readyState;
                if (rs === 'loaded' || rs === 'complete') {
                    callback();
                }
            });
        }
    } else {
        callback();
    }

    function callback(){
        div.innerHTML = '<div style="font:700 40px/46px Arial,Verdana;position:fixed;padding:5px 10px;margin:0;z-index:1001;color:#444; background-color:#FFFB00;opacity:0.8;">This page already using jQuery v'+ jQuery.fn.jquery +'</div>';
        var el = div.firstChild;
        body.appendChild(el);
        el.style.left = Math.floor(((window.innerWidth || document.documentElement.clientWidth) - el.clientWidth) / 2) + 'px';
        el.style.top = Math.floor(((window.innerHeight || document.documentElement.clientHeight) - el.clientHeight) / 2) + 'px';
        setTimeout(function(){
            body.removeChild(el);
        },3000);
    }
})(window, document)

innerHTML操作的改进

function asyncInnerHTML(HTML, callback) {
    var temp = document.createElement('div'),
        frag = document.createDocumentFragment();
    temp.innerHTML = HTML;
    (function(){
        if(temp.firstChild){
            frag.appendChild(temp.firstChild);
            setTimeout(arguments.callee, 0);
        } else {
            callback(frag);
        }
    })();
}

看看上面的代码,对平常我们用的innerHTML做了些许改进,不管在用处上还是浏览器呈现上都有所进化。

  • 使用setTimeout防止出现浏览器堵塞现象(及长时间没反应,突然一下子呈现的现象)
  • 使用DocumentFragment提升效率

再来看下它的作用吧

var htmlStr = '<div><p>...</p><p>...</p><div><div>...</div>';
asyncInnerHTML(htmlStr, function(fragment){
    // You can treat 'fragment' as a regular node.
    document.body.appendChild(fragment);
});

我想这已经很明了了,这函数强于 string 转 DOM 并得到转化后的DOM对象,做点记录方便以后使用吧!

这函数的出处看这里

用JS动态监听CSS加载

周五时有个工作时需求等CSS加载完后后再执行些JS代码,但发现使用onload在Firefox chrome下不行但IE8下却可以。

第一次发现IE也有让我省心的时候啊!

问谷大叔得知研究这问题的人还挺多的:

  • 在射雕的lab中发现有两个测试 load js css css preload,讲得挺多的,而且在其seajs中已经运用上了,拜之~~
  • 在国外一相当大的专业问答网站中找到相同问题,也有不少人给出了解答 javascript capturing load event on link。主要讲到两种方案:
    1. 使用settimeout循环判断不同浏览器中当CSS加载完或失败时的特性,射雕使用的方案也是这种,但特性有所不同;
    2. 方案挺有意思的,同时创建link、img标签并将CSS的URL同时赋于两个标签,用img标签的onerror事件做为加载监听器,但这种方案会产生两个请求,并且img标签所发出的请求会标注不支持gzip。
  • Cross Browser Stylesheet Preloading中也提供了一解决方案,但代码是基于mootools写的,最重要的一点是延时判断link标签的ownerNode或owningElement属性,没用过这两个属性,不懂!!!

继续问谷大叔找到关于ownerNode(返回节点与此相关联的样式表文件的。)以及owningElement(返回附加到元素节点上的属性)的定义。

this.link.id = this.getID(); // 创建link标签时给标签加上了ID属性
// 注意 这里的file = document.styleSheets[0]; 或 document.getElementsByTagName('link')[0].sheet;
var owner = file.ownerNode ? file.ownerNode : file.owningElement;
if(owner && owner.id == this.getID()) {
    this._onready();
    return;
}

并且看到了对link标签事件支持情况:

IE6-IE9、opera  都支持link标签的 onload  onerror事件
firefox chrome  safari 都不支持link标签的 onload  onerror事件
2011-06-15Develop
none
没有评论

IE & FF 中的几处JS差异

尽管那需要用长串的、沉闷的不同分支代码来应付不同浏览器的日子已经过去,有的时候还是有必要做一些简单的区分和目标检测来确保某块代码能在用户的机器上正常运行。

这篇文章就是作者来介绍7个在IE和Firefox中不同的JavaScript句法。

  1. CSS “float” 值

访问一个给定CSS 值的最基本句法是:object.style.property,使用驼峰写法来替换有连接符的值,例如,访问某个ID为”header”的

<

div>的background-color值,我们使用如下句法:

document.getElementById("header").style.backgroundColor= "#ccc";

但由于”float”这个词是一个JavaScript保留字,因此我们不能用 object.style.float来访问,这里,我们可以在两种浏览器中这么做:

IE的语法:

document.getElementById("header").style.styleFloat = "left";

Firefox的语法:

document.getElementById("header").style.cssFloat = "left";
  1. 元素的推算样式

JavaScript可以使用object.style.property句法,方便地在外部访问和修改某个CSS样式,但其限制是这些句法只能取出已设的行内样式或者直接由JavaScript设定的样式。并不能访问某个外部的样式表。为了访问元素的”推算”样式,我们可以使用下面的代码:

IE的语法:

var myObject = document.getElementById("header"); 
var myStyle = myObject.currentStyle.backgroundColor;

Firefox的语法:

var myObject = document.getElementById("header");
var myComputedStyle = document.defaultView.getComputedStyle(myObject, null); 
var myStyle = myComputedStyle.backgroundColor;
  1. 访问元素的”class”

像”float”一样,”class”是JavaScript的一个保留字,在这两个浏览器中我们使用如下句法来访问”class”。

IE的语法:

var myObject = document.getElementById("header");
var myAttribute = myObject.getAttribute("className");

Firefox的语法:

var myObject = document.getElementById("header");
var myAttribute = myObject.getAttribute("class");

This syntax would also apply using the setAttribute method.

See a demo page that demonstrates these two different syntaxes

  1. 访问

就第3点中所提到的,我们同样需要使用不现的句法区分来访问

IE的语法:

var myObject = document.getElementById("myLabel"); 
var myAttribute = myObject.getAttribute("htmlFor");

Firefox的语法:

var = document.getElementById("myLabel");
var myAttribute = myObject.getAttribute("for");
  1. 获取鼠标指针的位置

计算出鼠标指针的位置对你来说可能是非常少见的,不过当你需要的时候,在IE和Firefox中的句法是不同的。这里所写出的代码将是最最基本的, 也可能是某个复杂事件处理中的某一个部分。但他们可以解释其中的异同点。同时,必须指出的是结果相对于Firefox,IE会有更在的不同,这种方法本身 就是有BUG的。通常,这种不同可以用”拖动位置”来得到补偿,但,那是另外一个主题的文章了: ) !

IE的语法:

var myCursorPosition = [0, 0];
myCursorPosition[0] = event.clientX;
myCursorPosition[1] = event.clientY;

Firefox的语法:

var myCursorPosition = [0, 0]; 
myCursorPosition[0] = event.pageX;
myCursorPosition[1] = event.pageY;
  1. 获取可见区域、窗口的大小

有时,我们会需要找到浏览器的可视位置的大小,通常我们称之为”可见区域”。

IE的语法:

var myBrowserSize = [0, 0]; 
myBrowserSize[0] = document.documentElement.clientWidth; 
myBrowserSize[1] = document.documentElement.clientHeight;

Firefox的语法:

var myBrowserSize = [0, 0];
myBrowserSize[0] = window.innerWidth;
myBrowserSize[1] = window.innerHeight;
  1. Alpha 透明

好吧,这并不是一个JavaScript句法问题,而是源自于CSS的Alpha透明。但当某个物体需要淡入/出则需要JavaScript来表 现,这是通过访问CSS的Alpha透明设置来完成的,通常在一个循环中完成。你需要通过来修改的JavaScript的代码如下::

IE的语法:

#myElement { filter: alpha(opacity=50); }

Firefox的语法:

#myElement { opacity: 0.5; }

IE的语法:

var myObject = document.getElementById("myElement");
myObject.style.filter = "alpha(opacity=80)";

Firefox的语法:

var myObject = document.getElementById("myElement");
myObject.style.opacity =   "0.5";

CSS命名的那点事

又是很久没写过东东了,今天在看张鑫旭blog中的《精简高效的CSS命名准则/方法》时,产生了不小的共鸣。

CSS的命名我使用过很多种方式:

  • 用功能名的拼音。感觉很二,也很长,写多了很快就不明白是什么了,因为我拼音也用得不多,打字一直用五笔,写多了就无法很快了解当前样式的意思。
  • 用功能名的对应英文词组组合。到是不会让自己感觉很二,但我自己的英文菜得无法言语,所以在写CSS时常常开着google的翻译网页,呵呵,不怕各位笑话。
  • 基于CSS属性命名些常用的样式。这是在我写CSS一段时间后慢慢形成的习惯,因为记忆方便,不用写个样式就去想下应该命名成什么。如果有独特需求也只需联合父层就可以进行独特需求的设置了。在我看来这种写法是将CSS属性进行最小单元封装的过程,但这样做也不是没有问题,后面会说到。

但我却从来没有总结过,惭愧啊~~

现在我接到项目一开始很是喜欢在头上写些样式,都成了我写页子的习惯了:

.cRed{color:#F00;}
.tC{text-align:center;}
.b{font-weight:700;}
.....

在写功能模块时给它一个ID,之后的样式就像

#mod .b{...}
#mod .tC{}

这样CSS不会有很多层,样式名也很短,我也不用在每次加入CSS时为想个样式名而花时间了。

这样的命名用起来很舒服,但也不是一点问题没有,如后期的维护上,需求改变时……,对面大量HTML源文件或被JS、PHP等语言引入到代码中的结构,修改它们是个痛苦的过程。

想当初CSS被疯狂提倡时的理由之一就是无需对HTML进行大规模的修改只需改个CSS的性能就能完成所要的。但这种方法进行的却是对CSS属性进行最小单元的封装,样式名称与属性名有着直接的联系,如果要进行修改,改CSS的性能就有点不妥了,让样只能让CSS看起来更加混乱。

所以使用这种方法需要有个平衡点,在定义模块结构时我不会使用这种方式,对于模块的建立我喜欢这样写:

<div id="modName" class="XXX">
    <div class="head">
        <div class="tit">
            <h3>模块名</h3>
        </div>
    </div>
    <div class="con"></div>
    <div class="floot"></div>
</div>

这里面的样式 head tit con floot在最外层都不会定义,起始定义点是#modName .head这样的,当然根据需求结构会有些不同,但基本是这样的。

所以我现写的CSS层级一般是两层,最多也就是四层。