The problem of Java Script shaking

problem description

after reading https://codeshelper.com/p/12. "s article on throttling and detrembling, I found that there was a position in the project that was more suitable to solve with debounce, so I decided to try it, but it was ok. I found that there was a new problem and I didn"t want to ask for advice.

specifically, there is a location in the project to display various contact information (Wechat, QQ, phone). When the mouse is moved into one of them, the corresponding number will be displayed, and then disappear after removal. After adding the detrembling code, it is found that as long as you move quickly between the three, the contact information removed will not disappear.

related codes

<script type="text/javascript">
    $(function() {
        $(".service_action_btn").hover(function() {
            var id_str = $(this).data("id");// -sharpcontact_qq
            debounce(showContact, $(id_str));
        }, function() {
            var id_str = $(this).data("id");// contact_qq
            debounce(hideContact, $(id_str));
        });
    });

    function debounce(method, context) {
        clearTimeout(method.tId);
        method.tId = setTimeout(function() {
            method.call(context);
        }, 500);
    }

    function showContact() {
        this.show();
    }
    function hideContact() {
        this.hide();
    }
</script>
Apr.09,2021

I wrote the article. I'll fill in the hole.

first of all, there is no problem for the anti-shake logic to be used here, and the possible effect is that the user swipes the mouse and does not want to change the display state in a hurry, so there is a buffer time.

then, this code has no problem with a single element. However, triggering between multiple elements is a problem. I gave it a try and quickly crossed the three button, only the last button-controlled text hide . So, why?

because hideContact is a global variable, and hideContact.tId is also a global variable. The timeId generated by the first unhover event is given to hideContact.tId ; the unhover event of the second button, clear hideContact.tId , will clear the first unhover event; similarly, the third clear is removed, and only the unhover of the third button is executed.

when the function is called for the second time, it clears the previous timer and sets another

supplement: solution (see comments), multiple modules sharing a state will make an error, so separate the state of each module will be OK, how to write the specific code will not be detailed.


logically, the first one to move in will not disappear, and if you cross it quickly, the hiding of the first one will not be triggered. I don't know why I moved in last and didn't disappear.

< hr >

I agree with the opinion downstairs. There is no need to add anti-shake when moving out. Immediately after removal, clear the displayed setTimeout and hide it. There is nothing wrong with the visual effect.

<script type="text/javascript">
    $(function() {
        $('.service_action_btn').hover(function() {
            var id_str = $(this).data('id');
            debounce(showContact, $(id_str));
        }, function() {
            var id_str = $(this).data('id');
            clearTimeout(showContact.tId);
            hideContact.call($(id_str));
        });
    });

    function debounce(method, context) {
        clearTimeout(method.tId);
        method.tId = setTimeout(function() {
            method.call(context);
        }, 500);
    }

    function showContact() {
        this.show();
    }
    function hideContact() {
        this.hide();
    }
</script>
< hr >

found that the relevant tag on the right side of codeshelper is a similar effect https://codeshelper.com/t/se., and show and hide are delayed, think about changing the code, hide without anti-shake only add delay.

<script type="text/javascript">
    $(function() {
        $('.service_action_btn').hover(function() {
            var id_str = $(this).data('id');
            debounce(showContact, $(id_str), true);
        }, function() {
            var id_str = $(this).data('id');
            debounce(hideContact, $(id_str), false);
        });
    });

    function debounce(method, context, show) {
        show ? clearTimeout(method.tId) : clearTimeout(showContact.tId);
        method.tId = setTimeout(function() {
            method.call(context);
        }, 500);
    }

    function showContact() {
        this.show();
    }
    function hideContact() {
        this.hide();
    }
</script>

hover events do not shake. If you add debounce, you may have your current problem, because the code may not be executed.
hover is only triggered once, not continuously, and it is not necessary to shake off.


is hideContact executed earlier than showContract? You print out the time in two ways to see if this is the problem.


what do you do to delay when you move the mouse out? Oh, the logic of the mouse move out should be to directly clear the timing function

 $(function() {
        $('.service_action_btn').hover(function() {
            var id_str = $(this).data('id');// -sharpcontact_qq
            debounce(showContact, $(id_str));
        }, function() {
            if (showConcat.tId){
               clearTimeout(showConcat.tId)
               showConcat.tId=null
            }
        });
    });
Menu