Set height of a div in vue js - javascript

I am using vue js . I want to set one div based on another div height, with pure javascript. the problem I am facing is I can't set the height using pure java script. but I can set it using jquery. can any one please help me to change this jquery to javascript . the code I am using is given
Vue.nextTick(function () {
var offsetHeight = document.getElementById('filterSection').offsetHeight;
$(".searchResultSection").css("max-height",`calc(100% - ${offsetHeight}px)`);
});
I need to change the jquery part into java script.

In fact, computed properties (https://v2.vuejs.org/v2/guide/computed.html#Computed-Properties) is the perfect option to solves your problem:
Declare a computed property who will return the filterSectionHeight
export default {
name: "App",
computed: {
filterSectionHeight() {
const filterSectionDOM = document.getElementById("filterSection");
return filterSectionDOM ? filterSectionDOM.offsetHeight : 0;
},
}
};
Define your div filterSection and searchResultsSection in your component (or App component), don't forget to add a :style attribute who handle the dynamic max-height provided to .searchResultsSection in your template
<div id="filterSection"></div>
<div class="searchResultsSection"
:style="{
'max-height': `calc(100% - ${filterSectionHeight}px)`
}">
</div>
Set height of each div to 100% in your css
#app {
height: 600px;
width: 100%;
}
#filterSection {
height: 100%;
background: rebeccapurple; //https://en.wikipedia.org/wiki/Eric_A._Meyer
}
.searchResultsSection{
height: 100%;
background: rebeccapurple;
opacity: 0.6;
}
You will find a full demo here > https://codesandbox.io/s/1rkmwo1wq

Not sure about the context of this change, but I'll try to give you some solutions based on best practices on how to achieve that:
If parent element has a fixed height, then children with height: 100% will adopt parents height.
.parent {
height: 200px;
}
.child {
height: 100%;
}
Use a vue-directive for DOM manipulation: https://v2.vuejs.org/v2/guide/custom-directive.html
Use v-bind:style="height: calc(100% - ${offsetHeight}px)\" on the element that you want to achieve the height!

You need to use the javascript DOM-style to do this.
Try this.
Vue.nextTick(function () {
var offsetHeight = document.getElementById('filterSection').offsetHeight;
var x = document.getElementsByClassName("searchResultSection");
x[0].style.maxHeight = "calc(100% - ${offsetHeight}px)";
});

Related

Get target style from Javascript while transitioning

During a transition, is there a way to see what the target value is for a style rule which is under transition? window.getComputedStyle gets the interpolated value, and element.style only looks at the style attribute (I think).
Here's a demo of the problem;
I'd like to retrieve the target height value of 1200px during the transition:
https://jsfiddle.net/EoghanM/xz5s3ua6/5/
setInterval(function() {
document.body.children[0].innerHTML = getComputedStyle(document.body.children[0])['height']
}, 300)
setTimeout(function() {
document.body.children[0].classList.toggle('changing')
}, 1000)
div {
height: 400px;
border: 1px solid red;
width: 200px;
transition: height 100s linear;
}
div.changing {
height: 1200px;
}
<div></div>
How about using getComputedStyle on a new instance of changing class?
You can create a div with the class changing and then use getComputedStyle to get the class properties (considering that the height of changing class will be the final height after the transition of your div) like this:
<div class="changing" id="new-changing-div"></div>
and get it's properties:
const element = document.querySelector('#new-changing-div');
const heightAttribute = window.getComputedStyle(element).getPropertyValue('height');
I'm 99% sure all of the DOM properties and methods for requesting the element's height (clientHeight, offsetHeight, getBoundingClientRect, etc.) will only give you the interpolated value. Another solution may be to read the value from the CSS stylehseet itself using the CSSOM.
In the code below, we search through the document's stylesheets checking if the selector exists in a rule declaration and if it does, return the value of the property we're looking for. You can console.log() various parts of the stylesheets and rules below to see how the browser stores the information as objects.
Of course this is a simple example based on a simple test case. There could be multiple rules using the same selector, but this will only find the first occurrence. The solution would need to be more robust to find the exact rule you're looking for.
function getCssRuleValue(selector, property) {
const styleSheets = document.styleSheets;
let styleSheetsLen = styleSheets.length;
while (styleSheetsLen--) {
const styleSheet = styleSheets[styleSheetsLen];
const rules = styleSheet.rules;
let rulesLen = rules.length;
while (rulesLen--) {
const rule = rules[rulesLen];
// The passed-in selector text is found in the rule text
if (rule.cssText.indexOf(selector) > -1) {
return rule.style[property];
}
}
}
// The selector/property was not found in any document stylesheets
return -1;
}
setInterval(function() {
document.body.children[0].innerHTML =
getComputedStyle(document.body.children[0])['height']
+ '<br>' +
getCssRuleValue('.changing', 'height')
}, 300)
setTimeout(function() {
document.body.children[0].classList.toggle('changing')
}, 1000)
div {
height: 400px;
border: 1px solid red;
width: 200px;
transition: height 100s linear;
}
div.changing {
height: 1200px;
}
<div></div>

