开发者

Is there an easy way to find the "javascript equivalent" of jQuery code?

I am doing a presentation on jQuery for some co-workers and I would like to demonstrate how certain tasks in javascript can be made easier using jQuery.

I have come up with a small jQuery function that does some element selection/animation and I was hoping to show them the javascript equivalent of this code.

My problem is that my javascript is a bit rusty and I'd rather not try to figure out how to implemen开发者_Go百科t this using javascript. Does anyone know of a way to generate javascript from jQuery? If not, can anyone recommend a good resource for finding side by side comparisons of equivalent javascript vs jQuery?

My code:

var move = 200;
$('#clickme').click(function() {
    $('#main div:even').animate({
        left:"+="+move
    }, 2000);
    move = -move;
});


This article has a good presentation that shows off exactly what you are trying to show your coworkers.

It shows how this :

var example = null; // object
function doMove() {
  example.style.left = parseInt(example.style.left)+1+'px';
  setTimeout(doMove,20); // call doMove in 20msec
}
function init() {
  example = document.getElementById('example'); // get the "example" object
  example.style.left = '0px'; // set its initial position to 0px
  doMove(); // start animating
}
window.onload = init;

Can be turned into this :

$("#element").animate({ left: 100px; });  


Because jQuery is implemented in JS, and not translated to it (like CoffeeScript or whatever), there's no accurate way to show one vs the other.

You could get at the same idea by profiling the jQuery and showing the result - "look at all the code the jQuery team wrote for us, and we get to use basically for free!" or by showing the definition of $().attr or another, similar method that hides a bunch of browser-specific quirks.


The simplest way if you don't already know how to accomplish a task in straight JavaScript is to look at the source code, see what it's doing, and write JavaScript that does the same thing.


here is some documentation on Javascript Animation The other javascript you will be implementing here is about selecting elements like selecting by tag name


Well I think you can try

document.querySelector('#clickme')

This is essentially similar to jquery $(' ') but this will the previous will return only one element .

There is no direct way as if you go through source of jquery , you will realize that node selection is parsed using regex which is not easy to implement for each code you want to write ,

Also there is a direct relation between the methods called :

For example here :

.click(function) -> .addEventListener('click',function,false);


I'd consider just showing them a bunch of examples of how easy it is to do things in jquery - animation, DOM manipulation, etc. If they have any understanding of javascript they'll have an idea of how much work it's saving and if they don't why are they making the decision?

A big point I would bring up is that everything in jquery just works, no more cross-browser issues.


The selector is simple enough that it translates to getElementById, though if it had been more complex the Sizzle library would have been invoked to get the elements.

Click is an alias for bind, with click specified. Bind works by adding an event. Here's a snippet from the source code:

add: function( elem, types, handler, data ) {
    if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
        return;
    }

    if ( handler === false ) {
        handler = returnFalse;
    } else if ( !handler ) {
        // Fixes bug #7229. Fix recommended by jdalton
        return;
    }

    var handleObjIn, handleObj;

    if ( handler.handler ) {
        handleObjIn = handler;
        handler = handleObjIn.handler;
    }

    // Make sure that the function being executed has a unique ID
    if ( !handler.guid ) {
        handler.guid = jQuery.guid++;
    }

    // Init the element's event structure
    var elemData = jQuery._data( elem );

    // If no elemData is found then we must be trying to bind to one of the
    // banned noData elements
    if ( !elemData ) {
        return;
    }

    var events = elemData.events,
        eventHandle = elemData.handle;

    if ( !events ) {
        elemData.events = events = {};
    }

    if ( !eventHandle ) {
        elemData.handle = eventHandle = function( e ) {
            // Discard the second event of a jQuery.event.trigger() and
            // when an event is called after a page has unloaded
            return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
                jQuery.event.handle.apply( eventHandle.elem, arguments ) :
                undefined;
        };
    }

    // Add elem as a property of the handle function
    // This is to prevent a memory leak with non-native events in IE.
    eventHandle.elem = elem;

    // Handle multiple events separated by a space
    // jQuery(...).bind("mouseover mouseout", fn);
    types = types.split(" ");

    var type, i = 0, namespaces;

    while ( (type = types[ i++ ]) ) {
        handleObj = handleObjIn ?
            jQuery.extend({}, handleObjIn) :
            { handler: handler, data: data };

        // Namespaced event handlers
        if ( type.indexOf(".") > -1 ) {
            namespaces = type.split(".");
            type = namespaces.shift();
            handleObj.namespace = namespaces.slice(0).sort().join(".");

        } else {
            namespaces = [];
            handleObj.namespace = "";
        }

        handleObj.type = type;
        if ( !handleObj.guid ) {
            handleObj.guid = handler.guid;
        }

        // Get the current list of functions bound to this event
        var handlers = events[ type ],
            special = jQuery.event.special[ type ] || {};

        // Init the event handler queue
        if ( !handlers ) {
            handlers = events[ type ] = [];

            // Check for a special event handler
            // Only use addEventListener/attachEvent if the special
            // events handler returns false
            if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
                // Bind the global event handler to the element
                if ( elem.addEventListener ) {
                    elem.addEventListener( type, eventHandle, false );

                } else if ( elem.attachEvent ) {
                    elem.attachEvent( "on" + type, eventHandle );
                }
            }
        }

        if ( special.add ) {
            special.add.call( elem, handleObj );

            if ( !handleObj.handler.guid ) {
                handleObj.handler.guid = handler.guid;
            }
        }

        // Add the function to the element's handler list
        handlers.push( handleObj );

        // Keep track of which events have been used, for event optimization
        jQuery.event.global[ type ] = true;
    }

    // Nullify elem to prevent memory leaks in IE
    elem = null;
}

