javascript not adding class to div - javascript

<div
id="overlay_block"
class="overlay-type overlay"
data-text-placement="{{ block.settings.overlay_position }}"
data-mobile-text-placement="{{ block.settings.overlay_mobile }}">
</div>
and this bit of javascript that should add/remove the div class on window resize.
var mq = window.matchMedia("(max-width: 767px)");
var overlayBlock = document.getElementById("overlay_block");
var textPlacement = overlayBlock.getAttribute("data-text-placement");
var mobileTextPlacement = overlayBlock.getAttribute("data-mobile-text-placement");
console.log("textPlacement: ", textPlacement);
console.log("mobileTextPlacement: ", mobileTextPlacement);
if (mq.matches) {
overlayBlock.classList.add(mobileTextPlacement);
overlayBlock.classList.remove(textPlacement);
} else {
overlayBlock.classList.add(textPlacement);
overlayBlock.classList.remove(mobileTextPlacement);
}
window.addEventListener("resize", function () {
if (window.innerWidth < 767) {
overlayBlock.classList.add(mobileTextPlacement);
overlayBlock.classList.remove(textPlacement);
} else {
overlayBlock.classList.add(textPlacement);
overlayBlock.classList.remove(mobileTextPlacement);
}
});
As you can see from the code I have logged to console the variables that contains the class that should be added to the div and they contain the correct values that are the css class i need to add:
textPlacement: position--left position--top
mobileTextPlacement: position--right position--bottom
Also if i replace one of the statements (e.g. overlayBlock.classList.add(textPlacement) with a string overlayBlock.classList.add("some text")
the string gets added correctly to the div class. Any hint on how to fix my code?
PS: I'd prefer to avoid using jquery
Any help appreciated

Ok so thanks to #CBroe hint I manager to fix my code. Here is the correct script
var mq = window.matchMedia("(max-width: 767px)");
var overlayBlock = document.getElementById("overlay_block");
var textPlacement = overlayBlock.getAttribute("data-text-placement");
var mobileTextPlacement = overlayBlock.getAttribute("data-mobile-text-placement");
var addClasses = function(elem, classList) {
var classes = classList.split(" ");
for (var i = 0; i < classes.length; i++) {
elem.classList.add(classes[i]);
}
};
var removeClasses = function(elem, classList) {
var classes = classList.split(" ");
for (var i = 0; i < classes.length; i++) {
elem.classList.remove(classes[i]);
}
};
if (mq.matches) {
addClasses(overlayBlock, mobileTextPlacement);
removeClasses(overlayBlock, textPlacement);
} else {
addClasses(overlayBlock, textPlacement);
removeClasses(overlayBlock, mobileTextPlacement);
}
window.addEventListener("resize", function() {
if (window.innerWidth < 767) {
addClasses(overlayBlock, mobileTextPlacement);
removeClasses(overlayBlock, textPlacement);
} else {
addClasses(overlayBlock, textPlacement);
removeClasses(overlayBlock, mobileTextPlacement);
}
});

Ok so this is the final piece of working code, definitely more elegant than the previous loop. With a simple mod to the original code.
var mq = window.matchMedia("(max-width: 767px)");
var overlayBlock = document.getElementById("overlay_block");
var textPlacement = overlayBlock.getAttribute("data-text-placement").split(" ");
var mobileTextPlacement = overlayBlock.getAttribute("data-mobile-text-placement").split(" ");
if (mq.matches) {
overlayBlock.classList.add(...mobileTextPlacement);
overlayBlock.classList.remove(...textPlacement);
} else {
overlayBlock.classList.add(...textPlacement);
overlayBlock.classList.remove(...mobileTextPlacement);
}
window.addEventListener("resize", function() {
if (window.innerWidth < 767) {
overlayBlock.classList.add(...mobileTextPlacement);
overlayBlock.classList.remove(...textPlacement);
} else {
overlayBlock.classList.add(...textPlacement);
overlayBlock.classList.remove(...mobileTextPlacement);
}
});

Related

PageRevealEffects connect to navbar

Hello all of the knowers of javascript,
I have a little problem about javascript and would like one of you to help me to solve the problem.
If you know the 'PageRevealEffects' plugin there are multiple pages that in one HTML are turning on by javascript.
Here are the plugin documentation and demo version at the bottom of documentation: https://tympanus.net/codrops/2016/06/01/multi-layer-page-reveal-effects/
So my problem is I want to connect the navbar and logo click to the plugin,
http://bagrattam.com/stackoverflow/PageRevealEffects/
Here is the code by which it works
(function() {
$('.navbar-brand').click(function(){
$(this).data('clicked', true);
});
var n;
$('#nav a').click(function () {
n = $(this).parent().index() + 1;
});
var pages = [].slice.call(document.querySelectorAll('.pages > .page')),
currentPage = 0,
revealerOpts = {
// the layers are the elements that move from the sides
nmbLayers : 3,
// bg color of each layer
bgcolor : ['#52b7b9', '#ffffff', '#53b7eb'],
// effect classname
effect : 'anim--effect-3'
};
revealer = new Revealer(revealerOpts);
// clicking the page nav
document.querySelector('.navbar-brand').addEventListener('click', function() { reveal('bottom'); });
var navli = document.getElementsByTagName("ul");
for (var i = 0; i < navli.length; i++) {
navli[i].addEventListener('click', function() { reveal('top'); });
}
// triggers the effect by calling instance.reveal(direction, callbackTime, callbackFn)
function reveal(direction) {
var callbackTime = 750;
callbackFn = function() {
// this is the part where is running the turning of pages
classie.remove(pages[currentPage], 'page--current');
if ($('.navbar-brand').data('clicked')) {
currentPage = 0;
} else {
currentPage = n;
}
classie.add(pages[currentPage], 'page--current');
};
revealer.reveal(direction, callbackTime, callbackFn);
}
})();
http://bagrattam.com/stackoverflow/PageRevealEffects/
Here is the solution
var n;
$('#navbar a').click(function(){
if($(this).attr('id') == 'a') {
n = 0;
} else if($(this).attr('id') == 'b') {
n = 1;
} else if($(this).attr('id') == 'c') {
n = 2;
} else if($(this).attr('id') == 'd') {
n = 3;
} else if($(this).attr('id') == 'e') {
n = 4;
};
});
var pages = [].slice.call(document.querySelectorAll('.pages > .page')),
currentPage = 0,
revealerOpts = {
// the layers are the elements that move from the sides
nmbLayers : 3,
// bg color of each layer
bgcolor : ['#52b7b9', '#ffffff', '#53b7eb'],
// effect classname
effect : 'anim--effect-3'
};
revealer = new Revealer(revealerOpts);
// clicking the page nav
document.querySelector("#a").addEventListener('click', function() { reveal('top'); });
document.querySelector("#b").addEventListener('click', function() { reveal('top'); });
document.querySelector("#c").addEventListener('click', function() { reveal('top'); });
document.querySelector("#d").addEventListener('click', function() { reveal('top'); });
document.querySelector("#e").addEventListener('click', function() { reveal('top'); });
// triggers the effect by calling instance.reveal(direction, callbackTime, callbackFn)
function reveal(direction) {
var callbackTime = 750;
callbackFn = function() {
classie.remove(pages[currentPage], 'page--current');
currentPage = n;
classie.add(pages[currentPage], 'page--current');
};
revealer.reveal(direction, callbackTime, callbackFn);
}

Displaying different image based on direction of resize

I have two images. I am trying to display one when the browser resizes left, and the other when it resizes right.
function adjustDirection() {
var last_pos_x = window.screenX;
if ( last_pos_x < window.screenX) {
document.getElementById("logo").style.backgroundImage = "url('logoRight.png')";
} else if (last_pos_x > window.screenX) {
document.getElementById("logo").style.backgroundImage = "url('logoLeft.png')";
}
}
window.onresize = adjustDirection;
However, it seems like my function only begins to works if last_pos_x is declared outside of the function, which is clearly wrong because it will only store window.screenX from load.
Any help would be greatly appreciated
Easiest solution is use jQuery. Store the posX value in DOM and retrieve it
HTML
<div id="aaa" data-posx="0"></div>
Javascript
function adjustDirection() {
var last_pos_x = $("#id").attr("data-posx");
$("#id").attr("data-posx",window.screenX);
if ( last_pos_x < window.screenX) {
document.getElementById("logo").style.backgroundImage = "url('logoRight.png')";
} else if (last_pos_x > window.screenX) {
document.getElementById("logo").style.backgroundImage = "url('logoLeft.png')";
}
}
window.onresize = adjustDirection;
New code with just js:
function adjustDirection() {
var last_pos_x = window.screenX;
return function() {
if (last_pos_x < window.screenX) {
document.getElementById("logo").style.backgroundImage = "url('logoRight.png')";
} else if (last_pos_x > window.screenX) {
document.getElementById("logo").style.backgroundImage = "url('logoLeft.png')";
}
last_pos_x = window.screenX;
}
};
var z = adjustDirection();
window.onresize = z;

How to make expand all/collapse all button in this certain script?

i would like to ask for help in a simple task i really need to do at my work (I am a javascript newbie). I made a simple collapsible list with script provided by this guy http://code.stephenmorley.org/javascript/collapsible-lists/ but what i need right now are two simple buttons as stated in the title: expand all and collapse whole list. Do you guys know if something like that can be implemented in this certain script? Please help :)
var CollapsibleLists = new function () {
this.apply = function (_1) {
var _2 = document.getElementsByTagName("ul");
for (var _3 = 0; _3 < _2.length; _3++) {
if (_2[_3].className.match(/(^| )collapsibleList( |$)/)) {
this.applyTo(_2[_3], true);
if (!_1) {
var _4 = _2[_3].getElementsByTagName("ul");
for (var _5 = 0; _5 < _4.length; _5++) {
_4[_5].className += " collapsibleList";
}
}
}
}
};
this.applyTo = function (_6, _7) {
var _8 = _6.getElementsByTagName("li");
for (var _9 = 0; _9 < _8.length; _9++) {
if (!_7 || _6 == _8[_9].parentNode) {
if (_8[_9].addEventListener) {
_8[_9].addEventListener("mousedown", function (e) {
e.preventDefault();
}, false);
} else {
_8[_9].attachEvent("onselectstart", function () {
event.returnValue = false;
});
}
if (_8[_9].addEventListener) {
_8[_9].addEventListener("click", _a(_8[_9]), false);
} else {
_8[_9].attachEvent("onclick", _a(_8[_9]));
}
_b(_8[_9]);
}
}
};
function _a(_c) {
return function (e) {
if (!e) {
e = window.event;
}
var _d = (e.target ? e.target : e.srcElement);
while (_d.nodeName != "LI") {
_d = _d.parentNode;
}
if (_d == _c) {
_b(_c);
}
};
};
function _b(_e) {
var _f = _e.className.match(/(^| )collapsibleListClosed( |$)/);
var uls = _e.getElementsByTagName("ul");
for (var _10 = 0; _10 < uls.length; _10++) {
var li = uls[_10];
while (li.nodeName != "LI") {
li = li.parentNode;
}
if (li == _e) {
uls[_10].style.display = (_f ? "block" : "none");
}
}
_e.className = _e.className.replace(/(^| )collapsibleList(Open|Closed)( |$)/, "");
if (uls.length > 0) {
_e.className += " collapsibleList" + (_f ? "Open" : "Closed");
}
};
}();
It is important to understand why a post-order traversal is used. If you were to just iterate through from the first collapsible list li, it's 'children' may (will) change when expanded/collapsed, causing them to be undefined when you go to click() them.
In your .html
<head>
...
<script>
function listExpansion() {
var element = document.getElementById('listHeader');
if (element.innerText == 'Expand All') {
element.innerHTML = 'Collapse All';
CollapsibleLists.collapse(false);
} else {
element.innerHTML = 'Expand All';
CollapsibleLists.collapse(true);
}
}
</script>
...
</head>
<body>
<div class="header" id="listHeader" onClick="listExpansion()">Expand All</div>
<div class="content">
<ul class="collapsibleList" id="hubList"></ul>
</div>
</body>
In your collapsibleLists.js
var CollapsibleLists =
new function(){
...
// Post-order traversal of the collapsible list(s)
// if collapse is true, then all list items implode, else they explode.
this.collapse = function(collapse){
// find all elements with class collapsibleList(Open|Closed) and click them
var elements = document.getElementsByClassName('collapsibleList' + (collapse ? 'Open' : 'Closed'));
for (var i = elements.length; i--;) {
elements[i].click();
}
};
...
}();

Js and Divs, (even <div> is difference)

I Have find a javascript code that works perfectly for showing a DIV.
but this code works only for showing one div for each page.
i want to include many DIVS for hiding and showing in the same page.
I was try to replace the div id and show/hide span id with a rundom php number for each include, but still is not working.
so how i have to do it?
the JS code:
var done = true,
fading_div = document.getElementById('fading_div'),
fade_in_button = document.getElementById('fade_in'),
fade_out_button = document.getElementById('fade_out');
function function_opacity(opacity_value) {
fading_div.style.opacity = opacity_value / 100;
fading_div.style.filter = 'alpha(opacity=' + opacity_value + ')';
}
function function_fade_out(opacity_value) {
function_opacity(opacity_value);
if (opacity_value == 1) {
fading_div.style.display = 'none';
done = true;
}
}
function function_fade_in(opacity_value) {
function_opacity(opacity_value);
if (opacity_value == 1) {
fading_div.style.display = 'block';
}
if (opacity_value == 100) {
done = true;
}
}
// fade in button
fade_in_button.onclick = function () {
if (done && fading_div.style.opacity !== '1') {
done = false;
for (var i = 1; i <= 100; i++) {
setTimeout((function (x) {
return function () {
function_fade_in(x)
};
})(i), i * 10);
}
}
};
// fade out button
fade_out_button.onclick = function () {
if (done && fading_div.style.opacity !== '0') {
done = false;
for (var i = 1; i <= 100; i++) {
setTimeout((function (x) {
return function () {
function_fade_out(x)
};
})(100 - i), i * 10);
}
}
};
Check out the Fiddle, you can edit code based on your needs ;)
$(function() {
$('.sub-nav li a').each(function() {
$(this).click(function() {
var category = $(this).data('cat');
$('.'+category).addClass('active').siblings('div').removeClass('active');
});
});
});
finaly i found my self:
<a class="showhide">AAA</a>
<div>show me / hide me</div>
<a class="showhide">BBB</a>
<div>show me / hide me</div>
js
$('.showhide').click(function(e) {
$(this).next().slideToggle();
e.preventDefault(); // Stop navigation
});
$('div').hide();
Am just posting this in case someone was trying to answer.

