How can i get 2 classes by id inside the same function - javascript

I need to target two div elements and toggle their classes simultanouesly.
I understand that I can get multiple divs "by ID" by using .querySelectorAll
but when I get to .classlist.toggle ("NewClassName"); how can I target two classes??
So here's some code:
#small-div{
background-color:#aaaaaa;
border: 3px solid #aaaaaa;
padding: 0px 0px 0px 0px;
margin: auto 10px auto auto;
border-radius: 10px;
overflow: auto;
}
.tobetoggled{
width: 45%;
float: left;
}
#small-div2{
background-color:#aaaaaa;
border: 3px solid #aaaaaa;
padding: 0px 0px 0px 0px;
margin: auto 10px auto auto;
border-radius: 10px;
overflow: auto;
}
.tobetoggled2{
width: 45%;
float: right;
}
.toggletothis{
width: 100%;
float: left;
position: fixed;
display: block;
z-index: 100;
}
.toggletothis2{
width: 100%;
float: left;
position: fixed;
display: block;
z-index: 100;
}
.whensmalldivistoggled{
display: none;
}/* when small-div is clicked, small-div toggles to class "tobetoggled" while small-div 2 simultaneously toggles to class "whensmalldivistoggled" (the display none class) */
<div id="container">
<div class="tobetoggled" onclick="function()" id="small-div">
</div>
<div class="tobetoggled2" onclick="separatefunction()" id="small-div2">
</div>
</div> <!-- end container -->
<script>
function picClicktwo() {
document.querySelectorAll("small-div, small-div2").classList.toggle("toggletothis, whensmalldivistoggled");
}
</script>
So as you can see one div is on the right, the other is on the left, each set to 45% width. So if I toggle one div to 100% width the browser still respects the other divs space instead of taking the whole 100%.
So I'm thinking if I can get the div on the right ,for example, to not display when the div on the left is toggled, it will be out of the way so the left div can take all 100%
Maybe im going about this the wrong way. Any help is welcome. Thanks.

You can create a single javascript function that sets appropriate classes on each element. Since you have only two elements it is not too complex.
HTML
<div id="container">
<div id="lefty" onclick="toggle('lefty', 'righty')">Lefty</div>
<div id="righty" onclick="toggle('righty', 'lefty')">Righty</div>
</div>
JS
function toggle(target, other)
{
var t = document.getElementById(target);
var o = document.getElementById(other);
if (!t.className || t.className == "inative")
{
t.className = "active";
o.className = "inactive";
}
else
{
t.className = "";
o.className = "";
}
}
CSS
#container {
background-color: lightgreen;
padding: 15px 0;
}
#container div {
color: white;
width: 45%;
display: inline-block;
}
#lefty {
background-color: blue;
}
#righty {
background-color: purple;
}
#container div.active {
width: 90%;
}
#container div.inactive {
display:none;
}
https://jsfiddle.net/dLbu9odf/1/
This could be made more elegant or capable of handling more elements with something like toggle(this) and then some DOM traversal and iteration in javascript, but that's a bit beyond scope. If that were the case I would recommend jQuery.

Related

Multiline text overflow (dotdotdot): wrap only word

