Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Why does some Javascript not enqueue correctly? WordPress

I take a well known premium theme that works well on many sites.

Now I build a new site. Now I add a small audio player. That seems to work fine, but now the dropdown menus don't show up on hover in the top nav.

In FireFox, using FireBug, I look at the page. There are no relevant errors. The only error is:

FB.getLoginStatus() called before calling FB.init().

So, what could cause the dropdowns to stop working?

What are some of the first things I should check for?

Answers (5)

2013-09-13

Francisco Javier Carazo Gil answers:

Have you tried to enqueue it in footer instead in header. Also it is important to see dependencies, maybe you have to wait to another JS to be executed.

Which JS calls FB.init(), this JS should be a dependency of the one which executes FB.getLoginStatus().


Lawrence Krubner comments:


This is all the Javascript on the page. I'm using the [[LINK href="https://github.com/cutout/gravy"]]Gravy[[/LINK]] theme. The drop down menus stopped working when the code for the audio player was added. There must be some kind of Javascript conflict, though there is no error message in FireBug. Another possibility is that some Javascript was previously being included and now, for some reason, is not.

<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>



<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver=1.7.2'></script>




<script type="text/javascript" src="//use.typekit.net/myi2ega.js"></script>



js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";


<link href="http://www.example.com/wp-content/plugins/html5-jquery-audio-player-pro/includes/css/style.css" type="text/css" rel="stylesheet" media="screen" />
<script type="text/javascript" src="http://www.example.com/wp-content/plugins/html5-jquery-audio-player-pro/includes/jquery-jplayer/jquery.jplayer.js"></script>
<script type="text/javascript">
/**
* Originally created by 23rd and Walnut for Codebasehero.com, then modified for WordPress plugin by Enigma Digital
* www.23andwalnut.com
* www.codebasehero.com
* www.enigmaweb.com.au
* License: MIT License
*/
jQuery.noConflict();
(function($) {
$.fn.ttwMusicPlayer = function(playlist, userOptions) {
var $self = this, defaultOptions, options, cssSelector, appMgr, playlistMgr, interfaceMgr, ratingsMgr, playlist,
layout, ratings, myPlaylist, current;

cssSelector = {
jPlayer: "#jquery_jplayer",
jPlayerInterface: '.jp-interface',
playerPrevious: ".jp-interface .jp-previous",
playerNext: ".jp-interface .jp-next",
trackList:'.tracklist',
tracks:'.tracks',
track:'.track',
trackRating:'.rating-bar',
trackInfo:'.track-info',
rating:'.rating',
rating_succes:'.rating-succes',
ratingLevel:'.rating-level',
ratingLevelOn:'.on',
title: '.title',
duration: '.duration',
price: '.price',
buy:'.buy',
buyy:'.buyy',
buyyy:'.buyyy',
buyNotActive:'.not-active',
buyyNotActive:'.nott-active',
buyyyNotActive:'.nottt-active',
buyActive:'.isactive',
playing:'.playing',
moreButton:'.more',
player:'.player',
artist:'.artist',
artistOuter:'.artist-outer',
albumCover:'.hmp_cover',
description:'.description',
descriptionShowing:'.showing'
};

defaultOptions = {
ratingCallback:null,
currencySymbol:'$',
//buyText:'BUY',
//buyyText:'BUY',
//buyyyText:'BUY',
tracksToShow:5,
autoplay:false,
jPlayer:{}
};

options = $.extend(true, {}, defaultOptions, userOptions);

myPlaylist = playlist;

current = 0;

appMgr = function() {
playlist = new playlistMgr();
layout = new interfaceMgr();

layout.buildInterface();
playlist.init(options.jPlayer);

//don't initialize the ratings until the playlist has been built, which wont happen until after the jPlayer ready event
$self.bind('mbPlaylistLoaded', function() {
$self.bind('mbInterfaceBuilt', function() {
ratings = new ratingsMgr();
});
layout.init();

});
};

playlistMgr = function() {

var playing = false, markup, $myJplayer = {},$tracks,showHeight = 0,remainingHeight = 0,$tracksWrapper, $more;

markup = {
listItem:'<li class="track">' +
'<span class="title"></span>' +
'<div class="rightdiv"><div class="button-float">' +
'' +
'</div>' +
'<div style="float:right;"><span class="duration"></span>' +
'<span class="price"></span>'+
'<span class="votes"></span></div></div>' +
'</li>',
ratingBar:'<span class="rating-level rating-bar"></span>'
};

function init(playlistOptions) {

$myJplayer = $('.ttw-music-player .jPlayer-container');


var jPlayerDefaults, jPlayerOptions;

jPlayerDefaults = {
swfPath: "jquery-jplayer",
supplied: "mp3, oga",
solution:'html, flash',
cssSelectorAncestor: cssSelector.jPlayerInterface,
errorAlerts: false,
warningAlerts: false
};

//apply any user defined jPlayer options
jPlayerOptions = $.extend(true, {}, jPlayerDefaults, playlistOptions);

$myJplayer.bind($.jPlayer.event.ready, function() {

//Bind jPlayer events. Do not want to pass in options object to prevent them from being overridden by the user
$myJplayer.bind($.jPlayer.event.ended, function(event) {
playlistNext();
});

$myJplayer.bind($.jPlayer.event.play, function(event) {
$myJplayer.jPlayer("pauseOthers");
$tracks.eq(current).addClass(attr(cssSelector.playing)).siblings().removeClass(attr(cssSelector.playing));
});

$myJplayer.bind($.jPlayer.event.playing, function(event) {
playing = true;
});

$myJplayer.bind($.jPlayer.event.pause, function(event) {
playing = false;
});

//Bind next/prev click events
$(cssSelector.playerPrevious).click(function() {
playlistPrev();
$(this).blur();
return false;
});

$(cssSelector.playerNext).click(function() {
playlistNext();
$(this).blur();
return false;
});

$self.bind('mbInitPlaylistAdvance', function(e) {
var changeTo = this.getData('mbInitPlaylistAdvance');

if (changeTo != current) {
current = changeTo;
playlistAdvance(current);
}
else {
if (!$myJplayer.data('jPlayer').status.srcSet) {
playlistAdvance(0);
}
else {
togglePlay();
}
}
});

buildPlaylist();
//If the user doesn't want to wait for widget loads, start playlist now
$self.trigger('mbPlaylistLoaded');

playlistInit(options.autoplay);
});

//Initialize jPlayer
$myJplayer.jPlayer(jPlayerOptions);
}

function playlistInit(autoplay) {
current = 0;

if (autoplay) {
playlistAdvance(current);
}
else {
playlistConfig(current);
$self.trigger('mbPlaylistInit');
//$myJplayer.jPlayer("play");

}
}

function playlistConfig(index) {
current = index;
$myJplayer.jPlayer("setMedia", myPlaylist[current]);
}

function playlistAdvance(index) {
playlistConfig(index);

if (index >= options.tracksToShow)
showMore();

$self.trigger('mbPlaylistAdvance');
$myJplayer.jPlayer("play");
}

function playlistNext() {
var index = (current + 1 < myPlaylist.length) ? current + 1 : 0;
playlistAdvance(index);
}

function playlistPrev() {
var index = (current - 1 >= 0) ? current - 1 : myPlaylist.length - 1;
playlistAdvance(index);
}

function togglePlay() {
if (!playing)
$myJplayer.jPlayer("play");
else $myJplayer.jPlayer("pause");
}

function buildPlaylist() {
var $ratings = $();

$tracksWrapper = $self.find(cssSelector.tracks);

//set up the html for the track ratings
for (var i = 0; i < 10; i++)
$ratings = $ratings.add(markup.ratingBar);

for (var j = 0; j < myPlaylist.length; j++) {
var $track = $(markup.listItem);

//since $ratings refers to a specific object, if we just use .html($ratings) we would be moving the $rating object from one list item to the next
$track.find(cssSelector.rating).html($ratings.clone());

$track.find(cssSelector.title).html(trackName(j));

$track.find(cssSelector.duration).html(duration(j));
$track.find(cssSelector.price).html(price(j));

// setRating('track', $track, j);

setBuyLink($track, j);
setBuyyLink($track, j);
setBuyyyLink($track, j);

$track.data('index', j);

$tracksWrapper.append($track);
}

$tracks = $(cssSelector.track);

$tracks.slice(0, options.tracksToShow).each(function() {
showHeight += $(this).outerHeight();
});

$tracks.slice(options.tracksToShow, myPlaylist.length).each(function() {
remainingHeight += $(this).outerHeight();
});

if (remainingHeight > 0) {
var $trackList = $(cssSelector.trackList);

$tracksWrapper.height(showHeight);
$trackList.addClass('show-more-button');

$trackList.find(cssSelector.moreButton).click(function() {
$more = $(this);

showMore();
});
}

$tracks.find('.title').click(function() {
playlistAdvance($(this).parents('li').data('index'));
});
}

function showMore() {
if (isUndefined($more))
$more = $self.find(cssSelector.moreButton);

$tracksWrapper.animate({height: showHeight + remainingHeight}, function() {
$more.animate({opacity:0}, function() {
$more.slideUp(function() {
$more.parents(cssSelector.trackList).removeClass('show-more-button');
$more.remove();

});
});
});
}

function duration(index) {
return !isUndefined(myPlaylist[index].duration) ? myPlaylist[index].duration : '-';
}

function price(index) {
return (!isUndefined(myPlaylist[index].price) ? options.currencySymbol + myPlaylist[index].price : '');
}

function setBuyLink($track, index) {
if (!isUndefined(myPlaylist[index].buy)) {
$track.find(cssSelector.buy).addClass(attr(cssSelector.buyActive)).attr('href', myPlaylist[index].buy).html(buyText(index));
}else{$track.find(cssSelector.buy).addClass(attr(cssSelector.buyNotActive)); }
}

function setBuyyLink($track, index) {
if (!isUndefined(myPlaylist[index].buyy)) {
$track.find(cssSelector.buyy).addClass(attr(cssSelector.buyActive)).attr('href', myPlaylist[index].buyy).html(buyyText(index));
}else{$track.find(cssSelector.buyy).addClass(attr(cssSelector.buyyNotActive)); }
}

function setBuyyyLink($track, index) {
if (!isUndefined(myPlaylist[index].buyyy)) {
$track.find(cssSelector.buyyy).addClass(attr(cssSelector.buyActive)).attr('href', myPlaylist[index].buyyy).html(buyyyText(index));
}else{$track.find(cssSelector.buyyy).addClass(attr(cssSelector.buyyyNotActive)); }
}

function buyyyText(index) {
return options.buyyyText;
}

function buyyText(index) {
return options.buyyText;
}

function buyText(index) {
//return (!isUndefined(myPlaylist[index].price) ? options.currencySymbol + myPlaylist[index].price : '') + ' ' + options.buyText;
return options.buyText;
}

return{
init:init,
playlistInit:playlistInit,
playlistAdvance:playlistAdvance,
playlistNext:playlistNext,
playlistPrev:playlistPrev,
togglePlay:togglePlay,
$myJplayer:$myJplayer
};

};

ratingsMgr = function() {
var $tracks = $self.find(cssSelector.track);
//Handler for when user hovers over a rating
$(cssSelector.rating).find(cssSelector.ratingLevel).hover(function() {
$(this).addClass('hover').prevAll().addClass('hover').end().nextAll().removeClass('hover');
});
//Restores previous rating when user is finished hovering (assuming there is no new rating)
$(cssSelector.rating).mouseleave(function() {
$(this).find(cssSelector.ratingLevel).removeClass('hover');
});


function bindEvents() {
$(cssSelector.rating_succes).css('display','none');
//Set the new rating when the user clicks
$(cssSelector.ratingLevel).click(function() {
var $this = $(this), rating = $this.parent().children().index($this) + 1, index;

var trackname = $(cssSelector.title+':first').text();


var postdata1 = 'action=my_special_ajax_call5&rating='+rating+'&trackname='+trackname;
//alert(postdata1);
jQuery.ajax({
type:'POST',
url:ajaxurl,
cache:false,
data: postdata1,
beforeSend:function(){

},
success:function(res){
$(cssSelector.rating_succes).html(res).fadeIn(500).delay(1000).fadeOut(500);
//window.setTimeout(function(){location.reload()},2000);

}
});
$this.prevAll().add($this).addClass(attr(cssSelector.ratingLevelOn)).end().end().nextAll().removeClass(attr(cssSelector.ratingLevelOn));
});
}



bindEvents();
};

interfaceMgr = function() {

var $player, $title, $artist, $albumCover;


function init() {
$player = $(cssSelector.player),
$title = $player.find(cssSelector.title),
$artist = $player.find(cssSelector.artist),
$albumCover = $player.find(cssSelector.albumCover);

setDescription();

$self.bind('mbPlaylistAdvance mbPlaylistInit', function() {
setTitle();
setArtist();
setRating('current', null, current);
setCover();
});
}


function buildInterface() {
var markup, $interface;

//I would normally use the templating plugin for something like this, but I wanted to keep this plugin's footprint as small as possible
markup = '<div class="ttw-music-player">' +
'<div class="player jp-interface">' +
'<div class="album-cover" id="check_cover">' +
'<span class="hmp_cover"></span>' +
' <span class="highlight"></span>' +
' </div>' +
' <div class="track-info">' +
' <p class="title"></p>' +
' <p class="artist-outer">By <span class="artist"></span></p>' +
' <div class="rating">' +
' <span class="rating-level rating-star"></span>' +
' <span class="rating-level rating-star"></span>' +
' <span class="rating-level rating-star"></span>' +
' <span class="rating-level rating-star"></span>' +
' <span class="rating-level rating-star"></span>' +
' <span class="rating-succes">Already rated</span>' +
' </div>' +
' </div>' +
' <div class="player-controls">' +
' <div class="main">' +
' <div class="previous jp-previous"></div>' +
' <div class="play jp-play"></div>' +
' <div class="pause jp-pause"></div>' +
' <div class="next jp-next"></div>' +
'<!-- These controls aren\'t used by this plugin, but jPlayer seems to require that they exist -->' +
' <span class="unused-controls">' +
' <span class="jp-video-play"></span>' +
' <span class="jp-stop"></span>' +
' <span class="jp-mute"></span>' +
' <span class="jp-unmute"></span>' +
' <span class="jp-volume-bar"></span>' +
' <span class="jp-volume-bar-value"></span>' +
' <span class="jp-volume-max"></span>' +
' <span class="jp-current-time"></span>' +
' <span class="jp-duration"></span>' +
' <span class="jp-price"></span>' +
' <span class="jp-full-screen"></span>' +
' <span class="jp-restore-screen"></span>' +
' <span class="jp-repeat"></span>' +
' <span class="jp-repeat-off"></span>' +
' <span class="jp-gui"></span>' +
' </span>' +
' </div>' +
' <div class="progress-wrapper">' +
' <div class="progress jp-seek-bar">' +
' <div class="elapsed jp-play-bar"></div>' +
' </div>' +
' </div>' +
' </div>' +
' </div>'+
' <div class="tracklist">' +
' <ol class="tracks"> </ol>' +
' <div class="more">View More...</div>' +
' </div>' +
' <div class="jPlayer-container"></div>' +
'</div>';

$interface = $(markup).css({display:'none', opacity:0}).appendTo($self).slideDown('slow', function() {
$interface.animate({opacity:1});

$self.trigger('mbInterfaceBuilt');
});
}

function setTitle() {
$title.html(trackName(current));
}

function setArtist() {
if (isUndefined(myPlaylist[current].artist))
$artist.parent(cssSelector.artistOuter).animate({opacity:0}, 'fast');
else {
$artist.html(myPlaylist[current].artist).parent(cssSelector.artistOuter).animate({opacity:1}, 'fast');
}
}

function setCover() {

$albumCover.animate({opacity:0}, 'fast', function() {
if (!isUndefined(myPlaylist[current].cover)) {
$("#check_cover").removeClass('classtohide');
var now = current;

if(now == current){
$albumCover.css({opacity:1}).html('<img src="' + myPlaylist[current].cover + '" alt="album cover" />');
}
}else{
document.getElementById("check_cover").className += " classtohide";
}
});
}

function setDescription() {
if (!isUndefined(options.description))
$self.find(cssSelector.description).html(options.description).addClass(attr(cssSelector.descriptionShowing)).slideDown();
}

return{
buildInterface:buildInterface,
init:init
}

};

/** Common Functions **/
function trackName(index) {
if (!isUndefined(myPlaylist[index].title))
return myPlaylist[index].title;
else if (!isUndefined(myPlaylist[index].mp3))
return fileName(myPlaylist[index].mp3);
else if (!isUndefined(myPlaylist[index].oga))
return fileName(myPlaylist[index].oga);
else return '';
}

function fileName(path) {
path = path.split('/');
return path[path.length - 1];
}

function setRating(type, $track, index) {
if (type == 'track') {
if (!isUndefined(myPlaylist[index].rating)) {
applyTrackRating($track, myPlaylist[index].rating);
}
}
else {
//if the rating isn't set, use 0
var rating = !isUndefined(myPlaylist[index].rating) ? Math.ceil(myPlaylist[index].rating) : 0;
applyCurrentlyPlayingRating(rating);
}
}

function applyCurrentlyPlayingRating(rating) {
//reset the rating to 0, then set the rating defined above
$self.find(cssSelector.trackInfo).find(cssSelector.ratingLevel).removeClass(attr(cssSelector.ratingLevelOn)).slice(0, rating).addClass(attr(cssSelector.ratingLevelOn));

}


/** Utility Functions **/
function attr(selector) {
return selector.substr(1);
}

function runCallback(callback) {
var functionArgs = Array.prototype.slice.call(arguments, 1);

if ($.isFunction(callback)) {
callback.apply(this, functionArgs);
}
}

function isUndefined(value) {
return typeof value == 'undefined';
}

appMgr();
};
})(jQuery);

