I have a script that is hiding the links to mp3 files.
<script type="text/javascript">
<!--//--><![CDATA[//><!--
jQuery(document).ready(function($){
$('a.sm2_button').each(function (i, el) {
var data = jQuery(el).data('song_link') || jQuery(el).data('song_link', undefined);
if (!data) {
jQuery(el).data('song_link', el.href);
el.href = '#';
el.setAttribute('href', '#');
}
$(el).bind("contextmenu", function(e) {
e.preventDefault();
});
});
});
//--><!]]>
</script>
The problem that I’m having is that after an ajax call the first part of the above code gets to run again and it ruins the ‘song_link’ of the html that was already there before the ajax call.
When I comment out the above code, it works well, but the links are not hidden anymore. Thus I’m sure the problem is with the above code.
Apparently there is no way to debug/watch the data elements that the jquery data function is using.https://stackoverflow.com/questions/65421997/how-to-see-jquerys-data-with-developer-tools
For playing the mp3 files I’m using this:
/**
* SoundManager 2 Demo: Play MP3 links via button
* ----------------------------------------------
*
* http://schillmania.com/projects/soundmanager2/
*
* A simple demo making MP3s playable "inline"
* and easily styled/customizable via CSS.
*
* A variation of the "play mp3 links" demo.
*
* Requires SoundManager 2 Javascript API.
*/
/*jslint white: false, onevar: true, undef: true, nomen: false, eqeqeq: true, plusplus: false, bitwise: true, regexp: false, newcap: true, immed: true */
/*global document, window, soundManager, navigator */
function BasicMP3Player() {
var self = this,
pl = this,
sm = soundManager, // soundManager instance
isTouchDevice = (navigator.userAgent.match(/ipad|iphone/i)),
isIE = (navigator.userAgent.match(/msie/i));
this.excludeClass = 'button-exclude'; // CSS class for ignoring MP3 links
this.links = [];
this.sounds = [];
this.soundsByURL = {};
this.indexByURL = {};
this.lastSound = null;
this.soundCount = 0;
this.config = {
// configuration options
playNext: false, // stop after one sound, or play through list until end
autoPlay: false // start playing the first sound right away
};
this.css = {
// CSS class names appended to link during various states
sDefault: 'sm2_button', // default state
sLoading: 'sm2_loading',
sPlaying: 'sm2_playing',
sPaused: 'sm2_paused'
};
// event + DOM utils
this.includeClass = this.css.sDefault;
this.addEventHandler = (typeof window.addEventListener !== 'undefined' ? function(o, evtName, evtHandler) {
return o.addEventListener(evtName,evtHandler,false);
} : function(o, evtName, evtHandler) {
o.attachEvent('on'+evtName,evtHandler);
});
this.removeEventHandler = (typeof window.removeEventListener !== 'undefined' ? function(o, evtName, evtHandler) {
return o.removeEventListener(evtName,evtHandler,false);
} : function(o, evtName, evtHandler) {
return o.detachEvent('on'+evtName,evtHandler);
});
this.classContains = function(o,cStr) {
return (typeof(o.className)!=='undefined'?o.className.match(new RegExp('(\s|^)'+cStr+'(\s|$)')):false);
};
this.addClass = function(o,cStr) {
if (!o || !cStr || self.classContains(o,cStr)) {
return false;
}
o.className = (o.className?o.className+' ':'')+cStr;
};
this.removeClass = function(o,cStr) {
if (!o || !cStr || !self.classContains(o,cStr)) {
return false;
}
o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),'');
};
this.getSoundByURL = function(sURL) {
return (typeof self.soundsByURL[sURL] !== 'undefined' ? self.soundsByURL[sURL] : null);
};
this.isChildOfNode = function(o,sNodeName) {
if (!o || !o.parentNode) {
return false;
}
sNodeName = sNodeName.toLowerCase();
do {
o = o.parentNode;
} while (o && o.parentNode && o.nodeName.toLowerCase() !== sNodeName);
return (o.nodeName.toLowerCase() === sNodeName ? o : null);
};
this.events = {
// handlers for sound events as they're started/stopped/played
play: function() {
pl.removeClass(this._data.oLink,this._data.className);
this._data.className = pl.css.sPlaying;
pl.addClass(this._data.oLink,this._data.className);
var url = this.url; // retrieve URL for active played MP3
file = url.substring(url.lastIndexOf('/')); // only keep filename of MP3
// Push an event to GA
try {
_gaq.push(['_trackEvent', 'mp3', 'play', file.substring(1)]);
}
catch(err)
{
var variable1 = err.message;
}
},
stop: function() {
pl.removeClass(this._data.oLink,this._data.className);
this._data.className = '';
},
pause: function() {
pl.removeClass(this._data.oLink,this._data.className);
this._data.className = pl.css.sPaused;
pl.addClass(this._data.oLink,this._data.className);
},
resume: function() {
pl.removeClass(this._data.oLink,this._data.className);
this._data.className = pl.css.sPlaying;
pl.addClass(this._data.oLink,this._data.className);
},
finish: function() {
pl.removeClass(this._data.oLink,this._data.className);
this._data.className = '';
if (pl.config.playNext) {
var nextLink = (pl.indexByURL[this._data.oLink.href]+1);
if (nextLink<pl.links.length) {
pl.handleClick({'target':pl.links[nextLink]});
}
}
}
};
this.stopEvent = function(e) {
if (typeof e !== 'undefined' && typeof e.preventDefault !== 'undefined') {
e.preventDefault();
} else if (typeof window.event !== 'undefined') {
window.event.returnValue = false;
}
return false;
};
this.getTheDamnLink = (isIE) ? function(e) {
// I really didn't want to have to do this.
return (e && e.target ? e.target : window.event.srcElement);
} : function(e) {
return e.target;
};
this.handleClick = function(e) {
// a sound link was clicked
if (typeof e.button !== 'undefined' && e.button>1) {
// ignore right-click
return true;
}
var o = self.getTheDamnLink(e),
sURL,
soundURL,
thisSound;
if (jQuery(o).data('song_link'))
{o.href = jQuery(o).data('song_link');}
if (o.nodeName.toLowerCase() !== 'a') {
o = self.isChildOfNode(o,'a');
if (!o) {
return true;
}
}
sURL = o.getAttribute('href');
if (!o.href || !soundManager.canPlayLink(o) || self.classContains(o,self.excludeClass)) {
return true; // pass-thru for non-MP3/non-links
}
if (!self.classContains(o,self.includeClass)) {
return true;
}
sm._writeDebug('handleClick()');
soundURL = (o.href);
thisSound = self.getSoundByURL(soundURL);
if (thisSound) {
// already exists
if (thisSound === self.lastSound) {
// and was playing (or paused)
thisSound.togglePause();
} else {
// different sound
thisSound.togglePause(); // start playing current
sm._writeDebug('sound different than last sound: '+self.lastSound.id);
if (self.lastSound) {
self.stopSound(self.lastSound);
}
}
} else {
// create sound
thisSound = sm.createSound({
id:'basicMP3Sound'+(self.soundCount++),
url:soundURL,
onplay:self.events.play,
onstop:self.events.stop,
onpause:self.events.pause,
onresume:self.events.resume,
onfinish:self.events.finish
});
// tack on some custom data
thisSound._data = {
oLink: o, // DOM node for reference within SM2 object event handlers
className: self.css.sPlaying
};
self.soundsByURL[soundURL] = thisSound;
self.sounds.push(thisSound);
if (self.lastSound) {
// stop last sound
self.stopSound(self.lastSound);
}
thisSound.play();
}
self.lastSound = thisSound; // reference for next call
o.href = '#';
return self.stopEvent(e);
};
this.stopSound = function(oSound) {
soundManager.stop(oSound.id);
if (!isTouchDevice) { // iOS 4.2+ security blocks onfinish() -> playNext() if we set a .src in-between(?)
soundManager.unload(oSound.id);
}
};
this.init = function() {
sm._writeDebug('basicMP3Player.init()');
var i, j,
foundItems = 0,
oLinks = document.getElementsByTagName('a');
// grab all links, look for .mp3
for (i=0, j=oLinks.length; i<j; i++) {
if (self.classContains(oLinks[i],self.css.sDefault) && !self.classContains(oLinks[i],self.excludeClass)) {
// self.addClass(oLinks[i],self.css.sDefault); // add default CSS decoration - good if you're lazy and want ALL MP3/playable links to do this
self.links[foundItems] = (oLinks[i]);
self.indexByURL[oLinks[i].href] = foundItems; // hack for indexing
foundItems++;
}
}
if (foundItems>0) {
self.addEventHandler(document,'click',self.handleClick);
if (self.config.autoPlay) {
self.handleClick({target:self.links[0],preventDefault:function(){}});
}
}
sm._writeDebug('basicMP3Player.init(): Found '+foundItems+' relevant items.');
};
this.init();
}
var basicMP3Player = null;
// use HTML5 audio for MP3/MP4, if available
soundManager.preferFlash = false;
soundManager.onready(function() {
// soundManager.createSound() etc. may now be called
basicMP3Player = new BasicMP3Player();
});
In the above code the href is set back to the original value from the song_link data element, and at the end is set again to “#”.
How can I prevent the second run triggered by ajax from ruining the ‘song_link’ jquery data element?