Is there a more efficient method to halt a jQuery animation plugin? Surely, there must be a more effective solution

After feeling under the weather for the past week and feeling incredibly bored, I decided to delve into the world of creating jQuery plugins. In just half an hour, I managed to put together a plugin that mimics the "wiggle" effect when pressing and holding down on a specific icon on an i(Phone|Pad|Pod Touch). Implementing the initial "wiggle" effect using CSS3 transitions was a breeze.

If you're curious to see the plugin in action, you can check it out here:

However, I hit a roadblock when trying to figure out how to make the icons stop wiggling. As someone new to creating jQuery plugins, I'm still trying to fully grasp how to save and manipulate the state of selected objects for future reference, such as through a callback or event.

To address this challenge, I resorted to creating an array to keep track of all the matched objects. This array serves as a way to maintain the state of objects with the wiggle effect applied.

Although my current solution technically works, it feels somewhat inefficient. I can't help but wonder if there's a more efficient, possibly built-in method within jQuery to achieve the same outcome.

If anyone could review this simple plugin and provide insights on how I can improve it, I would greatly appreciate it. I'm not looking for someone to rewrite my code, but rather some guidance through a real-world example or solid documentation.

Thank you in advance! :)

For those interested, here is the source code of the plugin:

Answer №1

To keep track of setTimeout's result in each object, you can do the following:

object.timeout = setTimeout(function(){
methods.rotate(object, step+1);
}, options.delay);

To stop the setTimeout function, simply call clearTimeout on the object:

clearTimeout(object.timeout);

Here is the updated plugin with these modifications:

(function($){
var rotatingObjectCollection = [];

$.fn.wiggle = function(method, options) {
    options = $.extend({
        rotateDegrees: ['1','2','1','0','-1','-2','-1','0'],
        delay: 35
    }, options);

    var methods = {
        rotate: function(object, step){
            if(step === undefined) {
                step = Math.floor(Math.random()*options.rotateDegrees.length);
            }

            var degree = options.rotateDegrees[step];
            $(object).css({
                '-webkit-transform': 'rotate('+degree+'deg)',
                '-moz-transform': 'rotate('+degree+'deg)'
            });

            if(step == (options.rotateDegrees.length - 1)) {
                step = 0;
            }

            object.timeout = setTimeout(function(){
                methods.rotate(object, step+1);
            }, options.delay);
        },
        stop: function(object) {
            $(object).css({
                '-webkit-transform': 'rotate(0deg)',
                '-moz-transform': 'rotate(0deg)'
            });

            clearTimeout(object.timeout);
            object.timeout = null;
        }
    };

    this.each(function() {
        if((method == 'start' || method === undefined) && !this.timeout) {
            methods.rotate(this);
        } else if (method == 'stop') {
            methods.stop(this);
        }
    });
    return;
}
})(jQuery);

While it may not be conventional to store custom data within objects like this, it does get the job done :)

Answer №2

To ensure smooth animation performance and prevent potential browser crashes, it is advisable to check if the targeted element is already in a wiggling state before initiating the animation again. This precaution is particularly important in cases where a user may repeatedly trigger the animation, causing the elements to get stuck in a loop.
Furthermore, maintaining chainability in your jQuery plugin is essential for seamless integration with other functions. The current implementation breaks the jQuery chain, preventing users from chaining additional actions after calling the plugin. By making a few adjustments, such as returning the plugin object at the end of execution, you can enable scenarios like

$(selector).wiggle().doSomethingElse();
.
The optimized version of the plugin code would resemble the following:

(function($){
$.fn.wiggle = function(method, options) {
    options = $.extend({
        rotateDegrees: ['1','2','1','0','-1','-2','-1','0'],
        delay: 35
    }, options);

    var methods = {
        rotate: function(object, step){
            if(step === undefined) {
                step = Math.floor(Math.random()*options.rotateDegrees.length);
            }

            var degree = options.rotateDegrees[step];
            $(object).css({
                '-webkit-transform': 'rotate('+degree+'deg)',
                '-moz-transform': 'rotate('+degree+'deg)'
            });

            if(step == (options.rotateDegrees.length - 1)) {
                step = 0;
            }

            object.timeout = setTimeout(function(){
                methods.rotate(object, step+1);
            }, options.delay);
            $(object).data('wiggling',true);
        },
        stop: function(object) {
            $(object).css({
                '-webkit-transform': 'rotate(0deg)',
                '-moz-transform': 'rotate(0deg)'
            });
            clearTimeout(object.timeout);
            $(object).data('wiggling',false);
        }
    };

    this.each(function() {
        if($(object).data('wiggling') == true && (method == 'start' || method === undefined)) {
            methods.rotate(this);
        } else if (method == 'stop') {
            methods.stop(this);
        }
    });
    return this;
}
})(jQuery);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Hover over with your mouse to open and close the dropdown menu in React JS

