Simple, don't show the spinner.
It's asynchronous anyway
Just don't show the spinner. The request itself is asynchronous. The user can continue using the page while the request is waiting in the background for a response. Only when the response is received, the success handler kicks in.
Alternative feedback
So instead of showing a spinner overlay, I'd show a small notification at the top of the page saying 'Saving....', something that doesn't block sight too much, maybe even just a small icon or animation in a corner, or on top of the button they clicked (see snippet below) to do the action.
Then, when the response is received show a more visible notification indicating success or error.
Handling navigation
Navigating away from the page would end the request. That doesn't mean that the PHP script is ended right away, but if you start outputting information and sending it to the client, your server will notice the connection is gone and it will kill the PHP script. You can prevent this and make PHP finish the request by using ignore_user_abort(true).
Minor detail: while the friend invite is being saved, you cannot really see that, so if you navigate to another page that also shows the friend invite button, it's tricky to make that show the right status. One solution might be to set a 'saving' flag as soon as you start saving the invite, but personally I wouldn't go that far. Just make sure you script gracefully handles a duplicate save and hide the collision from the user.
Prototype of inline indicator
Here is a small snippet to show what I mean by showing it inline. It doesn't do an actual request, but simulates it using setTimeout
. You can click each button and you can continue using the page. Instead of showing a big spinner, I just show a text in the button you just clicked, so you know which friend request you are saving.
So this way, there is more feedback to the user (the exact name that is saving), the feedback is less obtrusive (it's only there in the place of the button that should not be clicked anymore anyway), and you can show the response in the same place, or choose to show a notification (or both).
$('button').on('click', function(){
// Button is clicked. Disable and show an indicator.
var button = $(this);
button.prop('disabled', true);
button.text('saving...');
// Simulate the request that takes 5 seconds.
setTimeout(
function(){
// Simulate success
button.text('Saved!');
button.css('color', 'green');
}, 5000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>John <button>Send friend request</button>
<li>Jane <button>Send friend request</button>
<li>Jack <button>Send friend request</button>
<li>Janet <button>Send friend request</button>
</div>