下拉过滤速度极慢

时间:2015-01-09 作者:Guit4eva

我的frontpage上有两个下拉列表。第一个下拉列表选择自定义帖子类型,第二个下拉列表选择位置。第二个下拉列表根据第一个下拉列表的选择进行过滤(即,仅显示包含所选cpt的位置)。问题是,当选择第一个下拉列表中的选项时,加载第二个下拉列表选项需要很长时间。如果有人能看看我的代码,并可能帮助我找出造成延迟的原因,我将不胜感激!(以下是my functions.php文件和front page.php中的代码)

Functions.php:

function my_dropdown_categories( $taxonomy, $current_selected = \'\', $include = null ) {
// Get all terms of the chosen taxonomy
$terms = get_terms($taxonomy, array(\'orderby\' => \'name\'));

// our content variable
$list_of_terms = \'<select id="location"  class="selectboxSingle" name="location">\';

if ( ! is_wp_error( $terms ) ) foreach($terms as $term){

    // If include array set, exclude unless in array.
    if ( is_array( $include ) && ! in_array( $term->slug, $include ) ) continue;

    $select = ($current_selected == $term->slug) ? "selected" : ""; // Note: ==

    if ($term->parent == 0 ) {

        // get children of current parent.
        $tchildren = get_term_children($term->term_id, $taxonomy);

        $children = array();
        foreach ($tchildren as $child) {
            $cterm = get_term_by( \'id\', $child, $taxonomy );
            // If include array set, exclude unless in array.
            if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;
            $children[$cterm->name] = $cterm;
        }
        ksort($children);

        // OPTGROUP FOR PARENTS
        if (count($children) > 0 ) {
        //     $list_of_terms .= \'<optgroup label="\'. $term->name .\'">\';
             if ($term->count > 0)
                 $list_of_terms .= \'<option class ="group-result" value="\'.$term->slug.\'" \'.$select.\'>\' . $term->name .\' </option>\';
        } else
            $list_of_terms .= \'<option value="\'.$term->slug.\'" \'.$select.\'>\'. $term->name .\' </option>\';
        //$i++;

        // now the CHILDREN.
        foreach($children as $child) {
             $select = ($current_selected == $child->slug) ? "selected" : ""; // Note: child, not cterm
             $list_of_terms .= \'<option value="\'.$child->slug.\'" \'.$select.\'>\'. $child->name.\' </option>\';

        } //end foreach

        if (count($children) > 0 ) {
            $list_of_terms .= "</optgroup>";
        }
    }
}

$list_of_terms .= \'</select>\';

return $list_of_terms;
}

add_action( \'wp_ajax_wpse158929_get_terms_for_cpt\', \'wpse158929_get_terms_for_cpt\' );
add_action( \'wp_ajax_nopriv_wpse158929_get_terms_for_cpt\', \'wpse158929_get_terms_for_cpt\' );

function wpse158929_get_terms_for_cpt() {
$ret = array( \'html\' => \'\', \'error\' => false );

if ( ! check_ajax_referer( \'wpse158929_get_terms_for_cpt_submit_\', \'nonce\', false /*die*/ ) ) {
    $ret[\'error\'] = __( \'Permission error\', \'wpfm\' );
} else {
    $post_type = isset( $_REQUEST[\'post_type\'] ) ? $_REQUEST[\'post_type\'] : \'\';
    $taxonomy = isset( $_REQUEST[\'taxonomy\'] ) ? $_REQUEST[\'taxonomy\'] : \'\';
    $current_selected = isset( $_REQUEST[\'current_selected\'] ) ? $_REQUEST[\'current_selected\'] : \'\';

    if ( ! $post_type || ! $taxonomy ) {
        $ret[\'error\'] = __( \'Params error\', \'wpfm\' );
    } else {
        global $wpdb;
        $sql = $wpdb->prepare( \'SELECT t.slug FROM \' . $wpdb->terms . \' t\'
            . \' JOIN \' . $wpdb->term_taxonomy . \' AS tt ON tt.term_id = t.term_id\'
            . \' JOIN \' . $wpdb->term_relationships . \' AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id\'
            . \' JOIN \' . $wpdb->posts . \' AS p ON p.ID = tr.object_id\'
            . \' WHERE tt.taxonomy = %s AND p.post_type = %s AND p.post_status = %s\'
            . \' GROUP BY t.slug\'
            , $taxonomy, $post_type, \'publish\' );
        $include = $wpdb->get_col($sql);
        $ret[\'html\'] = preg_replace( \'/<\\/?select[^>]*>/\', \'\', my_dropdown_categories( $taxonomy, $current_selected, $include ) );
    }
}

wp_send_json( $ret );
}

Front-page.php

<form action="<?php bloginfo(\'url\'); ?>" method="get">
<?php
//$post_type = get_post_type_object( get_post_type($post) ); // GET SINGULAR NAME
$args = array(
\'public\'   => true,
\'_builtin\' => false
);
$output = \'objects\'; // names or objects, note names is the default
$operator = \'and\'; // \'and\' or \'or\'
$post_types = get_post_types($args, $output, $operator);
ksort($post_types);
echo \'<select data-placeholder="I need a:" class="fade-in three selectboxSingle" name="post_type">\';
foreach ( $post_types as $post_type ) {
$exclude = array(\'custom_type\',\'shelf\');
if(TRUE === in_array($post_type->name,$exclude)){
continue;
}
// Note: I think you need to use query_var here, rather than slug.
echo \'<option value="\'.$post_type->query_var.\'">\' . ucfirst($post_type->labels->singular_name) . \'</option>\';
}
echo "</select>";
?>

<?php 
// Set your custom taxonomy
$taxonomy = "location";
// Factored out taxonomy dropdown into function my_dropdown_categories() in "functions.php".
echo my_dropdown_categories( $taxonomy );
?>

<button class="submit-button alt" type="submit">Search</button>

<script type="text/javascript">
  jQuery(document).ready(function($) {
    $(\'select[name="post_type"]\').change(function (event) {
    $("#location").prop("disabled", false);
    $(\'.submit-button\').prop(\'disabled\', false);
    $(\'.submit-button\').removeClass("disabled");
    $(\'select[name="location"]\').html("<option value=\'\'>Loading...</option>");
    $(".selectboxSingle").trigger("chosen:updated");
      if($(\'select[name="post_type"]\').val() === \'book\'){
      $(\'#location\').prop(\'disabled\', true);
    }
      $.post("<?php echo admin_url(\'admin-ajax.php\'); ?>", {
      action: \'wpse158929_get_terms_for_cpt\',
      post_type: $(this).val(),
      taxonomy: <?php echo json_encode( $taxonomy ); ?>,
      current_selected: $(\'select[name="location"]\').val(),
      nonce: <?php echo json_encode( wp_create_nonce( \'wpse158929_get_terms_for_cpt_submit_\' ) ); ?>
    }, function( response ) {
    if ( response && !response.error ) {
    $(\'select[name="location"]\').html(response.html);
    $("#location-dropdown").prop("disabled", false);
    $(".selectboxSingle").trigger("chosen:updated");
    }
    }, \'json\'
    );
});

// Remove if you don\'t want to call change immediately.
$(\'select[name="post_type"]\').change();
$(\'select[name="location"]\').html("<option>Your location:</option>");
$(\'.submit-button\').prop(\'disabled\', true);
$("#location").prop("disabled", true);
$(\'.submit-button\').addClass("disabled");
    if ($(\'select[name="post_type"]\').val() !== \'\') {
        $(\'.submit-button\').prop(\'disabled\', false);
        $(\'.submit-button\').removeClass("disabled");
        $("#location").prop("disabled", false);
        }
    });

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

我很惊讶它的速度如此之慢,但您可以删除除一个之外的所有数据库调用&;大多数循环都是通过传递术语数据,而不仅仅是slugmy_dropdown_categories() 所以get_terms() 无需调用,再加上一些其他改进(见注释),例如:

    function my_dropdown_categories( $taxonomy, $current_selected = \'\', $terms = null, $no_select = false ) {
    // If all terms ever needed, uncomment following line.
    //if ( $terms === null ) $terms = get_terms($taxonomy, array(\'orderby\' => \'name\'));

    // our content variable - use array (& join at end) for efficiency
    $ret = array();

    if ( ! $no_select ) { // If not required, don\'t wrap in select.
        $ret[] = \'<select id="location"  class="selectboxSingle" name="location">\';
    }

    if ( $terms && ! is_wp_error( $terms ) ) {
        $parents = $children = array();
        foreach($terms as $term){
            if ($term->parent == 0 ) {
                $parents[] = $term;
            } else {
                $children[$term->parent][] = $term;
            }
        }

        foreach($parents as $term){
            $select = ($current_selected == $term->slug) ? "selected" : ""; // Note: ==

            if ( empty( $children[$term->term_id] ) ) {
                $ret[] = \'<option value="\'.$term->slug.\'" \'.$select.\'>\'. $term->name .\' </option>\';
            } else {
                //$ret[] = \'<optgroup label="\'. $term->name .\'">\';
                $ret[] = \'<option class="group-result" value="\'.$term->slug.\'" \'.$select.\'>\'. $term->name.\' </option>\';
                foreach ( $children[$term->term_id] as $child ) {
                     $select = ($current_selected == $child->slug) ? "selected" : "";
                     $ret[] = \'<option value="\'.$child->slug.\'" \'.$select.\'>\'. $child->name.\' </option>\';
                }
                //$ret[] = "</optgroup>";
            }
        }
    }

    if ( ! $no_select ) {
        $ret[] = \'</select>\';
    }

    return implode( "\\n", $ret );
}

add_action( \'wp_ajax_wpse158929_get_terms_for_cpt\', \'wpse158929_get_terms_for_cpt\' );
add_action( \'wp_ajax_nopriv_wpse158929_get_terms_for_cpt\', \'wpse158929_get_terms_for_cpt\' );

function wpse158929_get_terms_for_cpt() {
    $ret = array( \'html\' => \'\', \'error\' => false );

    if ( ! check_ajax_referer( \'wpse158929_get_terms_for_cpt_submit_\', \'nonce\', false /*die*/ ) ) {
        $ret[\'error\'] = __( \'Permission error\', \'wpfm\' );
    } else {
        $post_type = isset( $_REQUEST[\'post_type\'] ) ? $_REQUEST[\'post_type\'] : \'\';
        $taxonomy = isset( $_REQUEST[\'taxonomy\'] ) ? $_REQUEST[\'taxonomy\'] : \'\';
        $current_selected = isset( $_REQUEST[\'current_selected\'] ) ? $_REQUEST[\'current_selected\'] : \'\';

        if ( ! $post_type || ! $taxonomy ) {
            $ret[\'error\'] = __( \'Params error\', \'wpfm\' );
        } else {
            global $wpdb;
            // Get bare minimum of required data from database.
            $sql = $wpdb->prepare( \'SELECT t.term_id, t.name, t.slug, tt.parent FROM \' . $wpdb->terms . \' t\'
                . \' JOIN \' . $wpdb->term_taxonomy . \' AS tt ON tt.term_id = t.term_id\'
                . \' JOIN \' . $wpdb->term_relationships . \' AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id\'
                . \' JOIN \' . $wpdb->posts . \' AS p ON p.ID = tr.object_id\'
                . \' WHERE tt.taxonomy = %s AND p.post_type = %s AND p.post_status = %s\'
                . \' GROUP BY t.slug\'
                . \' ORDER BY t.name\'
                , $taxonomy, $post_type, \'publish\' );
            $terms = $wpdb->get_results( $sql );
            $ret[\'html\'] = my_dropdown_categories( $taxonomy, $current_selected, $terms, true /*no_select*/ );
        }
    }

    wp_send_json( $ret );
}
而且你可能不需要这个电话$(\'select[name="post_type"]\').change(); 在javascript中,您将立即覆盖select。。。

结束

相关推荐

将jQuery日期选择器添加到自定义发布类型Metabox

我已经创建了一个自定义的post类型元数据库,它可以很好地显示和运行。问题在于日期选择器似乎不起作用,当单击元框时,您可以输入它,而不是出现日期选择器。另一方面,我的脚本似乎都无法工作,尽管它们都已加载。编写加载所有脚本的代码。//Making jQuery Google API function modify_jquery() { if (!is_admin()) { // comment out the next two lines to load th