Is there a simpler way to write this code? - javascript

This code is designed to make the sections display = none/block onclick, is there an easier way to write it so it is simpler and less lines of code.
I feel like I shouldn't need to rewrite it each time per every link and there should be a way to have 1 script that will work with the whole navbar.
HTML
<header>
<img onclick="video()" id="logo" src="https://res.cloudinary.com/dnrojsaks/image/upload/v1587122319/Icons/logo-no-text_yyug8o.svg" alt="Mac Logo" style="width: 10vw;" />
<nav>
<a onclick="contact()">Contact</a>
<a onclick="work()">Work</a>
<a onclick="blog()">Blog</a>
</nav>
</header>
<main>
<section id="main" style="display: block;">
<h1>Mac Hooper</h1>
<p><strong>Developer.</strong><br> Progressive, modern web development.</p>
</section>
<section id="contact" style="display: none;">
macdevh#gmail.com
<div id="social">
<img src="https://res.cloudinary.com/dnrojsaks/image/upload/v1587129314/Icons/insta_maq9f2.svg" alt="Instagram Logo">
<img src="https://res.cloudinary.com/dnrojsaks/image/upload/v1587129314/Icons/glab_jumort.svg" alt="Twitter Logo">
<img src="https://res.cloudinary.com/dnrojsaks/image/upload/v1587129314/Icons/twit_t57gos.svg" alt="Gitlab Logo">
</div>
</section>
<section id="work" style="display: none;">
<div class="container">
<a href="https://lucycull.design" target="_blank" rel="noopener"><div class="card">
<img id="work-img" src="https://res.cloudinary.com/dnrojsaks/image/upload/v1587134668/Portfolio/lucy_ijnjoq.jpg" />
<h2>Lucy Cull</p>
</div></a>
</div>
</section>
<section id="blog" style="display: none;">
<div class="container">
<a href="https://medium.com/#machooper_69036/make-vscode-yours-e362dab48ff6" target="_blank" rel="noopener"><div class="card">
<img src="https://miro.medium.com/max/600/0*ZdpEvxpU6_SFxDzT.gif" />
<h2>Make VSCode Yours</p>
</div></a>
<a href="https://medium.com/#machooper_69036/my-setup-the-desk-5f4ed6824192" target="_blank" rel="noopener"><div class="card">
<img src="https://miro.medium.com/max/700/1*PFXyIbHjkQE-tGzlj6xMEA#2x.jpeg" />
<h2>My Desk</p>
</div></a>
<div class="card">
<img src="https://miro.medium.com/max/1400/1*qXN9PuwTmiHueFoeskJZnw.jpeg" />
<h2>My Tech Stack</p>
</a></div>
<div class="card">
<img src="https://miro.medium.com/max/700/1*PFXyIbHjkQE-tGzlj6xMEA#2x.jpeg" />
<h2>My Computer</p>
</div></a>
</div>
</section>
<section id="video" style="display:none;">
<video autoplay loop muted src="https://res.cloudinary.com/dnrojsaks/video/upload/v1587133353/Video/assets_img_header_bxtgiz.mp4"></video>
</section>
</main>
js
<script>
function video() {
var main = document.getElementById("main");
var video = document.getElementById("video");
var contact = document.getElementById("contact");
var work = document.getElementById("work");
var blog = document.getElementById("blog");
if (
video.style.display === "none") {
main.style.display = "none";
video.style.display = "block";
contact.style.display = "none";
work.style.display = "none";
blog.style.display = "none";
} else {
video.style.display = "none";
}
}
function contact() {
var main = document.getElementById("main");
var video = document.getElementById("video");
var contact = document.getElementById("contact");
var work = document.getElementById("work");
var blog = document.getElementById("blog");
if (
contact.style.display === "none") {
main.style.display = "none";
video.style.display = "none";
contact.style.display = "block";
work.style.display = "none";
blog.style.display = "none";
} else {
contact.style.display = "none";
}
}
function work() {
var main = document.getElementById("main");
var video = document.getElementById("video");
var contact = document.getElementById("contact");
var work = document.getElementById("work");
var blog = document.getElementById("blog");
if (
work.style.display === "none") {
main.style.display = "none";
video.style.display = "none";
contact.style.display = "none";
work.style.display = "block";
blog.style.display = "none";
} else {
work.style.display = "none";
}
}
function blog() {
var main = document.getElementById("main");
var video = document.getElementById("video");
var contact = document.getElementById("contact");
var work = document.getElementById("work");
var blog = document.getElementById("blog");
if (
blog.style.display === "none") {
main.style.display = "none";
video.style.display = "none";
contact.style.display = "none";
work.style.display = "none";
blog.style.display = "block";
} else {
blog.style.display = "none";
}
}