(function($) {
// $('img.photo',this).imagesLoaded(myFunction)
// execute a callback when all images have loaded.
// needed because .load() doesn't work on cached images

// mit license. paul irish. 2010.
// webkit fix from Oren Solomianik. thx!

// callback function is passed the last image to load
// as an argument, and the collection as `this`


$.fn.imagesLoaded = function(callback) {
var elems = this.filter('img'),
len = elems.length;

elems.bind('load',
function() {
if (--len <= 0) {
callback.call(elems, this);
}
}).each(function() {
// cached images don't fire load sometimes, so we reset src.
if (this.complete || this.complete === undefined) {
var src = this.src;
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
// data uri bypasses webkit log warning (thx doug jones)
this.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
this.src = src;
}
});

return this;
};
})(jQuery);


</script><script type="text/javascript">


var myPlaylist = [





{
mp3:'http://www.example.com/wp-content/uploads/2013/08/ConsortPavane.mp3',
oga:'http://www.example.com/wp-content/uploads/2013/09/ConsortPavane.ogg',
title:'Pavane',
artist:'Gabriel Fauré',
rating:'0',
price:'',
duration:'',
}, ];


jQuery(document).ready(function(){
jQuery('#myplayer').ttwMusicPlayer(myPlaylist, {

currencySymbol:'',
description:'',
buyText:'',
buyyText:'',
buyyyText:'',
autoplay:false,

});
});

</script>
<div id="myplayer"></div>


<script type='text/javascript' src='http://www.example.com/wp-includes/js/thickbox/thickbox.js?ver=3.1-20121105'></script>



Lawrence Krubner comments:

Here is an example of the Gravy theme:

http://dgparchitects.briworks.com/

The drop down menu is working in that example, as you can see in the screenshot. But somehow it does not work on my own site.