I have such example of my code:
<div class="container">
<div class="item n1">Proe Schugaienz</div>
<div class="item n2">Proe Schugaienz</div>
</div>
and i use such jQuery code:
$('.item').dotdotdot({
wrap: 'word',
fallbackToLetter: false
})
and css:
.item {
margin: 5px;
background: red;
padding: 2px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.n1 {
width: 8px;
}
.n2 {
width: 80px;
}
but as result i get:
as result i want achieve this:
is it possible with pure css or with dotdotdot.js?
if word (sentence) cannot match it's parent: then show only default one-line-text-overflow
if word (sentence) is able to fit parent word-by-word - then match it, no letter-hyphenation!
so i don't wanna my container to be extented by height (i have a lot of data, it's only an example, i could not hardcode some blocks)
https://plnkr.co/edit/IxS0CReJicRfDdeGpoPo?p=preview
you can use flex
<div class="container">
<span></span>
<em></em>
</div>
.container {
display: flex;
justify-content: center; /* centers content horizontally*/
align-items: center /* centers content vertically*/
}
Here is a proposal that prevents the word break - there are changes in the markup as well:
I'm using flexbox container item for the div inner that has dotdotdot applied - this ensures two things:
a. inner takes the width of the content
b. word-wrap: break-word applied by dotdotdot will not break the word
Now it is possible to detect when word break or overflow can happen - this would be when inner width exceeds item width.
So we can detect this in the callback of dotdotdot!
When words starts breaking, you need ellipsis - so replace the text with ... just like dotdotdot does.
See demo below:
$('.inner').dotdotdot({
wrap: 'word',
watch: 'window',
fallbackToLetter: false,
callback: function(isTruncated) {
// this detects 'break-word'
if($(this).outerWidth() > $(this).closest('.item').outerWidth()) {
$(this).text('...');
}
}
});
.item {
margin: 5px;
background: red;
padding: 2px;
display:flex;
height: 100px;
}
.n1 {
width: 12px;
}
.n2 {
width: 80px;
}
.n3 {
width: 150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery.dotdotdot/1.7.4/jquery.dotdotdot.js"></script>
<div class="container">
<div class="item n1">
<div class="inner">Proe Schugaienz.</div>
</div>
<div class="item n2">
<div class="inner">
Proe Schugaienz. More text here. More text here. More text here.
</div>
</div>
<div class="item n3">
<div class="inner">
Proe Schugaienz. More text here. More text here. More text here.
</div>
</div>
</div>
You should set display: inline-block; and line-height: 26px; (or any suitable value which you find suitable) to .n1 class and also increase the width to 16px (i.e. enough width to accomodate two letters). So the final css should be as follows:
.item {
margin: 5px;
background: red;
padding: 2px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.n1 {
line-height: 26px;
width: 16px;
}
.n2 {
width: 80px;
}
Also remove the lines of in script.js which u were using to achieve the same result. It should work for you.
I think easiest solution for this is css "text-overflow:elipsis".
You can use below css snippet for desired result.
.item.n1 {width: 20px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;}
Note that; width is your turning point for dots.
To the element you want to show with a ... Apply the following code
.example-element{
max-width: example-width;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
You can adjust the width at the maximum you want.
Since you are already using JS, this is how I would do it without any library/plugin.
const items = document.querySelectorAll('.item')
const log = document.querySelector('#log')
const MIN_WIDTH = 32
// Check if the elements are smaller than the MIN_WIDTH
// and apply a class to hide the text and show an ellipsis.
for (let item of items) {
if (item.clientWidth < MIN_WIDTH) {
item.classList.add('hidden')
}
}
.item {
background-color: red;
text-overflow: ellipsis;
overflow: hidden;
margin-bottom: 0.5rem;
padding: 0.2rem;
}
.n1 {
width: 1.5rem; // 24px
}
.n2 {
width: 6rem;
}
/*
This will hide the text and display an ellipsis instead
*/
.hidden {
position: relative;
white-space: nowrap;
}
.hidden::before {
content: '...';
display: block;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: red;
text-align: center;
}
<div class="container">
<div class="item n1">Proe Schugaienz</div>
<div class="item n2">Proe Schugaienz</div>
</div>
If you plan on changing the size of the elements, you can wrap the loop inside a function, and then call it when needed.
$.fn.overflow = function () {
return this.each(function () {
if ($(this)[0].scrollWidth > $(this).innerWidth()) {
$(this).css('overflow', 'hidden').css('text-overflow', 'ellipsis').css('white-space', 'nowrap').css('min-width', '16px');
}
});
};
$(function () {
$('.item').overflow();
});
.item {
margin: 5px;
background: red;
padding: 2px;
overflow: auto;
word-wrap: break-word;
}
.n1 {
width: 8px;
}
.n2 {
width: 80px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item n1">Proe Schugaienz</div>
<div class="item n2">Proe Schugaienz</div>
</div>
I agree to the answers provided before adding text-overflow: ellipsis; to the div's does work even if content does not overflow. I believe that you want to add the ellipsis at the beginning of the content which can be achieved by "reverse ellipsis" and without the help of any js code you can achieve this kind of output Here's a plnkr that I have created for you:
https://plnkr.co/edit/TwotVdtGMaTi6SWaQcbO?p=preview
.box {
width: 250px;
border: 1px solid silver;
padding: 1em;
margin: 1em 0;
}
.ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.reverse-ellipsis {
/* Your move. */
text-overflow: clip;
position: relative;
background-color: #FFF;
}
.reverse-ellipsis:before {
content: '\02026';
position: absolute;
z-index: 1;
left: -1em;
background-color: inherit;
padding-left: 1em;
margin-left: 0.5em;
}
.reverse-ellipsis span {
min-width: 100%;
position: relative;
display: inline-block;
float: right;
overflow: visible;
background-color: inherit;
text-indent: 0.5em;
}
.reverse-ellipsis span:before {
content: '';
position: absolute;
display: inline-block;
width: 1em;
height: 1em;
background-color: inherit;
z-index: 200;
left: -.5em;
}
body {
margin: 1em;
}
HTML
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<p>The goal would be to add ellipsis on the beginning and show the end of the content. Any idea?</p>
<div class="box ellipsis reverse-ellipsis"><span>Here is some long content that doesn't fit.</span></div>
<div class="box ellipsis reverse-ellipsis"><span>Here is some that does fit.</span></div>
</body>
</html>
All you need to do is add an extra element within .reverse-ellipsis (here a span); I hope this might help you.

Javascript - move elements by pressing another element

Lets say I have a div with images, however not all have space to be displayed at same the time, so I used CSS property white-space: nowrap and overflow: hidden, so elements don't break into new lines or expand over div.
Now I need JavaScript technique that will allow me to move them left or right so user can reach these not visible images aswell. Think of it as a slider.
It should have two navigation buttons, left and right, by pressing each, images move in specific direction. Movement should be animated (not moving instantly, instead, they should move over specific period, frame by frame)
Here is jsfiddle demo: http://jsfiddle.net/rfLffev7/
(red and green div represent a button that should trigger functions)
HTML:
<div id="container">
<div id="left"></div>
<div id="track">
<img src="">
<img src="">
<img src="">
<img src="">
<img src="">
<img src="">
<img src="">
<img src="">
</div>
<div id="right"></div>
</div>
CSS:
#container {
width: 600px;
height: 200px;
margin: 10px auto;
}
#left {
width: 50px;
height: 200px;
float: left;
background: #500;
}
#track {
width: 500px;
height: 200px;
float: left;
background: #333;
white-space: nowrap;
overflow: hidden;
}
#track img {
width: 100px;
height: 100px;
border: 1px solid #fff;
margin-top: 50px;
margin-left: 10px;
}
#right {
width: 50px;
height: 200px;
float: left;
background: #050;
}
I would use absolute positioning for that as the CSS will be simpler. For the JavaScript, it's quite simple.
Here, I subtract 116px from the "margin-left" to move #track to the left and add 116px to #track to move it back to the right. I have not added any "stops" at either end, so in theory you could keep scrolling indefinitely.
document.getElementById("left").onclick = function(){
var currentPlace = parseInt(document.getElementById("track").style.marginLeft) || 0;
document.getElementById("track").style.marginLeft = (currentPlace - 116) + "px"
}
document.getElementById("right").onclick = function(){
var currentPlace = parseInt(document.getElementById("track").style.marginLeft) || 0;
document.getElementById("track").style.marginLeft = (currentPlace + 116) + "px"
}
Here's a working example (using absolute positioning): http://jsfiddle.net/rfLffev7/1/
I also added an additional :nth-child(even) class to make it more obvious that the images are moving:
#track img:nth-child(even) {
border: 1px solid #f00;
}
You can move the inner track using margins. For example, check the element for its margin value, then for the size of the image (or whatever distance you want to move the track), then add those two values together, then apply the new value to the track.
$('#right').click(function(){
var moveDistance = $('#track').find('img').width()
var moved = $('#track').css('marginLeft');
var moveIt = moveDistance - parseInt(moved)
$('#track').css('marginLeft', -moveIt);
});
I have updated your example with what I mean. The green button is rigged to move the distance of 1 image + the previous value of the element margin.
http://jsfiddle.net/rfLffev7/4/
You'll also need to make a few changes to your css to keep the other elements positions.
#container {
width: 600px;
height: 200px;
margin: 10px auto;
overflow:hidden;
position:relative;
}
#left {
width: 50px;
height: 200px;
left:0;
background: #500;
position:absolute;
z-index:1;
}
#track {
width: auto;
height: 200px;
float: left;
background: #333;
white-space: nowrap;
overflow: hidden;
position:absolute;
left:50px;
}
#track img {
width: 100px;
height: 100px;
border: 1px solid #fff;
margin-top: 50px;
margin-left: 10px;
}
#track img:nth-child(even) {
border: 1px solid #f00;
}
#right {
width: 50px;
height: 200px;
background: #050;
position:absolute;
right:0;
}

