jquery/javascript play/stop asynchronous issue - javascript

I have a page that is essentially dynamically created (this is key), and in this page I have divs, and each div is supposed to play/pause a song.
The code works if I put alert, so that led me to believe that there is an asynchronous issue. So I tried to add a timeout to when I call play/pause, but that didn't work either.
How the code behaves right now is the first div functions flawlessly, but any other div does not work unless I put an alert.
Has anyone had experience with such an issue?
This is my code, I'm using livequery to pick up the dynamic elements.
EDIT:
The problem now is that only the first song is being played, nothing happens when I click play/pause buttons for the other songs.
function callAction(url) {
if (url == "music.html") {
var believe = new Audio('/assets/music/believe.mp3');
var hope = new Audio('/assets/music/hope.mp3');
var alf = new Audio('/assets/music/alf.mp3');
var thatnight = new Audio('/assets/music/thatnight.mp3');
var lostlove = new Audio('/assets/music/lostlove.mp3');
var time = new Audio('/assets/music/time.mp3');
$("body").on("click", ".pausebutton", function(){
var song = $(this).attr('name');
if (song != null && song == "believe") {
believe.pause();
}
if (song != null && song == "hope") {
hope.pause();
}
if (song != null && song == "alf") {
alf.pause();
}
if (song != null && song == "thatnight") {
thatnight.pause();
}
if (song != null && song == "lostlove") {
lostlove.pause();
}
if (song != null && song == "time") {
time.pause();
}
});
$("body").on("click", ".playbutton" ,function(){
var song = $(this).attr('name');
if (song != null && song == "believe") {
believe.play();
}
if (song != null && song == "hope") {
hope.play();
}
if (song != null && song == "alf") {
alf.play();
}
if (song != null && song == "thatnight") {
thatnight.play();
}
if (song != null && song == "lostlove") {
lostlove.play();
}
if (song != null && song == "time") {
time.play();
}
});
}
}
Not that html would really make a difference, but here is the html:
<div id="music">
<h1>Music</h1>
<br><br>
<div class="row">
<div class="musicEntry red">
<center><p class="musicTitle">Believe</p></center>
<center><p class="musicDate">July 27th 2014</p></center>
<div class="audio-controls">
<center><i name="believe" class="fa fa-play-circle fa-3x playbutton"></i></center>
<center><i name="believe" class="fa fa-pause fa-3x pausebutton"></i></center>
</div>
</div>
<div class="musicEntry red">
<center><p class="musicTitle">A Little Hope</p></center>
<center><p class="musicDate">March 8th 2014</p></center>
<div class="audio-controls">
<center><i name="hope" class="fa fa-play-circle fa-3x playbutton"></i></center>
<center><i name="hope" class="fa fa-pause fa-3x pausebutton"></i></center>
</div>
</div>
<div class="musicEntry red">
<center><p class="musicTitle">Alf Layla</p></center>
<center><p class="musicDate">April 23rd 2014</p></center>
<div class="audio-controls">
<center><i name="alf" class="fa fa-play-circle fa-3x playbutton"></i></center>
<center><i name="alf" class="fa fa-pause fa-3x pausebutton"></i></center>
</div>
</div>
</div>
<div class="row">
<div class="musicEntry red">
<center><p class="musicTitle">That Night</p></center>
<center><p class="musicDate">March 21th 2013</p></center>
<div class="audio-controls">
<center><i name="thatnight" class="fa fa-play-circle fa-3x playbutton"></i></center>
<center><i name="thatnight" class="fa fa-pause fa-3x pausebutton"></i></center>
</div>
</div>
<div class="musicEntry red">
<center><p class="musicTitle">Lost Love</p></center>
<center><p class="musicDate">July 30th 2012</p></center>
<div class="audio-controls">
<center><i name="lostlove" class="fa fa-play-circle fa-3x playbutton"></i></center>
<center><i name="lostlove" class="fa fa-pause fa-3x pausebutton"></i></center>
</div>
</div>
<div class="musicEntry red">
<center><p class="musicTitle">Time (Cover)</p></center>
<center><p class="musicDate">July 26th 2012</p></center>
<div class="audio-controls">
<center><i name="time" class="fa fa-play-circle fa-3x playbutton"></i></center>
<center><i name="time" class="fa fa-pause fa-3x pausebutton"></i></center>
</div>
</div>
</div>
</div>
This is only playing and pausing the first song. Do you have any idea why?