Just starting out with React JS and encountering a small issue. I'm trying to make the menu disappear when the mouse leaves that area, so I used onMouseOut and onMouseLeave to close it. However, I noticed that having these options in place prevents th ...

Align text vertically within Bootstrap carousel area

I'm struggling with centering text both horizontally and vertically in a Bootstrap 4 carousel. I've set up the bootply with a carousel, but the text is stuck in the upper left corner instead of being centered on the screen. <div class="carou ...

Add CSS styling to a particular div element when a button is clicked

I have been working on a new feature that involves highlighting a div in a specific color and changing the mouse pointer to a hand cursor. I successfully achieved this by adding a CSS class: .changePointer:hover { cursor: pointer; background-color ...

React Navigation Item Toolbar Misplacement

I've been trying to align the navigation item with the logo on the same line within the toolbar, but I'm facing an issue where they keep appearing in different rows. To see the error for yourself, check out the code sandbox here. This is how I s ...

Tips for applying various CSS properties to a single element using styled-components

Is there a way to style similar elements differently using different CSS properties in styled components? For example: <div></div> <div></div> With the knowledge I have, I can do: export const StyledDiv = styled.div` color: red; ` ...

JQuery is not able to render Hindi content properly

I am attempting to showcase some Hindi words using JQuery because these are essential contents that need to be displayed on every page of the website. Please note that this is a static website built with HTML and JQuery/JavaScript. Below is my JS file: in ...

Utilizing jQuery AJAX to Send an HTML Array to PHP

In my current HTML forms and jQuery AJAX workflow within the Codeigniter Framework, I've encountered a common issue that has yet to be resolved to suit my specific requirements. Here's the situation: HTML - The form includes an array named addre ...

Utilize a function from a separate JavaScript file by calling it within the $(document).ready(function()

Refer to this post for more information: Click here I attempted to access a function that was defined in another .js file based on the instructions from the post. However, I encountered an issue. Take a look at my code below: sildemenu.js $(document).re ...

Utilizing eval properly in JavaScript

One method I am using is to load a different audio file by clicking on different texts within a web page. The jQuery function I have implemented for this purpose is as follows: var audio = document.createElement('audio'); $(".text_sample ...

What is the best way to incorporate a specific term from the class into CSS styling

I am working on a webpage that includes '<a> <i> <label>' elements with specific classes. <a class="icon-home"></a> <label class="icon-pencil"></label> <i class="icon-display"></i> I want to ...

Executing Javascript code from a specified web address

Let's say I have an image that needs to be shifted vertically, and I achieve it using the following code snippet: document.getElementById('ImgID1').style.verticalAlign = However, the value by which I need to shift the image is provided thr ...

Troubleshooting problems with jQuery mmenu on Windows Phone (IE Mobile)

I am currently working on optimizing the mobile version of a website, utilizing jQuery MMenu for the menu. The functionality is seamless on various phones and tablets I have tested, except for Windows Phones... Even with the plugin configured with the "po ...

Transforming Highchart Drilldown Subtitles

Is there a way to modify the subtitle without altering the title? series: { cursor: 'pointer', point: { events: { click: function() {//alert ('Category: '+ this.category +&ap ...

Material design for Angular applications - Angular Material is

Recently, I decided to explore the world of Angular and its accompanying libraries - angular-material, angular-aria, and angular-animate. I'm eager to experiment with this new styling technique, but it seems like I've hit a roadblock right at the ...

Making adjustments to a Jquery data attribute can have a direct impact on CSS

My CSS is using a data attribute, but when I try to change it with jQuery, the change is not reflected on the screen or in the DOM. $('#new-1').data('count', 5); .fa-stack[data-count]:after { position: absolute; right: -20%; to ...

IIS Alert: Missing Images, CSS, and Scripts!

When I tried to publish my website using IIS, I encountered the error message Cannot read configuration file due to insufficient permissions. After attempting to add permissions for IIS_USRS and realizing that this user does not exist on my computer runnin ...

Shadow effect is present under every cell in the table row

I am struggling to create an HTML table with proper vertical spacing between rows and a shadow effect beneath each row. Unfortunately, the shadow always ends up overlapping other table content. I have tried adjusting the positioning of elements and setti ...

Is there a way to streamline a function that substitutes certain words?

Looking for ways to simplify my function that shortens words when the label wraps due to different screen resolutions. It seems like it could be more efficient to use arrays for long and short word pairs, but I'm not sure how to implement it. Check ou ...

Setting a div's background using JavaScript works flawlessly on jsfiddle.net, but encounters issues when implemented in actual code

contains the files you need. For reference, here is the link to the code on I have attempted to remove all unnecessary elements from the actual project, but it has not made a difference. document.getElementById("image").style.backgroundImage = "url(" + d ...

"Enhance your JQGrid experience with the Free-JQGrid Multiselect toolbar, which automatically refresh

I am facing an issue with refreshing my drop-down filters in the grid after making a server call to reload it. Initially, upon loading the page, the grid displays correctly with drop-down filters excluding quotes in canceled or expired status. However, w ...