首页 > 解决方案 > AJAX 按钮切换只工作一次,直到页面刷新

问题描述

我有一个按钮,允许用户“收藏”或“取消收藏”帖子。单击它应该在两种状态之间切换(通过在用户的转发器字段中添加或删除帖子 ID)。该功能有效,但只有一次,直到页面被刷新,然后它会再次工作。我无法弄清楚如何在不刷新页面的情况下使其重复工作。

好像如果一篇文章没有被收藏,点击按钮就会收藏该页面,然后再次点击它会继续尝试收藏它。只有当页面重新加载时,按钮才会识别出它已经被收藏,然后才会运行取消收藏功能。

我确定我忽略了一些简单的东西,但我无法弄清楚它是什么。任何帮助深表感谢!

这是我的 PHP 模板中按钮的代码:

<div id="favorites">
    <?php
    // Favorited indicator
    // Check if the user has any saved Favorites. If so, loop through them and if there are any matches, change the favorite heart icon to pink.
    if (have_rows('my_favorites', $currentUserID)) :
        while (have_rows('my_favorites', $currentUserID)) : the_row();
            $favorite_post_id = get_sub_field('post_id');
            $favorite_name = get_field('name', $favorite_post_id);
            // If the post ID exists
            if ($favorite_post_id == $post_ID) {
                array_push($check_favorites_array, 'yes');
            } else {
                array_push($check_favorites_array, 'no');
            }
        endwhile;
    endif;
    $post = get_post();
    $favorite_class = '';
    $nonce = wp_create_nonce('add_remove_dog_from_favorites_nonce');
    $link = '';
    if (in_array('yes', $check_favorites_array)) {
        $link = admin_url('admin-ajax.php?action=remove_dog_from_favorites&post_id=' . $post->ID . '&nonce=' . $nonce);
        $favorite_class = 'is-favorite';
    } else {
        $link = admin_url('admin-ajax.php?action=add_dog_to_favorites&post_id=' . $post->ID . '&nonce=' . $nonce);
        $favorite_class = 'not-favorite';
    }
    ?>
    <a href="<?php echo $link; ?>" data-post_id="<?php echo $post->ID ?>" data-nonce="<?php echo $nonce; ?>" data-user_id="<?php echo $currentUserID ?>" class="favorite-toggle <?php echo $favorite_class ?>" id="favorite-toggle">
        <i class="fas fa-heart"></i>
    </a>
</div>

以及函数的代码:

/ define the actions for the two hooks created, first for logged in users and the next for logged out users
add_action('wp_ajax_add_dog_to_favorites', 'add_dog_to_favorites');
add_action('wp_ajax_nopriv_add_dog_to_favorites', 'login_to_add_to_favorites');

// define the function to be fired for logged in users
function add_dog_to_favorites()
{

    // nonce check for an extra layer of security, the function will exit if it fails
    if (!wp_verify_nonce($_REQUEST['nonce'], 'add_remove_dog_from_favorites_nonce')) {
        exit('Woof Woof Woof');
    }


    $post_id = $_REQUEST['post_id'];
    $user_id = $_REQUEST['user_id'];
    $row = array(
        'post_id'       => $post_id
    );

    $contains_row = false;

    if (have_rows('my_favorites', $user_id)) :
        while (have_rows('my_favorites', $user_id)) : the_row();
            $sub_value = get_sub_field('post_id');
            if ($sub_value == $post_id) {
                $contains_row = true;
            }
        endwhile;
        if ($contains_row == false) {
            add_row('my_favorites', $row, $user_id);
        }
    endif;
    $contains_row = false;



    // If the above action fails, result type is set to 'error' and like_count set to old value, if success, update to new_like_count
    if ($post_id === false) {
        $result['type'] = 'error';
        // $result['like_count'] = $like_count;
    } else {
        $result['type'] = 'success';
        // $result['like_count'] = $new_like_count;
    }

    // Check if action was fired via Ajax call. If yes, JS code will be triggered, else the user is redirected to the post page
    if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
        $result = json_encode($result);
        echo $result;
    } else {
        header("Location: " . $_SERVER['HTTP_REFERER']);
    }

    // don't forget to end your scripts with a wp_die() function - very important
    wp_die();
}

// define the functtion to be fired for logged out users
function login_to_add_to_favorites()
{
    echo 'You must log in to like';
    wp_die();
}

// used here only for enabling syntax highlighting. Leave this out if it's already included in your plugin file.

// Fires after WordPress has finished loading, but before any headers are sent.

add_action('init', 'enqueue_add_dog_to_favorites_script');

function enqueue_add_dog_to_favorites_script()
{
    // Register the JS file with a unique handle, file location, and an array of dependencies
    wp_register_script('add_favorites_script', plugin_dir_url(__FILE__) . 'add_favorites_script.js', array('jquery'));

    // localize the script to your domain name, so that you can reference the url to admin-ajax.php file easily
    wp_localize_script('add_favorites_script', 'myAjax', array('ajaxurl' => admin_url('admin-ajax.php')));

    // enqueue jQuery library and the script you registered above
    wp_enqueue_script('jquery');
    wp_enqueue_script('add_favorites_script');
}




