getElementByID returns null (jsfiddle inside) - javascript

I'm trying to create custom buttons for a media player. The tricky part is that I want the play button to become a "loading" button that will later become a pause button but anyways.
I'm using 4 divs - stop / play / loading / pause, the last two being hidden (display:none;). I want to display the loading div instead of the play div when you click on the latter (in addition to activating the player). Yet when I call lyricsPlay("B"),document.getElementById("lyrics" + el + "1") seems to be returning null.
The stop button closes the container div (a popup which will contain the player), and stops the player. This part works fine.
Being pretty much a newbie when it comes to javascript, I'm sure this is a stupid mistake on my part but I'm at a complete loss in finding where it is. I've read many posts about getElementById() returning null but none of the solutions seems to apply to my case.
Below is my HTML code, but you can fiddle with it here:
function lyricsToggle(div_id) {
var el = document.getElementById(div_id);
if (el.style.display == 'none') {
el.style.display = 'block';
} else {
el.style.display = 'none';
}
}
function lyricsStop(videoID, divID) {
lyricsToggle(divID);
//jQuery('#lyrics' + videoID).tubeplayer('stop');
}
function lyricsPlay(el) {
var play = document.getElementById("lyrics" + el + "1"); //returns null??
var load = document.getElementById("lyrics" + el + "2"); //returns null??
lyricsToggle(play);
lyricsToggle(load);
//jQuery(video).tubeplayer("play");
}
#container {
margin-top: 60px;
margin-right: 100px;
}
.lyricsPlay {
width: 30px;
height: 30px;
float: right;
background-color: green;
}
.lyricsStop {
width: 30px;
height: 30px;
float: right;
background-color: red;
}
.lyricsLoad {
width: 30px;
height: 30px;
float: right;
display: none;
background-color: blue;
}
.lyricsPause {
width: 30px;
height: 30px;
float: right;
display: none;
background-color: yellow;
}
<body>
<div id="container">
<div id="lyricsB0" class="lyricsStop" onClick="lyricsStop('B', 'container')">
stop
</div>
<div id="lyricsB1" class="lyricsPlay" onClick="lyricsPlay('B')">
play
</div>
<div id="lyricsB2" class="lyricsLoad" onClick="lyricsLoad('B')">
loading
</div>
<div id="lyricsB3" class="lyricsPause" onClick="lyricsPause('B')">
pause
</div>
</div>
</body>

You are passing a element as div_id already to lyricsToggle() with:
var play = document.getElementById("lyrics" + el + "1");// as div_id
lyricsToggle(play);
so no need to do this inside lyricsToggle(div_id):
var el = document.getElementById(div_id);
Try this:
function lyricsToggle(div_id) {
var el = div_id; // and not: var el = document.getElementById(div_id);
if ( el.style.display == 'none' ) { el.style.display = 'block';}
else {el.style.display = 'none';}
}
Fiddle

Related

Javascript: can't change background on div click or change marginLeft on element

I tried to test changing backgroundColor and marginLeft on this simple example: https://jsfiddle.net/ntqLo6v0/2/
and couldn't make it work.
var collapsed = 0;
$('[data-toggle=collapse-button]').click(function() {
if (collapsed == 0) {
close();
} else {
open();
}
});
function close() {
document.getElementById("button").style.backgroundColor = "blue";
(document.getElementsByClassName("content")[0]).style.marginLeft = "20px";
collapsed = 1;
}
function open() {
document.getElementById("button").style.backgroundColor = "red";
(document.getElementsByClassName("content")[0]).style.marginLeft = "120px";
collapsed = 0;
}
.content {
background-color: green;
width: 200px;
height: 100px;
}
#button {
background-color: red;
width: 100px;
height: 50px;
margin: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="button" data-toggle="collapse-button">
button
</div>
<div class="content">
some content here
</div>
There is just a little issue: $('[data-toggle=collapse-button]').
You are using jQuery but do not define it. That's why you get a Uncaught ReferenceError: $ is not defined in the console.
Here is your updated fiddle where I added jQuery (in the resources left) in order to make your example running.