Just write a generic function that takes the section-name as parameter and then compute your style.display.

In such cases, I would always make use of combining classes and Id. Yes I know maybe someone has a better approach but this for me always is easier.
NB: I just wrote this here I didn't test it if it has bugs comment I will check it but it should work 100%.
Your style
<style>
.item
{
display: none;
}
</style
Your HTML
<nav>
<a class="link-item" id="contact">Contact</a>
<a class="link-item" id="work">Work</a>
<a class="link-item" id="blog">Blog</a>
</nav>
<span class="contact item">Put your video here</span>
<span class="work item">Your work content here</span>
<span class="blog item">Your blog content here</span>
Jquery
$(function()
{
$(".link-item").click(function(e)
{
var targetClassName = $(this).attr('id') //get the id of the clicked item so that you can
//display it later
$(".item").hide(function(e) //hide all item
{
$("."+targetClassName).show() //on callback display the item which was clicked using its classname
}
}
}
Disclaimer: I have done it with JQuery, you can convert this Jquery to Javascript. Your question was on Javascript so you might want JQuery or just do it with you Javascript but it should give you same results
I prefer JQuery(Javascript library) it's smaller and thus easily debugable. But if you want JS comment I can do it with Javascript

Related

I want to change 2 images at once

I have images in imageBox1 and imageBox2 and when I click button, is there any way that I can change images in both boxes at the same time? with JS?
For instance, I when I click "hello", I want to make image1-1 and image2-1 display together, and when I click "world", they image1-2 and image2-2 should display together.
<div class = "Button">
<button type="button">hello</button>
<button type="button">world</button>
</div>
<div class = "imageBox1">
<img src="image1-1.jpg">
<img src="image1-2.jpg">
</div>
<div class = "imageBox2>
<img src="image2-1.jpg">
<img src="image2-2.jpg">
</div>
You can add an event listener to each button that gets the index of the button relative to the other buttons, loops through each child in each div and shows the img whose index is the same as the button's.
const divs = document.querySelectorAll('.image');
const buttons = document.querySelectorAll('button')
buttons.forEach((e, i) => e.addEventListener('click', function() {
divs.forEach((f) => [...f.children].forEach((g, i1) => g.style.display = i == i1 ? "block" : "none"))
}))
img {
display: none;
}
<div class="Button">
<button type="button">hello</button>
<button type="button">world</button>
</div>
<div class="imageBox1 image">
<img src="https://www.gravatar.com/avatar/0fdacb141bca7fa57c392b5f03872176?s=48&d=identicon&r=PG&f=1">
<!-- image1-1.jpg -->
<img src="https://www.gravatar.com/avatar/0fdacb141bca7fa57c392b5f03872176?s=96">
<!-- image1-2.jpg -->
</div>
<div class="imageBox2 image">
<img src="https://www.gravatar.com/avatar/0fdacb141bca7fa57c392b5f03872176?s=96">
<!-- image2-1.jpg -->
<img src="https://www.gravatar.com/avatar/0fdacb141bca7fa57c392b5f03872176?s=48&d=identicon&r=PG&f=1">
<!-- image2-2.jpg -->
</div>
It sounds like what you're asking for is a way to show or hide specific images depending on which button the user clicks. If so, you can definitely do this with JavaScript.
Here's a beginner-friendly example using your HTML.
// set up some variables to make the code easier to read
const helloBtn = document.getElementById("hello-button")
const worldBtn = document.getElementById("world-button")
const img1 = document.getElementById("image1")
const img2 = document.getElementById("image2")
const img3 = document.getElementById("image3")
const img4 = document.getElementById("image4")
// When the user clicks the "hello" button, run a function named handleHelloClick
helloBtn.addEventListener("click", handleHelloClick);
// When the user clicks the "world" button, run a function named handleWorldClick
worldBtn.addEventListener("click", handleWorldClick);
// this function handles the "hello" click
function handleHelloClick() {
img1.style.display = "none";
img2.style.display = "block";
img3.style.display = "block";
img4.style.display = "none";
}
// this function handles the "world" click
function handleWorldClick() {
img1.style.display = "block";
img2.style.display = "none";
img3.style.display = "none";
img4.style.display = "block";
}
<div class="buttons">
<button id="hello-button" type="button">hello</button>
<button id="world-button" type="button">world</button>
</div>
<div class="imageBox1">
<img id="image1" src="https://randomuser.me/api/portraits/women/75.jpg">
<img id="image2" src="https://randomuser.me/api/portraits/men/76.jpg">
</div>
<div class="imageBox2">
<img id="image3" src="https://randomuser.me/api/portraits/women/78.jpg">
<img id="image4" src="https://randomuser.me/api/portraits/men/80.jpg">
</div>
first hide them with css
then show them when clicking by js
const hello = document.getElementById("hello")
const world = document.getElementById("world")
hello.onclick= () => {
document.querySelectorAll(".first").forEach(el=> el.style.display = "block")
}
world.onclick= () => {
document.querySelectorAll(".second").forEach(el=> el.style.display = "block")
}
.first, .second {
display : none
}
<div class = "Button">
<button id="hello" type="button">hello</button>
<button id="world" type="button">world</button>
</div>
<div class = "imageBox1">
<img class="first" src="https://dummyimage.com/200x100/000/fff&text=first">
<img class="second" src="https://dummyimage.com/200x100/000/fff&text=second">
</div>
<div class = "imageBox2">
<img class="first" src="https://dummyimage.com/200x100/000/fff&text=first">
<img class="second" src="https://dummyimage.com/200x100/000/fff&text=second">
</div>

On click show / hide content

I have a problem with javascript show/hide content from div. When I click on the first button I got content from that but when I click on the second I need to hide content from first and show content from second div. My code for this is:
<script type="text/javascript">
function showHideDiv(ele) {
var srcElement = document.getElementById(ele);
if (srcElement != null) {
if (srcElement.style.display == "block") {
srcElement.style.display = 'none';
}
else {
srcElement.style.display = 'block';
}
return false;
}
}
function showHideDiv1(ele) {
var srcElement = document.getElementById(ele);
if (srcElement != null) {
if (srcElement.style.display == "block") {
srcElement.style.display = 'none';
}
else {
srcElement.style.display = 'block';
}
return false;
}
}
</script>
HTML:
<div class="listsearch-header fl-wrap">
<h3>
<a class="button-one" onClick="showHideDiv('divMsg')" title="Relevant Title" href="#">Places</a>
<a class="button-two" onClick="showHideDiv1('divMsg1')" title="Relevant Title" href="#">Events</a>
</h3>
<div id="divMsg" style=" display:none">
<b>Places</b>
</div>
<div id="divMsg1" style="display:none">
<b>Events</b>
</div>
</div>
How to solve this when clicking on second button to hide content from the first button. Thanks, all
You could do with toggle the class based on clicked element
function showHideDiv(ele) {
var srcElement = document.getElementById(ele);
document.querySelectorAll('.box').forEach(a => a.classList.add('hide'))
if (srcElement != null) {
srcElement.classList.toggle('hide')
}
}
.hide {
display: none;
}
<div class="listsearch-header fl-wrap">
<h3>
<a class="button-one" onClick="showHideDiv('divMsg')" title="Relevant Title" href="#">Places</a>
<a class="button-two" onClick="showHideDiv('divMsg1')" title="Relevant Title" href="#">Events</a>
</h3>
<div id="divMsg" class="box hide">
<b>Places</b>
</div>
<div id="divMsg1" class="box hide">
<b>Events</b>
</div>
</div>
You could use a generic function which takes the actual elements to be shown or hidden as input parameters.
function showHideDiv(show, hide) {
document.getElementById(show).style.display = "block";
document.getElementById(hide).style.display = "none";
}
<div class="listsearch-header fl-wrap">
<h3>
<a class="button-one" onClick="showHideDiv('divMsg','divMsg1')" title="Relevant Title" href="#">Places</a>
<a class="button-two" onClick="showHideDiv('divMsg1','divMsg')" title="Relevant Title" href="#">Events</a>
</h3>
<div id="divMsg" style=" display:none">
<b>Places</b>
</div>
<div id="divMsg1" style="display:none">
<b>Events</b>
</div>
</div>

Improve this "next","previous" script, so that it could go up to atleast 3

I am trying to create a column containing items, within this column you can go to "next" or "prev" page.
This works fine and quick!
Now here my question is
How do I create up to page 8 or even more, so that you could scroll through the pages?.
I am trying something with this, but I somehow cant implement it into html
function next() {
var nextUrl = "Page + (index+1)";
}
function back() {
var prevUrl = "Page + (index-1)";
}
Here is my current setup
function show(elementID) {
var ele = document.getElementById(elementID);
if (!ele) {
alert("dit bestaat niet");
return;
}
var pages = document.getElementsByClassName('page');
for(var i = 0; i < pages.length; i++) {
pages[i].style.display = 'none';
}
ele.style.display = 'block';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="Page1" class="page" style="">
page 1
</div>
<div id="Page2" class="page" style="display:none">
page 2
</div>
<div class="column-wrapper">
<div class="pagination paginatioon--full">
<p>
<span onclick="show('Page1');">
prev
</span>
<span onclick="show('Page2');">
next </span>
</p>
</div>
</div>
You can do something like this :
var currentPageId = 1;
var totalpages = $('.page').length;
$('.prev').click(function(e) {
if (currentPageId > 1) {
currentPageId--;
show('Page' + currentPageId);
}
});
$('.next').click(function(e) {
if (currentPageId < totalpages) {
currentPageId++;
show('Page' + currentPageId);
}
});
function show(elementID) {
var ele = document.getElementById(elementID);
if (!ele) {
alert("dit bestaat niet");
return;
}
var pages = document.getElementsByClassName('page');
for (var i = 0; i < pages.length; i++) {
pages[i].style.display = 'none';
}
ele.style.display = 'block';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="Page1" class="page" style="">
page 1
</div>
<div id="Page2" class="page" style="display:none">
page 2
</div>
<div id="Page3" class="page" style="display:none">
page 3
</div>
<div class="column-wrapper">
<div class="pagination paginatioon--full">
<p>
<span class='prev'>
prev
</span>
<span class='next'>
next </span>
</p>
</div>
</div>

js slideshow classname property of null

I am making a slideshow for a website i am making.
but my slideshow keeps getting error
Cannot set property 'className' of null
here is my code:
window.onload=function(){
var slideshow = document.getElementsByClassName('slideshow').item(0),
train = slideshow.getElementsByClassName('train').item(0),
lists = document.getElementsByClassName('btns').item(0).getElementsByClassName('btn'),
currentSlide = 0;
(go2slide = function (n) {
if(n>lists.length-1) n=0;
if(n<0) n=lists.length-1;
train.style.left=(-310*n)+'px';
lists.item(currentSlide).className = '';
lists.item(n).className = 'active';
currentSlide=n;
})(0); // set active of first li
nextSlide = function(){
go2slide(currentSlide+1);
}
prvSlide = function(){
go2slide(currentSlide-1);
}
var autoPlayIv = false;
(autoPlayStart = slideshow.onmouseout = function(){
if(autoPlayIv) return;
autoPlayIv = setInterval(nextSlide, 2000);
})(); // run auto play
autoPlayStop = slideshow.onmouseover = function(){
clearInterval(autoPlayIv);
autoPlayIv = false;
}
slideshow.getElementsByClassName('next').item(0).onclick=nextSlide;
slideshow.getElementsByClassName('previous').item(0).onclick=prvSlide;
for (var i=0; i<lists.length; i++) {
(function(j){
lists.item(j).onclick=function(){
go2slide(j);
}
})(i);
}
}
i DO have a li tag classes as btn and a btns ul.
its item(0).
and here is the html related to it
<div class="body">
<div class="slide">
<div class="s1">
<div class="slideshow">
<div class="train">
<script type="text/javascript">
var slidesLen = 3;
for(var i=1;i<=slidesLen;i++){
document.write("<div style=\"background-image:url('../images/pic"+i+".jpg');\"></div>");
}
</script>
</div>
<div class="previous"></div>
<div class="next"></div></div>
<ul class="btns">
<i class="btn"></i>
<i class="btn"></i>
<i class="btn"></i>
</ul>
</div>
<div class="s2"></div>
<div class="s3"></div>
<div class="s4"></div>
<div class="s5">
<div class="I"></div>
<div class="II"></div>
<div class="III"></div>
</div>
</div>
<div class="text"></div>
</div>
and of course its only the body.php i am posting here. I don't think header.php which contains the menu and the css and js association tags are needed. tell me if it is

How did a doctype break my JavaScript?

I made a menu, and just now I added
<!DOCTYPE html>
to the document, and it ceases to function. However the code is still running, will still print to console on mouseover etc. I tried other doctypes and they break it too, it just stays static.
What is it about a doctype that could cause JavaScript to not work?
JS:
var total_width = "960";
var slide_width = "182";
var slide_margin = "10";
var expand_width = "374";
var icon_width = "32";
var icon_margin = "15";
var slide_number = "5";
function slideid(i) {
var m = document.getElementById("slide"+i);
var l = document.getElementById("slideimg"+i);
var k = document.getElementById("slidetext"+i);
var j = document.getElementById("slidediv"+i);
return [m, l, k, j]
}
function compat() {
if (window.opera) {
for (var i=1;i<6;i++) {
s = slideid(i);
s[3].style.position="relative";
s[3].style.bottom="46px";
}
}
if (document.all && !(window.opera)) {
for (var i=1;i<6;i++) {
s = slideid(i);
s[0].style.height="60px";
s[1].style.display="none";
var iecontents = s[2].innerHTML;
s[0].innerHTML=iecontents;
s[0].style.fontFamily="'astonishedregular',Impact,serif";
s[0].style.fontSize="40px";
s[0].style.color="#fff";
s[0].style.textDecoration="none";
s[0].style.padding="10px auto";
}
}
}
function expand(x) {
if (document.all && !(window.opera)) {
return
}
var shrink = new Array();
for (var i=1;i<6;i++) {
if (i === x) {
var expander = i;
}
else {
var d = shrink.length;
shrink[d] = i;
}
}
for (var i=0;i<4;i++) {
s = slideid(shrink[i]);
var slide_shrink = ((total_width-(5*slide_margin))-expand_width)/(slide_number-1);
s[1].style.marginLeft=(slide_shrink-icon_width)/2;
s[0].style.width=slide_shrink;
s[2].style.display="none";
s[3].style.width="0"
}
s = slideid(expander);
s[1].style.marginLeft=icon_margin;
s[0].style.width=expand_width;
s[2].style.display="inline-block";
s[3].style.width=expand_width-icon_width-icon_margin-7;
}
function shrink() {
if (document.all && !(window.opera)) {
return
}
for (var i=1;i<6;i++) {
s = slideid(i);
s[1].style.marginLeft=(slide_width-icon_width)/2;
s[0].style.width=slide_width;
s[2].style.display="none";
s[3].style.width="0";
}
}
And HTML:
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="style.css" />
<script src="menu.js"></script>
</head>
<body onload="compat()">
<div id="Menu" onMouseout="shrink()">
<a href="#" class="slide" id="slide1" onMouseOver="expand(1)">
<img id="slideimg1" src="home.png" />
<div id="slidediv1">
<h2 id="slidetext1">Home</h2>
</div>
</a>
<a href="#" class="slide" id="slide2" onMouseOver="expand(2)">
<img id="slideimg2" src="sound.png" />
<div id="slidediv2">
<h2 id="slidetext2">Music</h2>
</div>
</a>
<a href="#" class="slide" id="slide3" onMouseOver="expand(3)">
<img id="slideimg3" src="blog.png" />
<div id="slidediv3">
<h2 id="slidetext3">Blog</h2>
</div>
</a>
<a href="#" class="slide" id="slide4" onMouseOver="expand(4)">
<img id="slideimg4" src="note.png" />
<div id="slidediv4">
<h2 id="slidetext4">Bio</h2>
</div>
</a>
<a href="#" class="slide" id="slide5" onMouseOver="expand(5)">
<img id="slideimg5" src="way.png" />
<div id="slidediv5">
<h2 id="slidetext5">Links</h2>
</div>
</a>
</div>
</body>
You need to add "px" to marginLeft and width. Setting CSS style which requires units will not work without unit. And you are missing <html></html> tags.
function expand(x) {
if (document.all && !(window.opera)) {
return
}
var shrink = new Array();
for (var i=1;i<6;i++){
if (i === x) {
var expander = i;
}
else {
var d = shrink.length;
shrink[d] = i;
}
}
for (var i=0;i<4;i++){
s = slideid(shrink[i]);
var slide_shrink = ((total_width-(5*slide_margin)) - expand_width) / (slide_number-1);
s[1].style.marginLeft=(slide_shrink-icon_width)/2 +"px";
s[0].style.width=slide_shrink +"px";
s[2].style.display="none";
s[3].style.width="0"
}
s = slideid(expander);
s[1].style.marginLeft=icon_margin +"px";
s[0].style.width=expand_width + "px";
s[2].style.display="inline-block";
s[3].style.width= (expand_width-icon_width-icon_margin-7) +"px";
}
function shrink() {
if (document.all && !(window.opera)) {
return
}
for (var i=1;i<6;i++){
s = slideid(i);
s[1].style.marginLeft=(slide_width-icon_width)/2 +"px";
s[0].style.width=slide_width + "px";
s[2].style.display="none";
s[3].style.width="0";
}
}
document.all is a Microsoft thing, not covered by a standard (more in this other Q/A). Remove all use of it and use document.getElementById as necessary instead.
My guess is that if you look in the JavaScript console, you'll see errors related to document.all not existing, because while whatever browser you're testing on supported it in quirks mode, when you switched it to standards mode (by adding a doctype), it stopped supporting it.
Adding the HTML5 DOCTYPE (<!DOCTYPE html>) puts browsers into "Standards mode". Without it, the browser will be in "Quirks mode", which is essentially an IE5/legacy compatibility mode. MDN has more information on the subject, and a list of differences in behaviour in Firefox.
The biggest problem with your script is the use of document.all, which is a non-standard Microsoft thing. You'll want to use standard DOM stuff like document.getElementById.
include your count script before closing body tag and dont forget to add closing tag of html
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="style.css" />
<script src="menu.js"></script>
</head>
<body onload="compat()">
<div id="Menu" onMouseout="shrink()">
<a href="#" class="slide" id="slide1" onMouseOver="expand(1)">
<img id="slideimg1" src="home.png" />
<div id="slidediv1">
<h2 id="slidetext1">Home</h2>
</div>
</a>
<a href="#" class="slide" id="slide2" onMouseOver="expand(2)">
<img id="slideimg2" src="sound.png" />
<div id="slidediv2">
<h2 id="slidetext2">Music</h2>
</div>
</a>
<a href="#" class="slide" id="slide3" onMouseOver="expand(3)">
<img id="slideimg3" src="blog.png" />
<div id="slidediv3">
<h2 id="slidetext3">Blog</h2>
</div>
</a>
<a href="#" class="slide" id="slide4" onMouseOver="expand(4)">
<img id="slideimg4" src="note.png" />
<div id="slidediv4">
<h2 id="slidetext4">Bio</h2>
</div>
</a>
<a href="#" class="slide" id="slide5" onMouseOver="expand(5)">
<img id="slideimg5" src="way.png" />
<div id="slidediv5">
<h2 id="slidetext5">Links</h2>
</div>
</a>
</div>
</body>
</html>

Categories

Resources