Single page site + pushState?

时间:2015-01-19 作者:Desi

我有一个单页站点,通过Ajax在同一页上通过slide down div加载帖子。当帖子被“激活”时,我希望设置该状态,以便当我直接访问url时,它会转到div中已经显示的特定帖子。

My question is:

我是否在单个中创建帖子。php并调用它们减去页眉和页脚?还是将创建模板作为Ajax功能的一部分?请记住,我的下一个任务是找出如何实现history.js 因此,在url、历史堆栈等中设置状态。

Here\'s my Ajax function:

function my_load_ajax_content () {

    $args = array(
        \'p\' => $_POST[\'post_id\'],
        \'post_type\' => \'projects\'
        );

    $post_query = new WP_Query( $args );
    while( $post_query->have_posts() ) : $post_query->the_post(); ?>

    <div class="post-container">
        <div id="project-left-content">
            <?php the_title( \'<h1 class="entry-title">\', \'</h1>\' ); ?>
            <?php the_content(); ?>

            <!-- If there is a URL -->
            <?php if( get_field(\'url\') ): ?>
                <a href="http://<?php the_field(\'url\'); ?>" target="_blank"><?php the_field(\'url\'); ?></a>
            <?php endif; ?>
        </div>
        <div id="project-right-content">

            <?php if( have_rows(\'slides\') ): ?>

                <div id="slider">

                    <!-- Slider Setup -->
                    <?php if( have_rows(\'slides\') ):
                        $slideNumber = 0;
                        while ( have_rows(\'slides\') ) : the_row();
                        $slideNumber++;
                    ?>

                        <input type="radio" name="slider" id="slide<?php echo $slideNumber; ?>">

                    <?php endwhile;endif; ?>

                    <!-- Slide -->
                    <?php if( have_rows(\'slides\') ): ?>
                        <div id="slides">
                            <div id="overflow">
                                <div class="inner">

                                    <?php if( have_rows(\'slides\') ):
                                    while ( have_rows(\'slides\') ) : the_row();

                                        $slideImage = get_sub_field(\'slide_image\');
                                    ?>

                                    <article>
                                        <img src="<?php echo $slideImage; ?>" alt="<?php the_title(); ?>">
                                    </article>

                                    <?php endwhile;endif; ?>

                                </div><!-- #inner -->
                            </div><!-- #overflow -->
                        </div><!-- #slides -->

                    <?php endif; ?>

                    <!-- Controls -->
                    <?php if( have_rows(\'slides\') ):
                        $slideNumber = 0;
                    ?>
                        <div id="active">

                            <?php while ( have_rows(\'slides\') ) : the_row();
                                $slideNumber++;
                            ?>
                                <label for="slide<?php echo $slideNumber; ?>"></label>
                            <?php endwhile; ?>

                        </div><!-- #active -->
                    <?php endif; ?>
                </div><!-- #slider -->
            <?php endif; ?>
        </div><!-- #project-right-content -->
    </div><!-- .post-container -->

    <?php
    endwhile;
    wp_die();
}

add_action ( \'wp_ajax_nopriv_load-content\', \'my_load_ajax_content\' );
add_action ( \'wp_ajax_load-content\', \'my_load_ajax_content\' );

Here\'s a simplified version of my Ajax call:

$(\'.post-link\').on(\'click\', function(e) {
    e.preventDefault();

    var post_id = $(this).data(\'id\'),
        projectTitle = $(this).data(\'title\'),
        ajaxURL = site.ajaxurl;

    $.ajax({
        type: \'POST\',
        url: ajaxURL,
        context: this,
        data: {\'action\': \'load-content\', post_id: post_id },
        success: function(response) {
            $(\'#project-container\').html(response); // response
            return false;
        }
    });
});

Here\'s my HTML:

<div id="project-container"></div>
<div id="projects-list">

    <!-- Start the loop -->
    <?php $home_query = new WP_Query(\'post_type=projects\');

    while($home_query->have_posts()) : $home_query->the_post(); ?>

    <article class="project">
        <?php the_post_thumbnail( \'home-thumb\' ); ?>
        <div class="overlay">
            <a class="post-link" href="<?php the_permalink(); ?>" data-id="<?php the_ID(); ?>" data-title="<?php the_title(); ?>">+</a>
        </div>
    </article>

    <?php endwhile; ?>
    <?php wp_reset_postdata(); // reset the query ?>

</div><!-- #projects-list -->
如果有人能给我指路,我会非常感激。我似乎找不到关于单页WordPress网站和HTML5历史的太多信息。

编辑:将Ajax函数更新为完整版本(之前已简化)

3 个回复
最合适的回答,由SO网友:Steven 整理而成

我在上做了类似的事情einsteinworld.com.

我这样做的方式是在函数中使用函数。php来获取和呈现内容,然后我从single调用了相同的函数。php或通过ajax,具体取决于场景。

这样,您可以使用全局$post直接导航到页面,也可以通过ajax传入post id并查询$post。别忘了wp_localize_script 并添加您的function for use with ajax

使用历史记录。pushState在通过ajax调用时推送帖子的永久链接。

这是基本代码

/* In $(document).ready... */

History.pushState(null, [next-page-title], [next-page-url]);

$().update_content({
  post_id   : [next-page-id]
});


/* js function */

$.fn.update_content = function(args){

  var data = {
    action  : \'my_function\',// in functions.php
    post_id : args[\'post_id\']
  };

  $.post( MyAjax.ajaxurl, data, function(response) {
    if( response != 0 ){
      // put the returned content in the DOM
    }else{
      // Do something else      
    }
  });
};

/* in functions.php */

function my_function(){
  if( isset( $_POST[\'post_id\'] ) ){
    $post = get_post( $_POST[\'post_id\'] );
    $ajax = true;
  }else{
    $ajax = false;
  }

  echo [html-to-display-the-post-content]

  // if this is ajax\'d stop the output
  if( $ajax )
    die();
}
Update上面提到的网站已不再有效,但答案仍然有效:)

SO网友:kraftner

我想说,这主要取决于您加载的帖子的复杂性。

如果它们像。。。

<div class="post-container">
        <?php the_title( \'<h1 class="entry-title">\', \'</h1>\' ); ?>
        <?php the_content(); ?>
</div><!-- .post-container -->
。。。我只是把它放在AJAX处理程序中,然后就完成了。

如果帖子更复杂,您可能只希望通过AJAX将赤裸裸的数据作为JSON,并在客户端从中构建HTML,甚至可能使用一些前端框架。

历史js应该易于实现(作为一个单独的问题可能也会更好)。无论如何:

History.pushState({post_id:1}

History.Adapter.bind(window,\'statechange\',function(){
    var State = History.getState(); // {"post_id":1}
    //AJAX Call
});
。。。应该会给你带来很多好处。

如果你再详细说明一下,我可以改进这个答案。

SO网友:Privateer

我可以想到两个非常简单的方法:

使用函数的输出my_load_ajax_content 绘制<div id="project-container"></div> 加载页面时首次呈现页面时,请触发单击按钮

$(window).on(\'load\', function(){
    $(\'.post-link\').first().trigger(\'click\');
});
只要jQuery已加载并且您在顶部显示最近的帖子,当您第一次访问页面时,上述内容就会自动触发您的代码。

如果您不想在div和页面顶部都显示最新的帖子,可以通过跳过页面模板、使用pre-get posts过滤器等,调整页面模板,使其不绘制最新的帖子(例如列表中的第一篇帖子)。

结束

相关推荐

区分admin-ajax.php的两个实例

我已经在我的profile.php 页我希望能够使用pre_get_posts 但我找不到任何方法来区分此页面和常规媒体库(upload.php).使用全局$pagenow 退货admin-ajax.php 在这两种情况下。有没有其他方法可以判断哪个页面正在加载媒体库?