Trigger resize only once - javascript

I am trying to reverse two divs when the client's window is resized, but my function loops.
I know that this can be made very easy using flexbox, but I am more interested in understanding how to make it work using JS. Just got into learning JS and I am experimenting with functions.
when the client's window is below 58em, I want the divs to rearrange - like flex-direction: column-reverse; for example. when the window is not resized or it's size is bigger than 58em, the function should not do anything
var reverse = document.querySelectorAll(".reverse");
function reverseChildren(parent) {
for (var i = 1; i < parent.childNodes.length; i++){
parent.insertBefore(parent.childNodes[i], parent.firstChild);
}
}
window.addEventListener('resize', function () {
if (window.matchMedia("(max-width: 58em)").matches) {
for (i = 0; i < reverse.length; i++) {
reverseChildren(reverse[i]);
}
}
});
<div class=" reverse">
<div class="first">
<h4>some text</h4>
</div>
<div class="second">
<img src='https://images.unsplash.com/photo-1430026996702-608b84ce9281?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=600&h=338&fit=crop&s=363a88755a7b87635641969a8d66f7aa' alt="Registration screen">
</div>
</div>

You should listen for the match media instead of the resize event.
var reverse = document.querySelectorAll(".reverse");
/* Any other code that reverses the ordre of elements is viable within this function */
function reverseChildren(parent) {
let children = [];
for (var i = 0; i < parent.children.length; i++) {
children.push(parent.children[i]);
}
children = children.reverse().map(item => item.outerHTML).join('');
parent.innerHTML = children;
}
let media = window.matchMedia("(max-width: 58em)");
media.addListener(() => {
for (var i = 0; i < reverse.length; i++) {
reverseChildren(reverse[i]);
}
});
<div class=" reverse">
<div class="first">
<h4>some text</h4>
</div>
<div class="second">
<img src='https://images.unsplash.com/photo-1430026996702-608b84ce9281?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=600&h=338&fit=crop&s=363a88755a7b87635641969a8d66f7aa' alt="Registration screen">
</div>
</div>
<span class="mq-value"></span>

Related

Image file name stored in array then displayed through loop

I've correctly did this with displaying text in a p tag but i can't figure out why my image won't show up in the same manner and I'm not sure if it has to do with how it was set up in html.
let imgArray = ["beastiary.jpg"];
window.addEventListener("load", showImages);
function showImages() {
let i = 0;
let images = document.getElementsByTagName("img");
while (i < imgArray.length) {
images[i].innerHTML = imgArray[i]
i++
}
}
<div class="w3-col m3 l3 " style="padding-right: 5px">
<div class="w3-card-4 w3-theme-l1" id="book">
<img src="" alt="book">
<div class="w3-container w3-center w3-theme-d3">
<p></p>
</div>
</div>
</div>
I have tried to do away with using img and instead put it in a div using an id but it still won't show up. There will be more images I'm just making sure this one works first before I start adding the rest.
For showing image you need to set src to proper url
let imgArray = ["https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/800px-Image_created_with_a_mobile_phone.png"];
window.addEventListener("load", showImages);
function showImages() {
let i = 0;
let images = document.getElementsByTagName("img");
while (i < imgArray.length) {
images[i].src = imgArray[i]
i++
}
}
.img {
width: 200px;
height: 200px;
}
<img class='img'/>

Call javascript to preserve filter state when traverse from other page via href

