2 improvement
source | link
function smk_remove_post(){
    $('.smk-remove-post').on( 'click', function( event ){
        event.preventDefault();
        var _this = $(this);

        jQuery.ajax({
            type: "GET",
            url: ajaxurl,
            data: _this.attr('href').split('?')[1],
            success: function(response){
                console.log(response); // ok
                _this.text('All great, the post is removed.');
            }
        });
    });
}
smk_remove_post();

Edit: Also a small update to the code above. To process the query strings is required to delete the site path, else it may create unexpected problems. I've added this to data href:

.split('?')[1]
function smk_remove_post(){
    $('.smk-remove-post').on( 'click', function( event ){
        event.preventDefault();
        var _this = $(this);

        jQuery.ajax({
            type: "GET",
            url: ajaxurl,
            data: _this.attr('href'),
            success: function(response){
                console.log(response); // ok
                _this.text('All great, the post is removed.');
            }
        });
    });
}
smk_remove_post();
function smk_remove_post(){
    $('.smk-remove-post').on( 'click', function( event ){
        event.preventDefault();
        var _this = $(this);

        jQuery.ajax({
            type: "GET",
            url: ajaxurl,
            data: _this.attr('href').split('?')[1],
            success: function(response){
                console.log(response); // ok
                _this.text('All great, the post is removed.');
            }
        });
    });
}
smk_remove_post();

Edit: Also a small update to the code above. To process the query strings is required to delete the site path, else it may create unexpected problems. I've added this to data href:

.split('?')[1]
1
source | link

I finally got it.

First mistake was to process the same function twice. I've called it once after the function and one more time in ajax action. So when using the ajax call, the function got executed twice. In the example from the OP, this is not a problem at all, because it is simplified to do only one thing, but in my real code it does much more and can result in lost of unwanted data.

Also, I just needed to stop the ajax and get a custom responce, nothing more. Here is what I've did:

1. I've changed this:

smk_remove_post();

to this:

add_action('parse_query', 'smk_remove_post');

It is better to run the function later when needed in special action.

2. Next, I've modified the ajax handler: I've deleted this line smk_remove_post(); and changed the ajax action from wp_ajax_smk_remove_post_ajax to wp_ajax_smk_remove_post:

function smk_remove_post_ajax(){
    wp_die( 'ok' );
}
add_action('wp_ajax_smk_remove_post', 'smk_remove_post_ajax');

3. I've renamed the query string reaction to action. Changed it in the url, and function:

4. Finally modified the jQuery script. So it uses the admin-ajax.php and sends the url as data:

url: ajaxurl,
data: _this.attr('href'),

Here is the final code:

Link:

<a href="http://example.com/?action=smk_remove_post&id=1226&_nonce=7be82cd4a0" class="smk-remove-post">Remove post</a>

PHP code:

function smk_remove_post(){
    if( !empty( $_GET['action'] ) && 'smk_remove_post' == $_GET['action'] && !empty( $_GET['id'] ) ){
        if( current_user_can('edit_others_posts') && !empty($_GET['_nonce']) ){
            if( wp_verify_nonce( esc_html( $_GET['_nonce'] ), 'smk_remove_post' ) ){
                // Delete the post
                wp_delete_post( absint( $_GET['id'] ), true );
            }
        }
    }
}
add_action('parse_query', 'smk_remove_post');

function smk_remove_post_ajax(){
    wp_die( 'ok' );
}
add_action('wp_ajax_smk_remove_post', 'smk_remove_post_ajax');

Javascript:

function smk_remove_post(){
    $('.smk-remove-post').on( 'click', function( event ){
        event.preventDefault();
        var _this = $(this);

        jQuery.ajax({
            type: "GET",
            url: ajaxurl,
            data: _this.attr('href'),
            success: function(response){
                console.log(response); // ok
                _this.text('All great, the post is removed.');
            }
        });
    });
}
smk_remove_post();