The issue is your click event and dynamically loaded page. When there are dynamically added elements on your DOM, use $(selector).on('click', function(e){}) instead of click events. Below is the modified handler:
$(".playbutton").on("click", function(){
// Your code goes here
});

Have a look at this jsfiddle
http://jsfiddle.net/cVjg9/1/
If you use the method Inder described in the JSFiddle it doesn't work either. For some reason you have to attach it like this:
$("#container").on("click",".pausebutton",function(e){...});
The first selector can be any containing element, for example $("body").
Thinking about it...
The explanation is most likely because you're attaching the event to the top element, not the dynamic element. Every time you click on the surrounding container, the event will be caught and a check will be done whether you clicked on a ".pausebutton" sub-element. In other words, it's more performant to use a dedicated div which closely encapsulated the dynamically loaded elements, instead of just attaching it to the body. Otherwise it will throw events all over the place.
Attaching events like this doesn't work:
$(".pausebutton").on("click",function(e){...});
http://jsfiddle.net/J2LYX/
$(".pausebutton").click(function(e){...});
http://jsfiddle.net/X2rbJ/
Related question:
In jQuery, how to attach events to dynamic html elements?

I solved some of the problem by taking livequery out.
While I am getting my dynamic content using $.get(url), I made a function that acts as a switch. So something like this:
//Get the page here
$.get(url, function() {
//replace content of the page here
callAction(url);
});
// This acts as a switch statement, the javascript is being called just fine, and the code works perfectly now.
function callAction(url) {
if (url == "music.php"){
// do the following here
}
if (url == "blog.php"){
// do the following here
}
}
This worked for me. I didn't have to use livequery anymore. That plugin is terrible.

Related

JS DOM element to an object literal

I need a setTimeout that add a new class to the icon that you can see in my code, but I don't know how to create the DOM element for
<i class="fa fa-check-double" id='icon'></i>
inputText.addEventListener("keypress", event => {
if (event.key === "Enter") {
event.preventDefault();
chat.innerHTML += `<div class="ballon">
<div>${inputText.value}</div>
<span class="time">
${today.getHours()}:${today.getMinutes()}
<i class="fa fa-check-double" id='qui'></i>
</span>
</div>
`
inputText.value = ''
}
})
I don't know how to create the DOM variable that I need, I'm a newbie of course

How to change image on hover of multiple images

