zoukankan      html  css  js  c++  java
  • javaScript封装

    一、jQery是个好东西,不过要是能自己用javascript封装一些常用的函数的话,可以提高对javascript的理解

    //base.js
    //浏览器检测
    (function () {
        window.sys = {};
        var ua = navigator.userAgent.toLowerCase();    
        var s;        
        (s = ua.match(/msie ([d.]+)/)) ? sys.ie = s[1] :
        (s = ua.match(/firefox/([d.]+)/)) ? sys.firefox = s[1] :
        (s = ua.match(/chrome/([d.]+)/)) ? sys.chrome = s[1] : 
        (s = ua.match(/opera/.*version/([d.]+)/)) ? sys.opera = s[1] : 
        (s = ua.match(/version/([d.]+).*safari/)) ? sys.safari = s[1] :
        (s = ua.match(/webkit/([d.]+)/)) ? sys.webkit = s[1] : 0;
        
    //    if (/webkit/.test(ua)) sys.webkit = ua.match(/webkit/([d.]+)/)[1];
    })();
    //DOM加载,替换window.onload
    function addDOMLoad(fn) {
        
        var flag = false;
        var timer = null;
        function doReady() {
            if(flag) {
                window.clearInterval(timer);
                return ;
            }
            flag = true;
            
            fn();
        }
        if(document.addEventListener) {
            $(document).addEvent('DOMContentLoaded', function() {
                
                doReady();
                $(this).removeEvent('DOMContentLoaded', arguments.callee);
            });
            
        } else {
    
            timer = window.setInterval(function() {
                
                if(document && document.getElementById && document.getElementsByTagName && document.body) {
                    
                    doReady();
                    
                }
                
            }, 1);
    
        }
        
        
    };
    
    
    //用于每次创建一个Base对象,#seletor为id选择器,.selector为className选择器,
    //+selector为Name选择器,什么都不加tagname选择
    /**
     *selector:选择器或者DOM对象
     *pel:父DOM
     */
    function $(selector, pel) {
        //看是否穿了父元素
        if(arguments.length == 2) {
            
            pel = pel.el[0];
        }
        var base = new Base();
        //包装htmlDOM元素为Base对象
        if(arguments.length == 1 && typeof selector == "object") {
            base.el.push(selector);
            
            return base;
            
        }
        
        if(arguments.length == 1 && typeof selector == "function") {
            base.ready(selector);
            return base;
        }
        
        if(arguments.length == 0) {
            return base;
            
        }
        
        var arrStr = trim(selector).split(" ");
        base.el = [document];
        for(var n = 0; n < arrStr.length; n++) {
    
            
            base.find(arrStr[n]);
    
        
            
        }
        
        
        return base;
        
    }
    
    //Base的构造函数
    function Base() {
        this.el = [];
        
        
        
        
        
    }
    //DOM加载准备函数
    /**
     *fn:函数
     */
    Base.prototype.ready = function(fn) {
        
        addDOMLoad(fn);
        
    }
    //查找子元素
    /**
     *str:选择器
     */
    Base.prototype.find = function(str) {
        var headStr = str.charAt(0);
        var arr = [];
        var bott = null;
        var flag = false;
    
        for(var i = 0; i < this.el.length; i++) {
            var target = this.el[i];
    
            switch(headStr) {
                case "#" : //id选择器
                    
                    bott = (this.getById(str.substring(1)));
                    for(var j = 0; j < bott.length; j++) {
                        //查找是否有重复的元素
                        for(var n = 0; n < arr.length; n++) {
                            if(arr[n] == bott[j]) {
                                flag = true;
                                break;
                            }
                            
                        }
                        if(!flag) {
                            
                            arr.push(bott[j]);
                        }
                        
                        
                    }
                    break;
                
                case "." : //类选择器
                    
                    bott = this.getByClassName(str.substring(1), target);
                    for(var j = 0; j < bott.length; j++) {
                        //查找是否有重复的元素
                        for(var n = 0; n < arr.length; n++) {
                            if(arr[n] == bott[j]) {
                                flag = true;
                                break;
                            }
                            
                        }
                        if(!flag) {
                            
                            arr.push(bott[j]);
                        }
                        
                    }
    
                    break;
                    
                case "+" : //名称选择
                    bott = this.getByName(str.substring(1));
                    for(var j = 0; j < bott.length; j++) {
                        for(var n = 0; n < arr.length; n++) {
                            if(arr[n] == bott[j]) {
                                flag = true;
                                break;
                            }
                            
                        }
                        if(!flag) {
                            
                            arr.push(bott[j]);
                        }
                        
                    }
                    break;
                    
                default : //标签名选择器
                    
                    bott = this.getByTagName(str, target);
                    for(var j = 0; j < bott.length; j++) {
                        for(var n = 0; n < arr.length; n++) {
                            if(arr[n] == bott[j]) {
                                flag = true;
                                break;
                            }
                            
                        }
                        if(!flag) {
                            
                            arr.push(bott[j]);
                        }
    
                    }
                    break;
            
            }
            
        }
        
        this.el = arr;
        return this;
    
    }
    //通过id选择元素
    Base.prototype.getById = function(id) {
            
            
            return [(document.getElementById(id))];
    }
    
    Base.prototype.getByName = function(name) {
    
            return document.getElementsByName(name);
    }
    //通过标签名选择元素
    /**
     *tagName:标签名选择器
     *pel:父元素
     */
    Base.prototype.getByTagName = function(tagName, pel) {
            
            pel = pel || document;
    
            
            return pel.getElementsByTagName(tagName);
    }
    //类名选择函数
    /**
     *clazz:类名称
     *pel:父元素
     */
    Base.prototype.getByClassName = function(clazz, pel) {
            pel = pel || document;
            var el = pel.getElementsByTagName('*');
    
            var pattern = new RegExp("(\s|^)" + clazz + "(\s|$)");
            var arr = [];
            for(var i = 0; i < el.length; i++) {
                
                if(!!el[i].className.match(pattern)) {
                
                    arr.push(el[i]);
                }
                
                
            }
            
    
            return arr;
            
    }
    //css操作
    /**
     *attr:属性名
     *value:为此属性设值,不填为获取此属性值
     */
    Base.prototype.css = function(attr, value) {
        
        
        for(var i = 0; i < this.el.length; i++) {
            if(arguments.length == 1) {
                if(typeof attr != "object") {
                    
                    return getStyle(this.el[i],attr);
                }
                
                for(var c in attr) {
    
                    this.el[i].style[c] = attr[c];
                
                }
                return this;
            }
            
                this.el[i].style[attr] = value;
                
            
            
        }
        return this;
        
    }
    //html内容操作函数
    /**
     *value:设置html值,不填为选取html
     */
    Base.prototype.html = function(value) {
        
            for(var i = 0; i < this.el.length; i++) {
                if(arguments.length == 0) {
                    
                    return this.el[i].innerHTML;
                }
                this.el[i].innerHTML = value;
            }
            return this;
        
        
    }
    //获取DOM元素
    /**
     *index:DOM元素的下标
     */
    Base.prototype.getelByIndex = function(index) {
        if(index >= this.el.length) {
            
            throw new Error("数组超界!!!0~" + (this.el.length - 1));
        }
        
        
        return $(this.el[index]);
        
    }
    
    Base.prototype.getDOMElement = function(index) {
        if(index >= this.el.length) {
            
            throw new Error("数组超界!!!0~" + (this.el.length - 1));
        }
        
        
        return this.el[index];
        
    }
    
    
    
    //定义兼容的绑定事件函数
    /**
     *type:绑定的事件类型
     *fn:绑定的函数
     */
    Base.prototype.addEvent = function(type, fn) {
        for(var i = 0; i < this.el.length; i++) {
    
            if(typeof this.el[i].addEventListener != 'undefined') {//W3C
            
                this.el[i].addEventListener(type, fn, false);
            
            }/* else if(typeof this.el[i].attachEvent != 'undefined') {//IE,使用ie的attachEvent存在内存泄露问题,而且不能
                                                                    //解决重复绑定的问题,绑定多个函数,执行顺序反向
            //    this.el[i].attachEvent('on'+type, fn);
                
                
            }*/ else {//通用
                //this.el[i]['on'+type]=fn;
                var existsFn = false;
                if(!this.el[i].events) {
                    
                    this.el[i].events = {};
                    
                }
                if(!this.el[i].events[type]) {
                    
                    this.el[i].events[type] = [];
                    
                }
                for(var j = 0; j < this.el[i].events[type].length; j++) {
    
                    if(this.el[i].events[type][j] == fn) {
                        existsFn = true;
                        break;
                    }
                    
                }
                
                if(!existsFn) {
                    
                    this.el[i].events[type].push(fn);
                }
                
                
                this.el[i]['on' + type] = function() {
    
                    for(var n = 0; n < this.events[type].length; n++) {
                        
                        this.events[type][n]();
                    }
                    
                }
                
            }
        }
        
        return this;
        
    }
    
    
    //移除事件
    /**
     *type:事件类型
     *fn:绑定的函数
     */
    Base.prototype.removeEvent = function(type, fn) {
        for(var i = 0; i < this.el.length; i++) {
            if(typeof this.el[i].removeEventListener != 'undefined') {//W3C
            
                this.el[i].removeEventListener(type, fn, false);
            
            }/* else if(typeof this.el[i].detachEvent != 'undefined') {//IE
                this.el[i].detachEvent('on'+type, fn);
                
            }*/ else {
                //this.el[i]['on'+type]=null;
                var target = this.el[i];
                if(target.events && target.events[type]) {
                    for(var j = 0; j < target.events[type].length; j++) {
                        if(target.events[type][j] == fn) {
                            
                            target.events[type].splice(j,1);
                        }
                    
                    }
                    
                }
                
            
            }
            
        }
        
        return this;
        
    }
    //运动函数,opacity以0~100传参。
    /**
     *targetAttr:json对象属性
     *duration:动画执行的过渡时间
     *运动完成后调用的函数
     */
    Base.prototype.animate = function(obj){
        for(var i = 0; i < this.el.length; i++) {
            
            obj.element = this.el[i],
                
            
            startMove(obj);
        }
        
        return this;
        
    }
    //添加类
    /**
     *clazzName:类名
     */
    Base.prototype.addClass = function(clazzName) {
        for(var i = 0; i < this.el.length; i++) {
    
            if(this.el[i].className != '') {
                
                if(!this.el[i].className.match(new RegExp("(^|\s)" + clazzName + "(\s|$)"))) {
    
                    this.el[i].className += " " + clazzName; 
                    
                }
                
                
                
            } else {
                
                this.el[i].className = clazzName;
            }
            
            
        }
        
        return this;
        
    }
    //删除类
    /**
     *clazzName:类名
     */
    Base.prototype.removeClass = function(clazzName) {
        
        for(var i = 0; i < this.el.length; i++) {
        
            this.el[i].className = this.el[i].className.replace(new RegExp("(^|\s)" + clazzName + "(\s|$)")," "); 
    
        }
        
        return this;
    }
    //添加规则
    /**
     *num:第几个样式表(即第几个link)
     *selector:选择器
     *cssText:css样式,如background-color:red
     *position:样式规则的在样式里的位置
     */
    Base.prototype.addRule = function(num, selector, cssText, position) {
        var sheet = document.styleSheets[num];
        if(sheet.insertRule) {
            
            sheet.insertRule(selector + "{" + cssText + "}", position);
            
        } else if(sheet.addRule) {
            
            sheet.addRule(selector, cssText, position);
        }
        return this;
        
    }
    //删除规则
    /**
     *num:第几个样式表(即第几个link)
     *index:要删除的样式规则的位置
     */
    Base.prototype.removeRule = function(num, position) {
        var sheet = document.styleSheets[num];
        if(sheet.deleteRule) {//w3c
            sheet.deleteRule(position);
            
        } else if(sheet.removeRule) {//ie
            sheet.removeRule(position);
            
        }
        
        return this;
        
    }
    //绑定移入移出事件
    /**
     *showFn:移入函数
     *hideFn:移出函数
     */
    Base.prototype.hover = function(showFn, hideFn) {
        
        this.addEvent('mouseover', showFn);
        this.addEvent('mouseout', hideFn);
        return this;
        
    }
    
    Base.prototype.show = function() {
        
        for(var i = 0; i < this.el.length; i++) {
            
            this.el[i].style.display = "block";
            
        }
        return this;
    }
    //隐藏对象
    Base.prototype.hide = function() {
        
        for(var i = 0; i < this.el.length; i++) {
            
            this.el[i].style.display = "none";
            
        }
        return this;
    }
    //是元素相对浏览器居中
    Base.prototype.center = function() {
    
        var viewWidth = document.documentElement.clientWidth;
        var viewHeight = document.documentElement.clientHeight;
        
        for(var i = 0; i < this.el.length; i++) {
            var boxWidth = this.el[i].offsetWidth;
            var boxHeight = this.el[i].offsetHeight;
            this.el[i].style.top = (viewHeight - boxHeight) / 2 + 'px';
            this.el[i].style.left = (viewWidth - boxWidth) / 2 + 'px';
            
        }
        
        
        return this;
        
    }
    //绑定onresize事件
    /**
     *fn:函数
     */
    Base.prototype.resize = function(fn) {
    
        window.onresize = fn;
        return this;
    }
    //绑定点击事件
    /**
     *fn:函数
     */
    Base.prototype.click = function(fn) {
        
        this.addEvent('click',fn);
        
        return this;
        
    }
    //锁定屏幕
    Base.prototype.lock = function() {
    
        for(var i = 0; i < this.el.length; i++) {
            this.el[i].style.display = "block";
            this.el[i].style.width = getInner().width + 'px';
            this.el[i].style.height = getInner().height + 'px';
            
        }
        return this;
    }
    //取消锁定
    Base.prototype.unlock = function() {
        
        for(var i = 0; i < this.el.length; i++) {
            this.el[i].style.display = "none";
            
            
        }
        return this;
        
    }
    //插件封装函数
    /**
     *functionName:将要插入的函数名
     *fn:将要插入的函数
     */
    Base.prototype.extend = function(funtionName, fn) {
        
        Base.prototype[funtionName] = fn;
        return this;
    }
    
    //拖拽函数
    /**
     *handler:作为拖动句柄的Base对象
     */
    Base.prototype.drag = function(handler) {
        var that = this;
        if(this.el.length == handler.el.length) {
            for(var i = 0; i < handler.el.length; i++) {
            handler.el[i].index = i;
            handler.el[i].onmousedown = function(e) {
                    e = e || window.event;
                    var current = that.el[this.index];
                    var topHeight = e.clientY - current.offsetTop;
                    var leftWidth = e.clientX - current.offsetLeft;
                    
                    document.onmousemove = function(evt) {
                        evt = evt || window.event;
                        var top = evt.clientY - topHeight;
                        var left = evt.clientX - leftWidth;
                        var width = current.offsetWidth;
                        var height = current.offsetHeight;
                        var windowWidth = getInner().width;
                        var windowHeight = getInner().height;
                        if(top < 0) {
                            top = 0;
                            
                        } else if(top > (windowHeight - height)) {
                            top = windowHeight - height;
                            
                        }
                        if(left < 0) {
                            
                            left = 0;
                        } else if(left > (windowWidth - width)) {
                            left = windowWidth - width;
                            
                        }
    
                        current.style.top = top + 'px';
                        current.style.left = left + 'px';
                
                        
                    }
                    
                    document.onmouseup = function() {
                    
                        document.onmousemove = null;
                            
                        document.onmouseup = null;
                    }
                
                }
                
                
            
            }
            
            
            
        } else {
            
            throw new Error("拖动元素与拖动句柄不一致!!!");
        }
        return this;
        
    }
    //获取属性和设置属性
    /**
     *attr:属性名
     *value:属性值,可选
     */
    Base.prototype.attr = function(attr, value) {
        
        if(arguments.length == 1) {
            return this.el[0].attr;
            
        }
        
        for(var i = 0; i < this.el.length; i++) {
            
            this.el[i].attr = value;
        }
        return this;
    }
    //选取下一个元素
    Base.prototype.next = function() {
        for(var i = 0; i < this.el.length; i++) {
            if(this.el[i].nextSibling == null) {
    
    
                throw new Error("没有找到元素!!!");
                
            } else {
                while(this.el[i].nextSibling.nodeType == 3) {
                    
                    this.el[i] = this.el[i].nextSibling;
                }
                this.el[i] = this.el[i].nextSibling;
                if(this.el[i] == null) {
                    throw new Error("没有找到元素!!!");
                    
                }
            }
            
        }
        return this;
    }
    //控制移动框的位置
    Base.prototype.controllDrag = function() {
        
        for(var i = 0; i < this.el.length; i++) {
                if(this.el[i].offsetTop > getInner().height - this.el[i].offsetWidth) {
                    
                    this.el[i].style.top = getInner().height - this.el[i].offsetHeight + "px";
                } else if(this.el[i].offsetTop < 0){
                    this.el[i].style.top = 0;
                    
                }
                if(this.el[i].offsetLeft > getInner().width - this.el[i].offsetWidth) {
                    
                    this.el[i].style.left = getInner().width - this.el[i].offsetWidth + "px";
                } else if(this.el[i].offsetLeft < 0) {
                    
                    this.el[i].style.left = 0;
                }
                
            }
    }
    
    //切换状态函数
    Base.prototype.toggle = function() {
        var args = arguments;
        for(var i = 0; i < this.el.length; i++) {
            
            (function(element) {
                var count = 0;
                $(element).addEvent('click', function() {
                args[count++ % args.length].call(element);
                
                });
            })(this.el[i]);
            
            
        }
        
    }
    //绑定事件
    /**
     *type:事件类型
     *fun:函数
     */
    Base.prototype.bind = function(type, fun) {
        this.addEvent(type, fun);
        return this;
        
    }
    
    //获取表单元素
    /**
     *name:表单元素的name
     */
    Base.prototype.form = function(name) {
        for(var i = 0; i < this.el.length; i++) {
            this.el[i] = this.el[i][name];
            
        }
        return this;
    }
    
    //获取表当元素的值或者设置值
    Base.prototype.value = function(value) {
        var arr = [];
        for(var i = 0; i < this.el.length; i++) {
            if(value) {
                this.el[i].value = value;
                
            } else {
                
                arr.push(this.el[i].value);
            }
            
        }
        return arr;
    }
    
    //获取元素内的文本
    Base.prototype.text = function(textContent) {
        var arr = [];
        for(var i = 0; i < this.el.length; i++) {
            if(textContent) {
                
                if(this.el[i].textContent) {
                
                    this.el[i].textContent = textContent;
                
                } else if(this.el[i].innerText){
                    
                    this.el[i].innerText = textContent;
                }
            } else {
                
                arr.push(this.el[i].textContent || this.el[i].innerText);
            }
            
        }
        return arr;
    }
    
    
    //获取出发事件的对象
    /**
     *evt:ie的事件对象
     */
    function getTarget(evt) {
        
        evt = evt || window.event;
        
        return evt.target || evt.srcElement;
        
    }
    
    //取得window浏览器的内部大小
    
    function getInner() {
        if(window.innerWidth) {
            return {
                window.innerWidth,
                height:window.innerHeight
                
            };
            
        } else {
            
            return {
                document.documentElement.clientWidth,
                height:document.documentElement.clientHeight
                
            };
        }
        
    }
    
    //运动框架函数
    /**
     *obj:对象,以下为obj内的属性
     *element:将要运动的对象
     *targetAttr:需要做出变化的css属性
     *duration:过渡时间
     *fn:运动完成后调用的函数
     *isBuffer:是否使用缓冲动画
     */
    function startMove(obj){
        if(!obj.duration || obj.duration == 0) {
            
            obj.duration = 30;
        }
        clearInterval(obj.element.timer);
        var attrValue;
        obj.element.timer = setInterval(function(){
            var flag = true;
            
            for(var c in obj.targetAttr){
                if(c == 'opacity') {
                    attrValue = getStyle(obj.element,c) * 100;
                } else {
                    attrValue = parseInt(getStyle(obj.element,c));
                    
                }
                if(obj.isBuffer == true) {
                    //js中if与for没有作用域
                    var speed = (obj.targetAttr[c] - attrValue) / 10;
                    
                    
                } else if(obj.targetAttr[c] > attrValue) {
                    speed = 10;
                    
                } else {
                
                    speed = -10;
                }
                
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
    
                if(obj.isBuffer == true) {
                    if(Math.abs(attrValue - obj.targetAttr[c]) < Math.abs(speed)) {
                        obj.element.style[c] = obj.targetAttr[c];
                        
                    }
                    if(attrValue != obj.targetAttr[c]) {
                        flag = false;
                        if(c == 'opacity') {
                            obj.element.style[c] = (attrValue + speed) / 100;
                            obj.element.style.filter = 'alpha(opacity:' + (attrValue+speed) + ')';
                        } else {
                            obj.element.style[c] = attrValue + speed + 'px';
                        }
                    }
                    
                } else if(Math.abs(attrValue - obj.targetAttr[c]) < Math.abs(speed)) {
                    flag = true;
                    obj.element.style[c] = obj.targetAttr[c];
                } else {
                    flag = false;
                    obj.element.style[c] = attrValue + speed + 'px';
                    
                }
                
            }
            
            if(flag == true) {
                clearInterval(obj.element.timer);
                if(obj.fn) {
                    obj.fn();
                }
            }
            
        },obj.duration);
        
    }
    //获得计算后的样式
    /**
     *el:需要获取属性的对象
     *attr:属性
     */
    function getStyle(el,attr){
        if(window.currentStyle || el.currentStyle) {
            return window.currentStyle || el.currentStyle[attr];
        } else if(window.getComputedStyle){
            return getComputedStyle(el,null)[attr];
        }
    }
    //获取滚动条滚动的距离
    function getDocumentScroll() {
        
        return {
            top:document.documentElement.scrollTop || document.body.scrollTop,
            left:document.documentElement.scrollLeft || document.body.scrollLeft
        }
        
    }
    
    //扩张IE中的event
    /**
     *evt:ie的事件对象
     */
    function eventWapper(evt) {
        evt.preventDefault = preventDefault;
        
        evt.stopPropagation = stopPropagation;
        
        return evt;
    }
    
    //ie组织默认行为
    function preventDefault() {
    
        this.returnValue = false;
    }
    //ie组织冒泡
    function stopPropagation() {
            
        this.cancelBubble=true;
    }
    //去掉字符串的左右的空格,并把字符间的多个空格,改成一个空格
    /**
     *str:需要做空格处理的字符串
     */
    function trim(str) {
        str = str.replace(/(^s*)|(s*$)/g, "");
        str = str.replace(/s+/g, " ");
        return str;
    }
    
    function createXHR() {
        if (typeof XMLHttpRequest != 'undefined') {
            return new XMLHttpRequest();
        } else if (typeof ActiveXObject != 'undefined') {
            var version = [
                                        'MSXML2.XMLHttp.6.0',
                                        'MSXML2.XMLHttp.3.0',
                                        'MSXML2.XMLHttp'
            ];
            for (var i = 0; version.length; i ++) {
                try {
                    return new ActiveXObject(version[i]);
                } catch (e) {
                    //跳过
                }    
            }
        } else {
            throw new Error('您的系统或浏览器不支持XHR对象!');
        }
    }
    
    //名值对转换为字符串
    function params(data) {
        var arr = [];
        for (var i in data) {
            arr.push(encodeURIComponent(i) + '=' + encodeURIComponent(data[i]));
        }
        return arr.join('&');
    }
    
    
    //封装ajax
    function ajax(obj) {
        var xhr = createXHR();
        obj.url = obj.url + '?rand=' + Math.random();
        obj.data = params(obj.data);
        if (obj.method === 'get') obj.url += obj.url.indexOf('?') == -1 ? '?' + obj.data : '&' + obj.data;
        if (obj.async === true) {
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    callback();
                }
            };
        }
        xhr.open(obj.method, obj.url, obj.async);
        if (obj.method === 'post') {
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.send(obj.data);    
        } else {
            xhr.send(null);
        }
        if (obj.async === false) {
            callback();
        }
        function callback() {
            if (xhr.status == 200) {
                obj.success(xhr.responseText);            //回调传递参数
            } else {
                alert('获取数据错误!错误代号:' + xhr.status + ',错误信息:' + xhr.statusText);
            }    
        }
    }
  • 相关阅读:
    android学习计划
    Android源码下载及开发环境的搭建
    I2C总线时序
    I2C原理和实例
    sql语句获取字段扩展属性
    浏览器兼容:火狐不支持webq格式图片
    js节流函数中的参数传递
    分享插件使用
    图片等比例自适应填充
    window.event在IE和Firefox的异同
  • 原文地址:https://www.cnblogs.com/honger/p/5985908.html
Copyright © 2011-2022 走看看