I'm currently building a React project, I'm introducing a js code which is needed to display a popup properly. The code from the beginning is for clearing the URL from (#nameOfThePopup) and is introducing 2 functions : Close() and Open().
It runs just great in a normal HTML page, but when i want to fill it in my React project, it does some compilation problems, specificly 2 lines:
history.replaceState(null, null, ' ');
event.stopPropagation();
I did try to make it in ComponentDidmount() method and introduce it in public index.html as a script but still the same compilation errors.
There is my full code:
import React from 'react';
class Popup extends React.Component {
/*Clear URL from #popup1 in the end*/
history.replaceState(null, null, ' '); /*<=== error compile*/
/*declar variables and clear the popup from the DOM*/
let id_popup = document.querySelector('#popup1');
let popup = id_popup.parentNode;
popup.removeChild(id_popup);
/*Opening the popup */
Open() {
popup.appendChild(id_popup);
event.stopPropagation(); /*<=== error compile*/
let class_popup = document.querySelector('.popup');
window.addEventListener('click', function (e) {
if (!class_popup.contains(e.target)) {
Close();
}
});
}
/*Closing the popup */
Close() {
popup.removeChild(id_popup);
history.replaceState(null, null, ' ');
}
render() {
return (
<div>
<input type="submit" onClick={this.Open} />
<title>test popup</title>
<div id="popup1" className="overlay">
<div className="popup">
<h2>Title</h2>
<a className="close" onClick={this.Close} href="javascript://">
×
</a>
<div className="content">
my popup content
</div>
</div>
</div>
</div>
)
}
}
export default Popup;
Css :
.overlay {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
transition: opacity 500ms;
visibility: hidden;
opacity: 0;
}
.overlay:target {
visibility: visible;
opacity: 1;
}
.popup {
margin: 70px auto;
padding: 20px;
background: #fff;
border-radius: 5px;
width: 60%;
position: relative;
transition: all 5s ease-in-out;
}
.popup h2 {
margin-top: 0;
color: #333;
font-family: Tahoma, Arial, sans-serif;
}
.popup .close {
position: absolute;
top: 20px;
right: 30px;
transition: all 200ms;
font-size: 30px;
font-weight: bold;
text-decoration: none;
color: #333;
}
.popup .close:hover {
color: #06D85F;
}
.popup .content {
height: 60%;
overflow: auto;
}
#media screen and (max-width: 700px) {
.box {
width: 70%;
}
.popup {
width: 70%;
}
}
</style>
Thank you.
It seems like your component is rendered on the server, if it is the case, history.replaceState(null, null, ' '); won't compile because history is a member of window which does not exist on the server. So you will need to check if your code is running on the server or the client, there are different ways to do this depending on the SSR framework you are using, for instance nextjs provides process.browser which is true if on the client or undefined in node:
if(process.browser) window.history.replaceState(null, null, ' ');
Then for your event.stopPropagation part, event is not defined anywhere in the code you provided, so there must be a problem in your implementation (maybe add it to the function parameter.)
Related
I have a custom web component that I am trying to make which looks like this
But it looks like this after I reload the page
Notice the thin white div at the very bottom of each image.
I notice that I get the desired result (the fist image) immediately following a Webpack build triggered by saving this component's javascript file. Each time I reload the page, the second image is rendered on screen. What causes this behavior? I will attach the pertinent parts of my code below. (The styling for the large yellow and white components is done for privacy)
FeaturedProjectCard.js
const template = document.createElement('template')
template.innerHTML = `
<style>
.bottomDivider {
position: absolute;
bottom: 0;
width: 75%;
height: 1px;
margin: 0;
background-color: white;
}
.container {
position: relative;
width: 1000px;
isolation: isolate;
}
.description {
border-radius: 10px;
padding: 25px;
color: white;
background-color: white;
}
.linksContainer {
display: flex;
}
.linksContainer > a {
width: 20px;
padding: 10px;
color: white;
transition: color 0.5s;
}
.linksContainer > a:first-child {
padding-left: 0;
}
.linksContainer > a:hover {
color: yellow;
}
.projDesc {
width: 50%;
display: flex;
flex-direction: column;
pointer-events: none;
}
.projDesc > * {
width: fit-content;
pointer-events: auto;
}
.projImage {
position: absolute;
top: 50%;
right: 0;
height: 300px;
transform: translateY(-50%);
background-color: yellow;
border-radius: 5px;
z-index: -1;
}
.projImage > img {
height: inherit;
border-radius: inherit;
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
opacity: 0;
transition: opacity 0.5s, filter 0.5s, -webkit-filter 0.5s;
}
.projImage > img:hover {
opacity: 1;
filter: grayscale(0%);
-webkit-filter: grayscale(0%);
}
.projectHeading {
margin: 10px 0;
color: yellow;
font-size: 12pt;
}
.projectName {
display: inline;
margin: 15px 0;
font-size: 21pt;
color: white;
}
.softwareContainer {
margin: 25px 0 10px 0;
color: white;
}
.softwareContainer > span:not(:last-child) {
padding-right: 30px;
}
</style>
<div class="container">
<div class="projDesc">
<span class="projectHeading">Recent Project</span>
<span class="projectName"></span>
<div class="description"></div>
<div class="softwareContainer"></div>
<div class="linksContainer"></div>
</div>
<div class="projImage">
<img>
</div>
<p class="bottomDivider"></p>
</div>
`
class FeaturedProjectCard extends HTMLElement {
constructor() {
super()
//Enable shadow DOM
this.attachShadow({ mode: 'open' })
this.shadowRoot.appendChild(template.content.cloneNode(true))
//Insert project image
this.shadowRoot.querySelector('img').src = this.getAttribute('image')
//Insert project heading
this.shadowRoot.querySelector('.projectName').textContent = this.getAttribute('heading')
//Insert project description
this.shadowRoot.querySelector('.description').innerHTML = //Get description text
//Insert software array
const softwareItems = //Get items
if(softwareItems) {
const softwareContainer = this.shadowRoot.querySelector('.softwareContainer')
for(let i = 0; i < softwareItems.length; i++)
softwareContainer.innerHTML += `<span>${softwareItems[i].textContent}</span>`
}
//Insert link array
const links = //Get links
if(links) {
const linksContainer = this.shadowRoot.querySelector('.linksContainer')
for(let i = 0; i < links.length; i++) {
linksContainer.innerHTML += `<a target="_blank" href="${links[i].getAttribute('target')}">${links[i].innerHTML}</a>`
}
}
//Handle reverse attribute
if(this.hasAttribute('reversed')) {
this.shadowRoot.querySelector('.bottomDivider').style.right = 0;
this.shadowRoot.lastElementChild.style.height = `${this.shadowRoot.lastElementChild.offsetHeight}px`
const projDesc = this.shadowRoot.querySelector('.projDesc')
const projImage = this.shadowRoot.querySelector('.projImage')
const softwareItems = Array.from(this.shadowRoot.querySelectorAll('.softwareContainer > span'))
projDesc.style.position = 'absolute'
projDesc.style.right = '0'
projDesc.style.left = 'auto'
projImage.style.left = '0'
projImage.style.right = 'auto'
projDesc.style.alignItems = 'flex-end'
softwareItems.splice(0, 1)[0].style.padding = '0'
const padding = getComputedStyle(softwareItems[0]).getPropertyValue('padding-right')
softwareItems.forEach(item => {
item.style.paddingLeft = padding
item.style.paddingRight = '0'
})
}
//Clear markup
this.innerHTML = null
}
}
window.customElements.define('featured-project-card', FeaturedProjectCard)
I use these component in HTML with the following syntax.
<featured-project-card class="" reversed image="/something.png" heading="Heading">
I think that the root cause of this behavior is the inclusion of the optional 'reversed' attribute. The other components that don't use this attribute are not affected by this issue since div.projDesc has position: static for those instances. This allows the div.container to resize. These images show the only component where this attribute is used. I will end this post with one final image of a component without the 'reversed' attribute for reference. In essence, I achieve the reverse effect by setting the div.projDesc properties position, right, and left to absolute, 0, and auto respectively. Consequently, I had to set the div.container height equal to what it was prior to these changes. Otherwise the element would not size correcly since position: absolute is being used on the only child with position: static
I used a ResizeObserver to see if the div.projDesc was resizing itself more than once and indeed it was. To wrap up, the 'reversed' div.projDesc is resizing itself strangely (likely because of how the 'reverse' attribute is handled) as opposed to non 'reversed' elements. I am aware that there may be an easier way to solve this problem and I am open to suggestions, however, I would like to pin down the source of this behavior in hopes of gaining a better understanding of the nuances of HTML, CSS, & JS. I am more than happy to clarify myself for anyone that is willing to lend a hand. Thank you in advance!
Non reversed component
I have some code working to make 2 div tags visible only when another div is clicked (an attempt to make a custom title bar)The 2 divs are invisible initially.
const {remote} = require('electron');
var win = remote.getCurrentWindow();
win.setSize(810,610);
function max(){
var win = remote.getCurrentWindow();
if(win.isMaximized()){
win.unmaximize();
document.getElementById('file').style.right = "744px";
document.getElementById('about_us').style.right = "664px";
}else{
win.maximize();
document.getElementById('file').style.right = "1314px";
document.getElementById('about_us').style.right = "1234px";
}
}
hidden = true;
function get(el){
return document.getElementById(el);
}
function open_file_menu(){
var fileMenu = [get('file_menu'),get('file_menu2')];
if (hidden == false){
for (i = 0;i<fileMenu.length;i++){
fileMenu[i].style.visibility = 'hidden';
hidden = true;
}
}
else{
for (i = 0;i<fileMenu.length;i++){
fileMenu[i].style.visibility = 'visible';
hidden = false;
}
}
}
body,html{
width: 47.5pc;
height: 100pc;
overflow: hidden;
-webkit-app-region:drag;
z-index: 0;
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: monospace;
z-index: 1;
}
#container{
width: 100pc;
height: 100pc;
display: block;
position: absolute;
right: 40px;
top: 0;
}
#container nav{
display: grid;
width: 100pc;
height: 2.2pc;
background-color: #333333;
z-index: 1;
}
span{
position: absolute;
top:0;
transform: translateX(100px);
color:#dacbcb;
font-size: 1.5em;
font-weight:bold;
background-color: #222222;
padding-left: 25px;
padding-right: 25px;
padding-top: 7px;
padding-bottom: 6px;
transition: ease-in-out 1ms;
-webkit-app-region:no-drag;
}
#buttons{
position: absolute;
right: 120px;
}
#maximize{
transform: translateX(-124px);
}
#maximize span:hover,#minimize:hover span,.menu1:hover,.menu2:hover{
background-color: #333333;
}
#file{
position: absolute;
right:743px;
}
#about_us{
position: absolute;
right:663px;
#run{
transform: translateY(100px);
}
.menu1{
font-size: 1.1em;
padding-left: 25px;
padding-right: 25px;
padding-top: 10px;
padding-bottom: 8px;
}
.menu2{
font-size: 1.1em;
padding-left: 25px;
padding-right: 25px;
padding-top: 10px;
padding-bottom: 8px;
}
#file_menu{
visibility: hidden;
background-color: #222222;
transform: translateY(34px);
font-size: 1.1em;
}
#file_menu2{
visibility: hidden;
background-color: #222222;
transform: translateY(63px);
font-size: 1.1em;
padding-left: 25px;
padding-right: 17px;
padding-top: 7px;
padding-bottom: 6px;
}
.fm{
z-index: 2;
}
#file_menu:hover,#file_menu2:hover{
background-color: #333333;
}
<!DOCTYPE html>
<html>
<head>
<script src="init.js"></script>
<script src="text_editor.js"></script>
<meta charset="UTF-8">
<title>Extorc App</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div onclick="uff()">
<span id = "file_menu" class = "fm">new</span>
</div>
<div>
<span id = "file_menu2" class = "fm">open</span>
</div>
<div id="container">
<nav>
<div id="buttons">
<div id="file" onclick="open_file_menu()">
<span class = "menu1">file</span>
</div>
<div id="about_us">
<span class = "menu2">about..us</span>
</div>
<div id="maximize" onclick="max()">
<span>+</span>
</div>
</div>
</nav>
</div>
</body>
</html>
The code works ... the menu opens up with 2 divs displaying but the divs are un clickable or probably totally passive (i have set a :hover background color in my css)Though , this problem ends if i open the 2 divs and then maximize the window..then they become interactable and then after minimizing also they work which means the divs are un-interactable initially but then after one maximize , they work...any fix for that....should i not use visibility here?
Edit Not only by fullscreen but also if i resize the window , the buttons start working , and starting the window as fullscreen : true, doesnt make it work
You cannot put all the body as draggable: -webkit-app-region:drag; on body,html
You will have to define a specific area where it defined as draggable.
My recommendation define a specific area / SVG that means drag and don't put clickables on it.
E.g take a look at known electron products (VSCODE, Slack) you have specific regions from which you can drag from.
Hope I have helped.
So I have a pop up that originally showed on every webpage. After some modification to include the use of cookies to stop the webpage loading every single session, the pop up no longer shows. I can't figure out why and after extensive testing, research and just straight up asking for help I've concluded I do not have enough of an understanding on the subject.
If anyone is able to help me understand why its not working and help with a solution.
<div id='popup' style="display:none">
<div class='cnt223'>
<h1>Important Notice</h1>
<p>
Test!
<br />
<br />
OK
KO
</p>
</div>
</div>
<script>
function setCookie(cname, cvalue) {
window.document.cookie = cname + "=" + cvalue;
}
function getCookie(cname) {
var ca = decodeURIComponent(document.cookie).split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim().split('=');
if (cname == c[0] && c.length > 1) {
return c[1];
}
}
return "";
}
function checkCookie() {
if (getCookie("ageverification") == "") {
$('#popup').show();
$('#popup a.close').click(function ( event ) {
event.preventDefault();
$('#popup').hide();
setCookie("ageverification", 'true');
});
$('#popup a.goBack').click(function ( event ) {
event.preventDefault();
goBack();
});
} else {
return null;
}
}
function goBack() {
window.history.go(-2);
}
checkCookie();
CSS "This is just on the same HTML page for now"
<style type="text/css">
#overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
filter:alpha(opacity=70);
-moz-opacity:0.7;
-khtml-opacity: 0.7;
opacity: 0.7;
z-index: 100;
display: none;
}
.cnt223 a{
text-decoration: none;
}
.popup{
width: 100%;
margin: 0 auto;
display: none;
position: fixed;
z-index: 101;
}
.cnt223{
min-width: 600px;
width: 600px;
min-height: 150px;
margin: 100px auto;
background: #f3f3f3;
position: relative;
z-index: 103;
padding: 15px 35px;
border-radius: 5px;
box-shadow: 0 2px 5px #000;
}
.cnt223 p{
clear: both;
color: #555555;
/* text-align: justify; */
font-size: 20px;
font-family: sans-serif;
}
.cnt223 p a{
color: #d91900;
font-weight: bold;
}
.cnt223 .x{
float: right;
height: 35px;
left: 22px;
position: relative;
top: -25px;
width: 34px;
}
.cnt223 .x:hover{
cursor: pointer;
}
</style>
Is the element with id "popup" nested within (a child of) the element with id "overlay" ? If it is, the element with id "overlay" has got display:none; , meaning the popup might be displaying, but it's parent is not. Try replacing:
$('#popup').show();
with:
$('#popup, #overlay').show();
Another problem could be that the Javascript is executed before the browser added the element with id "popup" to it's DOM. Try replacing:
checkCookie();
with:
$(function () { checkCookie(); });
I am working on my personal website currently. For the frontend I am using Vue.js with vue-router. Until today the transition worked fine, you can see here: https://imanuel.ulbricht.codes/ (you need to scroll down or use the arrow key down). But after some changes that I cannot really find it stopped working.
This is how it "works" now: https://imanuel-not-working.ulbricht.codes/. I really have no idea what I changed, that might affect this change in behavior, maybe someone has an idea.
Side note: The published code has sourcemaps enabled so you should see the complete Vue.js source code.
Another point, the code should animate the page transition, that doesn't happen currently. After 2h searching I couldn't find the root of the problem, if anyone could give me a hint what code might be the cause I will add it to the question.
This is the code, that might cause the issue:
App.vue
<template>
<div class="ulbricht-app" id="app" #wheel="navigateWheel" #keyup.down="navigateNext" #keyup.up="navigatePrevious">
<ribbon v-if="!$route.meta.isHelloWorld"/>
<transition>
<div class="ulbricht-slice__top" :class="{ 'ulbricht-slice__hello-world': $route.meta.isHelloWorld }"></div>
</transition>
<NavIndicator v-if="!$route.meta.isHelloWorld"/>
<transition name="ulbricht-router__fade" mode="out-in">
<router-view/>
</transition>
<transition>
<div class="ulbricht-slice__bottom" v-if="!$route.meta.isHelloWorld"></div>
</transition>
</div>
</template>
<script>
export default {
components: {
NavIndicator,
Ribbon
},
name: 'App',
mounted() {
window.addEventListener('keyup', (event) => {
if (event.key === 'ArrowUp') {
this.navigatePrevious();
} else if (event.key === 'ArrowDown') {
this.navigateNext();
}
});
},
methods: {
navigateWheel($event) {
if ($event.deltaY > 0) {
this.navigateNext();
} else {
this.navigatePrevious();
}
},
navigateNext() {
if (this.$route.meta.next) {
this.$router.push(this.$route.meta.next);
}
},
navigatePrevious() {
if (this.$route.meta.previous) {
this.$router.push(this.$route.meta.previous);
}
}
}
};
</script>
<style lang="scss">
.ulbricht-app {
.ulbricht-slice__top {
background: var(--primary);
position: absolute;
width: 200%;
z-index: 0;
transition: transform 0.4s, height 0.4s;
height: 250px;
transform: skewY(-3deg);
left: 0;
top: -210px;
&.ulbricht-slice__hello-world {
transition: transform 0.4s, height 0.2s;
top: -25px;
height: 120%;
transform: skewY(15deg);
}
}
.ulbricht-router__fade-enter-active {
span,
p,
h1,
img {
transition: opacity 0.3s;
opacity: 1;
}
}
.ulbricht-router__fade-leave-active {
span,
p,
h1,
img {
transition: opacity 0.3s;
opacity: 0;
}
}
}
</style>
And one of the components, they basically all look the same just the content varies.
<template>
<div class="ulbricht-app ulbricht-app__hello">
<img class="ulbricht-hello__background" src="../assets/background.png" alt="">
<div class="ulbricht-hello__content">
<h1 class="ulbricht-hello__header">
Hello World, I am Imanuel
</h1>
<p class="ulbricht-hello__text">
What I do is dead simple, I write software, design websites and landscapes,<br/>
let me show you what I am capable of
</p>
<router-link class="ulbricht-chevron" :to="$route.meta.next">
<span class="ulbricht-chevron__button"></span>
</router-link>
</div>
</div>
</template>
<script>
export default {
name: 'HelloWorld'
};
</script>
And the NavIndicator component, I think after adding this component it stopped working, but I am not sure.
<template>
<div class="ulbricht-sidenav">
<router-link :to="$route.meta.previous || ''" class="ulbricht-sidenav__chevron is--up"
:class="{'is--disabled': !$route.meta.previous}"></router-link>
<router-link :to="nav" class="ulbricht-sidenav__dot" :class="{'is--active': $route.name === nav.name}"
:title="nav.meta.title" v-for="nav in navs"></router-link>
<router-link :to="$route.meta.next || ''" class="ulbricht-sidenav__chevron is--down"
:class="{'is--disabled': !$route.meta.next}"></router-link>
</div>
</template>
<script>
import Routes from "../router/Routes";
export default {
name: "NavIndicator",
computed: {
navs() {
return Routes;
}
}
}
</script>
<style lang="scss">
.ulbricht-sidenav {
position: fixed;
right: 1em;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
z-index: 9999;
}
.ulbricht-sidenav__chevron {
&::before {
border-style: solid;
border-width: 0.25em 0.25em 0 0;
content: '';
display: inline-block;
height: 0.45em;
left: 0.15em;
position: relative;
vertical-align: top;
width: 0.45em;
border-color: var(--primary);
margin-right: 0.3em;
}
&.is--disabled {
&::before {
border-color: var(--primary-grey);
}
}
&.is--up {
&::before {
transform: rotate(-45deg);
top: 0.5em;
}
}
&.is--down {
&::before {
top: 0;
transform: rotate(135deg);
}
}
}
.ulbricht-sidenav__dot {
border-radius: 50%;
width: 1em;
height: 1em;
border: 0.2em solid var(--primary-opaque-0\.5);
margin-top: 0.25em;
margin-bottom: 0.25em;
transition: border 0.3s, background 0.3s;
&.is--active {
background: var(--primary);
}
&:hover {
border: 0.2em solid var(--primary-opaque-0\.7);
background: var(--primary);
}
}
</style>
Removing this component, however, didn't have an effect.
As addition, here is the Github Link, so you can investigate all of the source code if I might have forgotten something, that might be relevant.
https://github.com/DerKnerd/imanuel.ulbricht.codes/tree/98272361549617191bb6d6f5d88ad88c94cbdcfe
There is a <!-- --> comment between
<div class="ulbricht-slice__top ulbricht-slice__hello-world"></div>
and
<div class="ulbricht-app ulbricht-app__hello">
on the copy of your site that is not working. Something is being rendered/removed there.
It may be causing a CSS selector to be applied incorrectly.
I am wanting to display the service-specificBar-tab of serviceBarId1 on page load and hide the other tabs, which is working. However, the part that isn't working like I want is when I click on that tab, I want the rest of the other three tabs to show in the order in which the HTML is and then when I click on the first tab again, for tabs 2, 3 and 4 to close. The method I am using now is acting very buggy. When you click on serviceBarId1 to open the tabs, all of the tabs open, but then one disappears - this didn't happen until I added:
$("#serviceBarId1").click(function() {
$("#serviceBarId2").hide(1000);
$("#serviceBarId3").hide(1000);
$("#serviceBarId4").hide(1000);
});
When I try to close the tabs, nothing happens.
What am I doing wrong?
$("#serviceBarId1").addClass("active");
$("#serviceBarId2").hide();
$("#serviceBarId3").hide();
$("#serviceBarId4").hide();
$("#serviceBarId1").click(function() {
$(".service-specificBar-tab").first().show("fast", function showNext() {
$(this).next(".service-specificBar-tab").show("fast", showNext);
});
});
$("#serviceBarId1").click(function() {
$("#serviceBarId2").hide(1000);
$("#serviceBarId3").hide(1000);
$("#serviceBarId4").hide(1000);
});
#gray {
background: #f9f9f9;
width: 100%;
height: 700px;
position: relative;
}
#service-specificBar-container {
position: relative;
top: 50px;
width: 100%;
padding: 25px 0;
}
#service-specificBar {
width: 100%;
height: 100px;
position: relevant;
}
.service-specificBar-tab {
width: 25%;
height: 100%;
display: inline-block;
margin: 0;
padding: 0px;
text-align: center;
font-size: 1.6em;
}
.service-specificBar-tab:nth-child(odd) {
background: #dbdbdb;
transition: ease-in-out .3s;
cursor: pointer;
}
.service-specificBar-tab:nth-child(even) {
background: #FFF;
transition: ease-in-out .3s;
cursor: pointer;
}
#serviceBarId1:hover,
#serviceBarId2:hover,
#serviceBarId3:hover,
#serviceBarId4:hover {
transition: ease-in-out .3s;
color: #FFF;
}
#serviceBarId2:hover {
background: #0085A1;
}
#serviceBarId3:hover {
background: #a11c00;
}
#serviceBarId4:hover {
background: #00a16d;
}
/*----Test for page swithces ----*/
#serviceBarId1.active {
background: #a10085;
color: #FFF;
}
#serviceBarId2.active {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="gray">
<div id="service-specificBar-container">
<div id="service-specificBar">
<div class="service-specificBar-tab" id="serviceBarId1">A</div>
<div class="service-specificBar-tab" id="serviceBarId2">B</div>
<div class="service-specificBar-tab" id="serviceBarId3">C</div>
<div class="service-specificBar-tab" id="serviceBarId4">D</div>
</div>
</div>
</div>
On the click event you could check the number of visible items. If the length of the visible divs is 1, show the siblings, otherwise, hide them:
$("#serviceBarId1").click(function() {
if ($('#service-specificBar').find(':visible').length == 1) {
$(".service-specificBar-tab").first().show("fast", function showNext() {
$(this).next(".service-specificBar-tab").show("fast", showNext);
});
} else {
$(".service-specificBar-tab").next().hide("fast", function hideNext() {
$(this).next(".service-specificBar-tab").hide("fast", hideNext);
});
}
});
Fiddle Demo