键盘导航的jQuery标签键盘、标签、jQuery

2023-09-11 01:14:34 作者:没有公主命也要有女王范

如何让键盘导航左/上/右/下(像照片库)功能 jQury标签历史?演示无键盘功能在 http://dl.dropbox.com/u/6594481/标签/ index.html的的 所需要的功能: 1.键盘上/下>做出选择和CSS显示主动嵌套Ajax选项卡,从1日至去年水平 2.键盘上的左/右>变化后退/前进内容主动嵌套Ajax选项卡标签 3.多了一种选择,使主动嵌套的AJAX选项卡上的混凝土嵌套Ajax选项卡的水平光标式 阅读与http://stackoverflow.com/questions/2975003/jquery-tools-to-make-keyboard-and-cookies-feature-for-ajaxed-tabs-with-history

  / **
 * @许可
 * jQuery的工具@VERSION Tabs- UI设计的基础知识。
 *
 *无版权或许可证。做你喜欢的。
 *
 * http://flowplayer.org/tool​​s/tabs/
 *
 *日期:2008年11月
 *日期:@DATE
 * /
(函数($){

    //静态构造
    $ .tools = $ .tools || {版本:@VERSION'};

    $ .tools.tabs = {

        CONF:{
            标签:'A',
            当前:当前,
            onBeforeClick:空,
            的onClick:空,
            效果:默认,
            initialIndex:0,
            事件:点击,
            旋转:假的,

            // 1.2
            历史:假的
        },

        addEffect:函数(名称,FN){
            效果[名] = FN;
        }

    };

    VAR效果= {

        //简单的触发作用
        默认:功能(我,做){
            。this.getPanes()隐藏()EQ(我).show()。
            done.call();
        },

        / *
            组态:
                 -  fadeOutSpeed​​(正值确实淡入淡出)
                 -  fadeInSpeed
        * /
        褪色:功能(我,做){

            变种CONF = this.getConf(),
                 速度= conf.fadeOutSpeed​​,
                 窗格= this.getPanes();

            如果(速度){
                panes.fadeOut(速度);
            } 其他 {
                panes.hide();
            }

            panes.eq(我).fadeIn(conf.fadeInSpeed​​,完成);
        },

        //基本手风琴
        幻灯:功能(我,做){
            this.getPanes()效果基本show(200)。
            。this.getPanes()当量(ⅰ).slideDown(400,完成);
        },

        / **
         * AJAX效果
         * /
        AJAX:功能(我,做){
            。this.getPanes()EQ(0).load(this.getTabs()EQ(我).attr(HREF),完成);
        }
    };

    VAR瓦;

    / **
     *水平手风琴
     *
     * @ pcated德$ P $将被替换的更健壮的实现
     * /
    $ .tools.tabs.addEffect(水平,功能(我,做){

        //存储原始窗格到内存的宽度
        (!瓦特)如果{瓦特= this.getPanes()当量(0).WIDTH()。 }

        //设置当前面板的宽度为零
        。this.getCurrentPane()动画({宽度:0},函数(){$(本).hide();});

        //成长打开面板到原来的宽度
        。this.getPanes()EQ(我).animate({宽度:W},函数(){
            $(本).show();
            done.call();
        });

    });


    功能选项卡(根,paneSelector,CONF){

        无功自我=这一点,
             触发= root.add(本),
             标签= root.find(conf.tabs)
             窗格= paneSelector.jquery? paneSelector:root.children(paneSelector)
             当前;


        //确保卡和窗格被发现
        如果(!tabs.length){标签= root.children(); }
        如果(panes.length!){窗格= root.parent()找到(paneSelector)。 }
        如果(panes.length!){窗格= $(paneSelector); }


        //公共方法
        $ .extend(这一点,{
            点击:函数(I,E){

                VAR选项卡= tabs.eq(我);

                如果(typeof运算我=='字串'和;&安培; i.replace(#,)){
                    标签= tabs.filter([HREF * =+ i.replace(#,)+]);
                    I = Math.max(tabs.index(标签),0);
                }

                如果(conf.rotate){
                    VAR最后= tabs.length -1;
                    如果(I< 0){返回self.click(最后,E); }
                    如果(I>去年){返回self.click(0,E); }
                }

                如果(!tab.length){
                    如果(当前与GT; = 0){回归自我; }
                    I = conf.initialIndex;
                    标签= tabs.eq(我);
                }

                //当前标签被点击
                如果(我===电流){回归自我; }

                //可能性取消点击动作
                Ë= E || $ .Event();
                e.type =onBeforeClick;
                trigger.trigger(即[I]);
                如果(e.isDefault prevented()){返回; }

                //调用效果
                效果[conf.effect] .CALL(自我,我,函数(){

                    //的onClick回调
                    e.type =的onClick;
                    trigger.trigger(即[I]);
                });

                //默认行为
                电流= I;
                tabs.removeClass(conf.current);
                tab.addClass(conf.current);

                回归自我;
            },

            使用getconf:函数(){
                返回的conf;
            },

            getTabs:函数(){
                返回选项卡;
            },

            getPanes:函数(){
                返回窗格;
            },

            getCurrentPane:函数(){
                返回panes.eq(电流);
            },

            getCurrentTab:函数(){
                返回tabs.eq(电流);
            },

            getIndex:函数(){
                返回电流;
            },

            下一篇:函数(){
                返回self.click(当前+ 1);
            },

            preV:函数(){
                返回self.click(电流 -  1);
            }

        });

        //回调
        $每个(onBeforeClick,的onClick.split(,),功能(ⅰ,姓名){

            // 组态
            如果($ .isFunction(CONF [名])){
                $(个体经营).bind(姓名,CONF [名]);
            }

            // API
            自[名] =功能(FN){
                $(个体经营).bind(姓名,FN);
                回归自我;
            };
        });


        如果(conf.history&安培;&安培; $ .fn.history){
            $ .tools.history.init(片);
            conf.event =历史;
        }

        //设置点击操作为每个标签
        tabs.each(函数(一){
            $(本).bind(conf.event,功能(五){
                self.click(I,E);
                返回e的preventDefault()。
            });
        });

        //交叉表锚链接
        panes.find(一个[HREF = ^#])。点击(函数(五){
            self.click($(本).attr(HREF),E);
        });

        //打开最初的标签
        如果(的location.hash){
            self.click(的location.hash);
        } 其他 {
            如果(conf.initialIndex === 0 || conf.initialIndex大于0){
                self.click(conf.initialIndex);
            }
        }

    }


    // jQuery插件实现
    $ .fn.tabs =功能(paneSelector,CONF){

        //返回现有实例
        VAR EL = this.data(标签);
        如果致发光(EL){返回报; }

        如果($ .isFunction(CONF)){
            CONF = {onBeforeClick:CONF};
        }

        //设置的conf
        CONF = $ .extend({} $ .tools.tabs.conf,CONF);

        this.each(函数(){
            EL =新的选项卡($(本),paneSelector,CONF);
            $(本)的.d​​ata(标签,EL);
        });

        返回conf.api?萨尔瓦多:这一点;
    };

})(jQuery的);

/ **
 * @许可
 * jQuery的工具@VERSION史返回的AJAX应用程序按钮
 *
 *无版权或许可证。做你喜欢的。
 *
 * http://flowplayer.org/tool​​s/tool​​box/history.html
 *
 *日期:2010年3月
 *日期:@DATE
 * /
(函数($){

    无功散,IFRAME,链接,inited;

    $ .tools = $ .tools || {版本:@VERSION'};

    $ .tools.history = {

        初始化:功能(ELS){

            如果(inited){返回; }

            // IE
            如果($ .browser.msie&功放;&安培; $ .browser.version<'8'){

                //创建的iframe,是不断检查哈希变化
                如果(!IFRAME){
                    IFRAME = $(< IFRAME />中)ATTR(src用户的javascript:假;)。隐藏()得到(0);
                    $(机构)追加(IFRAME);

                    的setInterval(函数(){
                        VAR IDOC = iframe.contentWindow.document,
                             H = idoc.location.hash;

                        如果(散!==高){
                            $ .event.trigger(散,H);
                        }
                    },100);

                    setIframeLocation(的location.hash ||'#');
                }


            //其他浏览器扫描直接的location.hash更改,恕不IFRAME黑客
            } 其他 {
                的setInterval(函数(){
                    VAR H =的location.hash;
                    如果(H!==哈希){
                        $ .event.trigger(散,H);
                    }
                },100);
            }

            链接=!链接? ELS:links.add(ELS);

            els.click(功能(E){
                VAR HREF = $(本).attr(HREF);
                如果(IFRAME){setIframeLocation(HREF); }

                //处理非锚链接
                如果(href.slice(0,1)!=#){
                    location.href =#+的href;
                    返回e的preventDefault()。
                }

            });

            inited = TRUE;
        }
    };


    功能setIframeLocation(H){
        如果(H){
            VAR DOC = iframe.contentWindow.document;
            doc.open()close()方法。
            doc.location.hash = H;
        }
    }

    //全球histroy变化监听器
    $(窗口).bind(散列功能(E,H){
        如果(H){
            links.filter(函数(){
              VAR HREF = $(本).attr(HREF);
              返回HREF = = ^ h || HREF == h.replace(#,);
            })触发(历史,[H]);
        } 其他 {
            links.eq(0).trigger(历史,[H]);
        }

        散列= H;
    window.location.hash =散列;
    });


    // jQuery插件实现
    $ .fn.history =功能(FN){

        $ .tools.history.init(本);

        //返回的jQuery
        返回this.bind(历史,FN);
    };

})(jQuery的);
$(函数(){
$(#列表)标签(#内容与GT;格,{效果:阿贾克斯,历史:真});
});
 

解决方案

下面是我会添加键盘功能,您的code。

不过,我想补充一点,在看pretty的大致相同的question您之前两天这个贴,这个网站设置,以帮助您找到您code问题,而不是写这一切给你。如果你希望别人写的所有code,雇人做,或你可能不得不学习如何(在需要与我们的故障排除帮助)自己做。

反正,我设置这个演示,以帮助您开始。希望有足够多的评论认为你能理解我在做什么,你可以把它从那里。

  $(函数(){
 VAR列表= $('#名单),
     imgPerRow = -1,
     循环=真;
 //找到第一个图像的Y轴偏移找到每行图像数量
 VAR topOffset = list.find。(IMG:当量(0)')偏移()之上,
     。numTabs = list.find('A')的长度 -  1,
     目前,newCurrent;

 功能changeTab(差异){
  电流= list.find('a.current')指数()。
  newCurrent =(循环)? (电流+差异+ numTabs + 1)%(numTabs + 1):当前+差异;
  如果(循环){
   如果(newCurrent> numTabs){newCurrent = 0; }
   如果(newCurrent℃,){newCurrent = numTabs; }
  } 其他 {
   如果(newCurrent> numTabs){newCurrent = numTabs; }
   如果(newCurrent℃,){newCurrent = 0; }
  }
  //不会触发改变,如果标签没有改变(非循环模式)
  如果(电流!= newCurrent){
   list.find('A'),EQ(newCurrent).trigger(点击)。 //触发点击选项卡
  }
 }

 名单
  //设置标签
  .tabs(#内容与GT;格,{效果:阿贾克斯,历史:真})

  //找到第一行图像数
  .find('IMG')。每个(函数(一){
   如果(imgPerRow℃,与功放;&安培; $(本).offset()顶> topOffset){
    imgPerRow =我;
   }
  });

  //设置箭头键
  //设置文件的演示,最好使用#list在最终版本中。
  (文档)$ .bind('的keyup',函数(E){
   VAR键= e.which;
   如果(钥匙> 36安培;&放大器;键< 41){
    如果(关键== 37){changeTab(-1); }         // 剩下
    如果(关键== 38){changeTab(-imgPerRow); } // 向上
    如果(关键== 39){changeTab(+1); }         // 对
    如果(关键== 40){changeTab(+ imgPerRow); } // 向下
    即preventDefault();
   }
  });

 //打开或者关闭的选项卡循环
 $(':按钮)点击(函数(){。
  循环=循环!;
  $('#loopStatus)文本(循环)。
 });

});
 
jQuery keyboard首页 文档和下载 jQuery虚拟键盘插件

How to make Keyboard navigation left/up/right/down (like for photo gallery) feature for jQury Tabs with History? Demo without Keyboard feature in http://dl.dropbox.com/u/6594481/tabs/index.html Needed functions: 1. on keyboardtop/down> make select and CSS showactivenested ajax tabs from 1-st to last level 2. on keyboardleft/right> changeback/forwardcontent ofactivenested ajax tabs tab 3. an extra option, makeactivenested ajax tab on 'cursor-on' on concrete nested ajax tabs level Read more detailed question with example pictures in http://stackoverflow.com/questions/2975003/jquery-tools-to-make-keyboard-and-cookies-feature-for-ajaxed-tabs-with-history

/**
 * @license 
 * jQuery Tools @VERSION Tabs- The basics of UI design.
 * 
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 * 
 * http://flowplayer.org/tools/tabs/
 *
 * Since: November 2008
 * Date: @DATE 
 */  
(function($) {

    // static constructs
    $.tools = $.tools || {version: '@VERSION'};

    $.tools.tabs = {

        conf: {
            tabs: 'a',
            current: 'current',
            onBeforeClick: null,
            onClick: null, 
            effect: 'default',
            initialIndex: 0,            
            event: 'click',
            rotate: false,

            // 1.2
            history: false
        },

        addEffect: function(name, fn) {
            effects[name] = fn;
        }

    };

    var effects = {

        // simple "toggle" effect
        'default': function(i, done) { 
            this.getPanes().hide().eq(i).show();
            done.call();
        }, 

        /*
            configuration:
                - fadeOutSpeed (positive value does "crossfading")
                - fadeInSpeed
        */
        fade: function(i, done) {        

            var conf = this.getConf(),            
                 speed = conf.fadeOutSpeed,
                 panes = this.getPanes();

            if (speed) {
                panes.fadeOut(speed);    
            } else {
                panes.hide();    
            }

            panes.eq(i).fadeIn(conf.fadeInSpeed, done);    
        },

        // for basic accordions
        slide: function(i, done) {
            this.getPanes().slideUp(200);
            this.getPanes().eq(i).slideDown(400, done);             
        }, 

        /**
         * AJAX effect
         */
        ajax: function(i, done)  {            
            this.getPanes().eq(0).load(this.getTabs().eq(i).attr("href"), done);    
        }        
    };       

    var w;

    /**
     * Horizontal accordion
     * 
     * @deprecated will be replaced with a more robust implementation
     */
    $.tools.tabs.addEffect("horizontal", function(i, done) {

        // store original width of a pane into memory
        if (!w) { w = this.getPanes().eq(0).width(); }

        // set current pane's width to zero
        this.getCurrentPane().animate({width: 0}, function() { $(this).hide(); });

        // grow opened pane to it's original width
        this.getPanes().eq(i).animate({width: w}, function() { 
            $(this).show();
            done.call();
        });

    });    


    function Tabs(root, paneSelector, conf) {

        var self = this, 
             trigger = root.add(this),
             tabs = root.find(conf.tabs),
             panes = paneSelector.jquery ? paneSelector : root.children(paneSelector),             
             current;


        // make sure tabs and panes are found
        if (!tabs.length)  { tabs = root.children(); }
        if (!panes.length) { panes = root.parent().find(paneSelector); }
        if (!panes.length) { panes = $(paneSelector); }


        // public methods
        $.extend(this, {                
            click: function(i, e) {

                var tab = tabs.eq(i);                                                 

                if (typeof i == 'string' && i.replace("#", "")) {
                    tab = tabs.filter("[href*=" + i.replace("#", "") + "]");
                    i = Math.max(tabs.index(tab), 0);
                }

                if (conf.rotate) {
                    var last = tabs.length -1; 
                    if (i < 0) { return self.click(last, e); }
                    if (i > last) { return self.click(0, e); }                        
                }

                if (!tab.length) {
                    if (current >= 0) { return self; }
                    i = conf.initialIndex;
                    tab = tabs.eq(i);
                }                

                // current tab is being clicked
                if (i === current) { return self; }

                // possibility to cancel click action                
                e = e || $.Event();
                e.type = "onBeforeClick";
                trigger.trigger(e, [i]);                
                if (e.isDefaultPrevented()) { return; }

                // call the effect
                effects[conf.effect].call(self, i, function() {

                    // onClick callback
                    e.type = "onClick";
                    trigger.trigger(e, [i]);                    
                });            

                // default behaviour
                current = i;
                tabs.removeClass(conf.current);    
                tab.addClass(conf.current);                

                return self;
            },

            getConf: function() {
                return conf;    
            },

            getTabs: function() {
                return tabs;    
            },

            getPanes: function() {
                return panes;    
            },

            getCurrentPane: function() {
                return panes.eq(current);    
            },

            getCurrentTab: function() {
                return tabs.eq(current);    
            },

            getIndex: function() {
                return current;    
            }, 

            next: function() {
                return self.click(current + 1);
            },

            prev: function() {
                return self.click(current - 1);    
            }        

        });

        // callbacks    
        $.each("onBeforeClick,onClick".split(","), function(i, name) {

            // configuration
            if ($.isFunction(conf[name])) {
                $(self).bind(name, conf[name]); 
            }

            // API
            self[name] = function(fn) {
                $(self).bind(name, fn);
                return self;    
            };
        });


        if (conf.history && $.fn.history) {
            $.tools.history.init(tabs);
            conf.event = 'history';
        }    

        // setup click actions for each tab
        tabs.each(function(i) {                 
            $(this).bind(conf.event, function(e) {
                self.click(i, e);
                return e.preventDefault();
            });            
        });

        // cross tab anchor link
        panes.find("a[href^=#]").click(function(e) {
            self.click($(this).attr("href"), e);        
        }); 

        // open initial tab
        if (location.hash) {
            self.click(location.hash);
        } else {
            if (conf.initialIndex === 0 || conf.initialIndex > 0) {
                self.click(conf.initialIndex);
            }
        }                

    }


    // jQuery plugin implementation
    $.fn.tabs = function(paneSelector, conf) {

        // return existing instance
        var el = this.data("tabs");
        if (el) { return el; }

        if ($.isFunction(conf)) {
            conf = {onBeforeClick: conf};
        }

        // setup conf
        conf = $.extend({}, $.tools.tabs.conf, conf);        

        this.each(function() {                
            el = new Tabs($(this), paneSelector, conf);
            $(this).data("tabs", el); 
        });        

        return conf.api ? el: this;        
    };        

}) (jQuery); 

/**
 * @license 
 * jQuery Tools @VERSION History "Back button for AJAX apps"
 * 
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 * 
 * http://flowplayer.org/tools/toolbox/history.html
 * 
 * Since: Mar 2010
 * Date: @DATE 
 */
(function($) {

    var hash, iframe, links, inited;        

    $.tools = $.tools || {version: '@VERSION'};

    $.tools.history = {

        init: function(els) {

            if (inited) { return; }

            // IE
            if ($.browser.msie && $.browser.version < '8') {

                // create iframe that is constantly checked for hash changes
                if (!iframe) {
                    iframe = $("<iframe/>").attr("src", "javascript:false;").hide().get(0);
                    $("body").append(iframe);

                    setInterval(function() {
                        var idoc = iframe.contentWindow.document, 
                             h = idoc.location.hash;

                        if (hash !== h) {                        
                            $.event.trigger("hash", h);
                        }
                    }, 100);

                    setIframeLocation(location.hash || '#');
                }


            // other browsers scans for location.hash changes directly without iframe hack
            } else { 
                setInterval(function() {
                    var h = location.hash;
                    if (h !== hash) {
                        $.event.trigger("hash", h);
                    }                        
                }, 100);
            }

            links = !links ? els : links.add(els);

            els.click(function(e) {
                var href = $(this).attr("href");
                if (iframe) { setIframeLocation(href); }

                // handle non-anchor links
                if (href.slice(0, 1) != "#") {
                    location.href = "#" + href;
                    return e.preventDefault();        
                }

            }); 

            inited = true;
        }    
    };  


    function setIframeLocation(h) {
        if (h) {
            var doc = iframe.contentWindow.document;
            doc.open().close();    
            doc.location.hash = h;
        }
    } 

    // global histroy change listener
    $(window).bind("hash", function(e, h)  { 
        if (h) {
            links.filter(function() {
              var href = $(this).attr("href");
              return href == h || href == h.replace("#", ""); 
            }).trigger("history", [h]);    
        } else {
            links.eq(0).trigger("history", [h]);    
        }

        hash = h;
    window.location.hash = hash;
    });


    // jQuery plugin implementation
    $.fn.history = function(fn) {

        $.tools.history.init(this);

        // return jQuery
        return this.bind("history", fn);        
    };    

})(jQuery);
$(function() {
$("#list").tabs("#content > div", {effect: 'ajax', history: true});
});​

解决方案

Here is how I would add the keyboard functionality to your code.

But, I want to add that after looking at pretty much the same question you posted two days prior to this one, that this site is set up to help you find problems in your code, not to write it all for you. If you want someone to write all the code, hire someone to do it or you'll probably have to learn how to do it yourself (with troubleshooting help from us as needed).

Anyway, I set up this demo to help you get started. Hopefully there are enough comments that you can understand what I was doing and you can take it from there.

$(function() {
 var list = $('#list'),
     imgPerRow = -1,
     loop = true;
 // find first image y-offset to find the number of images per row
 var topOffset = list.find('img:eq(0)').offset().top,
     numTabs = list.find('a').length - 1,
     current, newCurrent;

 function changeTab(diff){
  current = list.find('a.current').index();
  newCurrent = (loop) ? (current + diff + numTabs + 1) % (numTabs + 1) : current + diff;
  if (loop) {
   if (newCurrent > numTabs) { newCurrent = 0; }
   if (newCurrent < 0) { newCurrent = numTabs; }
  } else {
   if (newCurrent > numTabs) { newCurrent = numTabs; }
   if (newCurrent < 0) { newCurrent = 0; }
  }
  // don't trigger change if tab hasn't changed (for non-looping mode)
  if (current != newCurrent) {
   list.find('a').eq(newCurrent).trigger('click'); // trigger click on tab
  }
 }

 list
  // set up tabs
  .tabs("#content > div", {effect: 'ajax', history: true})

  // find number of images on first row
  .find('img').each(function(i){
   if (imgPerRow < 0 && $(this).offset().top > topOffset ) {
    imgPerRow = i;
   }
  });

  // Set up arrow keys
  // Set to document for demo, probably better to use #list in the final version.
  $(document).bind('keyup', function(e){
   var key = e.which;
   if (key > 36 && key < 41) {
    if (key == 37) { changeTab(-1); }         // Left
    if (key == 38) { changeTab(-imgPerRow); } // Up
    if (key == 39) { changeTab(+1); }         // Right
    if (key == 40) { changeTab(+imgPerRow); } // Down
    e.preventDefault();
   }
  });

 // toggle looping through tabs
 $(':button').click(function(){
  loop = !loop;
  $('#loopStatus').text(loop);
 });

});