function is undefined in firefox only

ok, the following code works ok in IE7+ and Chrome.
but for some reason, xfade is undefined in firefox
<html>
<body>
<div id="slider"></div>
<script type="text/javascript">
var Klimateka = {
Slider: function () {
// Check if we have a slider div on page
var slider = document.getElementById('slider');
if (slider != null) {
var images = ["slide-image-1.jpg", "slide-image-2.jpg", "slide-image-3.jpg", "slide-image-4.jpg"];
var i = images.length;
while (i) {
i -= 1;
var img = document.createElement("img");
img.src = "images/" + images[i];
slider.appendChild(img);
}
var d = document, imgs = new Array(), zInterval = null, current = 0, pause = false;
imgs = d.getElementById("slider").getElementsByTagName("img");
for (i = 1; i < imgs.length; i++) imgs[i].xOpacity = 0;
imgs[0].style.display = "block";
imgs[0].xOpacity = .99;
setTimeout("xfade()", 3500);
function xfade() {
cOpacity = imgs[current].xOpacity;
nIndex = imgs[current + 1] ? current + 1 : 0;
nOpacity = imgs[nIndex].xOpacity;
cOpacity -= .05;
nOpacity += .05;
imgs[nIndex].style.display = "block";
imgs[current].xOpacity = cOpacity;
imgs[nIndex].xOpacity = nOpacity;
setOpacity(imgs[current]);
setOpacity(imgs[nIndex]);
if (cOpacity <= 0) {
imgs[current].style.display = "none";
current = nIndex;
setTimeout(xfade, 3500);
} else {
setTimeout(xfade, 50);
}
function setOpacity(obj) {
if (obj.xOpacity > .99) {
obj.xOpacity = .99;
return;
}
obj.style.opacity = obj.xOpacity;
obj.style.MozOpacity = obj.xOpacity;
obj.style.filter = "alpha(opacity=" + (obj.xOpacity * 100) + ")";
}
}
}
},
bar: function () {
}
};
Klimateka.Slider();
i have setup a jsfiddler for testing:
http://jsfiddle.net/rTtKh/10/
This might only apply to Firefox:
functions do not hoist when declared inside a child block.
You declare xfade inside the if block, but you are calling it prior to the declaration:
setTimeout(xfade, 3500);
Put the function declaration on top.
You have to do the same with setOpacity inside xfade. <- That is not necessary.
Fix your line that says this: setTimeout("xfade()", 3500); to match your others:
setTimeout(xfade, 3500);
Use setTimeout(xfade, 3500) instead.

Categories