Immediately Invoked Function Expression For Page Defaults

I've tried to setup a very "vanilla" approach to this but cannot get the result.
I'm trying to reach into the DOM and the associated div styles using JS and effectively change the "display" property of the CSS.
The JS is error free but the CSS doesn't change.
(function() {
var singleCard = document.getElementById('card-container');
var manyCard = document.getElementById('card-container-many');
var allCard = document.getElementById('card-container') && document.getElementById('card-container-many');
var singleCardCss = document.querySelector('#card-container');
var manyCardCss = document.querySelector('#card-container-many');
var allCardCss = document.querySelector('#card-container') && document.querySelector('#card-container-many');
if (singleCardCss.display && manyCardCss.display === 'none') {
allCardCss.display = 'block';
} else {
allCardCss.display = 'none';
}
}());
#card-container {
position: relative;
display: none;
width: 280px;
height: 310px;
background-size: 640px 360px;
background-repeat: no-repeat;
border: 1px solid #222;
border-radius: 10px;
margin: 10px;
cursor: pointer;
}
#card-container-many {
position: relative;
display: none;
width: 280px;
height: 310px;
background-size: 640px 360px;
background-repeat: no-repeat;
border: 1px solid #222;
border-radius: 10px;
margin: 10px;
cursor: pointer;
}
<div class="container-fluid text-center">
<div id="card-container"></div>
</div>
<div class="container-fluid text-center">
<div id="card-container-many"></div>
</div>
The .style property is missing. For example:
allCardCss.style.display = 'block';
Also, the use of the AND operator is wrong I believe. It should be used in the if condition like so:
if (singleCardCss.style.display === "none" && manyCardCss.style.display === 'none') {...
Each side of the operand must be complete in a conditional even when it's a comparison between 2 objects (singleCardCSS and manyCardCSS) vs. the same condition ("none").
I took a third look and saw that allCardCSS is wrong as well, it should be:
var allCardCSS = document.querySelectorAll('div > div');
The result will be a NodeList of all divs that are a child of another div (singleCardCSS and manyCardCSS). This NodeList is an array-like object which you can do simple iterations upon in order to access the objects within. Notice how the for loop goes through the NodeList allCardCss.
Finally on the last statement has been eliminated because the else isn't needed since they are already .style.display="none". The first statements have been eliminated as well because .getElementById('ID') is identical to querySelector('#ID');
One last thing, I almost forgot about the parenthesis business:
Either of the following two patterns can be used to immediately invoke
a function expression, utilizing the function's execution context to
create "privacy."
(function(){ /* code */ }()); // Crockford recommends this one
(function(){ /* code */ })(); // But this one works just as well
-Ben Alman
So you are ok. The point is that if you have a set of extra parenthesis at the end then that'll be interpreted by the browser as an Expression Function which causes an Immediate Invocation*. The mention of privacy is referring to the IIFE with a closure which doesn't apply in your circumstance unless you make the latter part of the code into a function in which case you have a closure. In your case it's not needed since you aren't passing any variables from the outside of your function.
To those more knowledgeable. If there's anything I've said that to the contrary or omitted, please leave a comment with your downvote.
*it's IIFE a little mixed up in order in sentence but you get the picture 😉
Demo
(function() {
var singleCardCss = document.querySelector('#card-container');
var manyCardCss = document.querySelector('#card-container-many');
var allCardCss = document.querySelectorAll('div > div');
if (singleCardCss.style.display === "none" && manyCardCss.style.display === 'none') {
for (let i = 0; i < allCardCSS.length; i++) {
allCardCss[i].style.display = 'block';
}
}
}());
#card-container {
position: relative;
display: none;
width: 280px;
height: 310px;
background-size: 640px 360px;
background-repeat: no-repeat;
border: 1px solid #222;
border-radius: 10px;
margin: 10px;
cursor: pointer;
}
#card-container-many {
position: relative;
display: none;
width: 280px;
height: 310px;
background-size: 640px 360px;
background-repeat: no-repeat;
border: 1px solid #222;
border-radius: 10px;
margin: 10px;
cursor: pointer;
}
<div class="container-fluid text-center">
<div id="card-container"></div>
</div>
<div class="container-fluid text-center">
<div id="card-container-many"></div>
</div>
Your error is very common. You have to remove the last ) after your function. You close your IIFE after calling it. You can try but your function will be never call! You also can try to delete your variable allCardCss and allCard. I do not understand why do you initialize them with &&.
Replace:
(function() {
var singleCard = document.getElementById('card-container');
var manyCard = document.getElementById('card-container-many');
var allCard = document.getElementById('card-container') && document.getElementById('card-container-many');
var singleCardCss = document.querySelector('#card-container');
var manyCardCss = document.querySelector('#card-container-many');
var allCardCss = document.querySelector('#card-container') && document.querySelector('#card-container-many');
if (singleCardCss.display && manyCardCss.display === 'none') {
singleCardCss.display = 'block';
} else {
allCardCss.display = 'none';
}
}());
By:
(function() {
var singleCard = document.getElementById('card-container');
var manyCard = document.getElementById('card-container-many');
var singleCardCss = document.querySelector('#card-container');
var manyCardCss = document.querySelector('#card-container-many');
if (singleCardCss.display && manyCardCss.display === 'none') {
singleCardCss.display = 'block';
manyCardCss.display = 'block';
} else {
singleCardCss.display = 'none';
manyCardCss.display = 'none';
}
})();