I have a list of images and I want to be changed when I hover on it and then change back to the previous image on mouse leave. and each image is different. I have done it but it's not the right way of doing it. and I couldn't figure out the right way.
//html code: its actually long list but I'm just showing two of the list//
<li>
<div class="card">
<img class="my-img" id="my-img1" src="./images/AMH010301_G-1-dresslink.jpg" alt="Denim Jeans"onmouseover="hover1()" onmouseout="offhover1()">
<h1>Lorem1</h1>
<span class="price-first">$24.99</span>
<span class="price">$17.99</span>
<br>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star"></span>
<span class="fa fa-star"></span>
<p>Lorem ipsum dolor sit amet..</p>
<button class="add-to">Add to Cart</button>
</div>
</li>
<li>
<div class="card">
<img class="my-img" id="my-img2" src="./images/AMH010327_W-1-dresslink.jpg" alt="Denim Jeans" onmouseover="hover2()" onmouseout="offhover3()">
<h1>Lorem2</h1>
<span class="price-first">$24.99</span>
<span class="price">$14.99</span>
<br>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star"></span>
<span class="fa fa-star"></span>
<p>Lorem ipsum dolor sit amet..</p>
<button class="add-to">Add to Cart</button>
</div>
</li>
//javascript code//
function hover1() {
document.getElementById("my-img1").src = "./images/AMH010301_G-5-dresslink.jpg";
}
function offhover1() {
document.getElementById("my-img1").src = "./images/AMH010301_G-1-dresslink.jpg";
}
function hover2() {
document.getElementById("my-img2").src = "./images/AMH010327_W-5-dresslink.jpg";
}
function offhover2() {
document.getElementById("my-img2").src = "./images/AMH010327_W-1-dresslink.jpg";
}
function hover3() {
document.getElementById("my-img3").src = "./images/AMH011122_W-3-dresslink.jpg";
}
function offhover3() {
document.getElementById("my-img3").src = "./images/AMH011122_W-1-dresslink.jpg";
}
function hover4() {
document.getElementById("my-img4").src = "./images/AMH011200_W-3-dresslink.jpg";
}
function offhover4() {
document.getElementById("my-img4").src = "./images/AMH011200_W-2-dresslink.jpg";
}
Although what you've done works fine, the code looks a bit messier. The solution for a clean, well-organized code would be like this. First, you should consider that you can use a single javascript function to handle all 8 events since they belong to a related logical group. for example, you should have used a javascript function and use the e event param to identify the event triggered and then use a switch or any other suitable control structure to handle the events from different UI elements.
NOTE: another approach that I would recommend is using jquery library. Because it is optimized for this type of things.
Here's how I would do something like this with event listeners and a really simple swapping function. You could also do this with CSS which may be optimal depending on your case.
window.onload = function bindEvents(){
var img1 = document.querySelector('#my-img1');
img1.addEventListener('mouseover', function(){swapImage(img1, "./images/AMH010301_G-5-dresslink.jpg")});
img1.addEventListener('mouseout', function(){swapImage(img1, "./images/AMH010301_G-1-dresslink.jpg")});
}
function swapImage(el, elImg) {
el.src = elImg;
}

How to emulate an enter key just cliking a button?

