I am not a programmer! Anyway; I am working on a dictionary app, I need the user to be able to listen to the word when he clicks (or click a small button next to it). Every word is on its own p tag.
My approach was to give the p tag an id equal to the word,so for the word apple the p id will be id="apple", and the mp3 file name is "apple.mp3".
I need a general script (for the whole page) that grabs the id of the clicked element and push it into an embed inner html function that embeds an audio tag with the src="the clicked id.mp3" and play it.
Here what I was trying, but obviously I am missing the correct syntax
<!DOCTYPE html>
<html>
<head>
<title>Get ID of Clicked Element using JavaScript</title>
</head>
<body>
<button id='cat' >cat</button>
<button id='dog' >dog</button>
<script>
document.addEventListener('click', function(e) {
alert(e.target.id);
});
function playSound(soundfile) {
document.getElementById("the grapped Id").innerHTML=
"<embed src= the grapped id""+soundfile+"\" hidden=\"false\" autostart=\"true\" loop=\"false\" />";
}
</script>
</body>
</html>
Some notes:
Instead of id use data-* as more suitable attribute for such tasks.
Create audio elements using the Audio() constructor.
Keep loaded sounds in the memory to reduce the number of server requests and improve user experience.
<!DOCTYPE html>
<html>
<head>
<title>Click a word to listen it</title>
</head>
<body>
<p data-sound="cat">cat</p>
<p data-sound="dog">dog</p>
<script>
var sounds = {};
function loadSound(name) {
if (sounds[name]) {
return sounds[name];
}
var file = '/sounds/' + name + '.mp3',
sound = new Audio(file);
sound.onerror = function() {
alert('File not found: ' + file);
};
sound.onloadedmetadata = function() {
sounds[name] = sound;
};
return sound;
}
function playSound(name) {
var sound = loadSound(name);
if (sound.currentTime > 0) {
sound.pause();
sound.currentTime = 0;
}
sound.play();
}
document.addEventListener('click', function(e) {
if (e.target.dataset && e.target.dataset.sound) {
playSound(e.target.dataset.sound);
}
});
</script>
</body>
</html>
Related
I have one HTA file, one JS file is enqueued to the HTA file and HTML files with contents are loaded into the HTA file.
For example this is my_hta_file.hta
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=9.0" />
</head>
<body></body>
</html>
<script type="text/javascript" src="my_js_file.js"></script>
and this is my_js_file.js
function getFileContent(filePath) {
var fileStream = new ActiveXObject('ADODB.Stream');
fileStream.Type = 2;
fileStream.Charset = 'utf-8';
fileStream.Open();
fileStream.loadFromFile(filePath);
var fileContent = fileStream.ReadText();
fileStream.Close();
return fileContent;
}
// initial loading of home page
document.body.innerHTML = getFileContent('index.html');
var pageLinks = document.querySelectorAll('a');
for(i = 0; i < pageLinks.length; i++) {
var linkHref = pageLinks[i].getAttribute('href');
pageLinks[i].setAttribute('href','#!'+linkHref);
// I add this leading prefix to prevent following by the link when click by it
pageLinks[i].onclick = function() {
var page = this.getAttribute('href').substring(3);
if(page == '') {
var page = 'index';
}
// load HTML of the page by link path when click by the link
document.body.innerHTML = getFileContent(page+'.html');
}
}
and my HTML files with contents are:
index.html
Home
Second
Third
<div>Home page content</div>
second.html
Home
Second
Third
<div>Second page content</div>
third.html
Home
Second
Third
<div>Third page content</div>
When I click by a link, I need to load all the HTML content from the HTML file by the link path including the very links I click by.
If I open my HTA file and click the link "Second", I get the second page links and content successfully.
But after that if I click the link "Third", I get the error
Cannot find file 'file:///D:/third' ...
How to resolve the problem?
UPDATE 1
If I move my script to the bottom of the HTA body and add a div for loading HTML for example
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=9.0" />
</head>
<body>
<div id="body"></div>
<script type="text/javascript" src="my_js_file.js"></script>
</body>
</html>
and in my JS file load HTML into div i.e.
document.getElementById('body').innerHTML = ...
instead of
document.body.innerHTML = ...
the problem still remains
As said in the comments, all the links with attached event listeners are replaced by new elements when innerHTML is changed. These new links don't have the listeners which the old elements had.
The snippet below shows how you can use a function to reinit the listeners. The snippet assumes a content wrapper element is used (as you already seem to use it). I've also simplified the code a bit, and used more modern JS (since IE9 mode is used in the OP).
function getFileContent (filePath) {
// As it currently is
}
// Handles clicks on the links
function newContent (e) { // e contains information of the current event
var path = e.target.href || 'index',
body = document.getElementById('body');
e.preventDefault(); // Prevents the default action of the clicked link
body.innerHTML = getFileContent(path + '.html');
init(); // Initialize the new content
return;
}
// Initializes the page
function init() {
var links = document.querySelectorAll('a'),
i, ei;
for (i = 0, ei = links.length; i < ei; i++) {
links[i].addEventListener('click', newContent);
}
return;
}
// Initialize the first page
init();
I'm trying to get my head around - why is the DOM Nodes keeps on going up when I'm checking my website in the Performance Monitor.
I've added this simple code that just looping on:
1) adding and element to a wrap,
2) bind it with a click event.
3) removing it.
but still the DOM Nodes are always up the I check the performance.
any thoughts?
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
.wrap{
font-size:50px;
}
</style>
</head>
<body >
<div class="wrap">
<div></div>
</div>
<script>
var counter = 0;
setInterval(function () {
//increase counter (for display)
counter++;
//get wrap
var wrap = document.getElementsByClassName("wrap")[0];
//remove its children
while (wrap.firstChild) {
wrap.firstChild.removeEventListener("click", onclick);
wrap.removeChild(wrap.firstChild);
}
//create new element
var div = document.createElement("div"); // create a div element
div.innerHTML = 'hello mosh (' + counter + ')';
//bind events
div.addEventListener("click", onclick);
// append the div to wrap
wrap.appendChild(div);
}, 200);
//on click function
var onclick = function () { alert('click'); }
</script>
</body>
</html>
The v8 engine is garbage-collected, removed DOM elements are not destroyed immediately.
Occasionally unused (unreachable) objects are garbage-collected.
If I wait long enough, with your code, I do see DOM Nodes go back down to the original value (had to bump the interval to 20 to speed up the process).
For this reason it is often more efficient to not remove DOM elements, and instead just replace the HTML content.
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
.wrap2 {
font-size:50px;
}
</style>
</head>
<body >
<div class="wrap2">
<div></div>
</div>
<script>
var counter = 0;
var wrap = document.getElementsByClassName("wrap2")[0];
var div = wrap.getElementsByTagName("div")[0];
setInterval(function () {
counter++;
div.innerText = 'hello mosh (' + counter + ')';
}, 20);
//on click function
var onclick = function () { alert('click'); }
</script>
</body>
</html>
<style>
video
{
display:table;
width:100%;
height:100%;
}
</style><script type="text/javascript">
var myVideo = document.getElementsByTagName("video")[0];
myVideo.addEventListener("ended", function() {
window.location = "http://mariopaintforums.ddns.net/secret/contin_midi/";
}, true);
</script><body><center><video src="vid.mp4" autoplay>ur brosr is no html5 coocpopabl</video></center></body>
I want to redirect to a different page when a is done playing. Is this possible?
I don't want to try to "wait" for the amount of time that the video itself occupies, because it may take a while to load and it won't finish playing correctly.
The current code with the non-working answer is above.
You can listen to the ended event of the player, and perform your redirect in the callback function.
// Alternatively, use a jQuery selector to get your video element.
var myVideo = document.getElementsByTagName("video")[0];
myVideo.addEventListener("ended", function() {
console.log("The video has just ended!");
// Let's redirect now
window.location = "your_new_url";
}, true);
Give the video an id and create the event handler outside the event listener. Go to: PLUNKER and/or review Snippet below:
BTW, I noticed the code given has <style> and <script> tags before the starting tag of <body>. The only thing that should ever be before the <body> tag is it's only sibling that being the end tag of </head>. Copy the way the layout is in my demos and you should be OK. Place <style> in <head> and <script> before the closing tag of </body>.
SNIPPET
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>index.html</h1>
<video id="vid1" class="vid" src="http://html5demos.com/assets/dizzy.mp4" controls autoplay></video>
<script>
var vid = document.getElementById('vid1');
var loc = 'http://example.com';
vid.addEventListener('ended', function(e) {
jumpTo(loc);
}, false);
function jumpTo(url) {
window.location = url;
}
</script>
</body>
</html>
I am a complete noob and I have started trying to do a program which plays the sound of each letter's keycode every time it is pressed in the textbox and deletes the text every time I press the Spacebar.
The program clears the textbox when I use the space button, but it doesn't play sound with any character:
<!DOCTYPE html>
<html lang="en">
<head>
<title>keyCode example</title>
<script type="text/javascript">
function showKeyCode(e) {
var letter = e.keyCode
if (letter != 32)
{
var audio = new Audio(e.keyCode + ".wav");
audio.play();
}
else
{
document.getElementById("TextBox1").value = "";
}
}
</script>
</head>
<body>
<input TYPE = text ID="TextBox1" SIZE = 15 onkeyup="showKeyCode(event);">
</body>
</html>
Okay, I found a few problems in your code:
Don't use uppercase tag attributes.
Use quotes for attributes.
Include the <body> tag.
You forgot a semicolon after var letter = e.keyCode.
function showKeyCode(e) {
var letter = e.keyCode;
if (letter != 32) {
var audio = new Audio(e.keyCode + ".wav");
audio.play();
} else {
document.getElementById("TextBox1").value = "";
}
}
I have made a jsFiddle for you. It seems to work.
Furthermore, why do you use onkeyup and not onkeydown?
So I'm trying to complete some javascript and having trouble codeing links to update a image. In a parent window using my script I open a remote child window to operate the image. THe links on the child window open the first image and last image. Two more links control the "next" image and previous image.
Heres what I have so far
HTML PARENT WINDOW : (haven't figured out how to post html on here btw :( )
<html>
<head>
<title> </title>
<script type="text/javascript" src="scriptss.js">
</script>
</head>
<body>
<img src="images/img0.jpg" width="200px" height="200px" id="myImage" name="myImage" /></img>
<h1>XXX</h1>
<a href="#" id = "opens" >open</a>
</br>
close
</br>
</body>
<html>
Child Window HTML:
<html>
<head>
<title> Matt Beckley Assignment Remote</title>
<link rel="stylesheet" type="text/css" href="remote.css" />
<script type="text/javascript" src="scriptss.js">
</script>
</head>
<body>
<h1>My Remote</h1>
First Image
</br>
Next Image
</br>
Previous Image
</br>
Last Image
</br>
close
</body>
</html>
JAVASCRIPT child node
var newWindow = null;
window.onload = init;
var myImages = new Array();
//start loop - length depends on how many images you need to preload
for (var i=0; i<5; i++) {
//create new image object
var tempImage = new Image();
//assign name|path of image to src property of image object
tempImage.src = "img" + (i+1) + ".jpg";
}
function init()
{
for(var i=0; i<document.links.length; i++)
{
document.links[i].onclick = changeWindowState;
}
}
function windowOpen(){
if(newWindow && !newWindow.closed){
return true;
}
return false;
}
function changeWindowState()
{
if (this.id =="closes")
{
if(windowOpen())
{
newWindow.close();
}
else
{
alert("The window isn't open");
}
}
if (this.id =="closess")
{
if(windowOpen())
{
remotetest.html.close();
}
else
{
alert("The window isn't open");
}
}
if(this.id == "opens")
{
if(windowOpen())
{
alert("The Window is alreadyopen!");
}
else
{
newWindow = window.open ("remotetest.html","remoteWin","resizeable=no,width=200,height=200");
}
}
return false;
}
function first()
{
if(this.id == "first")
{
alert("box");
}
else(this.id == "first")
{
alert("box");
}
}
Anyways I'm preloading my images and I got that figured out correctly. I'm trying to access my element in the parent node in the image tag and display an array element 1-6. In other words image 1 thru image 6
THe idea is to press a button in the child node and display the first image element[0] for instand press another button element[5]
or press another button for next element[i+1] with an another button. THanks for the help.
There are quite some ways on how to communicate between parent and child window. See this for more info.