New to Javascript - changing style of element

So based on the value of a boolean, I want certain tabs in my sidebar to display/ hide when the page loads.
var someVar = true;
function show_ifTrue() {
if (Boolean(someVar) == true) {
document.getElementById('x').style.display = 'block';
console.log("I CHANGED IT");
}
else {
document.getElementById('x').style.background = 'red';
}
}
.sidebar {
position: fixed;
overflow-y: scroll;
top: 0;
bottom: 0;
float: left;
display: inline-block;
z-index: 50;
}
#tab {
display: block;
}
#x {
display: none;
}
<div class="sidebar">
Cats
Dogs
</div>
I have tried everything from taking out the display from .sidebar a{...} and giving each tab its own display property, using !important, changing in JS using style.cssText or setting attribute, I just can't get it to change the display.
In order to change the color, you have to call the function first, but you are never calling it, since onpageshow could only be added to <body>, so you could move it there - <body onpageshow='...'>. Or, if you still want to deal only with the div itself, do it onload:
window.onload=function(){
show_ifTrue();
}
This way too could also use your pageshow:
window.onpageshow=function(){
show_ifTrue();
}
Also, you don't need Boolean prefix in your function, just someVar == true.
It appears that you are missing the css closing braket for #tab (EDIT: OP edited this, but it could also have been part of the issue). Also, you might want to use window.onload, or onpageshow on the body element — it's the only element that it will work on. With that fixed, here's a working example:
window.onload = function () {
show_ifTrue();
}
var someVar = true;
function show_ifTrue() {
if (someVar === true) {
document.getElementById('x').style.display = 'block';
console.log('I CHANGED IT');
}
else {
document.getElementById('x').style.background = 'red';
}
}
.sidebar {
position: fixed;
overflow-y: scroll;
top: 0;
bottom: 0;
float: left;
display: inline-block;
z-index: 50;
}
#tab {
display: block;
}
#x {
display: none;
}
<div class="sidebar">
Cats
Dogs
</div>
I hope that helps!

Making <div>s disappear simultaneously

