具有可变高度和Ajax内容的jQuery动画滑块

时间:2012-06-25 07:40:12

标签: javascript jquery ajax tabs sequence

我在浮动div上有一系列链接(因此它们始终可见)。当用户点击一个时,我希望以下顺序发生:

  1. 页面向上滚动到顶部(ajax容器所在的位置)
  2. 当前内容滑出
  3. 新内容加载(ajax)
  4. 新内容幻灯片
  5. 注意:由于每个ajax文件中的内容不同,因此ajax容器需要扩展/收缩以适应。

    我想在没有jQuery UI的情况下这样做,并尽可能保持代码精简。

    我一直在谷歌搜索并尝试整天使用回调和队列功能,但很难让它按预期工作。如果有人能帮助我理解如何构建这些功能以使其正常工作,我将非常感激。

    我已经抽象了我的代码,以告诉您我在哪里: http://pastebin.com/xbJKPmnw

    它当前滑动页面顶部,并加载内容。但我还没有按顺序顺利地完成转换。

    非常感谢提前。

2 个答案:

答案 0 :(得分:3)

如果我理解正确,除了过渡本身之外,你已经整理了所有内容(正文滚动,ajax获取内容)。

这是我的原型,可以满足您的需求:

  1. 使旧内容滑出
  2. 使新内容滑入
  3. 调整动态内容容器的大小以适应新内容
  4. 工作jsFiddle:http://jsfiddle.net/dipish/vhd8e/

    代码非常苛刻,但提供了建议方法的主要思想。我使用链接的“rel”属性来引用静态模拟内容。在现实生活中,你会发出ajax请求,获取数据然后启动转换。

    示例html:

    <div id="primarynav">
                  <ul id="navigation">
                      <li><a href="page1.html" class="selected" rel="content1">Page 1</a></li>
                      <li><a href="page2.html" rel="content2">Page 2</a></li>
                      <li><a href="page3.html" rel="content3">Page 3</a></li>
                  </ul>
              </div>
    
    <div id="ajax-content"></div>
    
    <div class="preload">
        <div id="content1">I have a series of links on a floating div (so they're always visible). When a user clicks one, I would like the following to happen in sequence:
    
    The page scrolls up to the top (where the ajax container is located)
    The current content slides out
    The new content loads (ajax)
    The new content slides in
    NB: As the content in each ajax file is different, the ajax container will need to expand/contract to fit.
    
    I would like to do this without jQuery UI, and keep the code as lite as possible.
    
    I've been googling and attempting to do this with callbacks and queue functions all day, but struggle to get it working as intended. If anyone can please help me understand how to structure these functions to get it working I'd be incredibly grateful.
    
    I've abstracted my code to show you where I'm at: http://jsfiddle.net/Cz5kg/1/
    
    It currently slides the top of the page, and loads the content. But i'm yet to get the transitions working smoothly and in sequence.
    
    Many thanks in advance.</div>
    
        <div id="content2">I'm writing a simple javascript to calculate the time difference between server and user time. But something is going wrong.
    
    If I catch the javascript and php date i have:
    
    date("M d Y h:i:s A")
    php date : Wed Jun 27 2012 04:10:41 AM  
    
    new Date()
    J S date : Wed Jun 27 2012 10:10:40 GMT+0200 (CEST)   
    This is correct! I have two different time for local and server time.
    
    Now if I take the seconds time... something goes wrong:
    
    (php: date("U"))
    sec PHP: 1340784640    
    
    (js new Date().getTime()/1000 )
    sec J S: 1340784640
    I got the same time!
    
    Can you help me to fix it ?
    
    Thanks!
        </div>
    
        <div id="content3">I've been given a big project by a big client and I've been working on it for 2 months now. I'm getting closer and closer to a solution but it's just so insanely complex that I can't quite get there, and so I need ideas.
    
    The project is quite simple: There is a 1mil+ database of lat/lng coordinates with lots of additional data for each record. A user will visit a page and enter some search terms which will filter out quite a lot of the records. All of the records that match the filter are displayed (often clustered) on a Google Maps.
    
    The problem with this is that the client demands it's fast, lean, and low-bandwidth. Hence, I'm stuck. What I'm currently doing is: Present the first clusters, and when they hover over a cluster, begin loading in the data for that clusters children.
    
    However, I've upped it to 30,000 of the millions of listings and it's starting to drag a little. I've made as many optimizations that I possibly can. When the filter is changed, I AJAX a query to the DB and return all the ID's of the matches, then update the map to reflect this.
    
    So, optimization is not an option. I need an entirely new conceptual model for this. Any input at all would be highly appreciated, as this is an incredibly complex project of which I can't find anything in history even remotely close to it- I even looked at MMORPG's which have a lot of similar problems, and I have made a few, but the concept of having a million players in one room is still something MMORPG makers cringe at.
    
    I'll be awarding 500 rep as soon as it becomes available for anything that solves this.
    
    Thanks- Daniel.        
        </div>
    </div>
    

    一些CSS(大部分保持不变):

    ul li { float: left;margin: 0 15px 0 0; }
    
    #ajax-content { 
        width:500px; /* fixed width just for viewing convenience */
        clear:both; 
        border: solid 1px black; /* border just for debugging purposes */
        position: relative; /* to contain absolutely positioned children */
        height: 100px; /* initial height */
    }
    
    .preload { /* for test purposes */
        display: none;
    }
    
    .item-container {/* style your inner content*/}
    

    最后你修改了很多评论的JavaScript:

    $(document).ready(function() {
    
        var $navlinks = $('#navigation li a'),
            $ajaxcontent = $('#ajax-content'),
            animDur = 5000, // animation duration
            isTransitionRunning = false;
    
        $navlinks.click(function(e) {        
            e.preventDefault(); // prevent default action
            // block actions until current transition finishes
            if(isTransitionRunning) {
                return false;
            }                
            var contentWidth = $ajaxcontent.width(),
                newContent = $('#' + $(this).attr('rel')).html(), // mock content                
                $newItem = $(document.createElement('div')), // nested container for new content
                newItemHeight,
                newContentHeight,
                $oldItem = $ajaxcontent.children('.item-container');
    
            // set the flag indicating that the transition is running
            isTransitionRunning = true;
    
            $newItem.addClass('item-container');
    
            $('html, body').animate({scrollTop:0}, 'slow');              
    
            //$ajaxcontent.empty().append("<div id='loading'><img src='http://expression.ws/stackoverflow/load.gif' alt='Loading Content' /></div>");
            $navlinks.removeClass('selected');
            $(this).addClass('selected');
    
            /*$.ajax({ url: this.href, success: function(html) {
                $ajaxcontent.empty().append(html);
                }
            });*/
    
            // freeze current ajax container height
            $ajaxcontent.height($ajaxcontent.height());
            $ajaxcontent.css('overflow', 'hidden');
    
            // slide away old item (if any)
            if($oldItem.length) {
                $oldItem
                     // fix width so no wrapping occurs during transision
                    .width(contentWidth) 
                    // position absolutely
                    .css('position', 'absolute')
                    .animate({
                        left: -contentWidth // move new content at the right edge of container
                    },
                    animDur,
                    function() {
                        // remove old content at the end
                        // you may want to cache it instead
                         $oldItem.remove();
                    });
            }
    
            // append new content to container
            $newItem.html(newContent);
            $ajaxcontent.append($newItem);
            // fix new content width
            $newItem.width(contentWidth);
            // determine height of new content when it's appended to DOM
            newItemHeight = $newItem.height();
    
            // set up new content
            $newItem
                // move it to the right
                .css('position', 'absolute')
                .css('left', $ajaxcontent.width() + 'px')
                // sliding animation
                .animate({
                    left: 0
                }, 
                animDur,
                function() {
                    // restore css
                    $newItem.css('position', 'static');
                    $newItem.css('width', 'auto');
                });
    
            // change ajax container height
            $ajaxcontent.animate({
                height: newItemHeight
            },
            animDur,
            function() {
                // now let ajax container naturally wrap around its content
                $ajaxcontent.css('height', 'auto');
                $ajaxcontent.css('overflow', 'auto');
    
                // unset the transition running flag
                isTransitionRunning = false;
            });
    
            return false;
        });
    
        //$ajaxcontent.empty().append("<div id='loading'><img src='http://expression.ws/stackoverflow/load.gif' alt='Loading Content' /></div>");
        $.ajax({ url: 'page1.html', success: function(html) {
                $ajaxcontent.empty().append(html);
        }
        });
    });
    

    应该清楚那里发生了什么,但当然可以随意提出任何问题。我不是一个jQuery忍者,所以我在那里做的一些事情可能效率稍低,但这个想法仍然保持不变。

    实施的本质是:

    • 之前向容器中添加新内容,修改其尺寸并将其设为overflow: hidden;
    • 向DOM插入新内容后,要测量其高度(在将其设置为容器宽度之后)。这将是容器的目标宽度
    • 完成转换后,删除所有强制位置/尺寸恢复自然元素流的CSS(并非总是必要但通常建议使用);

    原型限制

    1. 假设已经通过ajax提取内容并准备插入
    2. 只向一个方向滑动
    3. 如果你的元素有填充和边距,你没有测试这段代码是如何工作的,你通常需要在这里进行一些调整,因为jquery的设置尺寸和定位元素的方法并不总是按照你的预期来处理它。 / LI>

      希望这有帮助!

      <强> UPD。 如果当前正在运行转换,我添加了阻止执行的简单逻辑,您可以通过StackOverflow上的编辑历史来查看差异。一般来说,这不是一个好方法,但它很容易实现。实现一个真正的抗点击雪崩的小部件需要更多的努力和更好的代码架构,让我知道你是否仍然想要这样或者你将要使用第三方小部件。

      对于使用AJAX数据提取进行绑定,您应该在已经提取内容时运行转换。这是伪代码:

      $navlinks.click(function(e) {        
          e.preventDefault(); // prevent default action
          // block actions until current transition finishes
          if(isTransitionRunning) {
              return false;
          }  
      
          // If content is static, you don't want to fetch it everytime,
          // consider implementing some caching mechanism
          $.ajax({ url: this.href, success: function(html) {
              // this function is basically all the code posted above 
              // except that it takes new html content as parameter
                  switchContent(html);
              }
          });
      });
      });
      

答案 1 :(得分:1)

http://explosion-pills.com/11185244.php

这个页面完成了我所想的你想要的东西(我没有任何造型;我会把它留给你)。

我认为你非常接近,你只需要改变元素排队的方式。在一些地方你也需要做的比我想象的要多一些(例如.empty().append.html())。

如果我不合时宜告诉我。

相关问题