2

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

  1. 页面向上滚动到顶部(ajax 容器所在的位置)
  2. 当前内容滑出
  3. 新内容加载(ajax)
  4. 新内容滑入

注意:由于每个 ajax 文件中的内容不同,ajax 容器需要扩展/收缩以适应。

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

我整天都在谷歌上搜索并尝试使用回调和队列函数来做到这一点,但很难让它按预期工作。如果有人可以帮助我了解如何构建这些功能以使其正常工作,我将不胜感激。

我已经抽象出我的代码来告诉你我在哪里:http: //pastebin.com/xbJKPmnw

它当前滑动页面顶部,并加载内容。但我还没有让过渡顺利且有序地进行。

提前谢谢了。

4

2 回答 2

3

如果我理解正确,除了转换本身之外,您已经整理好所有内容(正文滚动、ajax 获取内容)。

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

  1. 使旧内容滑出
  2. 使新内容滑入
  3. 调整动态内容容器的大小以适应新内容

工作 jsFiddle:http: //jsfiddle.net/dipish/vhd8e/

该代码非常hackish,但提供了建议方法的主要思想。我使用链接的“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);
    }
    });
});

​</p>

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

实现的本质是:

  • 向容器添加新内容之前,先修复它的尺寸并制作它overflow: hidden;
  • 将新内容插入 DOM 后,您要测量其高度(将其设置为容器的宽度后)。这将是容器的目标宽度
  • 完成过渡后,删除所有强制位置/尺寸恢复自然元素流的 CSS(并非总是必要的,但通常推荐);​</li>

原型限制

  1. 假设内容已经通过 ajax 获取并准备插入
  2. 只向一个方向滑动
  3. 如果您的元素具有填充和边距,则没有测试此代码的工作原理,您通常需要在此处进行一些调整,因为 jquery 设置尺寸和定位元素的方法并不总是像您期望的那样自动处理。

希望这可以帮助!

UPD。 如果当前正在运行转换,我添加了阻止执行的简单逻辑,您可以通过 StackOverflow 上的编辑历史记录查看差异。通常这不是一个好方法,但很容易实现。实现一个真正的抗点击雪崩小部件需要更多的努力和更好的代码架构,让我知道您是否仍想这样做,或者您是否打算为此使用 3rd 方小部件。

至于将其与 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);
        }
    });
});
});
于 2012-06-27T10:16:04.460 回答
1

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

这个页面做了我认为你在问的(我没有做任何样式;我会留给你)。

我认为您非常接近,您只需要稍微更改元素的排队方式即可。在某些情况下,您所做的也比我认为您需要做的要多(.empty().append例如.html())。

让我知道我是否偏离了标准。

于 2012-06-27T08:49:13.270 回答