My aim of the code which you'll find below is to make some kind of a filter. But for some reason it won't work.
As you can see when you try to hide the boxes when selecting the input box it won't work; but when you make var x, var x = document.getElementById("a"); it will work. Is there a way to hide all the different boxes?
function myFunction1() {
var x = [document.getElementById("a"), document.getElementById("b"), document.getElementById("c")];
if (x.style.display == 'block')
x.style.display = 'none';
else
x.style.display = 'block';
}
#a, #b, #c {
float: left;
width: 25%;
height: 200px;
background-color: #ffffff;
border: 1px solid #002261;
margin: -1px;
text-align: center;
display: block;
}
<input type="checkbox" onclick="myFunction1()">Try to hide all
<div id="a">item a</div>
<div id="b">item b</div>
<div id="c">item c</div>
As you can see you can't hide all the boxes simultaneously.
You are making a list([]) and then trying to style the list itself, not its contents.
JavaScript provides an easy list method for this, forEach():
function myFunction1() {
var x = [document.getElementById("a"), document.getElementById("b"), document.getElementById("c")];
x.forEach(function(item) {
if (window.getComputedStyle(item).display === 'block') item.style.display = 'none';
else item.style.display = 'block';
});
}
See this codepen demo
Note: your code had a minor bug in getting the style, item.style.display only gets inline styles, so the first time you call the function it will not hide the element. I fixed it in the above code and codepen with window.getComputedStyle(item).display.

Making a javascript popup draggable

I am creating a JavaScript popup. The code is as below.
The HTML:
<div id="ac-wrapper" style='display:none' onClick="hideNow(event)">
<div id="popup">
<center>
<h2>Popup Content Here</h2>
<input type="submit" name="submit" value="Submit" onClick="PopUp('hide')" />
</center>
</div>
</div>
The CSS:
#ac-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url("images/pop-bg.png") repeat top left transparent;
z-index: 1001;
}
#popup {
background: none repeat scroll 0 0 #FFFFFF;
border-radius: 18px;
-moz-border-radius: 18px;
-webkit-border-radius: 18px;
height: 361px;
margin: 5% auto;
position: relative;
width: 597px;
}
The Script:
function PopUp(hideOrshow) {
if (hideOrshow == 'hide') document.getElementById('ac-wrapper').style.display = "none";
else document.getElementById('ac-wrapper').removeAttribute('style');
}
window.onload = function () {
setTimeout(function () {
PopUp('show');
}, 0);
}
function hideNow(e) {
if (e.target.id == 'ac-wrapper') document.getElementById('ac-wrapper').style.display = 'none';
}
The jsFiddle Link:
http://jsfiddle.net/K9qL4/2/
The Issue:
The above script works fine, but I need to make the popUp draggable.
Here's some code that will do what you want. It relies only on an object called drag to store all its values, but you can easily alter that. The example relies on there being a div with the id of mydiv (a document.write() is used in this instance to supply that) that has a position attribute of absolute or fixed. You can see it in action at Jamie
document.write("<" + "div id='mydiv' style='background:blue; width:100px;"
"height:100px; position:fixed;'>" + "<" + "/div>");
var drag = new Object();
drag.obj = document.getElementById('mydiv');
drag.obj.addEventListener('mousedown', function(e)
{
drag.top = parseInt(drag.obj.offsetTop);
drag.left = parseInt(drag.obj.offsetLeft);
drag.oldx = drag.x;
drag.oldy = drag.y;
drag.drag = true;
});
window.addEventListener('mouseup', function()
{
drag.drag = false;
});
window.addEventListener('mousemove', function(e)
{
drag.x = e.clientX;
drag.y = e.clientY;
var diffw = drag.x - drag.oldx;
var diffh = drag.y - drag.oldy;
if (drag.drag)
{
drag.obj.style.left = drag.left + diffw + 'px';
drag.obj.style.top = drag.top + diffh + 'px';
e.preventDefault();
}
});
Use the
.draggable();
jquery function, here is your updated fiddle:
http://jsfiddle.net/N9rQK/
If you don't want to use jQuery, you should read this subject: Draggable div without jQuery UI

Categories