I am building a phonegap application and I get the following error message when debugging.
Uncaught TypeError: app.receivedEvent is not a function(…)** on line 18 of my JS code (I point it out below).
To be honest I have read many guides on the deviceready but I just can't figure out how to properly use it for my phonegap build code.
Here is my HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<!-- Include meta tag to ensure proper rendering and touch zooming -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/index.css" />
<!-- Include jQuery Mobile stylesheets -->
<link rel="stylesheet" href="css/jquery.mobile-1.4.5.min.css">
<link href='https://fonts.googleapis.com/css?family=Lobster|Anton|Patua+One' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/fact_page.css">
<title>One Direction Facts</title>
</head>
<body>
<div data-role="page" id="pageone">
<div data-role="header">
<h1>One Direction - Fact of the Day</h1>
</div>
<div id="deviceready" data-role="main" class="ui-content">
<h2 id="todayh2" class="invisible"> Today's One Direction Fact:</h2>
<div id="quotebox" class="PulseEffect icon">
<div id="ShineDiv" class="shine"></div>
<div class="facebox fade icon">
<div id="ShineDiv2" class=""></div>
</div>
<p class="hidden" id="qotd"> Welcome to<br><strong>One Direction Facts.</strong><br><br>You will get a random fact each day.</p>
</div>
<a id="nextQ" class="" data-role="button" data-ajax="false">View Fact</a>
<div class="XPmeter animateXP" >
<span id="bar" style="width: 20%"></span>
<div id="medaldiv">
<img id="medal" src="images/medal3.svg"><p id="lvl">1</p>
</div>
</div>
</div>
<div data-role="footer">
<h1>New Features Coming Soon!</h1>
</div>
</div>
<!-- --------------------JS------------------------ -->
<script src="./js/jquery-1.11.3.min.js"></script>
<script src="./js/jquery.mobile-1.4.5.min.js"></script>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" src="js/app_scripts.js"></script>
<script type="text/javascript" src="js/admob.js"></script>
<script type="text/javascript">
app.initialize();
</script>
</body>
</html>
Here is my JS:
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
/*--error is here-->*/ app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent:
$("#nextQ").click(function(){
var tempd = new Date(); //Get today's date
//Checks if localstorage had 'DateOpened' already stored
// Note that by adding strings in there, we end up with a string instead of adding.
// Note the order: Year first, then month, then day.
// Also, since we display it, we put separators in and add 1 to month (since Jan = 0).
var str = tempd.getFullYear() + "-" + (tempd.getMonth() + 1) + "-" + tempd.getDate();
console.log("Today's date: " + str);
var localVal = localStorage.getItem('DateOpened');
console.log("Previous localVal: " + localVal);
if(localVal != null){
var difference = localVal.localeCompare(str);
}
console.log("localeCompare: " + difference);
//If stored date is older than this date do something:
if(localVal == null || difference < 0){
// If the localstorage doesn't exist, nothing happens
console.log("App will now run once for today.")
//Run the JS for the app (give new quote since it is a new day)
var Quotes = [];
var ID = [];
var Tag = [];
//Get quotes from JSON file
$.ajax({
url: './json/facts.json',
dataType: 'json',
type: 'get',
success: function(data){
console.log(data);
console.log("successfully imported the JSON file");
console.log(data.length); //Returns 64
totalQ = data.length;
for (i = 0; i < totalQ; i++){
ID[i] = data[i][0];
Tag[i] = data[i][1];
Quotes[i] = data[i][2];
}
console.log(Quotes.length);
}
})
.done(function(data){ //This waits for AJAX to be done before running
var Quote = new String;
var qnumber = 0;
var totalQ //The total number of available quotes to choose from
var CurrentImage = String;
totalQ = Quotes.length - 1;
console.log("TotalQ = " + totalQ);
//Get list of which facts have already been seen
var seen = JSON.parse(localStorage.getItem('seen'));
console.log("var seen = " + seen);
if (seen == null){
var seen = new Array(totalQ);
for (var i = 0; i < seen.length; ++i) {
seen[i] = false;
}
console.log("var seen = " + seen);
}
//Get a Quote
ChooseQuote(0,totalQ);
//Change the image depending on the quote
//replace the quote with a new one
$("#qotd:visible").hide();
$("#ShineDiv").addClass("shine");
$(".facebox").css("background-image",CurrentImage);
$(".facebox").css("opacity","1.0");
$("#qotd").html(Quote);
console.log("Image Changed");
increaseXP();
//================
function ChooseQuote(min,max){
//Choose 2 random numbers, one for quotes one for image
var RandomNum = Math.floor(Math.random()*(max-min+1)+min);
var ImageNum = Math.floor(Math.random()*(5-1+1)+1);
Quote = Quotes[RandomNum];
CurrentImage = "url(./images/FaceBoxes/" + Tag[RandomNum] + "/" + Tag[RandomNum] + ImageNum + ".png)";
if (seen[RandomNum] == true ) {
//Choose new quote
ChooseQuote(0,totalQ);
console.log("Has this fact been seen before? Answer: " + seen[RandomNum] );
var numOfTrue = 0;
for(var i=0; i<=totalQ; i++){
if(seen[i] === "true")
numOfTrue++;
}
if (numOfTrue = totalQ) {
localStorage.setItem('All_Facts_Seen:', true);
console.log("All the Facts have been seen. Resetting Facts.");
seen = new Array(totalQ); //Empty the seen Array
localStorage.setItem('seen', JSON.stringify(seen)); //Save the empty Array
}
}
else {
seen[RandomNum] = "true";
console.log("This fact has never been seen.")
}
console.log(Quote);
console.log(CurrentImage);
//Remeber which fact is displayed
localStorage.setItem('Curr_Fact', Quote);
localStorage.setItem('Curr_ImgUrl', CurrentImage);
localStorage.setItem('seen', JSON.stringify(seen));
}
//==================
//Save the current date in local storage
localStorage.setItem('DateOpened',str);
console.log("The App Ran, you can get a new fact tomorrow");
console.log("Current LocalStorage Date: " + str);
});
}
else {
//If it is still the same day, show the last fact & image
var Quote = localStorage.getItem('Curr_Fact');
var CurrentImage = localStorage.getItem('Curr_ImgUrl');
$("#qotd:visible").hide(); //Hide main quote
$("#ShineDiv2").addClass("shine");
if ($('h2').hasClass("invisible")){ //if heading is invisble show it, remove that class
$('h2').css('visibility','visible').hide().fadeIn('slow').removeClass("invisible");
}
$(".facebox").css("background-image",CurrentImage);
setTimeout( function() { //This is so that the first image and new image don't crossfade/stretch
$(".facebox").css("opacity","1.0");
}, 100);
$("#qotd").html(Quote); //Replace the main message with the actual quote
console.log("Showing the same fact as before. Wait until tomorrow to get a new fact.");
}
},
};
$(window).load(function() {
var headerh;
var footerh;
var pageh;
var hbtn_nextq;
headerh = $("div[data-role='header']").outerHeight();
footerh = $("div[data-role='footer']").outerHeight();
pageh = $(window).height();
console.log(headerh + " " + footerh + " " + pageh);
var difference = pageh - headerh - footerh;
$(".ui-content").css("height", difference);
var h1, h2, h3, h4 , h5;
h1 = $(".ui-content").outerHeight();
h2 = $(".ui-content>h2").outerHeight();
h3 = $("#quotebox").outerHeight(true);
h4 = $("#nextQ").outerHeight();
h5 = ((h1 - h2 - h3 - h4) /2) - 50;
console.log(h1);
console.log(h2);
console.log(h3);
console.log(h4);
console.log(h5);
var h5s = h5 + "px";
//$("#quotebox").css("margin-top",h5s);
$(".ui-content>h2").css("margin-top",h5s);
//$("#nextQ").css("margin-bottom",h5s);
//ShowXP();
//Make the quotebox flip over on click
$(".facebox, #ShineDiv").click(function(){
$("#quotebox").removeClass("PulseEffect")
$("#ShineDiv").removeClass("shine");
$(".facebox").css("opacity","0");
$("#qotd").fadeIn("slow", function(){});
});
ShowXP();
});
function increaseXP(){
//Get the lvl and xp from storage
var lvl = localStorage.getItem("lvl", lvl);
var XP = localStorage.getItem("XP", XP);
console.log("Old XP = " + XP + " Old Level = " + lvl);
lvl = parseInt(lvl);
XP = parseInt(XP);
//Increase XP
XP = XP + 25;
//Increase lvl
if (XP >= 100){
lvl = lvl + 1;
localStorage.setItem('XP',XP);
localStorage.setItem('lvl',lvl);
UpdateXP(XP);
setTimeout(function() {
ShowUP(lvl);
}, 200);
XP = XP - 100;
console.log("Current XP = " + XP + " Current Level = " + lvl);
UpdateXP(XP);
}
localStorage.setItem('XP',XP);
localStorage.setItem('lvl',lvl);
UpdateXP(XP);
}
function ShowXP(){
var XP = localStorage.getItem("XP");
var lvl = localStorage.getItem("lvl");
if (XP == null){
XP = 0;
localStorage.setItem("XP", XP);
}
if (lvl == null){
lvl = 1;
localStorage.setItem("lvl",lvl);
}
lvl = parseInt(lvl);
XP = parseInt(XP);
$("#lvl").text(lvl);
$(".XPmeter > span#bar").each(function() {
$(this)
.data("origWidth", XP)
.width(0)
.animate({
width: $(this).data("origWidth") + "%" // or + "%" if fluid
}, 1200);
});
}
function UpdateXP(XP){
$(".XPmeter > span#bar").each(function() {
$(this)
.animate({
width: XP + "%" // or + "%" if fluid
}, 1200);
});
}
function ShowUP(new_level){
$("#medal").animate({height: "100px" },600, function(){
$("#lvl").text(new_level);
$("#medal").animate({height: "50px" },600);
});
$(".XPmeter > span#bar").width("0");
}
//-------------------------------------------------------------//
// //
// This is the scirpt that will get the facts and display them //
// //
//-------------------------------------------------------------//
That's because your receivedEvent is not defined as a functions but as a property of the app object so it can't be called as a function.
You to change it from:
// Update DOM on a Received Event
receivedEvent:
to:
// Update DOM on a Received Event
receivedEvent: function(id) {
Related
This is my first post on stackflow. I am pretty new to programming but I am trying to figure out how to efficiently produce a multi-functional function that will allow me to reveal information one step at a time for multiple divs/blocks seperately. For instance, this function only work for this specific button and div.
<!-- Function 1 -->
(function () {
var n = 1;
window.ShowStep1 = function () {
document.getElementById("Step1" + "-" + n++).style.visibility = "visible";
if (!document.getElementById("Step1" + "-" + n)) {
document.getElementById("step1").disabled = true;
}
document.getElementById("reset1").disabled = false;
}
window.ResetSteps1 = function () {
document.getElementById("step1").disabled = false;
document.getElementById("reset1").disabled = true;
var i = 1, step1; n = 1;
while (step1 = document.getElementById("Step1" + "-" + i)) {
step1.style.visibility = "hidden";
i++
}
}
})();
Where it will only work for the following:
<p>
<input type="button" onclick="ShowStep1()" value="Steps" id="step1"/>
<input type="button" onclick="ResetSteps1()" value="Reset" id="reset1" disabled="true"/>
</p>
But I want to do this with for many buttons with unique id's without having to manually make new functions. As of right now, in order for me to make multiple functions I have to manually create several of the Function 1 sets of code. How can I do this more efficiently if say I wanted to do 10 of these? The code works fine but I dont want to repeat myself. This code comes from the following link:
MathJax-demos-web-link
But I modified it in my own way. Any help and tips would be appreciated! Thanks in advance. For some reason there is an error in snippet but if you run it on jsfiddle it works fine. This is the entire script.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width">
<title>MathJax v3 dynamic equations using CSS and javascript</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script>
MathJax = {
tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]},
chtml: {
displayAlign: 'left'
},
startup: {
pageReady: function () {
//
// Do the usual startup (which does a typeset).
// When that is all done, un-hide the page.
//
return MathJax.startup.defaultPageReady().then(function () {
document.getElementById("hidden").disabled = true;
});
}
}
};
</script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-chtml.js"></script>
<script type="text/javascript">
<!-- Function 1 -->
(function () {
var n = 1;
window.ShowStep1 = function () {
document.getElementById("Step1" + "-" + n++).style.visibility = "visible";
if (!document.getElementById("Step1" + "-" + n)) {
document.getElementById("step1").disabled = true;
}
document.getElementById("reset1").disabled = false;
}
window.ResetSteps1 = function () {
document.getElementById("step1").disabled = false;
document.getElementById("reset1").disabled = true;
var i = 1, step1; n = 1;
while (step1 = document.getElementById("Step1" + "-" + i)) {
step1.style.visibility = "hidden";
i++
}
}
})();
<!-- Function 2 -->
(function () {
var n = 1;
window.ShowStep2 = function () {
document.getElementById("Step2" + "-" + n++).style.visibility = "visible";
if (!document.getElementById("Step2" + "-" + n)) {
document.getElementById("step2").disabled = true;
}
document.getElementById("reset2").disabled = false;
}
window.ResetSteps2 = function () {
document.getElementById("step2").disabled = false;
document.getElementById("reset2").disabled = true;
var i = 1, step2; n = 1;
while (step2 = document.getElementById("Step2" + "-" + i)) {
step2.style.visibility = "hidden";
i++
}
}
})();
</script>
<style>
#Step1-1, #Step1-2, #Step1-3, #Step1-4, #Step1-5,
#Step2-1, #Step2-2, #Step2-3, #Step2-4, #Step2-5 {
visibility: hidden;
}
</style>
</head>
<body>
<h1>Dynamic Equations in MathJax</h1>
<div id="frame">
<p>
Expand the following:
\begin{align}
(x+1)^2
&= \cssId{Step1-1}{(x+1)(x+1)} \\[3px]
&\cssId{Step1-2}{{} = x(x+1) + 1(x+1)} \\[3px]
&\cssId{Step1-3}{{} = (x^2+x) + (x+1)} \\[3px]
&\cssId{Step1-4}{{} = x^2 + (x + x) + 1} \\[3px]
&\cssId{Step1-5}{{} = x^2 + 2x + 1}
\end{align}
</p>
<p>
<input type="button" onclick="ShowStep1()" value="Steps" id="step1"/>
<input type="button" onclick="ResetSteps1()" value="Reset" id="reset1" disabled="true"/>
</p>
</div>
<div id="frame">
<p>
Expand the following:
\begin{align}
(x+1)^2
&= \cssId{Step2-1}{(x+1)(x+1)} \\[3px]
&\cssId{Step2-2}{{} = x(x+1) + 1(x+1)} \\[3px]
&\cssId{Step2-3}{{} = (x^2+x) + (x+1)} \\[3px]
&\cssId{Step2-4}{{} = x^2 + (x + x) + 1} \\[3px]
&\cssId{Step2-5}{{} = x^2 + 2x + 1}
\end{align}
</p>
<p>
<input type="button" onclick="ShowStep2()" value="Steps" id="step2"/>
<input type="button" onclick="ResetSteps2()" value="Reset" id="reset2" disabled="true"/>
</p>
</div>
</body>
</html>
The main change will be to create one version each of the two functions which take parameters rather than storing step information in variables which happens now.
However, before that, a couple of other observations:
The HTML is not 'legal' - ids need to be unique and frame ids are not unique in the given code.
This extra CSS styling a slight alarm bell, does it mean you can't have more than 5 steps?
#Step1-1, #Step1-2, #Step1-3, #Step1-4, #Step1-5,
#Step2-1, #Step2-2, #Step2-3, #Step2-4, #Step2-5 {
visibility: hidden;
}
This snippet renames the frame ids so they are unique, removes the multi-style settings above and substitutes the more general 'style elements whose id starts with Step'.
It then makes just one step-revealing function and one reset function and calls them with parameters. It does not try to store values of 'n' to show where the revealing has got to in each case but instead works it out each time by looking for those steps that are already visible.
Note that (as noted in the question) it is not possible to run this in the SO snippet system which is sandboxed so here is the complete code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width">
<title>MathJax v3 dynamic equations using CSS and javascript</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script>
MathJax = {
tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]},
chtml: {
displayAlign: 'left'
},
startup: {
pageReady: function () {
//
// Do the usual startup (which does a typeset).
// When that is all done, un-hide the page.
//
return MathJax.startup.defaultPageReady().then(function () {
document.getElementById("hidden").disabled = true;
});
}
}
};
</script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-chtml.js"></script>
<script>
(function () {
window.ShowStep = function (el, id) {
//go through all the elements with id id-n and set the first non visible one to visible
const steps = document.querySelectorAll('[id^="' + id + '"]');
for (let i = 0; i < steps.length; i++) {
if (steps[i].style.visibility != 'visible') {
steps[i].style.visibility = 'visible';
break;
}
}
el.nextElementSibling.disabled = false;
}
window.ResetSteps = function (el, id, reset) {
el.disabled = false;
//go through all the elements with id id-n and set them all to hidden
const steps = document.querySelectorAll('[id^="' + id + '"]');
for (let i = 0; i < steps.length; i++) {
steps[i].style.visibility = 'hidden';
}
}
})();
</script>
<style>
[id^="Step"] {
visibility : hidden;
}
</style>
</head>
<body>
<h1>Dynamic Equations in MathJax</h1>
<div id="frame1">
<p>
Expand the following:
\begin{align}
(x+1)^2
&= \cssId{Step1-1}{(x+1)(x+1)} \\[3px]
&\cssId{Step1-2}{{} = x(x+1) + 1(x+1)} \\[3px]
&\cssId{Step1-3}{{} = (x^2+x) + (x+1)} \\[3px]
&\cssId{Step1-4}{{} = x^2 + (x + x) + 1} \\[3px]
&\cssId{Step1-5}{{} = x^2 + 2x + 1}
\end{align}
</p>
<p>
<input type="button" onclick="ShowStep(this, 'Step1', 'reset1');" value="Steps"/>
<input type="button" onclick="ResetSteps(this, 'Step1', 'reset1')" value="Reset" disabled="true"/>
</p>
</div>
<div id="frame2">
<p>
Expand the following:
\begin{align}
(x+1)^2
&= \cssId{Step2-1}{(x+1)(x+1)} \\[3px]
&\cssId{Step2-2}{{} = x(x+1) + 1(x+1)} \\[3px]
&\cssId{Step2-3}{{} = (x^2+x) + (x+1)} \\[3px]
&\cssId{Step2-4}{{} = x^2 + (x + x) + 1} \\[3px]
&\cssId{Step2-5}{{} = x^2 + 2x + 1}
\end{align}
</p>
<p>
<input type="button" onclick="ShowStep(this, 'Step2', 'reset2');" value="Steps" id="step2"/>
<input type="button" onclick="ResetSteps(this, 'Step2', 'reset2')" value="Reset" id="reset2" disabled="true"/>
</p>
</div>
</body>
</html>
hey guys i got a balloon game that speeds up the balloon when i hover the mouse over one of them, got a few questions:
1.doesn't the speedup function just add to that balloons cell value?
it doesn't seem to change the pixels it should go up in any way,just updates the objects speed value
2.this function: onmouseover="speedUp(' + i + ')
when i hover the the object does it get a number associated with that object that was set by the render balloons function like a data attribute? i don't quite get this
here is the code:
'use strict';
var gNextId = 101;
var gBalloons = createBalloons()
var gInterval;
function startGame() {
renderBalloons();
gInterval = setInterval(() => {
moveBalloons();
}, 500);
}
function renderBalloons() {
var strHtml = '';
for (let i = 0; i < gBalloons.length; i++) {
var balloon = gBalloons[i];
strHtml += '<div class="balloon balloon' + (i + 1) +
'" onclick="popBalloon(this)" ' +
'" onmouseover="speedUp(' + i + ')" >' +
balloon.txt +
'</div>'
}
// console.log('strHTML', strHtml);
document.querySelector('.balloon-container').innerHTML = strHtml;
}
function moveBalloons() {
var elBalloons = document.querySelectorAll('.balloon');
for (let i = 0; i < elBalloons.length; i++) {
var balloon = gBalloons[i];
var elBalloon = elBalloons[i];
balloon.bottom += balloon.speed;
elBalloon.style.bottom = balloon.bottom + 'px';
if (balloon.bottom >= 800) clearInterval(gInterval);
}
}
function popBalloon(elBalloon) {
var popSound = new Audio('sounds/pop.mp3');
popSound.play();
elBalloon.classList.add('fade');
}
function speedUp(idxBalloon) {
console.log('Speeding up: ', gBalloons[idxBalloon])
gBalloons[idxBalloon].speed += 10;
}
function createBalloons() {
var ballons = [
createBalloon('A'),
createBalloon('B'),
createBalloon('C')
];
return ballons
}
function createBalloon(txt) {
return { id: gNextId++, bottom: 0, speed: 45, txt: txt }
}
The HTML if its needed:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="./css/main.css">
</head>
<body onload="startGame()">
<div class="balloon-container"></div>
</body>
<script src="./javascript/main.js"></script>
</html>
Each balloon has an object associated with it:
{ id: gNextId++, bottom: 0, speed: 45, txt: txt }
and stored in ballons array (aliased to gBalloons in top-level scope).
When the game starts, every 500ms each balloon is moved by the number of pixels defined in its speed property (performed by moveBalloons() function).
When you hover over a particular balloon, its speed increases by 10.
onmouseover handler knows which balloon speed to increase because it gets its position (index i) in gBalloons array: speedUp(' + i + ') upon creation of html.
I use mediaelementplayer
My code (why doesn't it work here)
(function() {
'use strict';
let media;
let mediaBtn = document.querySelectorAll(".button-play");
let mediaBtnPause = document.querySelectorAll(".button-pause");
let mediaTime;
let mediaTimeParts;
let mediaTimeSeconds;
$("iframe").mediaelementplayer({
success: function(mediaElement, domObject) {
media = mediaElement;
}
});
for (let i = 0; i < mediaBtn.length; i++) {
let mediaBtns = mediaBtn[i];
mediaTime = mediaBtns.innerHTML;
mediaTimeParts = mediaTime.split(':');
mediaTimeSeconds = (+mediaTimeParts[0]) * 60 * 60 + (+mediaTimeParts[1]) * 60 + (+mediaTimeParts[2]);
//console.log(i + ' ' + mediaTimeSeconds);
mediaBtns.addEventListener('click', function() {
media.setCurrentTime(mediaTimeSeconds);
media.play();
console.log('Click button # ' + i);
});
}
})();
button {
cursor: pointer;
margin: 10px;
padding: 5px 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mediaelement/4.2.9/mediaelement-and-player.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mediaelement/4.2.9/mediaelementplayer.min.css">
<!-- video 1 -->
<div class="media-wrapper">
<iframe class="video" width="560" height="315" src="https://www.youtube.com/embed/HIbAz29L-FA?modestbranding=1&playsinline=0&showinfo=0&enablejsapi=1&origin=https%3A%2F%2Fintercoin.org&widgetid=1" frameborder="0" allowfullscreen></iframe>
<button class="button-play">00:00:10</button>
<button class="button-play">00:00:20</button>
<button class="button-pause">pause</button>
</div>
<!-- video 1 -->
Example fiddle
now it turns out when you click on any button (except for a pause) - the start starts from the value of the last button. In this example, from 20 seconds.
For example, when you click on the button "<button class="button-play"> 00:00:10</button>" - the video starts from 20 seconds (from the value of the last button)
Why it happens?
How to solve this problem?
Thank you in advance
Because mediaTimeSeconds is reassigned everytime you run the for loop. Therefore it is assigned with the last value, while the button is clicked after it is assigned. You need to change it to
(function() {
'use strict';
let media;
let mediaBtn = document.querySelectorAll(".button-play");
let mediaBtnPause = document.querySelectorAll(".button-pause");
let mediaTime;
let mediaTimeParts;
$("iframe").mediaelementplayer({
success: function(mediaElement, domObject) {
media = mediaElement;
}
});
for (let i = 0; i < mediaBtn.length; i++) {
let mediaBtns = mediaBtn[i];
mediaTime = mediaBtns.innerHTML;
mediaTimeParts = mediaTime.split(':');
const mediaTimeSeconds = (+mediaTimeParts[0]) * 60 * 60 + (+mediaTimeParts[1]) * 60 + (+mediaTimeParts[2]);
//console.log(i + ' ' + mediaTimeSeconds);
mediaBtns.addEventListener('click', function() {
media.setCurrentTime(mediaTimeSeconds);
media.play();
console.log('Click button # ' + i);
});
}
})();
With full disclosure, I am brand new to JS. I don't fully comprehend the nature of the language (e.g. is it written in html, what is the difference between JS and html?). So needless to say, I am a novice. That being said, I'm trying to build an experiment in jspsych and I went through the tutorials, tried to run the sample code, and got "Invalid JavaScript Code." I cannot find any answers to why this is. It neither works in a browser or on JS Fiddle's testing software. I would appreciate any help with this.
P.S. I'm a decent programmer in Python, and the JS syntax seems pretty straight forward, but I'm out to sea when it comes to formatting, etc.
<html>
<head>
<title>My experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych-5.0.3/jspsych.js"></script>
<script src="jspsych-5.0.3/plugins/jspsych-text.js"></script>
<script src="jspsych-5.0.3/plugins/jspysch-single-stim.js"></script>
<link href="jspsych-5.0.3/css/jspsych.css" rel="stylesheet" type="text/css"></link>
</head>
<body>
</body>
<script>
/* define welcome message block */
var welcome_block = {
type: "text"
text: "Welcome to the experiment. Press any key to begin."
};
/*define instructions block*/
var instructions_block = {
type:"text",
text:"<p>In this experiment,a circle will appear in the center" +
"of the screen.</p><p>If the circle is <strong>blue</strong>," +
"press the letter F on the keyboard as fast as you can.</p>" +
"<p>If the circle is <strong>orange</strong>, do not press " +
"any key.</p>"+
"<div class ='left center-conten'><img src='img/blue.png'></img>" +
"<p class = 'small'><strong>Press the F key</strong></p></div>" +
"div class='right center-content'><img src='img/orang.png'></img>" +
"<p class='small'><strong>Do not press a key</strong></p></div>" +
"<p>Press any key to begin.</p>"
timing_post_trial: 2000
};
var test_stimuli = [
{
stimulus: 'img/blue.png',
data: { response: 'go'}
},
{
stimulus: 'img/orange.png',
data: { response: 'no-go'}
}
];
var all_trials = jsPsych.randomization.repeat(test_stimuli,10);
var post_trial_gap = function() {
return Math.floor( math.random() * 1500) + 750;
}
var test_block = {
type: 'single-stim',
choices: ['F'],
timing_response: 1500,
timing_post_trial: post_trial_gap,
on_finish: function(data){
var correct = false;
if(data.response == 'go' && data.rt > -1){
correct = true;
} else if(data.response == 'no-go' && data.rt == -1){
correct = true;
}
jsPsych.data.addDataToLastTrial({correct: correct});
},
timeline: all_trials
};
/*define debrief block*/
function getSubjectData() {
var trials = jsPsych.data.getTrialsofType('single-stim');
var sum_rt = 0;
var correct_trial_count = 0;
var correct_rt_count = 0;
for (var i = 0; i < trials.length; i++) {
if (trials[i].correct == true) {
correct_trial_count++;
if(trials[i].rt > -1){
sum_rt += trials[i].rt;
correct_rt_count++;
}
}
}
return {
rt: Math.floor(sum_rt/correct_rt_count),
accuracy: Math.floor(correct_trial_count / trials.length * 100)
}
}
var debrief_block = {
type: "text",
text: function() {
var subject_data = getSubjectData();
return"<p>You responded correctly on "+subject_data.accuracy+"% of "+
"the trials.</p><p>Your average response time was <strong>"+
subject_data.rt + "ms</strong>. Press any key to complete the "+
"experiment. Thank you!</p>";
}
};
/*create experiment timeline array*/
var timeline = [];
timeline.push(welcome_block);
timeline.push(instructions_block);
timeline.push(test_block);
timeline.pysh(debrief_block)
/*start the experiment*/
jsPsych.init({
experiment_structure: experiment,
on_finish: function() {
jsPsych.data.displayData();
}
});
</script>
</html>
Did you update the code posted here on SO? It looks like you still have some missing commas as I have indicated here with "//<-- YOU NEED A COMMA HERE". See below:
var welcome_block = {
type: "text", //<-- YOU NEED A COMMA HERE
text: "Welcome to the experiment. Press any key to begin."
};
/*define instructions block*/
var instructions_block = {
type:"text",
text:"<p>In this experiment,a circle will appear in the center" +
"of the screen.</p><p>If the circle is <strong>blue</strong>," +
"press the letter F on the keyboard as fast as you can.</p>" +
"<p>If the circle is <strong>orange</strong>, do not press " +
"any key.</p>"+
"<div class ='left center-conten'><img src='img/blue.png'></img>" +
"<p class = 'small'><strong>Press the F key</strong></p></div>" +
"div class='right center-content'><img src='img/orang.png'></img>" +
"<p class='small'><strong>Do not press a key</strong></p></div>" +
"<p>Press any key to begin.</p>", //<-- YOU NEED A COMMA HERE
timing_post_trial: 2000
};
EDIT: Another typo (math.random() should be Math.random());
var post_trial_gap = function() {
return Math.floor( Math.random() * 1500) + 750;
}
Here is the updated code:
/* define welcome message block */
var welcome_block = {
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
/* define instructions block */
var instructions_block = {
type: "text",
text: "<p>In this experiment, a circle will appear in the center " +
"of the screen.</p><p>If the circle is <strong>blue</strong>, " +
"press the letter F on the keyboard as fast as you can.</p>" +
"<p>If the circle is <strong>orange</strong>, do not press " +
"any key.</p>" +
"<div class='left center-content'><img src='img/blue.png'></img>" +
"<p class='small'><strong>Press the F key</strong></p></div>" +
"<div class='right center-content'><img src='img/orange.png'></img>" +
"<p class='small'><strong>Do not press a key</strong></p></div>" +
"<p>Press any key to begin.</p>",
timing_post_trial: 2000
};
/* define test block */
var test_stimuli = [
{
stimulus: "img/blue.png",
data: { response: 'go' }
},
{
stimulus: "img/orange.png",
data: { response: 'no-go' }
}
];
var all_trials = jsPsych.randomization.repeat(test_stimuli, 10);
var post_trial_gap = function() {
return Math.floor( Math.random() * 1500 ) + 750;
}
var test_block = {
type: "single-stim",
choices: ['F'],
timing_response: 1500,
timing_post_trial: post_trial_gap,
on_finish: function(data){
var correct = false;
if(data.response == 'go' && data.rt > -1){
correct = true;
} else if(data.response == 'no-go' && data.rt == -1){
correct = true;
}
jsPsych.data.addDataToLastTrial({correct: correct});
},
timeline: all_trials
};
/* define debrief block */
function getSubjectData() {
var trials = jsPsych.data.getTrialsOfType('single-stim');
var sum_rt = 0;
var correct_trial_count = 0;
var correct_rt_count = 0;
for (var i = 0; i < trials.length; i++) {
if (trials[i].correct == true) {
correct_trial_count++;
if(trials[i].rt > -1){
sum_rt += trials[i].rt;
correct_rt_count++;
}
}
}
return {
rt: Math.floor(sum_rt / correct_rt_count),
accuracy: Math.floor(correct_trial_count / trials.length * 100)
}
}
var debrief_block = {
type: "text",
text: function() {
var subject_data = getSubjectData();
return "<p>You responded correctly on "+subject_data.accuracy+"% of "+
"the trials.</p><p>Your average response time was <strong>" +
subject_data.rt + "ms</strong>. Press any key to complete the "+
"experiment. Thank you!</p>";
}
};
/* create experiment timeline array */
var timeline = [];
timeline.push(welcome_block);
timeline.push(instructions_block);
timeline.push(test_block);
timeline.push(debrief_block);
/* start the experiment */
jsPsych.init({
timeline: timeline,
on_finish: function() {
jsPsych.data.displayData();
}
});
After fetching the library and creating a blue and orange png I ran the experiment with the following correction to your last code post. The plugin name you have is incorrect. By the way, my time was 303ms.
<script src="jspsych-5.0.3/plugins/jspsych-single-stim.js"></script>
Hello I have a query regarding Kendo UI's Window Content. Basically I've picked up a nice little desktop-like (WebOS) setup that I'd like to fiddle around with. The application windows "openWin1" and "openWin2" are defined but are empty and have no content. Where do I add the content? In HTML5 or Javascript?
Any help would be greatly appreciated. I'm quite new to this.
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Masrani Global OS</title>
<link href="styles/kendo.common.min.css" rel="stylesheet">
<link href="styles/kendo.default.min.css" rel="stylesheet">
<link href="css/system.css" rel="stylesheet">
<script src="js/jquery.min.js"></script>
<script src="js/kendo.web.min.js"></script>
<script src="js/kendo.window.min.js"></script>
<script src="custom.js"></script>
</head>
<body>
<div id="titleBar"><a id="openWin1" class="topBtn" href="#">Terminal</a><a id="openWin2" class="topBtn" href="#">Media Player</a></div>
<div id="deskTop"></div>
<div id="statusBar"><ul id="statusBarBtns"><li id="hideAll"><a class="statBarBtn" href="#">Show Desktop</a></li></ul><div id="logText"></div></div>
</body>
</html>
custom.js:
function log(data){
console.log(data);
}
function repositionWindow(elementName){
var thisWindow = $("#" + elementName).closest('.k-window'),
winOffset = thisWindow.offset(),
thisWindowWidth = thisWindow.width()
thisWindowHeight = thisWindow.height()
bottomEdge = winOffset.top + thisWindowHeight
rightEdge = winOffset.left + thisWindowWidth
deskTopOffset = $('#deskTop').offset()
deskTopHeight = $('#deskTop').height();
deskTopBottom = deskTopOffset.top + deskTopHeight - 25
deskTopWidth = deskTopOffset.left + $('#deskTop').width() - 2;
if(thisWindowWidth>$('#deskTop').width()){thisWindow.width($('#deskTop').width());}
if(bottomEdge>deskTopBottom){thisWindow.css('top',winOffset.top - (bottomEdge - deskTopBottom)+'px');}
if(rightEdge>deskTopWidth){thisWindow.css('left',winOffset.left - (rightEdge - deskTopWidth)+'px');}
if(winOffset.top < deskTopOffset.top){ thisWindow.css('top',(deskTopOffset.top+2)+'px');}
if(winOffset.left < deskTopOffset.left){thisWindow.css('left',deskTopOffset.left + 'px');}
if(thisWindow.offset().top<deskTopOffset.top){thisWindow.css('top',deskTopOffset.top+'px');thisWindow.height(deskTopHeight-25);}
}
function createWindow(elementName,Icon,WindowTitle,Width,Height){
$('body').append('<div id="'+elementName+'"></div>');
var window = $("#" + elementName);
if (!window.data("kendoWindow")) {
$('#statusBarBtns').append('<li id="statbar_'+elementName+'"><a class="statBarBtn" href="#WIN-'+elementName+'">'+WindowTitle+'</a></li>');
window.kendoWindow({
width: Width+"px",
height: Height+"px",
title: WindowTitle,
actions: ["Custom","Maximize", "Close"],
close: function(){
$('#statbar_'+elementName).remove();
$("#"+elementName).data("kendoWindow").destroy();
if(elementName == 'myWindow'){
$('#openWin1').show();
}
if(elementName == 'myWindow2'){
$('#openWin2').show();
}
},
activate: function(e){
repositionWindow(elementName);
},
dragend: function(e){
repositionWindow(elementName);
},
resize: function(e){
repositionWindow(elementName);
}
});
$("#" + elementName +'_wnd_title').parent().prepend('<img class="windowLeftIcon" src="icons/'+Icon+'.png"/>');
window = $("#" + elementName).data("kendoWindow");
var vv = window.wrapper.find(".k-i-custom");
vv.removeClass('k-i-custom').addClass('k-i-minimize2');
vv.click(function (e) {
$("#" + elementName).closest('.k-window').hide();
})
}
}
$('.statBarBtn').live('click',function(e){
e.preventDefault();
var elementName = $(this).attr('href');
if(elementName == '#') return;
elementName = elementName.replace("#WIN-","");
var wnd = $("#"+elementName).data("kendoWindow");
if(wnd.element.is(":hidden")){
$("#" + elementName).closest('.k-window').show();
wnd.toFront();
} else {
$("#" + elementName).closest('.k-window').hide();
}
});
$(document).ready(function() {
$('#openWin1').click(function(){
createWindow('myWindow','server','Terminal',500,300);
$(this).hide();
});
$('#openWin2').click(function(){
createWindow('myWindow2','server','Media Player',400,200);
$(this).hide();
});
$('#hideAll').click(function(){
$(".k-window-content").each(function(){
$(this).closest('.k-window').hide();
});
});
});
In your JavaScript, a div is created and added to the DOM:
$('body').append('<div id="'+elementName+'"></div>');
The Kendo Window object is then set up on the created div:
var window = $("#" + elementName);
if (!window.data("kendoWindow")) {
...
window.kendoWindow({...});
}
Therefore, any HTML content nested within the created div will be displayed within the Kendo Window, i.e.:
$('body').append('<div id="'+elementName+'"><p>This will appear in the window</p></div>');