JS闭包!function(){}()

叹号后面跟函数!function
和加号后面跟函数+function
都是跟(function(){})();这个函数是一个意思,都是告诉浏览器自动运行这个匿名函数的,因为!+()这些符号的运算符是最高的,所以会先运行它们后面的函数

H5移动端调用浏览器Geolocation方法获取手机gps经纬度方法

具体请看下面代码:

<script>
    var x=document.getElementById("demo");
    function getLocation() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(showPosition,showError);
        } else {
            x.innerHTML="当前浏览器不支持Geolocation";
        }
    }
    function showPosition(position) {
        x.innerHTML="Latitude: " + position.coords.latitude + "<br />Longitude: " + position.coords.longitude;
    }
    function showError(error) {
        switch(error.code) {
            case error.PERMISSION_DENIED:
                alert("User denied the request for Geolocation.")
                break;
            case error.POSITION_UNAVAILABLE:
                alert("Location information is unavailable.")
                break;
            case error.TIMEOUT:
                alert("The request to get user location timed out.")
                break;
            case error.UNKNOWN_ERROR:
                alert("An unknown error occurred.")
                break;
        }
    }
    </script>

 

ie8 及以下不支持 array.map 的解决方式

今天做项目的时候,无意乱用map方法,chrome和firefox支持,但是IE8不支持,网上找了一下有木有解,发现国外有大神写了array.prototype的map扩展

JS源码:

success:function(res){
    $('#busicode').find('.select-loading').text('请选择');
        res.data.map(function(element){
        $('#busicode').append('<option value="'+element.busicode+'">'+element.businame+'</option>');
    });
}

array.prototype.map方法:

// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.com/#x15.4.4.19
if (!Array.prototype.map) {
    Array.prototype.map = function(callback, thisArg) {

        var T, A, k;

        if (this == null) {
            throw new TypeError(" this is null or not defined");
        }

        // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
        var O = Object(this);

        // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
        // 3. Let len be ToUint32(lenValue).
        var len = O.length >>> 0;

        // 4. If IsCallable(callback) is false, throw a TypeError exception.
        // See: http://es5.github.com/#x9.11
        if (typeof callback !== "function") {
            throw new TypeError(callback + " is not a function");
        }

        // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
        if (thisArg) {
            T = thisArg;
        }

        // 6. Let A be a new array created as if by the expression new Array(len) where Array is
        // the standard built-in constructor with that name and len is the value of len.
        A = new Array(len);

        // 7. Let k be 0
        k = 0;

        // 8. Repeat, while k < len
        while(k < len) {

            var kValue, mappedValue;

            // a. Let Pk be ToString(k).
            //   This is implicit for LHS operands of the in operator
            // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
            //   This step can be combined with c
            // c. If kPresent is true, then
            if (k in O) {

                // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
                kValue = O[ k ];

                // ii. Let mappedValue be the result of calling the Call internal method of callback
                // with T as the this value and argument list containing kValue, k, and O.
                mappedValue = callback.call(T, kValue, k, O);

                // iii. Call the DefineOwnProperty internal method of A with arguments
                // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
                // and false.

                // In browsers that support Object.defineProperty, use the following:
                // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });

                // For best browser support, use the following:
                A[ k ] = mappedValue;
            }
            // d. Increase k by 1.
            k++;
        }

        // 9. return A
        return A;
    };
}

参考来源:GO >>

 

原生JS快速获取和更改标签里面的属性值

今天看代码的时候遇到一个原生JS的知识点,下图的

code1  code2

this.id.split('-')[1]

/* 
这里的this是点击那个<button></button>整个对象代码
假设点击了第一个default的<button>
this.id = "switcher-default"
this.id.split('-') = [switcher,default]
this.id.split('-')[1] = "default"
*/

原生javascript扩展知识:

getAttribute:取得属性;
setAttribute:设置属性;

a[0].id
//"header"
a[0].className
//"Xman"
a[0].getAttribute('attrName');
//获取attrName的值,例如 title、style、data-XX等
a[0].setAttribute('attrName','value');
/*
设置attrName的值,在value处输入对应的值,这个value是直接覆盖原来的值,如果你设置了style,如果里面已经有一个样式了,你要加个背景就要在原有的值上加上背景的样式。
例:font-size:16px; 增加背景:font-size:16px; background:#ccccccc;
*/

 

console.log

code3

最近做的一些JS代码

一、立即执行匿名函数,详细内容请参考:JavaScript中的立即执行函数表达式

方法一:

(function(){ 
 console.log("test");
})();

方法二:

(function(){ 
 console.log("test");
}());

jQuery和一些流行库的方法:

(function( window, undefined ) {
 // code here
}) ( window );

其他方法:

// 如果本身就是expression,那么根本不需要做任何处理
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();

// 如果你不在乎返回值,可以这么做
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();

// 还有更奇葩的方式,但是不知道性能如何,来自
// http://twitter.com/kuvos/status/18209252090847232
new function(){ /* code */ }
new function(){ /* code */ }()

二、根据URL来判断当前页面用的语言,调用预设好的样式;

var pathname = location.pathname;

if (pathname.indexOf("/ru/") === 0) {
 document.getElementsByClassName("navigation")[0].className = "navigation lang_ru";
} else if (pathname.indexOf("/es/") === 0) {
 document.getElementsByClassName("navigation")[0].className = "navigation lang_es";
} else if (pathname.indexOf("/it/") === 0) {
 document.getElementsByClassName("navigation")[0].className = "navigation lang_it";
} else if (pathname.indexOf("/fr/") === 0) {
 document.getElementsByClassName("navigation")[0].className = "navigation lang_fr";
} else if (pathname.indexOf("/pt/") === 0) {
 document.getElementsByClassName("navigation")[0].className = "navigation lang_pt";
} else if (pathname.indexOf("/de/") === 0) {
 document.getElementsByClassName("navigation")[0].className = "navigation lang_de";
}

三、内部函数可以使用外部的$(this)对象,直接在后面加.bind(this)

!function(){
 var hoverTimer, outTimer;
 $(document).on('mouseenter', '.myac', function(){
 clearTimeout(outTimer);
 hoverTimer = setTimeout(function(){
 $(this).addClass('myac_show').find('.myac_list').slideDown(); 
 }.bind(this), 300)
 }
 )
 $(document).on('mouseleave', '.myac', function(){
 clearTimeout(hoverTimer);
 outTimer = setTimeout(function(){
 $(this).removeClass('myac_show').find('.myac_list').slideUp('fast');
 }.bind(this), 150)
 }
 )
}()

四、ajax替换html内容后,原先写的时间无效:

修改前代码:

 $('.myac').hover(
     function(){
     $(this).find('.myac_list').slideDown();
     $(this).addClass('myac_show');
 },
 function(){
     $(this).find('.myac_list').slideUp();
     $(this).removeClass('myac_show');
 });

解决方法一:

ajax替换html内容不能替换改变.myac层的内容,可以替换修改 里面的子元素内容,例如.myac_list的;因为.myac拿来触发事件了;

解决方法二:

把.hover()事件用.on()绑定 document,具体代码如下:

$(document).on('mouseenter', '.myac', function(){
         /*function code*/
     }
 );
 $(document).on('mouseleave', '.myac', function(){
         /*function code*/
     }
 );