I have a number of webpages in a report each page has a checbox filter that if selected calls javascript to show hide some elements of the page, the checkbox filter enables to true, all pages are created in advance. The user can traverse from one pages by clocking on a url .
The trouble is because the pages are created in advance the filter always default to true, even if just set to false by user on previous page. I think I need to call some javascript to set the value of the filter to the value of the filter on the calling page but because traversing form page to page via a hyperlink I dont know how to call the Javascript.
FYI
Html Filter
<div class="mb-2">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" name="showLabels" id="showLabels" checked="checked" onclick="toggleLabelsFilter('showLabels');">
<label for="showLabels" id="showLabelslabel" class="form-check-label">
Show Labels
</label>
</div>
</div>
Example html that will have elements hidden
<figure class="figure" style="position:relative">
<a href="StatusReport00017_byfolder00021.html">
<img src="../images/E__Melco_TestMusic_WAV_WAV_Antonin Dvorak; Itzhak Perlman, Daniel Barenboim, Samuel Sanders.jpg" class="figure-img" width="200" height="200">
</a>
<div style="position:absolute; top:144px;">
<div class="badge ml-2 badge-primary">
12 files
</div>
</div>
<div style="position:absolute; top:166px;">
<div class="badge ml-2 badge-success">
12 MB
</div>
<div class="badge ml-2 badge-warning">
0 Discogs
</div>
</div>
<figcaption class="figure-caption">
<a href="StatusReport00017_byfolder00021.html">
Antonin Dvorak; Itzhak Perlman, Daniel Barenboim, Samuel Sanders
</a>
</figcaption>
</figure>
Javascript
function toggleLabelsFilter(filterName)
{
var checkbox = document.getElementById(filterName);
if(checkbox.checked)
{
var badges = document.getElementsByClassName("badge");
for (i = 0; i < badges.length; i++)
{
badges[i].style.visibility = "visible";
}
}
else
{
var badges = document.getElementsByClassName("badge");
for (i = 0; i < badges.length; i++)
{
badges[i].style.visibility = "hidden";
}
}
}
Edit Update
Attempt based on comments
Called when user selects checkbox
function toggleLabelsFilter()
{
var checkbox = document.getElementById("showLabels");
if(checkbox.checked)
{
sessionStorage.setItem("showLabels", true);
var badges = document.getElementsByClassName("badge");
for (i = 0; i < badges.length; i++)
{
badges[i].style.visibility = "visible";
}
}
else
{
sessionStorage.setItem("showLabels", false);
var badges = document.getElementsByClassName("badge");
for (i = 0; i < badges.length; i++)
{
badges[i].style.visibility = "hidden";
}
}
}
Called when page loaded
function checkFilter()
{
if(sessionStorage.getItem("showLabels")==true)
{
document.getElementById("showLabels").checked=true;
var badges = document.getElementsByClassName("badge");
for (i = 0; i < badges.length; i++)
{
badges[i].style.visibility = "visible";
}
}
else
{
document.getElementById("showLabels").checked=false;
var badges = document.getElementsByClassName("badge");
for (i = 0; i < badges.length; i++)
{
badges[i].style.visibility = "hidden";
}
}
}

How to set an attribute as percentage in jQuery?

