Chrome 20.x issue (bug?) with classes applied/removed at intervals via jQuery
Here's a fun one for those of you who love to bang your heads against the computer keyboard.
Site: http://blduke.com.php53-27.dfw1-2.websitetestlink.com
Fun little jQuery thing going on right below the navigation here. It's actually a radial menu (plugin). The plugin includes functions that will trigger the rotation clockwise and counterclockwise, and by default the radial menu isn't shown. So I've got the code to initialize the radial menu, the code to show it immediately, and code to trigger the next rotation at intervals. Finally I've used the plugin's API to hook into the afterAnimation option to make sure that an "active" class is applied to the "active" menu item - I'm going to use it to do some fun CSS stuff, rotate some to the right of this graphic, etc. You can see that the "active" class on the list items right now just adds a red background.
This works absolutely perfectly in IE8+, Firefox, Safari, and versions 17.0-19.0 of Chrome. In Chrome 20.x it breaks in a weird way.
The active class still swaps to the appropriate list item when it should, but the browser is doing something weird, like delaying the rendering of the active class on the new item, or skipping it entirely at some points, or showing it on two items (the item it was last on, and the next one)
No script errors, and I'm baffled, as is the plugin dev. Anyone have any ideas, insight?
My Code:
jQuery(document).ready(function($) {
$("#radial_container").radmenu({
listClass: 'list', // the list class to look within for items
itemClass: 'item', // the items - NOTE: the HTML inside the item is copied into the menu item
radius: 130, // radius in pixels
animSpeed:400, // animation speed in millis
centerX: 0, // the center x axis offset
centerY: 0, // the center y axis offset
angleOffset: 30, // in degrees,
afterAnimation: function($m){ // after the animation triggers, grab the "active" menu item (object) to recieve the "active" class
$("#radial_container").radmenu(2);
}
}).radmenu("show"); // Show the menu straight off, we don't need to trigger with a click
setInterval(function() { // automatically rotate the menu at intervals
$('#radial_container').radmenu('next');
}, 4000);
});
I edited your code slightly while testing locally:
setInterval(function() { // automatically rotate the menu at intervals
$('.radial_div div').removeClass('active'); //add this line
$('#radial_container').radmenu('next');
}, 4000);
Tested on Chrome 20 and FF16a.
This will ensure that all divs lose the active
class when you call the rotation plugin, and it is properly added back to the top item when the afterAnimation
function runs.
Then new issue seems quite hard to debug, as I can't get it to happen constantly. However, try this:
afterAnimation: function($m){ // after the animation triggers, grab the "active" menu item (object) to recieve the "active" class
setTimeout(function() {
$("#radial_container").radmenu(2);
}, 0);
}
This will ensure that the radmenu
function is only called after the current function stack has finished processing, I watched it for a couple minutes and it didn't bug even once.
Also, if you want to start the top item with the active
class already, you can just add:
$('.radial_div div:nth-child(3)').addClass('active');
Anywhere inside the .ready
function.
Why do you need a plugin for that? You are just animating top and left of three simple elements. Why not write it manually. It won't be longer that the sample code you provided for sure.
function setPosition(element, position) {
var placements = [[100,100], [200, 200], [0, 200]] ; //for instance
$(element).stop().animate({left: placements[position][0]+ 'px', top: placements[position][1] + 'px'});
if (position == 0) { $(element).addClass('activeMenuItem');}
}
var state = 0;
function rotateMenu(direction) {
state += direction;
if (state < 0) state = 2;
if (state > 2) state = 0;
$('.menuItem').removeClass('activeMenuItem');
setPosition('#item0', state % 3);
setPosition('#item1', (state + 1) % 3);
setPosition('#item2', (state + 2) % 3);
}
That's it. rotateMenu(1)
rotates to one direction while rotateMenu(-1)
rotates it another direction.
Your menu items will have class="menuItem" and id="item".
Here is jsFiddle for a little demo.
链接地址: http://www.djcxy.com/p/10988.html