Show one element if another is above a certain height

I have a following HTML:
<span class="day-number">{{day-number}}</span>
<div class="event-box">
<div class="event-container">
</div>
<div class="more-events">more ...</div>
</div>
Event-container is filled with an unknown number of .event elements like the following:
<div class="event">{{event-name}}</div>
I want to show or hide the .more element based on if the .event-container has a height of over 76px (equal to the height of four .event elements stacked).
The styling for the above elements:
.event {
text-align: left;
font-size: .85em;
line-height: 1.3;
border-radius: 3px;
border: 1px solid #3a87ad;
background-color: #3a87ad;
font-weight: normal;
color: whitesmoke;
padding: 0 1px;
overflow: hidden;
margin-bottom: 2px;
cursor: pointer;
}
.event-box {
max-height: 76px;
overflow: hidden;
position:relative;
}
.event-box .more-events {
height: 10px;
position: absolute;
right: 0;
bottom: 10px;
display: none;
z-index: 5;
}
No styling for .event-container
I can do what I want with Javascript (jQuery):
$(".event-box").each(function(){
var $this = $(this);
if($this.children(".event-container").height() > 76){
$this.children(".more-events").css("display", "block");
} else {
$this.children(".more-events").css("display", "");
}
});
And run that every time a make a change, but I'd rather do it with CSS.
Is this possible? Maybe with pseudo elements or media queries or something?
JSFIDDLE: http://jsfiddle.net/pitaj/LjLxuhx2/
If changing the markup is acceptable there is a possibility to achieve a somewhat similarly looking page without using JavaScript to show or hide, here is the Fiddle
I have removed <div class="more-events">more ...</div> line and made elements of event class to get hide when it is necessary I also made them to appear when hovering over more ... .
The CSS I have added:
.event:nth-child(n){
display: none;
}
.event:nth-child(1),.event:nth-child(2),.event:nth-child(3),.event:nth-child(4){
display: block;
}
.event:nth-child(5){
text-indent: -9999px;
position: relative;
display: block;
color: black;
border: none;
background-color: #FFF;
}
.event:nth-child(5)::before{
position: absolute;
text-indent: 0px;
content: "more ...";
display: block;
}
.event:nth-child(5):hover{
position: static;
text-indent: 0;
border: 1px solid #3a87ad;
background-color: #3a87ad;
color: whitesmoke;
}
.event:nth-child(5):hover::before{
display:none;
}
.event:nth-child(5):hover ~ .event:nth-child(n){
display: block;
}
And for .event-box class I have commented out max-height: 76px; because in my browser 76px was not equal to the height of four .event elements stacked. Also removed update function.
I dont think it's possible using css only. but for better approach in what you are trying to do.instead of using max-height for .event-box I use this css which is add display:none to +4.event on your event container:
.event-box .event-container .event:nth-child(n+5){
display: none;
}
and now when it's more than 4 .event your more text appears. FIDDLE
UPDATE:
HERE I make little change in you js as well and make it more professional,
while you are using template to render the page, maybe you can do it as follow
<div class="event-container">
{{#each events}}
<div class="event">{{event-name}}</div>
{{/each}}
</div>
{{#if canshowmore}}
<div class="more-events">more ...</div>
{{/if}}
and
function canshowmore() {
return events.length >= 4;
}

How do I make one element change by hovering over another?

I'm trying to do what many have asked before, but even after trying everything I still can't get the results I want.
I have an image 600px by 1600px, 4 images of 600px by 400px in a vertical line. I want to show 600px by 400px of the image at any one time. Ideally I would be able to hover over an element somewhere on my page and move the image upwards to reveal the other portions of the 600px by 400px image. In effect, I'd have 4 images viewable by hovering over 4 the elements.
I've tried various css3 and jquery solution but none have worked. I would appreciate any help with this.
HTML
<div class="mainimage">
<div class="buttonsection">
<div class="button1">Button 1</div>
<div class="button2">Button 2</div>
<div class="button3">Button 3</div>
<div class="button4">Button 4</div>
</div><!--end of buttonsection-->
<div class="rollingimage">
<img src="IMG/four-pics.png">
</div><!--end of rollingimage-->
</div><!--end of mainimage-->
</div><!--end of main content-->
CSS
.mainimage {
position: relative;
top: 0px;
left: 0px;
width: 900px;
height: 400px;
border: 2px solid #E78F25;
margin: 0 10px 20px 0;
}
.buttonsection {
width: 290px;
height: 400px;
position: relative;
float: left;
}
.button1,
.button2,
.button3,
.button4 {
display: inline;
height: 98px;
width: 290px;
border: 1px solid #E78F24;
text-align: center;
float: left;
}
.rollingimage {
width: 598px;
height: 400px;
position: relative;
overflow: hidden;
top: 0px;
left: 0px;
float: right;
}
jquery
$(document).ready(function(){
$(".button1").hover(function(){
$('.rollingimage').stop().animate({'top': '-200px'}, 1500);
});
});
Here is the jsfidle: http://jsfiddle.net/dirtyd77/jCvYm/1/
Thanks yet again
Gary
Just for fun, no JS:
http://jsfiddle.net/coma/MTWdb/5/
HTML
<div id="foo">
Button 1
Button 2
Button 3
Button 4
<div></div>
</div>
CSS
#foo {
width: 400px;
border: 2px solid #E78F25;
position: relative;
}
#foo > div {
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 200px;
background: #fff url(http://placekitten.com/600/1600) no-repeat 0 0;
transition: background-position .5s;
}
#foo > a {
display: block;
width: 200px;
line-height: 100px;
text-align: center;
text-decoration: none;
}
#foo > a + a {
border-top: 1px solid #E78F25;
}
#foo > a:nth-child(1):hover ~ div {
background-position: 0 0;
}
#foo > a:nth-child(2):hover ~ div {
background-position: 0 -400px;
}
#foo > a:nth-child(3):hover ~ div {
background-position: 0 -800px;
}
#foo > a:nth-child(4):hover ~ div {
background-position: 0 -1200px;
}
You need to change the positioning of the image inside the div, not the div itself. To animate my example, you could add CSS transitions for better performance than JS animations.
http://jsfiddle.net/jCvYm/8/
$('.rollingimage').find('img')
As Dom mentioned, the jsFiddle you provided didn't reference the jQuery library. It also didn't included any actual images, and only contained code for one of the three buttons. I doubt those were the original problems you were having, though. (The missing reference to jQuery might have been.)
Once I had those straightened out, I noticed that hovering the button caused the picture to slide out of the screen, instead of scrolling. The simplest way to fix that is to move the img element, instead of moving the div. (The more natural way would be to change the scroll position of the div, but I don't recall how to do that off the top of my head.)
Added CSS:
.rollingimage img {
position: relative;
}
New JS:
$(document).ready(function(){
$(".button1").hover(function(){
$('.rollingimage img').stop().animate({'top': '0px'}, 1500);
});
$(".button2").hover(function(){
$('.rollingimage img').stop().animate({'top': '-400px'}, 1500);
});
$(".button3").hover(function(){
$('.rollingimage img').stop().animate({'top': '-800px'}, 1500);
});
$(".button4").hover(function(){
$('.rollingimage img').stop().animate({'top': '-1200px'}, 1500);
});
});
jsFiddle: http://jsfiddle.net/jCvYm/6/

disable parent page on layer show

I have a hidden layer and when the user clicks a button the layer is set to show. How can I make the parent page become disabled/greyed out so the user cannot click anything on the parent page until the layer has been closed(set to hide)
similar to lightbox galleries
I call a function in the layer from the parent page from a button(edit) click
edit.onclick=function(){
edit_box('show');
}
then on the layer I call the show function
function edit_box(showhide)
{
if(showhide == "show")
{
document.getElementById('popupbox').style.visibility="visible";
}else if(showhide == "hide"){
document.getElementById('popupbox').style.visibility="hidden";
}
}
the css for the #popup is
#popupbox{
padding:0;
margin: 0px auto;
background:white;
border: solid #000000 1px;
z-index: 9000;
font-family: arial;
visibility: hidden;
}
and the html is
<div id="popupbox">
<div class="close"><a href="javascript:edit_box('hide');" >close</a></div>
any pointers greatly appreciated as I do not know where to start on this one and can only find code relivent to pop up boxes elsewhere online
why dont you try with jQuery, jQuery("#popupbox").hide();
Change your style to
#popupbox{
padding:0;
margin: 0px auto;
position:fixed;
top:0; left:0; right:0; bottom: 0;
display:none;
background: rgba(255,255,255,0.5);
border: solid #000000 1px;
z-index: 9000;
font-family: arial;
}
and your function to
function edit_box(showhide)
{
if(showhide == "show")
{
$('#popupbox').show();
} else if (showhide == "hide") {
$('#popupbox').hide();
}
}
if you want to support browsers that do not understand rgba colors then use a semi-transparent background .png image
ok sorted this out with
css on parent page
.black_overlay{
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index:1001;
-moz-opacity: 0.8;
opacity:.80;
filter: alpha(opacity=80);
}
css on layer page
.white_content {
display: none;
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
padding: 16px;
border: 16px solid orange;
background-color: white;
z-index:1002;
overflow: auto;
}
then the js on parent page within function calling popup layer
document.getElementById('fade').style.display='block'
html div on parent page
<div id="fade" class="black_overlay"></div>
js on popup layer
function edit_box(showhide){
if(showhide == "show"){
document.getElementById('popupbox').style.display='block';
document.getElementById('popupbox').style.visibility="visible";
}else if(showhide == "hide"){
document.getElementById('popupbox').style.display='none';
document.getElementById('fade').style.display='none'
document.getElementById('popupbox').style.visibility="hidden";
}
}
and the html on the layer
<div id="popupbox" class="white_content">
<div class="close"><a href="javascript:edit_box('hide');" >close</a></div>
</div>

Categories

Resources