Note that there are various clever things going on there so that this works no matter what.

Animate works like this:

animate: function( prop, speed, easing, callback ) {
    var optall = jQuery.speed(speed, easing, callback);

    if ( jQuery.isEmptyObject( prop ) ) {
        return this.each( optall.complete, [ false ] );
    }

    // Do not change referenced properties as per-property easing will be lost
    prop = jQuery.extend( {}, prop );

    return this[ optall.queue === false ? "each" : "queue" ](function() {
        // XXX 'this' does not always have a nodeName when running the
        // test suite

        if ( optall.queue === false ) {
            jQuery._mark( this );
        }

        var opt = jQuery.extend( {}, optall ),
            isElement = this.nodeType === 1,
            hidden = isElement && jQuery(this).is(":hidden"),
            name, val, p,
            display, e,
            parts, start, end, unit;

        // will store per property easing and be used to determine when an animation is complete
        opt.animatedProperties = {};

        for ( p in prop ) {

            // property name normalization
            name = jQuery.camelCase( p );
            if ( p !== name ) {
                prop[ name ] = prop[ p ];
                delete prop[ p ];
            }

            val = prop[ name ];

            // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
            if ( jQuery.isArray( val ) ) {
                opt.animatedProperties[ name ] = val[ 1 ];
                val = prop[ name ] = val[ 0 ];
            } else {
                opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
            }

            if ( val === "hide" && hidden || val === "show" && !hidden ) {
                return opt.complete.call( this );
            }

            if ( isElement && ( name === "height" || name === "width" ) ) {
                // Make sure that nothing sneaks out
                // Record all 3 overflow attributes because IE does not
                // change the overflow attribute when overflowX and
                // overflowY are set to the same value
                opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];

                // Set display property to inline-block for height/width
                // animations on inline elements that are having width/height
                // animated
                if ( jQuery.css( this, "display" ) === "inline" &&
                        jQuery.css( this, "float" ) === "none" ) {
                    if ( !jQuery.support.inlineBlockNeedsLayout ) {
                        this.style.display = "inline-block";

                    } else {
                        display = defaultDisplay( this.nodeName );

                        // inline-level elements accept inline-block;
                        // block-level elements need to be inline with layout
                        if ( display === "inline" ) {
                            this.style.display = "inline-block";

                        } else {
                            this.style.display = "inline";
                            this.style.zoom = 1;
                        }
                    }
                }
            }
        }

        if ( opt.overflow != null ) {
            this.style.overflow = "hidden";
        }

        for ( p in prop ) {
            e = new jQuery.fx( this, opt, p );
            val = prop[ p ];

            if ( rfxtypes.test(val) ) {
                e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();

            } else {
                parts = rfxnum.exec( val );
                start = e.cur();

                if ( parts ) {
                    end = parseFloat( parts[2] );
                    unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );

                    // We need to compute starting value
                    if ( unit !== "px" ) {
                        jQuery.style( this, p, (end || 1) + unit);
                        start = ((end || 1) / e.cur()) * start;
                        jQuery.style( this, p, start + unit);
                    }

                    // If a +=/-= token was provided, we're doing a relative animation
                    if ( parts[1] ) {
                        end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
                    }

                    e.custom( start, end, unit );

                } else {
                    e.custom( start, val, "" );
                }
            }
        }

        // For JS strict compliance
        return true;
    });
}

Again, a lot of cleverness to ensure this does what you expect.

In real life, a getElementById, with an event listener, then a loop that uses setStyle on the element repeatedly to get an animation would work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