I use jQuery matchHeight. It's used to make all elements in a row the same height.
I have a page with a lot of elements and it is very slow to load and also if you resize the browser (that fire the matchHeight update) you have to wait the finish of the function.
Here you can find an example (open it in fullscreen).
As you can see I include Bootstrap (Css on and jScript on the end of page), jQuery, the plugin MatchHeight and in my script.js I initialize it with this code:
jQuery( document ).ready( function( $ ) {
// matchHeight
$(function() {
$('.col-eq-height').matchHeight({
property: 'min-height'
});
});
});
The page contain a lot of elements with class "col-eq-height" where I apply the matchHeight functionality.
How can I increase the performance of this plugin?
For example applying the matchHeight only for the showing elements (based by scroll position) and not for all elements on each browser window resize.
Thanks and sorry for my English
DISCLAIMER: This is pretty much a non-answer, because you've asked what I'd pretty much consider a non-question. Nobody is going to write extensive code like that for you, especially not with such an arbitrary question as "can you make this faster?". You have also provided no attempts at what you've tried to do.
Honestly, basically anything can have its performance increased. If you're asking for somebody to test and develop something that's fast for your particular use case, then you'd better check your bank balance and hire yourself a professional. That can be a very challenging task, depending on what "fast" means to you. Here's a list of the very basics about optimizing JavaScript.
Also, for the love of God please could you be more specific in your questions than
where I apply the matchHeight functionality.
That doesn't help people to understand what it is you're trying to achieve. What's the context, i.e., what kind of page are you designing here? Maybe then the question would not be "improve the plugin's performance", but instead, "what other designs/methods of design can I use that don't have such massive performance penalties?".
If you want a list of items displayed and there are hundreds, why not paginate them, like Google does? Or an infinite scroll?
Also, if it's element positioning you're after, why not attempt to calculate exactly what type of layout you want first, then use CSS? I've never had to use jQuery for non-animated HTML design, and I'm increasingly using CSS for animations, too. Maybe you should reconsider exactly what type of layout you are after and try to use CSS first. JavaScript is going to be CPU expensive if you're playing with thousands of elements' styling.
EDIT: As per the comments, if the question is rephrased to "how can I make the child elements of a row the same height as the row", we could do the following:
.container {
display: table;
}
.child {
width: 30px;
background-color: red;
display: table-cell;
vertical-align: top;
}
.content {
display: inline-block;
height: 100%;
width: 100%;
background-color: blue;
}
<div class="container">
<div class="child">
a<br />a<br />a
</div>
<div class="child">
a<br />a<br />a<br />a<br />a<br />a<br />a
</div>
<div class="child">
<div class="content">
a<br />a<br />a
</div>
</div>
</div>
Here, you can see that the elements are all the same height, without needing flexbox (which is still occasionally unsupported). Hope that helps.
Related
Alright, I have no idea what I'm doing. I thought that there would be a library for this, but apparently there isn't.
Problem Explanation
I have a complicated React Application.
There exists
Main Page Element
A content container
A display container
The element I want to scroll to
I am trying to find a solution that will scroll to an element on a page and force all parent scrollbars to scroll to the appropriate location in order to view the element on screen.
Example
<html>
<head />
<body>
<div style="background:red; display: block; height: 1000px; overflow-y: auto">
Root Parent
<div>
<div style="background:green; display: block; height: 1000px;overflow-y: auto">
Another Parent
<div>
<div style="background:blue; display: block; height: 1000px; overflow-y: auto"></div>
<div style="background:purple; display: block; height: 1000px; overflow-y: auto">
<div id="targetElement">Scroll here</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
JS Fiddle Here
https://jsfiddle.net/10f83ush/
Solutions I've tried
I found zen scroll
But in their How to Use Section - 1.4 they explicitly state it isn't supported
https://zengabor.github.io/zenscroll/#howtouse
I found this this thread here
Scroll all nested scrollbars to bring an HTML element into view
And I thought that would work but it doesn't.
If I do element.scrollIntoView that doesn't work either because it's got two sets of scrollable parent/grandparent that both need to scroll to.
Request
How the heck do I get all the parents of the target I want to scroll towards to all scroll towards the correct location to show the element on the page?
I feel like I'm going crazy. It's 2020 and I can't simply scroll to an element that's nested inside other scrollable elements?!
EDIT
To clarify, I'm not trying to do a million scroll bars at a time (Yes this is bad UI/UX), but the solution I'm searching for should support as many as possible. There are multiple solutions I've found where the answer has been solved, but only for one or two scroll bars and then ignored more than two. I would love for guidance or help on how to handle any amount of parent scroll bars when trying to scroll a nested element into view.
Without creating a more complicated solution I opted to use a library called scroll-into-view.
https://github.com/KoryNunn/scroll-into-view
https://www.npmjs.com/package/scroll-into-view
This library is AMAZING - and it does EXACTLY what I wanted which is scrolling elements into view.
Additionally it supports arbitrarily offsetting the scroll location, the ability to filter scrollable areas so that it doesn't change focus from the entire page, and a ton of other amazing features.
This was so good I decided to contribute to the patreon for it!
If you're looking for a solution I would suggest trying this library out!
I am creating a template and I want to know how to Auto Arrange multiple height box in css or javascript.
I already tried to change the CSS and Javascript and I've also searched on Google but I've had no luck yet.
I am giving here image for clear to know what i am looking for i am showing in this image...
please check image before replay what i need
thank you
Have you looked at a library like Masonry?
http://masonry.desandro.com/
To auto-arrange elements with differing heights, there are a bunch of different libraries out there you can use. One such library is Masonry.
Try out the snippet below:
new Masonry(document.getElementById('container'), {
itemSelector: '.item'
});
.item {
width: 25%;
}
.one {
background-color: orange;
height: 100px;
}
.two {
background-color: green;
height: 150px;
}
.three {
background-color: blue;
height: 200px;
}
<div id="container">
<div class="item one"></div>
<div class="item two"></div>
<div class="item one"></div>
<div class="item two"></div>
<div class="item three"></div>
<div class="item three"></div>
<div class="item one"></div>
<div class="item two"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/masonry/3.3.0/masonry.pkgd.min.js"></script>
Take a look at existing tools to do this like Shuffle and masonry. (Shuffle actually uses masonry.)
You haven't provided much detail so my answer can't have much either. It looks like you are looking for CSS Columns. Tables with table-layout: fixed; might also be of use. These layouts are called Pinterest Layouts or Mosaic Layouts
I have good news and bad news, followed by more good news.
The good news is that flexbox is exactly the sort of thing you could use out-of-the-box for this. No js required -- You will set up the flow direction to be in column mode, and you will turn on wrapping. I've provided a fiddle:
https://jsfiddle.net/cev0ug3y/
The bad news is that for this to work, you have to know the height ahead of time. This is fine when you have a small fixed set of items to show, or if the scrolling is set up to be horizontal, but it's not so good when you want that Pinterest-like infinite scroll.
The good news is that there are a lot of people before you who've solved this using javascript -- I'd really recommend using one of those. Refreshing the answers, I see Masonry and Shuffle have already been suggested, so I'll throw in one of my favorites (by the guy who wrote Masonry): Isotype - http://isotope.metafizzy.co/layout-modes.html
If you still want to roll your own, the idea is very simple:
Initialize an array of leading edges which record the vertical height of each column of your display. You'll be initializing this to zero.
For each item you need to place, find the minimum leading edge who, with its neighbors, can accommodate your item.
Set the leading edge of all participating columns to the value of the leading edge you chose plus the height of your item.
You will be using position: absolute to do this. If you don't know the height of images ahead of time, you might be stuck waiting for the load to complete before placing each item. If your items are different widths, you may have holes in your display, and there are techniques to minimize this, but it doesn't look like that's what you are doing here. Despite all of these caveats, this should get you started, but I'd still look at third party libraries for inspiration.
tl;dr = "Anyone know how to apply chained classes for IE6 using jQuery or similar?"
Right,
perhaps I ask the impossible? I consider myself fairly new to Javscript and jQuery, but that being said, I have written some fairly complex code recently so I am definitely getting there... however I am now possed with a rather interesting issue at my current freelance contract.
The previous web coder has taken a Grid-960 approach to the HTML and as a result has used chained classes to style many of the elements. The example below is typical of what can be found in the code:
<div class='blocks four-col-1 orange highlight'>Some content</div>
And in the css there will be different declarations for: (not actual css... but close enough)
.blocks {margin-right:10px;}
.orange {background-image:url(someimage.jpg);}
.highlight {font-weight:bold;}
.four-col-1 {width:300px;}
and to make matters worse... this is in the CSS:
.blocks.orange.highlight {background-colour:#dd00ff;}
Anyone not familiar with this particular bug can read more on it here: http://www.ryanbrill.com/archives/multiple-classes-in-ie/ it is very real and very annoying.
Without wanting to go into the merrits of not chaining classes (I told them this, but it is no longer feasible to change their approach... 100 hand coded pages into a 150 page website, no CMS... sigh) and without the luxury of being able to change the way these blocks are styled... can anyone advise me on the complexity and benefits between any of my below proposed approaches or possible other options that would adequately solve this problem.
Potential Solution 1
Using conditional comments I am considering loading a jquery script only for IE6 that:
Reads the class of all divs in a certain section of the page and pushes to an array
creates empty boxes off screen with only one of the classes applied at a time
Reads the applied CSS values for each box
Re-applies these styles to the individual box, somehow bearing in mind the order in which they are called and overwriting conflicting instructions as required
Potential Solution 2
read the class of all divs in a certain section of the page and push to an array
Scan the document for links to style sheets
Ajax grab the stylesheets and traverse looking for matching names to those in class array
Apply styles as needed
Potential Solution 3
Create an IE6 only stylesheet containing the exact style to be applied as a unique name (ie: class='blocks orange highlight' becomes class='blocks-orange-highlight')
Traverse the document in IE6 and convert all spaces in class declarations to hyphens and reapply classes based on new style name
Summary:
Solution 1 allows the people at this company to apply any styles in the future and the script will adjust as needed. However it does not allow for the chained style to be added, only the individual style... it is also processor intensive and time consuming, but also the most likely to be converted into a plugin that could be used the world over
Solution 2 is a potential nightmare to code. But again will allow for an endless number of updates without breaking
Solution 3 will require someone at the companty to hardcode the new styles every time they make a change, and if they don't, IE6 will break.
Ironically the site, whilst needing to conform to IE6 in a limited manner, does not need to run wihtout javascript (they've made the call... have JS or go away), so consider all jQuery and JS solutions to be 'game on'.
Did I mention how much i hate IE6?
Anyway... any thoughts or comments would be appreciated.
I will continue to develop my own solution and if I discover one that can be turned into a jQuery plugin I will post it here in the comments.
Regards,
Mike.
edit: added tl;dr to the top.
Here's a combination solution: http://code.google.com/p/ie7-js/
Fixes the multiple class bug and some other selector issues you may encounter.
I believe that if you look closely at how IE6 handles class chaining, and if the order of the class names are consistent, then you can avoid some of the IE6 issues with careful class coding.
First have a look at your provided HTML example:
<div class='blocks four-col-1 orange highlight'>Some content</div>
IE6 will apply the CSS in the order of the class names, starting with 'blocks' and continue through to 'highlight'.
Now look at your initial group of classes:
.blocks {margin-right:10px;}
.orange {background-image:url(someimage.jpg);}
.highlight {font-weight:bold;}
.four-col-1 {width:300px;}
These would be applied without any problems as each applies different properties. However, if you should, say, apply a different background with 'highlight' you should see that it will override the one set with 'orange'.
Using this same logic approach, let's have a look at the last class you defined:
.blocks.orange.highlight {background-colour:#dd00ff;}
This class should only apply to objects that have all three class names applied. What happens in IE6 is the first two class names are ignored and only the last class name is used to apply the styling. This means that any object that has the class 'highlight' will receive the new background property. (PS: the CSS property should be background-color, no 'u')
However, if you use other selector methods you can possibly avoid the limitations by applying nested ids/classes [#section .blocks] and/or object associations [form input.highlight]. This complicates the process I know, but at some point we simply need to stop trying to fully support out dated software.
Note: IE6 has not received any updates for two years and the browser itself is nine years old. The browser has two successors and a third is already in development. There should be some cutoff where an acceptable loss of presentation is allowed.
OK... as there is some confusion about what I am asking:
I have been called in to work on a project that is almost completed.
There are no templates.
There are 100+ pages, hand coded and a looming deadline. Here is some actual code from the HTML/CSS all written by the last guy (not abreviated like above):
<div class="block four-col-1 gold black-bg">
<h1>Self Managed Super</h1>
<a class="highlight" href="#"><span class="left bottom">
<strong><span class="text-white">Bolster your<br />
portfolio</span><br /></strong>
with unique<br />
investment<br />
options</span>
<img src="/AU/individuals/_images/superannuation-2.png" alt="" /></a>
</div>
<div class="block four-col-1 grey-light black-bg">
<h1>Self Managed Super</h1>
<a class="highlight" href="#"><span class="left bottom">
<strong><span class="text-white">Financial <br />
flexibility,</span></strong> <br />
into and <br />
throughout <br />
retirement
</span>
<img src="/AU/individuals/_images/superannuation-3.png" alt="" /></a>
</div>
and here is some of the relevant CSS:
.block .highlight {display:block;position:relative;height:auto;min-height:110px;-webkit-border-radius: 4px;-moz-border-radius: 4px;border-radius: 4px;}
.block .highlight:hover {border:1px solid #ddd;}
.block .bottom {position:absolute;font-size:11px;line-height:12px; bottom:10px;letter-spacing:-0.2px; }
.block .left {float:left;font-size:11px;margin-left:8px;width:75%;}
.block.black-bg p, .block.black-bg p * {color:#828282;}
.block.black-bg p * span.text-white {color:#fff;}
.block img {position:absolute;bottom:0;right:1px;z-index:0}
.block .highlight img {position:absolute;bottom:0;right:0px;z-index:0}
.highlight:hover {opacity: .75; filter: alpha(opacity=75); -ms-filter: "alpha(opacity=75)";-khtml-opacity: .75;-moz-opacity: .75; overflow:visible;}
.content .block.black-light.highlight, .block.black-light .highlight, .block.black-light
.block-inner {background:url(/AU/_images/system/block-black-light.gif) no-repeat top left;}
.content .block.grey-light.highlight, .block.grey-light .highlight, .block.grey-light
.block-inner {background:url(/AU/_images/system/block-grey-light.gif) no-repeat top left;}
.content .block.orange.highlight, .block.orange .highlight, .block.orange .block-inner {background:url(/AU/_images/system/block-orange.gif) no-repeat top left;}
.content .block.gold.highlight, .block.gold .highlight, .block.gold .block-inner {background:url(/AU/_images/system/block-gold.gif) no-repeat top left;}
.content .block.blue-light.highlight, .block.blue-light .highlight, .block.blue-light .block-inner {background:url(/AU/_images/system/block-blue-light.gif) no-repeat top left;}
.content .block.blue-dark.highlight, .block.blue-dark .highlight, .block.blue-dark .block-inner {background:url(/AU/_images/system/block-blue-dark.gif) no-repeat top left;}
.content .block.black-light.black-bg.highlight, .block.black-light.black-bg .highlight, .block.black-light.black-bg .block-inner {background:url(/AU/_images/system/black-block-black-light.gif) no-repeat top left;}
.content .block.grey-light.black-bg.highlight, .block.grey-light.black-bg .highlight, .block.grey-light.black-bg .block-inner {background:url(/AU/_images/system/black-block-grey-light.gif) no-repeat top left;}
.content .block.orange.black-bg.highlight.block.orange.black-bg .highlight, .block.orange.black-bg .block-inner {background:url(/AU/_images/system/black-block-orange.gif) no-repeat top left;}
.content .block.gold.black-bg.highlight, .block.gold.black-bg .highlight, .block.gold.black-bg .block-inner {background:url(/AU/_images/system/black-block-gold.gif) no-repeat top left;}
.content .block.blue-light.black-bg.highlight, .block.blue-light.black-bg .highlight, .block.blue-light.black-bg .block-inner {background:url(/AU/_images/system/black-block-blue-light.gif) no-repeat top left;}
.content .block.blue-dark.black-bg.highlight, .block.blue-dark.black-bg .highlight, .block.blue-dark.black-bg .block-inner {background:url(/AU/_images/system/black-block-blue-dark.gif) no-repeat top left;}
(Code is essentially exactly as he wrote it, in all it's unformatted, hideous beauty.)
If you can be bothered to read all that (and most of you probably can't - hence my abbreviations above) you would see that whilst some classes are unique and do not conflict, some do. The result is that some blocks which are expected to be balck, in EI6 are blue, and the margins in EI6 are often wrong, and the absolutely positioned images also break particularly when combined with an IE PNGFix to make them appear transparent as expected.
Also, due to the nature of the deadlines, assume that going over each and every of the 100+ pages and editing the HTML is no longer an option. This was my recommendation from day one and whislt the client accepts that what they have is well and truly less than ideal, they are also working to a tight deadline.
This leaves only two options for edits. Change the CSS so it works across all browsers (as this is called on each page), or generate some Javascript (again, this can be called onto each page using an include) to do something with the HTML on every page on the site, or something else tricky. Changing code in the included pages is easy, changing the HTML in each of the blocks in question is out.
I completely understand what everyone is commenting on so far and thanks for those... they were my initial solutions in both cases, and I wouldn't be on here if they were an option.
Thanks to everyone who has read this, but I really am trying to find some super tricky solution to the entire problem of non-chaining classes in IE6. potentially for broader use than this project. However I now only have 5 working days to find the answer before my contract ends, so if we don't we will just hack an IE6 style sheet that makes all the blocks appear in one way on that browser and leave it at that. I would prefer to find a universal solution, but... meh. Hopefully 18 months from now the user base of IE6 will be so low that it's no longer an issue.
Thanks everyone.
Cheers,
Mike.
I think you may have missed the point of my earlier comment. I was not confused about your request but was trying to explain how you might approach the task should the coding of the site be consistent.
For a more detailed example, lets take a line from your last CSS example, minus the actual styling properties:
.content .block.orange.highlight, .block.orange .highlight, .block.orange .block-inner { }
Following the behavior of Internet Explorer 6 in regards to chained CSS classes, that line of code would be seen by IE6 as:
.content .highlight, .orange .highlight, .orange .block-inner { }
Notice that the chained class names are ignored for all except the last name in the chain. Since you had already rejected the JavaScript solutions that were proposed by others, the only solution I can see is to design your CSS class definitions with this IE6 limitation in mind as you code.
This does not make the task simple as the whole reason for chaining the classes is to be able to apply special conditional styling without increasing the DOM nodes of the document. However, in order to continue to support enhanced feature programming in IE6, without the help of some JavaScript solutions, you will simply have to put in more effort to find older conventional methods for the same result. I know this comment is likely a bit late for your project but I hope it helps with the planning process when dealing with IE6 styling.
I want to create a jquery script that works like the iphones "slide to unlock" bar. i want to have 2 divs, the container, and the slider. i want to be able to drag the slider to the right, and when the slider reaches the very right of the container, have it do something.
i don't want to use jqueryUI in doing this, that library is too bloated, i've seen some other drag and drop scripts out there but a lot of what i've tried has utterly failed, so now i'm back to step 1 wondering if there's a really simple way to drag a div and when it reaches the very right of it's container, to 'do something'.
i would REALLY appreciate any help at all, i think my hair is falling out over this.
nick
I'd suggest using a library that already does what you're looking for, in terms of actually sliding an object.
jquery UI
This is of course a link to the JQuery UI library. However, most UI (User Interface) libraries come with the ability to slide objects, so choose whichever one you're most familiar with. If you're not familiar with one, I'd suggest doing some research.
The JQuery library should give you the ability to slide the object and check the slide objects value, so you'll know when to run your lock/unlock script. As mentioned, though, I'm sure most other libraries will give you the same abilities.
Well, you can attach to the mousedown event, then on mousemove set the location of the div to be the location of the mouse (offset by the original offset), until mouseup (revert to original position), or sufficiently to the right "do something". Sounds simple enough?
So I know this post is REALLY old, but I'm trying to execute the solution that McKay proposed. I'm really quite new to jquery so don't roast me for this :D Maybe someone has a hint on how I can get this to work.
EDIT: Oh, and I'm also on a solution for this using jquery UI.
$(".slider-handle").mousedown(function() {
$(".slider-handle").on("mousemove", function(){
$(".slider-handle").css("margin-left" === "event.pageX" + "px");
});
});
.unlock-slider {
background: #d1d1d1;
width: 300px;
height: 50px;
position:relative;
}
.slider-handle {
height: 70px;
width: 70px;
border-radius: 50%;
background: tomato;
position: absolute;
z-index: 10;
}
<div class="slider-wrapper">
<div class="unlock-slider">
<div class="slider-handle">
</div>
</div>
</div>
I'm styling a form by using a table with fixed-width columns and I want the input elements inside the <td> to fill the container. I know the CSS box model and I know the elements would bleed through with width: 100%, but the problem is with its consistency.
<input> elements bleed through as expected but <select> elements don’t. This results in making my fields not line up properly. I've tried all properties like overflow, display, whitespace... it doesn’t make any difference. What’s with the <select> element? I can see in Firebug that they have the same box model properties with the input element, but they don’t render the same.
I’m using HTML 5 doctype and this happens both in Firefox and Chrome.
Right now, I’m fixing this using a JS function which selects all elements with class stretch and computes and sets the static width to make it fit inside the container. This perfectly lines up the elements of the form. (I had to exclude <select> elements because their widths were already okay... weird quirk.)
Is there a pure CSS solution to this? I wouldn’t want to run this function everytime a part of the page is updated, like on AJAX calls...
You could use box-sizing: border-box; on textfields and textarea's.
It solves te difference with the selectbox.
The best way is to fake the borders of the elements with a div.
<div class="formholder>
<textarea></textarea>
</div>
With this CSS:
.formholder {padding:10px;background:white;border:1px solid #ccc}
.formholder textarea {width:100%;padding:0;margin:0;background:white;border:0}
Of course, you can expand that for other fields. Some browsers might give you issues. Chrome and webkit allow you to resize textareas but if you add resize: none; to your CSS, it should disable it but YMMV.
It may help you to know the following results from various usability studies.
1) For most forms, people prefer to see the label just above the form element:
2) People find it useful if the form elements are sized appropriately to help suggest how much information is expected.
<ul>
<li><label for="firstname">First Name</label><br>
<input type="text" id="firstname" name="firstname" size="15"></li>
<li><label for="age">Age</label><br>
<input type="text" id="age" name="age" size="3"></li>
<!-- ... more list items -->
</ul>
Note: the list in this example would be styled so that it doesn't appear as a bullet-point list. Using lists in this way helps with accessibility as screen readers will tell the user how many items are contained in the list.
I thought this might be useful as it suggests that your efforts may be a bit wasted trying to layout the form in a table and stretch all inputs to the same length.
http://dev.w3.org/html5/markup/input.html#input
Not the most helpful answer, but CSS styling of form elements is pretty unreliable between browsers. A JavaScript solution like yours is the best bet.
Two reasons for the unreliability:
Some features of form elements can’t be described by CSS. The <select> element is a good example: there aren’t any CSS properties that can describe the different ways a <select> element looks on different operating systems.
Trying to work out which CSS properties should affect form elements, and how, is a rat’s nest for browser makers, so they’ve mostly left it alone. Safari is a notable exception; see e.g. http://webkit.org/blog/17/the-new-form-controls-checkbox-2/
You can argue that form elements should look the same between sites regardless of the site owners’ intentions, so that users know what they’re clicking on.
See http://meyerweb.com/eric/thoughts/2007/05/15/formal-weirdness/ for a deeper examination.
Say your html looks somewhat like this:
<form><table><tr>
<td><input type="text" /></td>
<td><select><option /><option /></select></td>
</tr></table></form>
How about just using the input and select for setting the width?
td { width: auto; }
input[type=text] { width: 100px; }
select { width: 100px; }
Or did I get your problem wrong?
The following CSS works for Moz Firefox, for html input elements (submit, button, text), textarea elements, and even select elements. The select elements are nearly equal length in the browser I'm trying.
table {width:100%;}
form input { width: 100%; }
form textarea { width: 100%; overflow-y: scroll; resize: vertical; }
form select { width: 100%; }