- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good morning,
I have a crosswalk app 1826 which plays a short sound file when a phrase is tapped on the screen and this is working fine, so, I decided to improve it and added a search function which searches the App's pages for a match and copies the matching phrases to the search page. The problem is that when I tap on the phrase on the search page an audio control bar appears, it does not appear on the original page. I have compared the code on the original with the search page and they are identical.
Below is sample code from the original page
<div class="english"> How old are you? <div class="wrapper"> <a class="formal spanish" data-ignore="true" href="ageHowOldF.mp3">F: Cuántos años tiene?</a> <a class="informal spanish" data-ignore="true" href="ageHowOldI.mp3">I: Cuántos años tienes?</a> </div> <!-- End .wrapper --> </div> <!-- End English -->
This shows the search page using xdk debug when it searched for "how old"
I tried hard coding an extra phrase on the search page which played correctly with no audio control bar. Could someone point me in the right direction on this please?
Thanks,
Tony
- Tags:
- HTML5
- Intel® XDK
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I should add that I get the same results when I use XDK/Debug and when I do an upload/ Build/Download to my Galaxy S4
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Tony, it's not clear to me why you are getting the audio controls, other than the web engine might be creating an audio tag to handle the playback of the mp3 file. I recommend a different approach where you do not rely on the web engine to playback the mp3 files. Instead, you use an audio playback API. This demo app contains some media playback examples that might help > https://github.com/xmnboy/hello-cordova (look for the btnBark*() functions in the main.js file). The HTML5 version relies on a hidden audio tag you'll find in the index.html file.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Paul,
Thanks for the suggestions, I am using an event listener which should be picking up all taps/ clicks to do the playback wherever they occur and then calls jQuery I think the problem is that in these copied elements for some reason this listener is failing in some way and it's going to the web engine - using debug with an event listener on Touch End I see it goes to af.ui.jquery.min.js which is unintelligible to me. Below is the jQuery function that should handle all taps/ clicks, fyi it changes the background color from yellow to white, checks for a double tap/ and also a tap vs swipe before playing the sound file,
jQuery(function($){ var highlight = 'yellow', origcolor = 'transparent', curSnd = null, istouch = !!('ontouchstart' in window) || !!('ontouchstart' in document.documentElement) || !!window.ontouchstart || (!!window.Touch && !!window.Touch.length) || !!window.onmsgesturechange || (window.DocumentTouch && window.document instanceof window.DocumentTouch); function playstop(e){ e.preventDefault(); var $this = $(this); if(curSnd && curSnd.sound){ if(this === curSnd.tag){ curSnd.sound.stop(); return; } curSnd.sound.stop(); } $this.stop(true, true).css({backgroundColor: highlight}); var filename = this.href.substring(this.href.lastIndexOf('/')), myMedia = new Media( this.href, function() { myMedia && myMedia.release(); curSnd = myMedia = null; $this.stop(true, true).animate({backgroundColor: origcolor}, 500); }, function(e) { myMedia && myMedia.release(); curSnd = myMedia = null; $this.stop(true, true).animate({backgroundColor: origcolor}, 500); window.console && console.log ("Audio play error - " + filename + "\ncode: " + e.code + "\nmessage: " + e.message); } ); curSnd = {tag: this, sound: myMedia}; curSnd.sound.play(); } // End playstop $('.spanish').click(function(e){e.preventDefault();}).each(function(i, snd){ if(istouch){ var $snd = $(snd); snd.addEventListener('touchstart', function(e){$snd.data({tstart: new Date().getTime(), tx: e.pageX, ty: e.pageY});}, false); snd.addEventListener('touchend', function(e){ var ds = $snd.data('tstart'); if(!ds){return;} var vx = Math.abs(e.pageX - $snd.data('tx')), vy = Math.abs(e.pageY - $snd.data('ty')); if(vx < 20 && vy < 20 && new Date().getTime() - ds < 400){ playstop.apply(snd,); $snd.data({tstart: null, tx: null, ty: null}); } }, false); } }); });
Thanks for any assistance, the app is complete and working perfectly apart from this problem...sigh.
Tony
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The thing that bothers me is your list of <a> tags in the search results. Each one has an href="file.mp3" in it, which I'm expecting will cause the runtime engine to try and play those when they are touched, because the normal action when touching an <a> tag is to follow the href link...
<div class="wrapper"> <a class="formal spanish" data-ignore="true" href="ageHowOldF.mp3">F: Cuántos años tiene?</a> <a class="informal spanish" data-ignore="true" href="ageHowOldI.mp3">I: Cuántos años tienes?</a> </div> <!-- End .wrapper -->
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Paul,
Thanks for the reply - on a Saturday !!
You're right that the search results page contains English phrases followed by one or more Spanish phrases each of which has an href="file.mp3"...The rest of the app is exactly the same - an English phrase followed by one or more Spanish phrases with an href="file.mp3".. and these all work correctly - ie no audio control bar. I even tried hard coding an English/Spanish pair of phrases on the search results page and this plays correctly with no audio control bar, it's only the phrases found and copied by the searchApp js function that are producing the audio control bar.
Here's the searchApp function
function searchApp() { var $searchTerm = $(".searchField").val().toLowerCase(); // Convert search term to all lower case var $searchResults = ""; document.getElementById("searchResultsDiv").innerHTML = ""; $(".english").each(function () { if ($(this).text().toLowerCase().match($searchTerm)) { // If this specific '.english' class $searchResults += this.outerHTML; // Append all HTML contents of '.english' div into $searchResults variable } }); $("#searchResultsDiv").html($searchResults); // Within searchResultsP <p> tag, write $searchResults variable to HTML }; // /searchApp
I'm doing some more testing right now but it looks like it's going into af.ui.jquery.min.js immediately after tapping one of the errant phrases.
Thanks again for your time, I'll provide another update later this evening.
Tony
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Paul,
I think I know what the problem is that's causing the audio control bar to appear when i tap the results of a search, it does not appear when I tap existing app content.
I have a jQuery function that executes on document ready and this deals with all taps in the app. Now when I run the search function this copy/ pastes the selected elements in the app to the search page and as these search results weren't there on document ready no click handler is assigned to them and so a tap causes the app to use the web engine. Sound reasonable?
I've been digging around on SO and found several similar problems (assigning a click handler to dynamic html) which said I should use .on() and assign the click event to the body tag - or any parent element, there were several examples shown. I have tried, along with a friend who's much better at js than me, and we haven't been able to get it to work yet, but I think/ hope we're on the right track.
Below is the doc ready function as it currently exists, if you could suggest how I should implement .on () I'd really appreciate some guidance on this, here's a link to one of the recommended solutions on SO http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements?rq=1 . I should add that when I tried the audio control bar appeared on all taps so clearly i did something wrong...again. Thanks for any assistance you can provide. ~Tony
The code below also resets the background color, checks for a tap or swipe and also checks for a double tap.
jQuery(function($){ var highlight = 'yellow', origcolor = 'transparent', curSnd = null, istouch = !!('ontouchstart' in window) || !!('ontouchstart' in document.documentElement) || !!window.ontouchstart || (!!window.Touch && !!window.Touch.length) || !!window.onmsgesturechange || (window.DocumentTouch && window.document instanceof window.DocumentTouch); function playstop(e){ e.preventDefault(); var $this = $(this); if(curSnd && curSnd.sound){ if(this === curSnd.tag){ curSnd.sound.stop(); return; } curSnd.sound.stop(); } $this.stop(true, true).css({backgroundColor: highlight}); var filename = this.href.substring(this.href.lastIndexOf('/')), myMedia = new Media( this.href, function() { myMedia && myMedia.release(); curSnd = myMedia = null; $this.stop(true, true).animate({backgroundColor: origcolor}, 500); }, function(e) { myMedia && myMedia.release(); curSnd = myMedia = null; $this.stop(true, true).animate({backgroundColor: origcolor}, 500); window.console && console.log ("Audio play error - " + filename + "\ncode: " + e.code + "\nmessage: " + e.message); } ); curSnd = {tag: this, sound: myMedia}; curSnd.sound.play(); } // End playstop $('.spanish').click(function(e){e.preventDefault();}).each(function(i, snd){ //$('body').on('click', '.spanish', function(i){ if(istouch){ var $snd = $(snd); //var $snd = $(i.currentTarget); snd.addEventListener('touchstart', function(e){$snd.data({tstart: new Date().getTime(), tx: e.pageX, ty: e.pageY});}, false); //i.currentTarget.addEventListener('touchstart', function(e){$snd.data({tstart: new Date().getTime(), tx: e.pageX, ty: e.pageY});}, false); //i.currentTarget.addEventListener('touchend', function(e){ snd.addEventListener('touchend', function(e){ var ds = $snd.data('tstart'); if(!ds){return;} var vx = Math.abs(e.pageX - $snd.data('tx')), vy = Math.abs(e.pageY - $snd.data('ty')); if(vx < 20 && vy < 20 && new Date().getTime() - ds < 400){ //playstop.apply(i.currentTarget,); playstop.apply(snd, ); $snd.data({tstart: null, tx: null, ty: null}); } }, false); } }); });

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page