JavaScript on click change width by class

If I click a button I can assign it a function like bellow
document.getElementById("mySidenav").style.width = "250";
This works fine, however I wish do give it a different width for different screen sizes so I was going to set the width in a class so that i can use a css media query.
instead of .style.width = "250";how can I tell it to take the values of a CSS class instead ?>
Just for reference, CSS names cannot start with digits, per the W3C spec. Your edited post removes the need for this comment but it's worth noting.
To manipulate classes via JavaScript, either use className (as in myElement.className = 'some-class') or the classList interface. However, you specifically mentioned "different screen sizes" and this is a prime candidate for responsive CSS queries using the #media selector.
With all that being said:
JavaScript example
// CSS
#mySidenav {
width: 1000px;
}
#mySidenav.responsive-class {
width: 500px;
}
// JS
const mySidenav = document.querySelector('#mySidenav');
window.addEventListener('resize', function() {
if (window.innerWidth < 200) {
mySidenav.classList.add('responsive-class');
}
else {
mySidenav.classList.remove('responsive-class');
}
});
CSS example
#mySidenav {
width: 1000px;
}
#media query and (max-width: 200px) {
#mySidenav {
width: 500px;
}
}
As you can see, the latter example is much simpler. Go with the CSS approach. A halo will appear over you.
I used #Shenh's answer to work out a solution +1 Sheng.
Please see bellow I added new class and removed class
function openNav() {
document.getElementById("mySidenav").classList.add('popoutwidth');
}
function closeNav() {
document.getElementById("mySidenav").classList.remove('popoutwidth');
}

It is possible to load a CSS class into a Javascript/Jquery variable?

Im new in javascript/Jquery and I was wondering if is possible to load an existing css class into a variable to use it later.
Example:
/* CSS */
.view {
position: absolute;
height: 214px;
width:1964px;
padding:2px;
}
And in a javascript File load into a variable to use it like this:
//Javascript
var view = load(".view");
view.width // I get 1964px
view.height // I get 214px
Thanks.
You have to use the jQuery like this:
var view = $('.view');
Then you can iterate over all elements with the class view.
Do it by:
$.each(view, function(){
// then you can get all the width and height elements
// to use them, put them in an object or in an array
})
I'm not sure why you would do this unless you are amending HTML elements, but could you use getComputedStyle? Please note I am using good old JS here not jQuery...
/* CSS */
.view {
position: absolute;
height: 214px;
width:1964px;
padding:2px;
}
and in your JS
//Javascript
window.onload = function () {
var view = document.querySelector('.view'),
styles = getComputedStyle(view);
console.log(styles.width);
console.log(styles.height);
}
More info here
I haven't tested this but this is how I would go about it...

Why is the scrollWidth of a valid text area undefined?

I have found many answers suggesting I use scrollWidth and scrollHeight to get the content width and height, respectively, of a text area. However, my code returns the scrollWidth as undefined. Any idea why this could be the case?
function changewidth(o) {
if ($(o).val().length>8)
{
var current = $(o).css("width");
console.log($(".name").scrollWidth+'px');
$(o).css("width",$(".name").scrollWidth+'px');
}
}
And this javascript function is being called by this text area:
<textarea rows="1" onkeyup="changewidth(this)" class="name" type="textarea" placeholder="name"></textarea>
The console prints undefinedpx. Based on research, I have tried to alter the CSS and currently have the following:
.name {
width: 100px;
margin: 0;
padding: 0;
border: none;
font-size: 20px;
color: #00B45E;
resize: none;
overflow: hidden;
}
You have to try this, No need to wrap currently passed object into $() unless you need it.
function changewidth(o) {
if ($(o).val().length > 8) {
var current = $(o).css("width");
console.log(o.scrollWidth + 'px'); // o.scrollWidth
$(o).css("width", o.scrollWidth + 'px'); // use object as o direclty
}
}
With pure Javascript
function changewidth(o) {
if (o.value.length>8)
{
var current = o.style.width;
console.log(o.scrollWidth+'px');
o.style.width = o.scrollWidth+'px';
}
}
Fiddle
With pure javascript
Demo
scrollWidth
scrollWidth only applies to plain Javascript, it seems you are using it on jQuery.
instead of $(".name").scrollWidth try changing it to document.getElementsByClassName("name").scrollWidth

Why are "fadeIn" and "fadeOut" functions moving my divs?

I'm starting a new website and I'm using JQuery for display a div inside another (a title). I have 4 divs displayed inline-block and my result need to be like this :
I'm using Jquery for display the div containing "Accueil" with the function fadeIn and fadeOut but my problem is the following : When the move is over a div, the hidden div is animated and fade in like desired but the other div (on the right) is moving down !
My html is the following :
The left box :
<div class="box-interactive box-interactive1">
<div class="contenu-box">
titi 1
</div>
<div id="bandeau1" class="bandeau">
rr
</div>
</div>
The right box :
<div class="box-interactive box-interactive2">
<div class="contenu-box">
titi 2
</div>
<div id="bandeau2" class="bandeau" style="display : block;">
accueil 2
</div>
</div>
My css :
/*CSS for boxes and interactive text*/
.box-interactive {
width: 300px;
height: 200px;
background-color: red;
margin: 20px;
display: inline-block;
size: fixed;
}
.contenu-box{
width: 300px;
height: 160px;
}
.bandeau {
width: 300px;
height: 40px;
background-image: url("../../img/Alex/accueil.png");
background-size: auto 100%;
position: relative;
display: none;
}
And my JS :
$(function(){
$("div[class^='box-interactive']").hover(
function(){
var id = new Array;
id = $(this).attr('class').split(' ');
for (var i in id) {
if(id[i].match('box-interactive.+')){
var idnum = 'bandeau'+id[i].substring(15);
$("#"+idnum+"").fadeIn(800);
}
}
},
function(){
var id = new Array;
id = $(this).attr('class').split(' ');
for (var i in id) {
if(id[i].match('box-interactive.+')){
var idnum = 'bandeau'+id[i].substring(15);
$("#"+idnum+"").fadeOut(500);
}
}
}
);
});
The second div (it works in both ways) is moving down with specificities : the top of the moving div is equal to the bottom of the first div (the one befor the hidden). Do you have an explaination ?
Fiddle : http://jsfiddle.net/Msh2T/1/ open large the right window to see the problem ;) thx
fadeIn and fadeOut will set an element to "display: none" once the animation completes, removing it from the layout. If you don't want the animation to affect the layout, animate the opacity.
$("#"+idnum+"").animate({opacity: 0}, 800);
...
$("#"+idnum+"").animate({opacity: 1}, 800);
You can float the .bandeau divs so that they aren't affecting the inline layout flow, effectively limiting their scope to the parent div.
.bandeau {
width: 300px;
height: 40px;
background-image: url("../../img/Alex/accueil.png");
background-size: auto 100%;
position: relative;
display: none;
float: left; /* ADD THIS */
}
Fiddle: http://jsfiddle.net/Msh2T/3/
One option would be to animate the opacity either to 1 or to 0 instead of using fadeIn and fadeOut:
$("#"+idnum+"").animate( { opacity:1 }, 800 );
and
$("#"+idnum+"").animate( { opacity:0 }, 500 );
Here's a working fiddle to demonstrate this approach.
A few other notes about the code...
First, your hover-in and hover-out functions are nearly identical. Any time you have that much code that is so similar, it's a very good idea to combine it into a single function.
Where you have this code:
var id = new Array;
id = $(this).attr('class').split(' ');
it's unnecessary to have the new Array, since you are just replacing the value in the next line. Also, I recommend using a plural name for an array instead of a singular name:
var ids = $(this).attr('class').split(' ');
The next line is:
for (var i in id) {
Never use a 'for..in' loop on an array. It will bite you if anyone ever augments Array.prototype with new methods or properties. Instead, use a numeric for loop or an iterator such as jQuery's $.each().
Next is this code:
if(ids[i].match('box-interactive.+')){
var idnum = 'bandeau'+id[i].substring(15);
...
When you use .match to test a string like this, you can also use it to extract the part of the string you want, without resorting to a brittle-to-maintain .substring(15) call:
var match = ids[i].match( /box-interactive(.+)/ );
if( match ) {
var idnum = 'bandeau' + match[1];
...
Now having said all this, why not simplify things much further and let jQuery do all the work for you? There's no need for any of this fancy array looping and checking of classnames. You can replace the entire JavaScript code with this:
$(function(){
$("div[class^='box-interactive']").hover(
function(){
$(this).find('.bandeau').animate( { opacity:1 }, 800 );
},
function(){
$(this).find('.bandeau').animate( { opacity:0 }, 500 );
}
);
});
Updated fiddle
(You may note that I've contradicted my first piece of advice here and didn't combine the bit of duplicate code in the hover-in and hover-out functions. But there's now so little code that that the duplication isn't worth worrying about.)
Try using z-index in your CSS to stack your divs on top of each other

Categories