I am just wondering about how can I emulate an ENTER key clicking a button. It is designed as this image, as it is an input field, its working with the enterkey and its inserting the text correctly.
But the button designed has to work as if the "enter" key has been pressed.
For example:
Text: "Hi there"+ENTER KEY --> WORKS WELL;
Text: "Hi there"+ Click button as ENTER KEY PRESSED --> I dont know how to implement it.
The code is the below:
<div class="message-input">
<input name="message" id="textEle" placeholder="Escribe aquí...">
<button class="sendMsg">
<span id="sendBtn" class="fa-stack fa-2x visible-xs">
<i class="fa fa-circle fa-stack-2x" style="color:#0f2638"></i>
<i class="fa fa-paper-plane-o fa-stack-1x fa-inverse"></i>
</span>
</button>
</div>
I have already the following javascript code, where is cheking every single input key and when its the ENTER one it makes the insert action:
Template.channel.events({
'keyup [name="message"]' ( event, template ) {
handleMessageInsert( event, template );
}
}
Please let me know if there is any way to do it.
Thanks a lot!
So with native JS:
// buttonEle would be your button, textEle would be your text input
buttonEle.addEventListener('click', function (e) {
var event = document.createEvent('KeyBoardEvent');
event.initEvent('keypress', true, false);
event.key = 'Enter';
event.keyCode = 13;
// now dispatch the event from whichever element your other listener is bound on im gonna assume this is the text input
textEle.dispatchEvent(event);
});
Or with jquery
$(buttonEle).on('click', function (e) {
var event = jQuery.event('keypress', {'keyCode': 13, 'key': 'Enter'});
$(textEle).trigger(event);
});
#prodigitalson's answer in the meteor way:
template.html
<template name = "magic">
...
...
<div class="message-input">
<input name="message" placeholder="Escribe aquí...">
<button class="sendMsg">
<span id="sendBtn" class="fa-stack fa-2x visible-xs">
<i class="fa fa-circle fa-stack-2x" style="color:#0f2638"></i>
<i class="fa fa-paper-plane-o fa-stack-1x fa-inverse"></i>
</span>
</button>
...
...
</template>
template.js
Template.magic.events({
// when you click the button
'click .sendMsg' (event){
event.preventDefault();
// same #prodigitalson's code
var e = jQuery.Event("keypress");
e.which = '13';
$(textEle).trigger(e);
}
});
Edit : Check out this answer for simulating a keypress.

Audio wont play after loading contents with AJAX

First of all im new to jquery i have tried googling my problem , spent hours to fix this and i couldn't find any , so here i am .
In the below code i have fetched some information ( Songs details ) from database and loaded them to div via ajax .. Up to this point everything works just fine .
script using to load content via AJAX
$(document).ready(function() {
$("#results" ).load( "ajax/profile_ajax.php"); //load initial records
//executes code below when user click on pagination links
$("#results").on( "click", ".pagination a", function (e){
e.preventDefault();
$(".loading-div").show(); //show loading element
var page = $(this).attr("data-page"); //get page number from link
$("#results").load("ajax/profile_ajax.php",{"page":page}, function(){ //get content from PHP page
$(".loading-div").hide(); //once done, hide loading element
});
});
});
<div class="loading-div"><img src="../pagination/ajax-loader.gif" ></div>
<div id="results"></div><!-- content will be loaded here -->
Script im using to play audio
$(function () {
var curAudio;
$(".playback").click(function (e) {
e.preventDefault();
var song = $(this).next('audio')[0];
if (curAudio && song != curAudio && !curAudio.paused) {
curAudio.pause();
$(curAudio).prev().html('<i class="fa fa-play"></i> Play');
}
if (song.paused) {
song.play();
curAudio = song;
$(this).html('<i class="fa fa-pause"></i> Stop');
} else {
song.pause();
curAudio = undefined;
$(this).html('<i class="fa fa-play"></i> Play');
}
curPlaying = $(this).parent()[0].id;
});
});
I have above code to played the fetched music . Now the problem is None of the Buttons are functional even though my code worked fine before i use AJAX .
My Fecthed HTML is like this
<div id="4">
Track Name :- <b>Heros</b>
<br />By :- <a target="_blank" href="../members/profile.php?id=1">USER NAME</a>
<br />
<button class="playback btn btn-primary btn-sm hdnbtn"><i class="fa fa-play"></i> Play</button>
<audio src="../members/memberfiles/1/Heros.mp3">
Your browser does not support HTML5 audio.
</audio>
<a class="btn btn-sm btn-success hdnbtn" href="../members/downloader.php?fld=1&name=Heros.mp3" name="dwn"><i class="fa fa-download"></i> Download MP3</a>
<button class="sharer btn btn-sm btn-danger hdnbtn" type="button"><span class="fa fa-share-alt"></span> Share</button>
<a target="_blank" href="#" class="hide btn btn-sm btn-social btn-facebook socialhdn"><i class="fa fa-facebook"></i> Share on Facebook</a>
<a target="_blank" href="#" class="hide btn btn-sm btn-social btn-twitter socialhdn"><i class="fa fa-twitter"></i> Tweet this </a>
<a target="_blank" href="#" class="hide btn btn-sm btn-social btn-google-plus socialhdn"><i class="fa fa-google-plus"></i> Share on goole</a>
<br />
<i class="fa fa-minus"> Show Less</i>
<input type="hidden" value="Heros.mp3" name="file_name">
<input type="hidden" value="bWVtYmVyZmlsZXMvMS9IZXJvcy5tcDM=" name="link">
What i really need is to play the fetched content using the 2nd script (audio) i posted . i have no idea how to fix this . Tried hours of googling and various suggested methods. None of them worked for me . Please Point out what went wrong . i really appreciate it !
use below code to play audio . you also check Event delegation to attach event to dynamically created element. Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
$(function () {
var curAudio;
$(document).on('click',".playback",function (e) {
e.preventDefault();
var song = $(this).next('audio')[0];
if (curAudio && song != curAudio && !curAudio.paused) {
curAudio.pause();
$(curAudio).prev().html('<i class="fa fa-play"></i> Play');
}
if (song.paused) {
song.play();
curAudio = song;
$(this).html('<i class="fa fa-pause"></i> Stop');
} else {
song.pause();
curAudio = undefined;
$(this).html('<i class="fa fa-play"></i> Play');
}
curPlaying = $(this).parent()[0].id;
});
});

How to modify the class attribute in ng-repeat module?

Here is my plunker.enter link description here
I'm a newer to AngularJS and I want to modify the class style of the star to show if it's marked.
<div class="col-sm-6 col-md-4 col-lg-4 cell-project" ng-repeat="project in projects">
<div class="panel panel-primary panel-project">
<div class="panel-heading" ng-switch="project.PermissionStatus">
<span ng-bind="project.ProjectName"></span>
<i class="fa fa-gear i-setup" ng-switch-when="1"></i>
<div ng-switch-when="0" ng-switch="project.CollectionStatus">
<i class="fa fa-star i-setup" ng-switch-when="1" ng-click="updateCol(0)"></i>
<i class="fa fa-star-o i-setup" ng-switch-when="0" ng-click="updateCol(1)"></i>
</div>
</div>
</div>
</div>
And here is the updateCol function:
$scope.updateCol = function(collectionStatus){
if (1 === collectionStatus) {
console.log("marked");
//$(this).removeClass("fa fa-star-o i-setup ng-scope");
//$(this).addClass("fa fa-star i-setup ng-scope");
//do something to change its class from "fa-star-o" to "fa-star"
}
else if (0 === collectionStatus) {
console.log("unmarked");
//do something to change its class from "fa-star" to "fa-star-o"
}};
How to solve this? When I use id selector, all the classes are changed, not the one that I want to modify. Please help me.
in the click handler just update the value of CollectionStatus
<i class="fa fa-star i-setup" ng-switch-when="1" ng-click="project.CollectionStatus = 0"></i>
<i class="fa fa-star-o i-setup" ng-switch-when="0" ng-click="project.CollectionStatus = 1"></i>
Demo: Plunker
Using ng-class
<div class="panel-heading" ng-switch="project.PermissionStatus">
<span ng-bind="project.ProjectName"></span>
<i class="fa fa-gear i-setup" ng-switch-when="1"></i>
<i class="fa i-setup" ng-class="{'fa-star': project.CollectionStatus == 1, 'fa-star-o': project.CollectionStatus == 0 }" ng-click="updateStatus(project)"></i>
</div>
then
$scope.updateStatus = function(project){
project.CollectionStatus = project.CollectionStatus == 0 ? 1 : 0;
//do your ajax here
if (1 === project.CollectionStatus) {
console.log("marked");
//$(this).removeClass("fa fa-star-o i-setup ng-scope");
//$(this).addClass("fa fa-star i-setup ng-scope");
//do something to change its class from "fa-star-o" to "fa-star"
}
else if (0 === project.CollectionStatus) {
console.log("unmarked");
//do something to change its class from "fa-star" to "fa-star-o"
}
};
Demo: Plunker
1 === collectionStatus is not equal to true === collectionStatus, so you should use 1 == collectionStatus or simply collectionStatus
$scope.updateCol = function(collectionStatus){
if (collectionStatus) {
console.log("marked");
//$(this).removeClass("fa fa-star-o i-setup ng-scope");
//$(this).addClass("fa fa-star i-setup ng-scope");
//do something to change its class from "fa-star-o" to "fa-star"
}
else{
console.log("unmarked");
//do something to change its class from "fa-star" to "fa-star-o"
}};

Categories

Resources