📜 ⬆️ ⬇️

About jQuery and bicycles - my addition

Immediately I hasten to inform you that I am in no way connected with the author of the previous article . However, after reading it and seeing such a positive response from the community to the article, I was also inspired and decided to add some of my observations and knowledge, and it can also serve as my entry point into the community.

For the seed, let's start with a simple one.

1. Write as you say it out loud.


Your task before other programmers is to show what you are doing, and not how you are doing it.

Before you write another piece of code, think and say out loud or to yourself what you are going to do. For example: "We need to clear this element." Many immediately, without thinking, mold:
$(".info").html("") 

because earlier they used the convenient phrase .innerHTML = "" . More preferred option:
 $(".info").empty() 

')
These same programmers often clear an item before putting new information into it:

 $(".info").html("").html("<b>Ok</b>") 


But don't forget - you write on jQuery! And he cares about you, and .html() will clear the element itself before inserting a new value.

And he will do it more competently than to do it through .innerHTML . The fact is that inside the cleared element there can be such elements on which you previously hung up event handlers or anchored data using .data() . jQuery will clean this and there will be no memory leak.
By the way, sometimes in order to remove information, it is better not just to clear the element, but to delete it altogether:

 $(".info").remove() 


Further…

It is unlikely when writing this:

 $("#history").css("display", "none") $("#description").css("display", "none") $("#category").css("display", "none") $("#contact").css("display", "none") 


You said: "Delete history, delete description, delete categories, delete contacts." Most likely, you said: "Delete history, description, categories and contacts." So write this:

 $("#history, #description, #category, #contact").hide() 


and don't forget that jQuery loves you, and that there is .hide() to hide the element, and .hide() for showing.

2. mouseenter/mouseleave vs mouseover/mouseout


You’ve probably noticed a nuisance: sometimes, when you hang up a couple of mouseover/mouseout events on an element to display a pop-up hint, this hint is mouseover/mouseout . And this happens due to the fact that inside the element on which you hung handlers, is another element. When you hover the mouse cursor over it, the browser generates a mouseout event for your external element, and a mouseover event for the internal element, and then again a mouseover for the external element, which leads to a jitter.

But jQuery loves us and offers us another pair of events - mouseenter/mouseleave , which solve this problem as follows. For the transferred handlers a certain wrapper becomes. At the moment when the cursor moves to the inner element, a mouseout event is mouseout for the outer element. At the same time, jQuery is not so naive and is not conducted on the machinations of the browser. The skeptical wrapper function checks the event.relatedTarget property — what the cursor is mouseleave at — and if it is inside an external element, it does not call the mouseleave handler that you mouseleave . And no flicker.

In addition to this, don't forget about the .hover(handlerIn, handlerOut) function .hover(handlerIn, handlerOut) , which accepts two handlers and hangs them like mouseenter and mouseleave :

 $(selector).hover(function() { tooltip.show() }, function() { tolltip.hide() }) 

UPD : Comrade. Waxer reminds us that since version 1.8 .hover() is considered an obsolete function.

3. .parent() VS .closest()


Often I stumble upon such a construction:

 var person = $(".name").parent().parent().parent() 


It is clear that here is an attempt to get to an important parent who has important information, or which contains another necessary element. And what if, while you were on vacation, your $(".name") nestles in another place, but within the framework of the same person ? Many craftsmen call .parent() cyclically to the desired element.

More advanced ones know that there are .parentsUntil(selector) , which will return all parents to the specified one (excluding it). But still the decision is cumbersome:

 var person = $(".name").parentsUntil(".person").last().parent() 


But there is a more visual way:

 var person = $(".name").closest(".person ") 


If we recall that we write code in the way we would express it with words, then this option is more suitable for its transparency and brevity.

4. $.ajax() - less is better but better!


We all love AJAX, especially $.ajax() . How much do you love him? In a previous article by another author cited the usefulness of working with this component. I'll bring a couple of my own ...

I can hardly lie if I say that you often - if not always - access the same file using AJAX, passing different commands to it for different actions. You do not produce a bunch of files for short actions, I hope? It is even possible that you always pass some parameter that does not change; and maybe you always return only json. Let's simplify our life a bit, because jQuery loves us:

 $.ajaxSetup({ dataType: "json", url: "ajax.php", data: { user_id: userId } }); 


Now we don’t have to specify these parameters each time when querying, it’s enough only distinctive for this operation:

 $.ajax({ data: { product_id: productId }, success: function(json) { console.log(json) }, alert: " ..." //  ? .  }) 

and requests will not be replete with repetitions of code that we do not like so much. Note that the data parameters from $.ajaxSetup and $.ajax are glued together, and their sum is sent to the server (parameters from $.ajax overwrite the same from $.ajaxSetup ).

5. $.ajax() - notify the user


So ... Or maybe now we will notify the user about our underground affairs and we will give him messages with AJAX requests? I'm sure you thought about it, but avoided because you often have to write the same thing.

For simplicity of the example, we will issue messages in this way:

 <div id="popup" class="---"></div> 


And we associate it with our requests:

 $("#popup").ajaxSend(function(event, xhr, options) { $(this).text(options.alert || "...").show() }).ajaxStop(function() { $(this).fadeOut("fast") }) 

.ajaxSend() calls the handler every time an AJAX request occurs. Here we display the transmitted (see above) message or the default message.

.ajaxStop() is called at the end, after all AJAX requests have been processed; those. if you have several AJAX requests processed in parallel, the handler will be called only once - after the execution of the last request.

And if you want to issue a new message each time in a separate pop-up, you need to change the code quite a bit:

 $("body").ajaxSend(function(event, xhr, options) { $('<div class="popup" />') .appendTo(this) .css({/*  */}) .text(options.alert || "...") .delay(2000) //   2  .fadeOut("fast", function() { $(this).remove() }) }) 


You can also attend to the positioning of the popup, adding the calculation of its future coordinates.

6. $ .ajax () - notify the code


Let's now look at our popup from the example above on the other hand. Suppose one person is the developer of some complex widget, which displays information about current events on the page. And another person develops the business logic itself and implements AJAX requests. Obviously, the need for a widget could have arisen after many AJAX requests had been written. Those. while only one person works on the project. If we loved our code and our future colleagues as much as jQuery likes us, we would have foreseen the need for other code to notify him of the completion of some of our AJAX actions. And would do so:

 $.ajax({ data: { action: "search-name", name: $("#name").val() }, beforeSend: function() { $(searchForm).trigger("start.search") }, complete: function() { $(searchForm).trigger("finish.search") } }) 


Now we can not worry that someone in the future will rush into our possession and spoil the raspberries. It is enough for us to inform (in the comments?) That everyone can subscribe, if they like so, to the start.search and finish.search :

 $(searchForm) .on("start.search", function() { //    }) .on("finish.search", function() { //    }) 


After all, we are given the opportunity to create our own types of events, generate them and subscribe to them. It's simple! :) jQuery loves us.

Source: https://habr.com/ru/post/149349/


All Articles