Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: Assigning a click handler to dynamic elements

  1. #1
    Join Date
    Aug 2010
    Posts
    86
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Default Assigning a click handler to dynamic elements

    Good morning John,
    Several months ago you kindly helped me create code for a smartphone app that played a short sound file using jQuery when a phrase was tapped on the screen, this is working perfectly – thanks.

    I have now added a search function which searches the app and copies matching phrases to the search results page and this is almost working. The problem I’m having is that when I tap a phrase on the search results page the app invokes the system sound player which displays an audio control bar.

    I think the problem is that the click handler is assigned at document ready and of course the search results are not defined and so a click handler is not assigned to the search results.

    I have been digging around and found several similar issues which were resolved by using .on() and assigning it to the <body> tag or any parent element. When I tried this I found that all taps invoked the system sound player….sigh.

    I would really appreciate your assistance with this. Below is your original code which was invoked at document ready and you will see commented out attempts to use the .on() solution
    Code:
    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
    // jourdan	$('body').on('click', '.spanish', function(e){e.preventDefault();}).each(function(i, snd){
    	$('.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, [e]);
    					playstop.apply(snd, [e]);          	
    				$snd.data({tstart: null, tx: null, ty: null});
    	          	}
              	}, false);         
    	}
         });
        });
    Thanks for any assistance you can provide.

    Tony
    Last edited by Beverleyh; 03-15-2015 at 02:42 PM. Reason: Formatting

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Well, it's important to know which version of jQuery you are using. The on() function did not become available until version 1.7.x prior to that the function was live() and it had a different syntax. I think live() continued to work until jQuery 1.9.x when it was dropped.

    Do you know which jQuery version you are using?

    Another issue is that, if you are using a touch device, there is no intrinsic touch event in jQuery, so you will need to use something other than pure jQuery to capture that anyway.

    Finally, for now, the code you posted above looks broken to me - that is, I can't see it working at all for any device, as the closures (denoted by the { and } brackets) do not appear to correspond to the basic rules of javascript functionality.

    I'll have a closer look at it, it's possible I'm wrong about that last thing and/or can see how to fix that part of it. I also should be able to come up with a basic routine to use regular javascript to do an on() or live() type of thing for touch devices.

    In the meantime, do you have a working copy of the code without the attempts at on() in it? If so, let me see that. Oh and let me know the jQuery version you are using.

    Oh, one other thing - when exactly was I last working with you on this? Knowing that will make it relatively easy for me to locate my copies of the work at that time, which may come in handy.
    Last edited by jscheuer1; 04-06-2015 at 04:59 AM. Reason: more specificity on versions
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. #3
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    OK, hmm, looks like the code you posted was OK I think. I still need to know the jQuery version. But as long as it is 1.7 or later and I've made no errors, this should take care of things (replace the code you posted with this):

    Code:
    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
    	$('body').on('click', '.spanish', function(e){e.preventDefault();});
            if(istouch){
            	document.body.addEventListener('touchstart', function(e){
            			var $snd = $(e.target);
            			if(!$snd.hasClass('spanish')){return;}
            			$snd.data({tstart: new Date().getTime(), tx: e.pageX, ty: e.pageY});
            		}, false);
            	document.body.addEventListener('touchend', function(e){
            			var $snd = $(e.target);
            			if(!$snd.hasClass('spanish')){return;}
    		          	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.get(0), [e]);          	
    					$snd.data({tstart: null, tx: null, ty: null});
    		          	}
            		}, false);
    	}
    
        });
    Let's see what happens.

    I've been looking at this a bit more and reading up on the jQuery .on() function. This should also work and might be a little easier to follow:

    Code:
    jQuery(function($){
            var highlight = 'yellow', origcolor = 'transparent', curSnd = null;
    	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
    	$('body').on('click touchstart touchend', '.spanish', function(e){
    		if(e.type === 'click'){
    			e.preventDefault();
    		} else if (e.type === 'touchstart'){
    			$(this).data({tstart: new Date().getTime(), tx: e.pageX, ty: e.pageY});
    		} else {
    			var $snd = $(this), ds = $snd.data('tstart'), vx, vy;
    	          	if(!ds){return;}
    	          	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(this, [e]);          	
    				$snd.data({tstart: null, tx: null, ty: null});
    	          	}
    		}
    	});
    });
    Last edited by jscheuer1; 04-06-2015 at 04:59 AM. Reason: detail, add option
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  4. #4
    Join Date
    Aug 2010
    Posts
    86
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Default Almost working...

    Hello John,

    Thanks for the code. To answer your question, I'm using jQuery 2.1.3 and we last worked on this in the summer of 2014.

    Since I originally posted this question I have made some progress. I was able to get the .on() solution to assign click handlers on touchstart/end on the dynamically created elements - comparing your code with mine I have to admit my solution is not as elegant, but it does seem to work. I will also try substituting your code. My problems are not completely over though.

    You may recall we had to decide if this was a touch or swipe and it does this by identifying the x/y coordinates on touchstart/end and also calculating the duration, movement in x/y <20px and duration < 400ms was assumed to be a touch. I am able to access the time on touchstart/end and calculate the duration but I have been unable to access the x/y coordinates.

    The problem I think is that the original handler used js and I am now using jQuery so e.pageX and e.pageY does not work.
    Below is the click handler as it is now and below that a summary showing console log results of my various attempts to get the x/y coordinates.

    Current click handler - note several sections are commented out just to get it to work, sorry if that makes it harder to read.

    Code:
    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){
            console.log("Start playstop");
    		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);
    			}
    		);
    		console.log("playstop - Start playing sound")
    		curSnd = {tag: this, sound: myMedia}; 
    		curSnd.sound.play();
    	} // End playstop
         $(".wrapper")  //i'm attaching all event handlers to body, so everything with .spanish class will have them attached
            .on("click", ".spanish", function(e) {
                e.preventDefault();
            })
            .on("touchstart", ".spanish", function(e) {
                if (istouch) {
    		console.log("touch Start detected");
    		$sndStartT = new Date().getTime();
    		console.log("touchstart T = " + $sndStartT);
    		$sndStartX = event.pageX;
    		console.log("touchstart X = " + $sndStartX);
    		$sndStartY = event.pageY;
    		console.log("touchstart Y = " + $sndStartY);
    		
          /*	$sndStart = $(this);
                    $sndStart.data({
                        tstart: new Date().getTime(),
                        tx: e.pageX,
                        ty: e.pageY
                    }); */
    			}
    		})
            .on("touchend", ".spanish", function(e) {
    	console.log("touch End detected");
    	$sndEndT = new Date().getTime();
    	console.log("touchend T = " + $sndEndT);
    	$sndEndX = event.pageX;
    	console.log("touchend X = " + $sndEndX);
    	$sndEndY = event.pageY;
    	console.log("touchend Y = " + $sndEndY);
                if (istouch) {
    		console.log("touchend detected istouch val = " + istouch); 
                    var $snd = $(this);
                    var snd = this;
                    var ds = $sndStartT; //$sndStart.data('tstart');
    				console.log("touchend ds = " + ds); 
    				if (!ds) {
                        return;
                    }
    		/*		var vx = Math.abs(e.originalEvent.touches[0].pageX - $sndStart.data('tx'));
    				console.log("touchend vx = " + vx); 
                    var vy = Math.abs(e.originalEvent.touches[0].pageY - $sndStart.data('ty'));
                    Math.abs(e.originalEvent.touches[0].pageY - $sndStart.data('ty'));
    				console.log("touchend vx= "+ vx +" vy= " + vy + " ds = " + ds); */
    		/*	TEMPORARILY REMOVE THE CALCULATION
    			var vx = Math.abs($sndStartX - $sndEndX);
    				console.log("touchend vx = " + vx); 
    				var vy = Math.abs($sndStartY - $sndEndY);
    				console.log("touchend vy = " + vy); 
    				var vt = Math.abs($sndStartT - $sndEndT);
    				console.log("touchend vt = " + vt); */
    				vt = 200;
    				vx = 10;
    				vy = 10;
                    if (vx < 20 && vy < 20 && vt < 400 /*new Date().getTime() - ds < 400 */) {
    	      console.log("touchend tap detected and about to call playstop");
                        playstop.apply(snd, [e]);
                        $sndStart.data({
                            tstart: null,
                            tx: null,
                            ty: null
                        });
                    }
                }
            });
        });
    Within the touchstart and touchend functions I tried various versions to try and get pageX and pageY values, none of them worked but in case it helps here's a summary of what I tried and the console log results, in all cases the clickhandlers were triggered correctly and the start/ end times were displayed correctly.
    Code:
    $sndStartX = e.pageX; // returns "undefined"
        $sndStartX = event.pageX; // returns "0"
        $sndStartX = event.originalEvent.touches[0].pageX; // returns "Cannot read property 'touches' of undefined" 
        $sndStartX = event.originalEvent.pageX; // returns "Cannot read property 'pageX' of undefined
    Thanks,

    Tony

  5. #5
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    pageX and pageY are event properties in jQuery. The problem appears to be that you misunderstand the meaning of the word event. Unlike in early IE, there is no free floating global event. To access the event properties one must obtain a reference to the event as an argument/parameter to the handler function.

    Try my code, I do this without thinking. I know, for you it's harder. You have used e here:

    Code:
    .on("touchstart", ".spanish", function(e) {
    and here:

    Code:
    .on("touchend", ".spanish", function(e) {
    to represent the event. The problem is that here:

    Code:
    $sndStartX = event.pageX;
    you abandon e and use the currently undefined word 'event'.

    Again, agreement between the argument/parameter used in the function parenthesis (e) in this case is now the event, not some abstract and undefined in this case word as 'event' that you're using.change to (change here and similar):

    Code:
    $sndStartX = e.pageX;
    And, as long as no other errors are impacting it, things will work.

    Still, I highly recommend that you try my code (either the 1st or 2nd one), I think you will be happier with it in the long run. It may need to be tweaked, but as far as I can tell in testing and reading up on it, it should be fine as is.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  6. #6
    Join Date
    Aug 2010
    Posts
    86
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Default still getting e.pageX/Y "Undefined"

    Hi John,

    Thanks so much for the explanation and code, I went ahead and installed the second code sample then ran a test which produced no sound when tapped, so I added a few console.log statements and tested again. Below is the console log output and below that is the code showing where I added console.log statements.

    Console log - note e.pageX and e.pageY show as undefined, also $snd.data('tx') and $snd.data('ty').
    Check for click, touchstart, touchend index.html:54
    e.type = touchstart index.html:55
    touchstart e.type = touchstart index.html:60
    Check for click, touchstart, touchend index.html:54
    e.type = click index.html:55
    Click e.type = click index.html:57
    Check for click, touchstart, touchend index.html:54
    e.type = touchend index.html:55
    touchend e.type = touchend index.html:63
    ds = 1428409175059 index.html:66
    e.pageX = undefined index.html:67
    e.pageY = undefined index.html:68
    $snd.data('tx') = undefined index.html:69
    $snd.data('ty') = undefined index.html:70
    vx = NaN index.html:72
    vy = NaN

    Here's the script showing the console.log statements

    Code:
    jQuery(function($){
            var highlight = 'yellow', origcolor = 'transparent', curSnd = null;
    	function playstop(e){
    		console.log("playstop entered");
    		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
    	$('body').on('click touchstart touchend', '.spanish', function(e){
    		console.log("Check for click, touchstart, touchend");
    		console.log("e.type = " + e.type);
    		if(e.type === 'click'){
    			console.log("Click e.type = " + e.type);
    			e.preventDefault();
    		} else if (e.type === 'touchstart'){
    			console.log("touchstart e.type = " + e.type);
    			$(this).data({tstart: new Date().getTime(), tx: e.pageX, ty: e.pageY});
    		} else {
    			console.log("touchend e.type = " + e.type);
    			var $snd = $(this), ds = $snd.data('tstart'), vx, vy;
    	          	if(!ds){return;}
    				console.log("ds = " + ds);
    				console.log("e.pageX = " + e.pageX);
    				console.log("e.pageY = " + e.pageY);
    				console.log("$snd.data('tx') = " + $snd.data('tx'));
    				console.log("$snd.data('ty') = " + $snd.data('ty'));
    	          	vx = Math.abs(e.pageX - $snd.data('tx')); vy = Math.abs(e.pageY - $snd.data('ty'));
    				console.log("vx = " + vx);
    				console.log("vy = " + vy);
    	          	if(vx < 20 && vy < 20 && new Date().getTime() - ds < 400){
    				playstop.apply(this, [e]);          	
    				$snd.data({tstart: null, tx: null, ty: null});
    	          	}
    		}
    	});
    });
    In case it helps here's a sample html section showing an English phrase followed by a Spanish phrase

    HTML Code:
    <div class="english">
                  How much does she weigh?
    </div> <!-- End English -->	
    <div class="wrapper">
    <a class="spanish" data-ignore="true" href="ageWeightFemale.mp3">Cuánto pesa ella?</a>
    </div> <!-- End .wrapper -->
    Quote Originally Posted by jscheuer1 View Post
    pageX and pageY are event properties in jQuery. The problem appears to be that you misunderstand the meaning of the word event. Unlike in early IE, there is no free floating global event. To access the event properties one must obtain a reference to the event as an argument/parameter to the handler function.

    Try my code, I do this without thinking. I know, for you it's harder. You have used e here:

    Code:
    .on("touchstart", ".spanish", function(e) {
    and here:

    Code:
    .on("touchend", ".spanish", function(e) {
    to represent the event. The problem is that here:

    Code:
    $sndStartX = event.pageX;
    you abandon e and use the currently undefined word 'event'.

    Again, agreement between the argument/parameter used in the function parenthesis (e) in this case is now the event, not some abstract and undefined in this case word as 'event' that you're using.change to (change here and similar):

    Code:
    $sndStartX = e.pageX;
    And, as long as no other errors are impacting it, things will work.

    Still, I highly recommend that you try my code (either the 1st or 2nd one), I think you will be happier with it in the long run. It may need to be tweaked, but as far as I can tell in testing and reading up on it, it should be fine as is.

  7. #7
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Well, before we go running around thinking this is something we can fix in jQuery, let's first see if it's jQuery's fault or not. To do that - try the first code. If that works fine and I have an idea how to fix jQ. If that doesn't work, there may be some other problem, or we may need a different approach altogether, one which initializes these items in the way items already on the page were initialized before we started all this. That can be done, we just have to wait until the search is complete and the results posted, then we can initialize them. A unique container may be needed for the search results so that the original items aren't initialized twice.

    But, first try the first code from my previous post:

    Code:
    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
    	$('body').on('click', '.spanish', function(e){e.preventDefault();});
            if(istouch){
            	document.body.addEventListener('touchstart', function(e){
            			var $snd = $(e.target);
            			if(!$snd.hasClass('spanish')){return;}
            			$snd.data({tstart: new Date().getTime(), tx: e.pageX, ty: e.pageY});
            		}, false);
            	document.body.addEventListener('touchend', function(e){
            			var $snd = $(e.target);
            			if(!$snd.hasClass('spanish')){return;}
    		          	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.get(0), [e]);          	
    					$snd.data({tstart: null, tx: null, ty: null});
    		          	}
            		}, false);
    	}
    
        });
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  8. The Following User Says Thank You to jscheuer1 For This Useful Post:

    tonybabb (04-08-2015)

  9. #8
    Join Date
    Aug 2010
    Posts
    86
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Default

    Thanks John, I tried the first code example and it worked perfectly. Once again I'm in your debt.

    Tony

  10. #9
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Great! You can just use that. And, though the problem before could be something else, I think I know what that means and how to fix the code that didn't work. In jQuery there is the jQuery passed event and the original event. Sometimes the jQuery passed event doesn't have all of the properties of the original event, and sometimes it has more. In this case I think it likely is dropping the pageX and pageY properties from the touch events. Usually jQuery justifies doing something like that because a property is non-standard for the event like, I think it is wheel movement for mousewheel events. However, according to the W3C standards, touch events are supposed to have pageX and pageY, so I'm not sure the logic here. In the code that does work, we are not using jQuery to process the event, and so it does have the standard pageX and pageY. We could probably still use the jQuery processing if we were to query the original event object instead of the jQuery passed one - Much easier to do than explain. If you're interested, I can setup a demo for that.

    In any case, you can continue using what's working now. I'm just curious if my guess about the problem before was is right or not, though it almost has to be.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  11. #10
    Join Date
    Aug 2010
    Posts
    86
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Default

    Hello John,

    Yes I'd like to try and understand what's happening with jQuery. Thanks for your explanation, I get the idea. Before I reached out to you I had tried several different attempts to get the pageX and pageY using jQuery. Here are the statements I tried and the console log results are shown in comments on each line.

    Code:
    $sndStartX = e.pageX; // returns "undefined"
        $sndStartX = event.pageX; // returns "0"
        $sndStartX = event.originalEvent.touches[0].pageX; // returns "Cannot read property 'touches' of undefined" 
        $sndStartX = event.originalEvent.pageX; // returns "Cannot read property 'pageX' of undefined
    Tony

Similar Threads

  1. jQuery Problem - Assigning dynamic value
    By neo_philiac in forum JavaScript
    Replies: 0
    Last Post: 12-16-2010, 03:09 PM
  2. Adding Elements to Arrays - elements lost
    By Henamot in forum Flash
    Replies: 0
    Last Post: 03-19-2009, 10:30 AM
  3. An easy way to add dynamic elements
    By tvd in forum JavaScript
    Replies: 4
    Last Post: 05-17-2007, 10:33 AM
  4. Dynamic table with elements value fetching
    By Muthukumar in forum Dynamic Drive scripts help
    Replies: 1
    Last Post: 12-22-2005, 06:58 AM
  5. Replies: 2
    Last Post: 03-23-2005, 10:29 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •