How can i add/remove class according as div width ? I tried some codes but I have no idea about jquery codes. I'd like add div class according as antoher div width. Just i need add class like that. If container is smaller than 600px "add class" to content div else "remove class" from content div. These are my codes;
<div class="container">
<div class="content"></div>
</div>
$(window).resizeboxes(function() {
if ($(".container").width < 600){
$( ".content" ).addClass( ".content_600" );
}
});
else{
removeClass('.content_600')
}
$(window).trigger('resizeboxes');
This works, though the code is changed slightly. There were some problems with the syntax also, so I've corrected those (for instance the else statement was slightly misplaced). Here is a working example:
https://jsfiddle.net/vt0nbx36/3/
Here is the code:
var resizeboxes = function() {
if ($(".container").width() < 600)
{
$(".content").addClass("content_600");
}
else
{
$(".content").removeClass("content_600")
}
};
resizeboxes();
$(window).resize(function(){
resizeboxes();
});
For this need exactly, you have jQuery's .toggleClass() function. It takes the class name as a first parameter, and optional second boolean parameter that states wether the class name should be added or removed. You can find the documentation here
$(".content").toggleClass("content_600", ($(".container").width() < 600));
Even tho your question is a JS related question, CSS as a matter of fact can handle this like no other beast can (mostly)!
CSS allows you to use media-queries to resize your content based on the width of the viewport.
The upside of this is that the browser will handle this for you within the rendering engine rather than having JS between your change and the rendering engine.
The major downside is that you can't define the width of element A based on element B but are unfortunately locked to using the viewport as an indicator.
Before I explain why you'd want to use CSS I'd like to point out why you don't want to use JS for this if possible.
The jQuery.resize eventhandler fires inconsistently across browsers and it fires alot of times usually.
This causes your scrolling to clog up and make your webpage feel laggy.
If there's anything your users will dislike it's the fact that scrolling is controlled by something they don't even know of which is slowing you down.
As for a CSS solution, a media query looks like this:
.my-selector {
width: 900px;
}
#media all and (max-width: 600px) {
.my-selector {
width: 600px;
...
}
}
You wrap your code in a sort-of conditional that allows you to be very flexible with manipulating elements on the page.
What happens in the above piece of code is that when the parser reads the CSS it sees the first selector not in a media query so it applies width: 900px; then it sees a media query and sees the other rule for my-selector however it will only apply that rule when the screen is at that width we defined in the #media ... rule. When you resize CSS handles things differently behind the scenes so it's much faster than JS in that case.
I'm not sure if it actually applies to your situation but if your container is sized by the viewport rather than parent elements this should be possible and I thought it'd be nice atleast to show you a good way of playing with element dimensions.
Also, you can use #media to for instance make a webpage print friendly by changing the all to print for example and setting the background-color: transparent for an element - saves ink ^.^ which is an additional extra on top of the general awesomeness of media queries.
Hope it helps, good luck if you wish to make your webpage 5 times faster ;)
Related
I am adding an element in the dom using javascript. I have added an using insertBefore() to place it where I want it on the mobile view. But in desktop it is supposed to be placed on a different space on the website. How can i solve this?
Just using CSS is not an option due to already existing elements that i cant't move.
var priceWrapper = document.querySelector('.price-info-wrap')
var mainContainer = document.querySelector('.price-info')
var addUrgency = document.getElementById('urgency')
priceWrapper.insertBefore(addUrgency, mainContainer)
The code provided is how I have placed "addUrgency" witch is the div I need to put elsewhere on desktop.
You can do it, but it's a bad idea.
Lay out your elements starting with smallest screen width you need, then work outwards from there using CSS Media queries to adjust the layout at specific screen widths as and when you need to.
In this case, if you can't do it any other way you could have both elements where you like them and then show/hide depending on the viewport width. Something like:
#media (min-width:800px) {
//your non-mobile styles and classes go here
.desktop-element{
display: inline-block;
}
.mobile-element{
display:none;
}
}
You could use navigator.userAgent and determine if the browser is a mobile browser. There is also an question with really good answeres on doing that on StackOverflow: Detecting a mobile browser
Another option is to check the viewport-size with javascript. Which can be a better solution in the case you have css-rules in place that are responsive to the viewport-size , like: #media (width):
let width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
After that it is a simple if-else to decide where to place your element.
You can use the onresize event. But, I have to note, that having two identical elements (perhaps using clone() to copy #addUrgency) in the DOM on their right places and display/not display them using CSS media queries instead of using Javascript to re-lay elements every time the viewport is resized is a better solution. However, to answer your question here is the most straightforward approach using your code. It also worth to note, that resize event can fire pretty fast, so you probably will want to throttle the function relay (answers are on StackOverflow).
function relay(){
var addUrgency = document.getElementById('urgency');
if(`mobile view`){ //here goes a condition to determine what view you have.
var priceWrapper = document.querySelector('.price-info-wrap');
var mainContainer = document.querySelector('.price-info');
priceWrapper.insertBefore(addUrgency, mainContainer);
}else{
// Insert where you want it on desktop view
}
}
window.onload = function() {
relay();
document.body.addEventListener("resize", relay);
};
You could do this using JavaScript but I wouldn't recommend this approach as I believe this is achievable in most cases with plain HTML and CSS. One method would be using display: grid and placing the elements in the desired rows/columns on mobile (If you are of course utilizing a mobile-first approach) and then redistributing them on larger screens with media queries. Additionally, you could of course make use of position: absolute whenever this strategy does not completely do the job.
Here is a great article, in case you are not completely familiar with display: grid.
Evernote places a max-width limit on web view content, and I have identified its location in Chrome developer tool(F12). Evidence: Unticking the checkbox beside "max-width" will stretch the table to full window width.
My question is, how can I remove that css statement with JavaScript code?
I have tried this:
document.getElementById("container").style.removeProperty("max-width")
but in vain.
The above web page can be reached at http://www.evernote.com/l/ABXYD6q6bM9MyaAfRs78hQnq6VMINfVJODg/
Given that this statement isn't set as inline style, you won't be able to remove it.
However, you could change its value and set it to none by adding an inline style declaration, which will override the current value.
Demo:
var elem = document.getElementById('container');
elem.style.maxWidth = 'none';
Not sure how webview works, but could you try using javascript to add a new class to it that added a max-width of 100%?
document.getElementById("container").classList.add('no-max-width');
then in the styles.css put
.no-max-width {
max-width: 100%; }
If that's not possible, then try
document.getElementById("container").style.maxWidth('100%');
Though I sometimes have trouble with .styles so not sure if that is exactly right, plus I've read it's better to add classes rather than play with css styles in JS, but also not sure how accurate that is.
So Im trying to change the width of a specific element in real time. Meaning that as you scale the browser window, the element changes width along with it.
Now, the way im calculating this width is by using another element as a reference point. So i just basically copy the reference element's width and apply it to my own element. However the problem is that this is only applied after every page refresh instead of a real time change.
Im using the following jquery code:
$("#lists ul").css("width", $("#lists").width());
As you can see, the code is pretty simple. #lists ul is the elements whose width I am attempting to change and #lists is the reference element. My question is, is there a way to achieve this effect? or should I use a different approach? thanks for the help!
No need to use JavaScript to adjust widths. This should be all you need:
#lists ul { width: 100%; }
What you're trying to do sounds crazy. As others have pointed out, using a percentage in CSS is probably much smarter.
If you insist on doing it this way though... I'm guessing your event is firing within $(document).ready(). Instead, try this.
$(window).resize(function(){
$("#lists ul").css("width", $("#lists").width());
});
You can use a combination of JavaScript and CSS. I don't know what your specific needs are, but you can easily set the width of an object like this:
var element=document.getElementById("my_element");
element.style.width=10+"px";// Simple as that.
If you just want to scale your element based on its parent element's size, this is best done with CSS percent width and height.
CSS:
#my_element{
width:20%;
}
Then CSS takes care of all your scaling needs whenever the parent element is resized.
CSS by itself may not look like what you want it to be, but if you make sure to define all applicable CSS properties of your element (like margin, padding, border, etc...) and then bolster the layout with JavaScript, you can do quite a bit.
I have a list of divs in which I display the preview of longer documents. The documents use varying font styles. So I don't have a constant line height. Here is an example: http://jsfiddle.net/z56vn/
I need to only show the first few lines of each document. We've determined that 300px is about right. If I simply set a max-height of 300px to the divs, then depending on text properties (size, padding, margin) the bottom of last line gets clipped.
How can I set a max-height for each block that will be close to 300px but that will not cause clipping?
The solution can use CSS, Javascript and jQuery.
Those two questions are similar but their solutions assume a constant line height.
Show first 3 lines in html paragraph
Show first line of a paragraph
The algorithm to calculate all the factors perfectly using only javascript would be too complex.
With css3 there is line-clamp
But this works only on modern browsers.
p{
margin:20px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
DEMO
http://jsfiddle.net/MM29r/
this allows you to set the number of lines you want to display before adding the 3 dots.
now you want 300px... so:
var p=document.getElementsByTagName('p')[0],
lineheight=parseInt(window.getComputedStyle(p).getPropertyValue("line-height"));
var lines=Math.floor(300/lineheight);
p.style['-webkit-line-clamp']=lines;
so this gives you an element that is 300px or less
DEMOS
http://jsfiddle.net/MM29r/1/
http://jsfiddle.net/MM29r/2/
NEEDED VALUES: line-height
Now if you want to make the box exactly 300px height just add margins or paddings to the paragraphs.But that depends on your preferences.
if you have some questions just ask.
Note
every js function that adds 3 dots at the end by calculating the words would be to resources intensive to apply in a real world website.
a better approach would be to calculate every paragraph one time and add the clamped result to a db or store it in the static website.
but then again every browser displays fonts in a different way.
EDIT
Here is a different way to display partial content.
Using max-height & -webkit-column-count
https://stackoverflow.com/a/20691677/2450730
DEMO
http://jsfiddle.net/HNF3d/10/
the support is slightly higher than line-clamp and you are abe to display the whole content.
EDIT2
Fading image at the bottom.
p{
width:300px;
max-height:300px;
overflow:hidden;
}
p:before{
content:"";
display:block;
position:absolute;
margin-top:240px;
background:-webkit-linear-gradient(top,rgba(255,255,255,0) 0%,rgba(255,255,255,1) 80%);
height:60px;
width:300px;
}
http://jsfiddle.net/MM29r/9/
EDIT3
fading image old browsers (use real images links, not base64)
http://jsfiddle.net/MM29r/13/
One alternative is to use the dotdotdot jQuery plugin.
Its used like
$("div.text_element").dotdotdot({
ellipsis : "...",
wrap : "word"
});
This way, you can just concern yourself with the div dimensions rather than line height or other CSS attributes. Also, it allows you to trigger events to show and hide the hidden text.
You should look for line clamping techniques
A list of them can be found here http://css-tricks.com/line-clampin/
As you can see the above link explains various methods to achieve line clamping, but only one of them is truly a cross browser solution. There seems to be a javascript library that solves this problem exactly, and it works even if you use various font sizes or styles
Clamp.js [ https://github.com/josephschmitt/Clamp.js ]
Here is an example
var paragraph = document.getElementById("myParagraphId");
$clamp(paragraph, {clamp: 3});
You could definitely use Clamp.js, which is a JavaScript plugin created by Joseph Schmitt. The minified version of the code can be found here.
You could then use it like this:
var elem = document.getElementsByTagName("div");
for(var z=0;z < elem.length; z++){
$clams(elem[z], {clamp: '300px'});
}
Alternatively, you could use getElementsByClassName if not all your <div>s needed clamping.
Here what I would do in this case;
First we have to get the div and find out the line-height so I am assuming you got your div as jQuery object.
var $divToClamp = $("#");
var $cloneDiv = $divToClamp.clone();
$divToClamp.insertAfter($cloneDiv.html("A"));
// created a new div as same place with the div to get same css, from parents, class etc.
// i don t know how jQuery handles the ids you must check that
var lineHeightToClamp = $cloneDiv.height() * 3;
$cloneDiv.remove();
// remove the clone we are done with it this does not work create clone div as fixed position back of the actual div and visibility hidden (not display:none)
//now we now the line-height for 3 lines set the css
$divToClamp.css({
overflow : "hidden",
lineHeight: lineHeightToClamp
});
some thing similar to this should fix you case but there might be some exceptions like margin of the div i am not sure $cloneDiv.height() includes them or not.
also if there is another element (like span) in your div with different css that will also change the situation.
Hope this helps.
I have an interesting problem here. I'm using a class on the element as a switch to drive a fair amount of layout behavior on my site.
If the class is applied, certain things happen, and if the class isn't applied, they don't happen. Javascript is used to apply and remove the class. The relevant CSS is roughly like this:
.rightSide { display:none; }
.showCommentsRight .rightSide { display:block; width:50%; }
.showCommentsRight .leftSide { display:block; width:50%; }
And the HTML:
<body class="showCommentsRight">
<div class="container"></div>
<div class="leftSide"></div>
<div class="rightSide"></div>
</div>
<div class="container"></div>
<div class="leftSide"></div>
<div class="rightSide"></div>
</div>
<div class="container"></div>
<div class="leftSide"></div>
<div class="rightSide"></div>
</div>
</body>
I've simplified things but this is essentially the method. The whole page changes layout (hiding the right side in three different areas) when the flag is set on the body. This works in Firefox and IE8. It does not work in IE8 in compatibility mode. What is fascinating is that if you sit there and refresh the page, the results can vary. It will pick a different section's right side to show. Sometimes it will show only the top section's right side, sometimes it will show the middle.
I have tried:
- a validator (to look for malformed html)
- double checked my css formatting, and...
- making sure my IE7 hack sheet wasn't having an effect.
- putting the flag class on a different, non-body wrapper element (still has the same odd behavior)
So my question is:
- Is there a way that this behavior can be made reliable?
- When does IE7 decide to re-do styling?
Thanks everyone.
Sounds a bit like a problem I've had with ie7, where the DOM is updated but the pixels on screen is not (sometimes hovering the mouse over it triggers redraw). I found a dirty hack that worked in my case (spesudo-javascript):
//Just after changing the css class:
if(isIe7()){
addAnEmptyDivAboveTheChangedElement();
removeTheEmptyDivFromTheDom();
}
For some reason this brutal hack of adding and removing an element (it might even work if you add and remove it anywhere) causes ie7 to repaint the document. It may cause a flicker though and it's an expensive hack since it forces a full repaint in an already slow browser, that's why i only does so if I'm sure it's ie7 (to not slow every other browser just because ie7 is stupid).
Can't promise it will work, though... When I tried to find a solution to my problem I found lots of different hacks that didn't work. Fixing ie7's inconsistencies with javascript is pretty much trial and error woodoo. :)
PS:
I see toggling display is allready suggested, it might work, or as in my case, it did not. I had to actually remove the element from the dom tree to make it work..
Try this:
.showCommentsRight .rightSide { display:block !important; width:50%; }
.showCommentsRight .leftSide { display:block !important; width:50%; }
Close to a solution here, maybe someone else can bring it the last bit of the way.
The page behaves as expected if:
- If the style is assigned to the body by hand instead of using javascript.
(not an acceptable solution, but worth noting)
- If the elements that IE7 isn't updating (the .rightSide's) are manually pants-kicked with something like $(".rightSide").hide().show();
That second solution is darn close to workable, except that I actually am looking for show hide behavior out of my flag, so I'd want a less intrusive thing to change that will make IE refresh the styles.
It seems like you're running into either an IE6/IE7 reflow/repaint issue or IE6/IE7 layout issue.
See http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/ for a detailed and informative analysis of what triggers reflow, repaint, etc. Also see http://www.satzansatz.de/cssd/onhavinglayout.html to find out what causes an element in IE to "have layout".
You could trigger both "having layout" and a reflow by setting height: 1%;. This is known as the Holly hack, named after the first person to document it, Holly Bergevin.
Here is my two cents. An issue with expando object was happening, so the following worked for me with a settimout delay. My issue was the background image wasn't appearing when I inserted some HTML.
app.viewModel.modules.updateSpeech = function (element) {
if ($('html').hasClass('IE7')) {
var cssClass = $(element).attr('class') || element['class'];
if (cssClass)
setTimeout(function() { $(element).removeClass(cssClass).addClass(cssClass); }, 0);
}
};