-->

jQuery toggle sibling on focus/blur

2019-07-24 16:38发布

问题:

So I have this now and it works, but I wanted to know if there is an optimal way of writing this as I writing a mobile site and performance if a big thing.

Think tool-tip that slides down (toggles) under the element, I also have about 30 tool tip divs on the page as this will be for multiple elements

JS:

$('.mobile-tool-tip').each(function() { 
    $(this).hide();                         
    $(this).prev().focus(function() {
        $(this).next().slideToggle('fast');
    });
    $(this).prev().blur(function() {                    
        $(this).next().slideToggle('fast');
    });
});

HTML for mobile-tool-tip function

<div data-role="fieldcontain">
    <input type="text" name="telephone" id="telephone" placeholder="Phone Number*" />
    <div class="mobile-tool-tip" id="telephone_tip">Valid format <strong>999-999-9999</strong>. Please include the area code.</div>
</div>

Have been using this (Thanks Hunter) to toggle elements but cant get it to work with the next() and I don't want to code each tool tip div by hand

$("[name=field_name]").change(function() {
    var show = $(this).val();
    $("#hidden_div").toggle(show);
});

回答1:

A few suggestions:

  • Save a few milliseconds hiding .mobile-tool-tip elements with CSS.
  • Attach the event to the parent div. It's faster to find the parent element than find a siblings.
  • When you're looking for next or prev elements, and it's an specific element, I always suggest to use `nextAll(".mobile-tool-tip")
  • You're consuming time finding $(this).prev(). Don't do it twice. A lot of functions in jQuery returns a reference to the last query made, this is what enables you to chain calls (something like $(".anElement").hide().remove()). Make use of it to save time.
  • When you have an action to focus and other to blur, use an deterministic method to hide/show or enable/disable elements. This'll ensure that you didn't miss any event or special occasion, and will prevent for any bug related to it.

So:

$('.mobile-tool-tip').each(function() { 
    $(this).prev().focus(function() {
        $(this).nextAll(".mobile-tool-tip").slideDown('fast');
    }).blur(function() {                    
        $(this).nextAll(".mobile-tool-tip").slideUp('fast');
    });

});

Good luck!



回答2:

Some simple thoughts.

  1. You can cache your selector and chain your calls together to avoid any iteration over the dom.
  2. You could also create a closure of your tip in your focus and blur functions which will result in no additional dom iteration.

So you might end up with something like this...

$('.mobile-tool-tip').each(function() {
    var $tip = $(this);
    $tip.hide().prev().focus(function() {
        $tip.slideToggle('fast');
    }).blur(function() {                    
        $tip.slideToggle('fast');
    });
});

jsfiddle that shows a slight performance gain when triggering the event with a closure.



回答3:

You can try to combine some of the calls to the DOM by using a variable to hold the $(this).next() element. Depending on how big the file is, this can cut a substantial amount of time not having to make that call twice.

var nextElement = $(this).next();
$(this).prev().blur(function(){
$(nextElement).slideToggle();
}