Dynamically check height of an element - javascript

I want to check the height of an element every time the site changes, because of a viewport resize or a click event.
At the moment I'm using the following code:
jQuery(function ($) {
var height = document.getElementById("head").offsetHeight;
var x = document.getElementsByClassName("dropdown-menu");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.top = height + 'px';
}
});
It's possible that the height of "head" changes. So I need to check the actual height if there are any changes at the site/viewport.
Is there a way to do so?

You can check on window resize
$( window ).resize(function() {
//check element height
});

You can use onresize event listener of javascript
var header= document.getElementById("head")
header.addEventListener('onresize', function(){
// do your code here
});

var element = document.getElementById("head"),
height;
function eventHandler () {
height = element.offsetHeight;
console.log(height);
// rest of your code
}
window.addEventListener('resize', eventHandler)
element.addEventListener('click', eventHandler)
You can bind two different event listeners and pass the same function as a callback if you want to share code logic and reduce redundancy.

My solution:
$( window ).ready(function() {
var height = document.getElementById("head").offsetHeight;
var x = document.getElementsByClassName("dropdown-menu");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.top = height + 'px';
}
});
$( window ).click(function() {
setTimeout(function() {
var height = document.getElementById("head").offsetHeight;
var x = document.getElementsByClassName("dropdown-menu");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.top = height + 'px';
}
}, 500);
});
$( window ).resize(function() {
var height = document.getElementById("head").offsetHeight;
var x = document.getElementsByClassName("dropdown-menu");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.top = height + 'px';
}
});
The timeout is for the correct height after the click and an animation.

Related

Unwrap my carousel when resize the browser

$(function(){
var x = $('.my__list').children();
for (var i = 0; i < x.length ; i += 2) {
var windowSize = $(window).width();
if(windowSize < 500) {
x.slice(i,i+1).wrapAll('<div class="'+ i +'"></div>');
}
if(windowSize > 500) {
x.slice(i,i+2).wrapAll('<div class="'+ i +'"></div>');
console.log("test");
}
}
});
I want to unwrap all my list when the browser's width change. At the moment it only change when the user refresh the browser. Thank you.
I get the source from https://codepen.io/Kibs/pen/aNzvBG
I fixed the problem by using a row function from slick and some modification inside slick.js. There is some bug from rows: 2 to rows: 1 when i used it in responsive settings.
I got the answer from here and it works for me:
Slick.prototype.buildRows = function() { ... }
Slick.prototype.cleanUpRows = function() { ... }
and change the if condition from if(.options.rows > 1) to if(.options.rows > 0)
You can hook this up to the window resize event, or in JQuery $(window).resize():
$(function(){
resizeAndWrap(); // Runs once on page load
$(window).resize(function() {
resizeAndWrap(); // Runs everytime window is resized
});
});
function resizeAndWrap() {
var x = $('.my__list').children();
for (var i = 0; i < x.length ; i += 2) {
var windowSize = $(window).width();
if(windowSize < 500) {
x.slice(i,i+1).wrapAll('<div class="'+ i +'"></div>');
}
if(windowSize > 500) {
x.slice(i,i+2).wrapAll('<div class="'+ i +'"></div>');
console.log("test");
}
}
}
Here is the codepen example with my changes

Setting data type value to an element when it reaches the top of the viewport

I have a hex colour value stored on each section and when a section reaches the top of the screen (-180px for the header) I want to assign a css property to the header element in order to change the text colour as you scroll through the sections. I am not getting any errors and I am having trouble debugging this issue.
http://www.amypreston.co.uk/
$(window).load(function() {
var $header = $("header");
var numberOfSections = $("section").length;
var sectionOffsets = [];
var sectionColour = $("section").eq(i).data("colour");
for(var i = 0; i < numberOfSections; i++) {
sectionOffsets.push($("section").eq(i).offset().top);
}
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
for(var i = 0; i < numberOfSections; i++) {
if(scrollTop > sectionOffsets[i] - 180) {
$header.css('color', 'sectionColour');
}
}
});
});
I dont know if it happened by accident, but the line
var sectionColour = $("section").eq(i).data("colour");
is out of place. it uses a variable i which is only defined in the window scroll handler.
notice that you need to retrieve the section color each time the scroll handler runs, and not only on window load. you need to place this line from above in the loop inside the scroll handler.
Plus, as stated on the comments, you need to use the sectionColour as a variable, and not as a string like you do now. the single quote marks must be removed, so 'sectionColour' turns into sectionColour.
here is your fixed code:
$(window).load(function() {
var $header = $("header");
var numberOfSections = $("section").length;
var sectionOffsets = [];
for(var i = 0; i < numberOfSections; i++) {
sectionOffsets.push($("section").eq(i).offset().top);
}
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
for(var i = 0; i < numberOfSections; i++) {
if(scrollTop > sectionOffsets[i] - 180) {
var sectionColour = $("section").eq(i).data("colour");
$header.css('color', sectionColour);
}
}
});
});
On a side note, you could shorten your code into this:
$(window).scroll(function () {
$("section").each(function () {
if ($(window).scrollTop() > $(this).offset().top - 180) {
$("header").css('color', $(this).data("colour"));
}
});
}).scroll();