I am unable to set css attribute {left: $numberEquivalentToPercent} in jQuery
var targets = $('.parallax__layer__cell');
var i = 1;
for(i = 1; i <= targets.length; i++)
{
if (targets.parents('.parallax__layer--bg').length) {
//apply to only those element that have a parent having class "parallax__layer--bg"
targets.eq(i).css('left', toString(60*i)+ "%");
}
}
The above code(in JS) is expected to produce the same effect as below(in CSS)
.parallax__layer__cell:nth-child(1) { left: 0%; }
.parallax__layer__cell:nth-child(2) { left: 60%; }
.parallax__layer__cell:nth-child(3) { left: 120%; }
.parallax__layer__cell:nth-child(4) { left: 180%; }
.parallax__layer__cell:nth-child(5) { left: 240%; }
Basically I am trying to convert a static code to dynamic code
What if you put 60 * i into a variable called numPercent and then do numPercent.toString() to convert it to a string?
var targets = $('.parallax__layer__cell');
var i = 1;
for(i = 1; i <= targets.length; i++)
{
if (targets.parents('.parallax__layer--bg').length) {
//apply to only those element that have a parent having class "parallax__layer--bg"
var numPercent = 60*i;
targets.eq(i).css('left', numPercent.toString() + "%");
}
}
Here is working code:
var targets = $('.parallax__layer__cell');
var i ;
for(i = 0; i < targets.length; i++)
{
if (targets.eq(i).parents('div.parallax__layer--bg').length) {
targets.eq(i).css('left', 60*i + "%");
}
}
.parallax__layer__cell{
position:absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
<div class="parallax__layer--bg">
<div class="parallax__layer__cell">a</div>
</div>
<div class="parallax__layer--bg">
<div class="parallax__layer__cell">b</div>
</div>
<div class="parallax__layer--bg">
<div class="parallax__layer__cell">c</div>
</div>
<div class="parallax__layer--bg">
<div class="parallax__layer__cell">d</div>
</div>
<div class="parallax__layer--bg">
<div class="parallax__layer__cell">e</div>
</div>
<div>
<div class="parallax__layer__cell">--no parent--</div>
</div>
</div>
I believe this is a timing issue between parallax script and your script. Since css loads first parallax script works fine. But if you remove css and run your script after parallax script it may not do the same effect. Make sure your script runs before actual parallax script.

How to create pair game using node values and set a setTimeout() method

I want to create a pair game that if the same textnode is matched it will set the background in white to reveal the matched textnode if not it will set a timeout and get back in original state.
The Problem of this is if I use the childNodes.nodeValue in match it saids that ChildNodes.nodeValue is not a function. And I try another code. I declare a variable that calls the element tag name of div which is I append a textNode in div. I want to compare two consecutive childNodes of div and if it is the same node, I change the color of the background to white. and I use the setTimout method, if not the color of background will go back again in original state which is black, I am pretty confused about this.
can you scan my code and help me to figure out what is the problem of this code?
here is the code.
<html>
<head>
<style>
div.row {
clear : left;
margin: auto;
width: 520px;
}
div.col {width:100px;
height:100px;
border: 3px solid black;
float : left;
margin: 10px;
font-size: 75px;
text-align: center;
background-color: black;
}
</style>
</head>
<body>
<div class="row">
<div id="00" class="col"></div>
<div id="01"class="col"></div>
<div id="02"class="col"></div>
<div id="03"class="col"></div>
</div>
<div class="row">
<div id="10" class="col"></div>
<div id="11"class="col"></div>
<div id="12"class="col"></div>
<div id="13"class="col"></div>
</div>
<div class="row">
<div id="20" class="col"></div>
<div id="21"class="col"></div>
<div id="22"class="col"></div>
<div id="23"class="col"></div>
</div>
<div class="row">
<div id="30" class="col"></div>
<div id="31"class="col"></div>
<div id="32"class="col"></div>
<div id="33"class="col"></div>
</div>
<script>
var size = 4;
var player = 0;
var board = new Array(size);
for (var i = 0; i < size; i++) {
board[i] = new Array(size);
for (var j = 0; j < size; j++) {
board[i][j] = 0;
}
}
var div_elements = document.getElementsByClassName("col");
for (var i = 0; i < div_elements.length;i++) {
div_elements[i].addEventListener("click", function() {mclick(this);});
}
var count=0;
function mclick(obj) {
if(match(div_elements.childNodes[0].nodeValue) == match(div_elements.childNodes[1].nodeValue)
{
obj.style.backgroundColor="white";
}
else{
setTimeout(function(){ obj.style.backgroundColor="white" }, 1000);
}
}
function shuffle() {
var value;
var text;
var text_node;
for (var i = 0; i < (size * size) ; i++) {
value = Math.ceil(Math.random() * 8);
board[Math.floor(i/4)][i %4] = value;
}
for (var i = 0; i < div_elements.length; i++)
{
text = board[Math.floor(i/4)][i%4];
text_node = document.createTextNode( text);
div_elements[i].appendChild(text_node);
}
}
shuffle();
</script>
</body>
</html>
You must be more specific. What kind of problem are you having? What are the error messages? What do you do that triggers the problem?
At least, put the code in a pastebin.com or something similar so that others don't need to setup a project for testing your whole stuff.

onload setInterval for carousel

I was messing around and making a simple carousel from scratch. At first I used onclick="function()" to toggle through the images, then I wanted to switch it out for an onload="setInterval(function, 4000)", but that seems to have broken something...
Here is the html:
<div id="carousel">
<div class="carousel-image" onload="setInterval(newImage(this), 4000)"><img src="http://placehold.it/350x150">1</div>
<div class="carousel-image-off" onload="setInterval(newImage(this), 4000)"><img src="http://placehold.it/350x150">2</div>
<div class="carousel-image-off" onload="setInterval(newImage(this), 4000)"><img src="http://placehold.it/350x150">3</div>
<div class="carousel-image-off" onload="setInterval(newImage(this), 4000)"><img src="http://placehold.it/350x150">4</div>
<div class="carousel-image-off" onload="setInterval(newImage(this), 4000)"><img src="http://placehold.it/350x150">5</div>
<div class="carousel-image-off" onload="setInterval(newImage(this), 4000)"><img src="http://placehold.it/350x150">6</div>
</div>
And here is the script:
<script>
var arr = 0;
function newImage(el){
var images = document.getElementById('carousel').children;
for (var i = 0; i < images.length; i++ ){
images[i].className = "carousel-image-off";
} if (arr < images.length-1){
arr++;
images[arr].className = "carousel-image";
} else {
arr = 0;
images[arr].className = "carousel-image";
}
}
</script>
I've simplified a little bit, changed a few things.
HTML
<div id="carousel">
<div class="carousel-image active"><img src="http://placehold.it/350x150">1</div>
<div class="carousel-image"><img src="http://placehold.it/350x150">2</div>
<div class="carousel-image"><img src="http://placehold.it/350x150">3</div>
<div class="carousel-image"><img src="http://placehold.it/350x150">4</div>
<div class="carousel-image"><img src="http://placehold.it/350x150">5</div>
<div class="carousel-image"><img src="http://placehold.it/350x150">6</div>
</div>
CSS
.carousel-image {
display:none;
}
.carousel-image.active {
display:inline;
}
JavaScript
function newImage() {
var images = document.getElementsByClassName('carousel-image');
for(var i = 0; i < images.length; i++ ) {
if(images[i].className.match('active'))
{
images[i].classList.remove('active');
if(i >= images.length-1)
{
images[0].classList.add('active');
}
else
{
images[i+1].classList.add('active');
}
break;
}
}
}
setInterval(
newImage,
1000
);
JSFiddle
http://jsfiddle.net/nasd0ska/2/
Note
If I were you, I'd use jQuery. So easy and handy for manipulating DOM!

Categories