/**
 * Remove Dog from Favorites
 */

// define the actions for the two hooks created, first for logged in users and the next for logged out users
add_action('wp_ajax_remove_dog_from_favorites', 'remove_dog_from_favorites');
add_action('wp_ajax_nopriv_remove_dog_from_favorites', 'login_to_remove_dog_from_favorites');

// define the function to be fired for logged in users
function remove_dog_from_favorites()
{

    // nonce check for an extra layer of security, the function will exit if it fails
    if (!wp_verify_nonce($_REQUEST['nonce'], 'add_remove_dog_from_favorites_nonce')) {
        exit('Woof Woof Woof');
    }


    $post_id = $_REQUEST['post_id'];
    $user_id = $_REQUEST['user_id'];



    if (have_rows('my_favorites', $user_id)) :
        while (have_rows('my_favorites', $user_id)) : the_row();
            $sub_value = get_sub_field('post_id');
            if ($sub_value == $post_id) {
                delete_row('my_favorites', get_row_index(), $user_id);
            }
        endwhile;
    endif;



    // If the above action fails, result type is set to 'error' and like_count set to old value, if success, update to new_like_count
    if ($post_id === false) {
        $result['type'] = 'error';
        // $result['like_count'] = $like_count;
    } else {
        $result['type'] = 'success';
        // $result['like_count'] = $new_like_count;
    }

    // Check if action was fired via Ajax call. If yes, JS code will be triggered, else the user is redirected to the post page
    if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
        $result = json_encode($result);
        echo $result;
    } else {
        header("Location: " . $_SERVER['HTTP_REFERER']);
    }

    // don't forget to end your scripts with a wp_die() function - very important
    wp_die();
}

// define the functtion to be fired for logged out users
function login_to_remove_dog_from_favorites()
{
    echo 'You must log in to like';
    wp_die();
}

还有我的jQuery:

jQuery(document).ready(function () {
  jQuery(".not-favorite").on("click", function (e) {
    e.preventDefault();
    buttonLike = jQuery(".is-favorite");
    post_id = jQuery(this).attr("data-post_id");
    nonce = jQuery(this).attr("data-nonce");
    user_id = jQuery(this).attr("data-user_id");
    jQuery.ajax({
      type: "post",
      dataType: "json",
      url: myAjax.ajaxurl,
      data: {
        action: "add_dog_to_favorites",
        post_id: post_id,
        nonce: nonce,
        user_id: user_id,
      },
      success: function (response) {
        if (response.type == "success") {
          console.log("success!");
          // const button = document.querySelector('.not-favorite');
          // button.classList.remove('not-favorite');
          // button.classList.add('is-favorite');

          // jQuery("#favorites").load(' #favorites');
          jQuery("#favorite-toggle").removeClass("not-favorite");
          jQuery("#favorite-toggle").addClass("is-favorite");
          linkText = jQuery("#favorite-toggle").prop("href");
          newLinkText = linkText.replace(
            "add_dog_to_favorites",
            "remove_dog_from_favorites"
          );
          jQuery("#favorite-toggle").attr("href", newLinkText);
        } else {
          alert("Your like could not be added");
        }
      },
    });
  });

  jQuery(".is-favorite").on("click", function (e) {
    e.preventDefault();
    buttonLike = jQuery(".not-favorite");
    post_id = jQuery(this).attr("data-post_id");
    nonce = jQuery(this).attr("data-nonce");
    user_id = jQuery(this).attr("data-user_id");
    jQuery.ajax({
      type: "post",
      dataType: "json",
      url: myAjax.ajaxurl,
      data: {
        action: "remove_dog_from_favorites",
        post_id: post_id,
        nonce: nonce,
        user_id: user_id,
      },
      success: function (response) {
        if (response.type == "success") {
          console.log("success!");
          // var button = document.querySelector('.is-favorite');
          // button.classList.remove('is-favorite');
          // button.classList.add('not-favorite');

          // jQuery("#favorites").load(' #favorites');
          jQuery("#favorite-toggle").removeClass("is-favorite");
          jQuery("#favorite-toggle").addClass("not-favorite");
          linkText = jQuery("#favorite-toggle").prop("href");
          newLinkText = linkText.replace(
            "remove_dog_from_favorites",
            "add_dog_to_favorites"
          );
          jQuery("#favorite-toggle").attr("href", newLinkText);
        } else {
          alert("Your like could not be added");
        }
      },
    });
  });
});

标签: phpjqueryajaxwordpress

解决方案


根据您的 js 代码,在页面加载时您“收藏”该页面,然后在click您“取消收藏”该页面。您的页面加载 AJAX 调用应检查该页面是否已被收藏,并更新状态。然后,在click您的 AJAX 上应检查用户是否喜欢或不喜欢并进行适当的调用(remove_dog_from_favorites / add_dog_to_favorites):

      type: "post",
      dataType: "json",
      url: myAjax.ajaxurl,
      data: {
        action: favoritesAction,
        post_id: post_id,
        nonce: nonce,
        user_id: user_id,
      }

推荐阅读