get interval ID from else statement when set in IF

I am attempting to create a responsive slider, that will change to a simple set of dot points when in mobile mode (< 940).
The issue I am facing is in my else statement I am unable to clearintervals that were made in the if statement, because t comes up as undefined. I have resorted to using
for (var i = 1; i < 99999; i++) window.clearInterval(i); to clear the interval which works, but I don't like it because it's ugly and cumbersome, is there another way of accomplishing this?
$(document).ready(function() {
function rePosition() {
//get responsive width
var container_width = $('.container').width();
//Slider for desktops only
if(container_width >= 940) {
//get variables
var slide_width = $('.slider_container').width();
var number_of_slides = $('.slider_container .slide').length;
var slider_width = slide_width*number_of_slides;
//set element dimensions
$('.slide').width(slide_width);
$('.slider').width(slider_width);
var n = 1;
var t = 0;
$('.slider_container').hover(function() {
clearInterval(t);
}, function() {
t = setInterval(sliderLoop,6000);
});
var marginSize = i = 1;
//Called in Doc Load
function sliderLoop(trans_speed) {
if (trans_speed) {
var trans_speed = trans_speed;
}
else
{
var trans_speed = 3000;
}
if (i < number_of_slides) {
marginSize = -(slide_width * i++);
}
else
{
marginSize = i = 1;
}
$('.slider').animate({ marginLeft: marginSize }, trans_speed);
}
t = setInterval(sliderLoop,6000);
$('.items li').hover(function() {
$('.slider').stop();
clearInterval(t);
var item_numb = $(this).index();
i = item_numb;
sliderLoop(500);
}, function() {
t = setInterval(sliderLoop,6000);
});
}
else
{
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
$('.slider').stop(true, true);
$('.slider').css('margin-left', '0px');
//rearrange content
if($('.slider .slide .slide_title').length < 1) {
$('.items ul li').each(function() {
var item_numb = $(this).index();
var content = $(this).text();
$('.slider .slide:eq(' + item_numb + ')').prepend('<div class="title slide_title">' + content + '</div>')
});
}
}
}
rePosition();
$(window).resize(function() {
rePosition();
});
});
Teemu's comment is correct. I'll expand on it. Make an array available to all of the relevant code (just remember that globals are bad).
$(document).ready(function() {
var myIntervalArray = [];
Now, whenever you create an interval you will need to reference later, do this:
var t = setInterval();//etc
myIntervalArray.push(t); //or just put the interval directly in.
Then to clear them, just loop the array and clear each interval.
for (var i=0; i<myIntervalArray.length; i++)
clearInterval(myIntervalArray[i]);
}
Umm, wouldn't t only be defined when the if part ran... as far as I can tell, this is going to run and be done... the scope will be destroyed. If you need to maintain the scope across calls, you'll need to move your var statements outside of reposition(), like so:
$(document).ready(function() {
var t = 0;
...
function rePosition() { ... }
});

Calculate largest width of a set of elements using jQuery

I have made a quick Jsbin: http://jsbin.com/ujabew/edit#javascript,html,live
What i'm trying to achieve is to find out which is the largest <section> out of the 3 from the link. So what i'd like is to, after the loop runs, is to have var width set to the largest possible number that any of the widths could be.
Code in progress posted in link
Here:
var maxWidth = Math.max.apply( null, $( elems ).map( function () {
return $( this ).outerWidth( true );
}).get() );
Live demo: http://jsfiddle.net/rM4UG/
Fleshing out Marc B's comment, using Math.max():
$(document).ready(function(){
var maxWidth = 0;
$('.content ul li').each(function(){
var itemWidth = $(this).outerWidth(true);
maxWidth = Math.max(maxWidth, itemWidth)
});
});
I believe you want to look into the underscore library. Specifically, the max method
$(document).ready(function(){
var maxWidth = 0;
$('section').each(function(){
w = $(this).outerWidth(true);
if ( w > maxWidth)
maxWidth = w;
});
});
Change the .each() loop to this:
var thisWidth = $(this).outerWidth(true);
if (thisWidth > width) {
width = thisWidth;
}
I have just written a function regarding this. I thought it might help others. (jQuery)
$.fn.largerWidth = function () { //function(p)
// where 'p' can be clientWidth or offsetWidth
// or anything else related to width or height
var s = this,m;
for (var i = 0; i < s.length; i++) {
var w = s[i].offsetWidth; // s[i][p];
(!m || w > m) ? (m = w) : null
}
return m;
}
This was my idea:
$(document).ready(function () {
var elements = $(".content ul li");
var count = elements.length - 1;
var width = [];
elements.each(function (n) {
width.push($(this).outerWidth(true));
if (count == n) {
width = Math.max.apply(Math, width);
}
});
});
I added the count of the number of elements and then runs the Math.max to get the largest number when each loop is done.

Use JavaScript to alter width of a div

I have some JavaScript code and a button which already has an event/action assigned to it, and I want to add a second event to the button. Currently the relevant bit of code looks like this:
events: {onclick: "showTab('"+n+"')"},
How do I amend this code so that it also increases the 'width' property of a div with class='panel', by a fixed amount e.g. 50px?
EDIT:
I understand. Problem is I don't know how to change id, only classname. The div is constructed in JavaScript using buildDomModel as follows:
this.buildDomModel(this.elements["page_panels"],
{ tag: "div", className: "tab_panel",
id: "tab_panel",
childs: [...]}
)
But the id doesn't get changed to 'tab_panel'. HOWEVER, classname does get changed to 'tab_panel' which is why i tried to use getelementbyclass. So the div has no id and I don't know how to create one using the buildDomModel but I can give unique class. I have put the code in original post too.
This:
events: {onclick: "showTab('"+n+"'); $('div.panel').width('50px');"},
Or you might want to add below line to showTab function.
$('div.panel').width('50px');
Update:
Or you can do with vanilla javascript:
function setWidth()
{
// since you are using a class panel, means more than one div, using loop
var divs = document.getElementsByTagName('div');
for(var i = 0; i < divs.length; i++)
{
// check if this div has panel class
if (divs[i].getAttribute('class') === 'panel')
{
// set the width now
divs[i].setAttribute('width', '50px');
}
}
}
Or if you want to apply the width to just one specific div, give that div an id and use this function instead:
function setWidth()
{
var div = document.getElementById('div_id');
div.setAttribute('width', '50px');
}
And later use it like this:
events: {onclick: "showTab('"+n+"'); setWidth();"},
Or you might want to add below line to showTab function.
setWidth();
Update 2:
Ok modify the function like this:
function setWidth()
{
var divs = document.getElementsByTagName('div');
for(var i = 0; i < divs.length; i++)
{
// check if this div has panel class
if (divs[i].getAttribute('class') === 'tab_panel')
{
// get previous width
var prevWidth = getComputedWidth(divs[i]);
// set the width now
divs[i].setAttribute('width', (prevWidth + 50));
}
}
}
function getComputedWidth(theElt){
if(is_ie){
tmphght = document.getElementById(theElt).offsetWidth;
}
else{
docObj = document.getElementById(theElt);
var tmphght1 = document.defaultView.getComputedStyle(docObj, "").getPropertyValue("width");
tmphght = tmphght1.split('px');
tmphght = tmphght[0];
}
return tmphght;
}
Note that with jQuery it should be this code in all:
function setWidth(){
jQuery('.tab_panel').each(function(){
jQuery(this).attr('style', 'width:' + (jQuery(this).width() + 50));
});
}
instead of the function you can use this line of JQuery code:
$('div.tab_panel').attr('style',"width:100px");
any way if you dont want it to be JQuery then this function should work :
function setWidth() {
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
// check if this div has panel class
if (divs[i].getAttribute('class') === 'tab_panel') {
// set the style now
divs[i].setAttribute('style', 'width:100px');
}
}
}
putting width attribute to div wouldnt work, you need to set its style,
so i expect any of the code i provided to work.
oh no the one i sent early just set width to a new value
this one should fix your problem :
var x = $('div.tab_panel')[0].style.width.replace("px", "");
x = x + 50;
$('div.tab_panel').attr('style', "width:" + x + "px");
ok here is a non JQuery Version :
function setWidth() {
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
if (divs[i].getAttribute('class') === 'tab_panel') {
var x = divs[i].style.width.replace("px", "");
x = x + 50;
divs[i].setAttribute('style', 'width:' + x + 'px');
}
}
ok here it is :
JQuery:
function Button1_onclick() {
var x = $('div.tab_panel')[0].clientWidth;
x = x + 50;
$('div.tab_panel').attr('style', "width:" + x + "px");
}
non JQuert:
function setWidth() {
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
if (divs[i].getAttribute('class') === 'tab_panel') {
var x = divs[i].offsetWidth;
x = x + 50;
divs[i].setAttribute('style', 'width:' + x + 'px');
}
}
}
this should work

Categories

Resources