I want to differentiate if an image is vertical or horizontal format and add a special class. I'm use this to fill my div fully with my image.
My HTML:
<a href="images/gallerie/image-1.jpg" data-lightbox="image-1" class="impression">
<img src="images/gallerie/image-1.jpg">
</a>
My CSS:
.wide {
height: 100%;
width: auto;
}
.tall {
height: auto;
width: 100%;
}
My JS (jQuery):
$('.impression').find('img').each(function() {
if($(this).width() / $(this).height() > 1) {
$(this).addClass('wide');
}
else {
$(this).addClass('tall');
}
});
It works only sometimes, and I don't know why.
On my iPhone it works never (Chrome).
Has anybody an other solution or maybe the reason why it works sometimes?
Thanks!
You need to use a load event handler so image is loaded before you can check dimensions
$('.impression').find('img').on('load',(function() {
// image is loaded now
if($(this).width() / $(this).height() > 1) {
$(this).addClass('wide');
}
else {
$(this).addClass('tall');
}
});
The each is not needed as jQuery will use each internally and this will be image instance
Most probably, you are running the function too soon and your images have not been loaded yet. In order to make sure, you can always console.log() the values of .width() and .height().
The best way to make sure the image has loaded when you check its dimensions is to use the load event.
$('img').on('load', function(){
// do your thing...
})
The rest is wrong, as pointed out by #charlietfl. The load event for img's does not propagate.
Better yet, instead of binding a listener to each img, just bind one on body for all your images, including the ones you will load later on, using some fancy async method:
$('body').on('load', 'img', function(){
// do your thing...
})
This second version will run every time an <img> will load in your DOM, not only when you run the script.
I need to call a function when a window is resized below the 400px breakpoint. The obvious solution to handle this would be to watch the window.resize() event like this:
Window.Resize Solution
script:
$(window).resize(function(){
if($(window).width() < 400)
console.log("trigger");
});
Window.resize Fiddle
However this triggers continuously as the resize happens, this can result in hundreds of calls on this function, and will trigger at unncessary times like resizing from 300px to 200px;
While trying to find a way to avoid this I came up with a solution using CSS media queries:
CSS Media Query Solution
script:
$(".foo").on('transitionend', function () {
console.log("trigger")
});
css:
.foo
{
width: 0;
height: 0;
color: white;
transition: 0.1s;
}
#media screen and (max-width: 400px) {
.foo {
color: gray;
}
}
CSS Media Query Fiddle
The idea here is that the CSS watches for the window to resize to 400px then applies an arbitrary transition to an invisible element. Once done, the transitionend event is fired and the listener calls on my function. This only happens once when the screen goes below 400px and once when it goes back above.
Now of course there are pitfalls to this solution:
IE8/IE9 don't support transitionend
You must create an unnecessary element for each resize event you want to watch
The code is inherently more confusing as it is a "hacky" technique.
But other than those downfalls I was wondering if this method would be more efficient/better use if you want to avoid the continuous calls. Or is the underlying implementation of media queries doing more work than the resize event would anyway.
I think your main complication is splitting the code over so many places. Yes, CSS is nice and all, but now your code is reliant on two places! The easiest way to sort this is to simply store your value in JS:
var isSmall = false;
$(window).resize(function(){
if(
(window.innerWidth < 400 && !isSmall) ||
(window.innerWidth > 400 && isSmall)
){
console.log('we have passed the treshold!');
isSmall = !isSmall;
}
}).resize();
I guess using the CSS transitionend would work, but it seems so cumbersome to keep in sync.
I'm working with Bootstrap and I want to put some photos into my div and I want them to be all at the same size ("standardize").
If they're too big (and they will always be) I want to resize them to fit in my div and crop them if necessary.
For the moment her is what I do :
I've tried to change the style of the image in jQuery in a function:
• If the height is bigger than the width, I switch the style to max-width:100% and height auto.
• Inversement if the width is bigger than the height.
But I'm still new to jQuery and I am probably doing something wrong; can someone light my lantern please?
Here is my jQuery
$(document).ready(function(){
photoResize();
$(window).resize(function(){
photoResize();
});
});
function photoResize(){
image_w = $('img').width();
image_h = $('img').height();
if(image_h > image_w)
{
$('img').css("max-width","100%");
$('img').height("auto");
}
else if(image_w > image_h)
{
$('img').css("max-height","100%");
$('img').width("auto");
}
}
And here is a Fiddle for a better view : https://jsfiddle.net/Baldrani/DTcHh/9801/
Simplicity
I do this quite often in the CMS we use at work for galleries etc. The method I use involves a jQuery library called imgLiquid.js.
This will turn an inline image into a background image on the parent div. It's good because you can achieve your desired effect. It will crop the image (as it technically becomes a background image) and will apply background-size: cover; and background-position: center center; as inline styles.
You can find the plugin here
To initialize the plugin you just need:
$(".myele").imgLiquid();
Overheads
The plugin is very small (roughly around 5.106 KB) so you don't need to worry about adding weight to the page. It really it the most simple method I've come across (bar using thumbnails generated from the sever-side - see note at the bottom).
Cue CSS
I've tested this thoroughly and found it gives excellent results. You may then ask... what happens to my parent divs (as technically the plugin hides the img element - which therefore means the parent element doesn't know what height to make itself).
An easy method to make things work responsively, or not:
.myelement:before{
content: "";
padding-top: 50%;
display: block;
}
This CSS will give your heights back to the wrapping element. So if you wanted certain proportions you could use this math:
h / w * 100 = your percentage for the padding-top.
Working Example
Small note
Technically if I had the control I'd advise just using thumbnails.. I assume you're using some sort of system that could technically just render cut down versions of the images? The reason I use this method — and suggested it — is that I don't have control over the CMS and I'm assuming you just want to manage the code that's being produced as it's not stated.
if you want to make your images the same size then you dont need any javascript or calculations, why not just set it in css?
.someUniqueContainer img{
width:300px;
height:300px; // or what ever height you want
}
I'm guessing that in reality you actually want to crop all your images to a set width/height. if that's the case you'll need a serverside script for that.
where are the images coming from? it would be easyer to just edit them. if they are coming from a user then you would resize/crop on the server on file upload
There were several mistakes in your code.
Please look at this jsfiddle, please see https://jsfiddle.net/DTcHh/9796/
$(document).ready(function () {
photoResize();
$(window).resize(function () {
photoResize();
});
});
function photoResize() {
image_w = $('img').width();
image_h = $('img').height();
if (image_h > image_w) {
$('img').css("max-width", "100%");
$('img').height("auto");
} else if (image_w > image_h) {
$('img').css("max-height", "100%");
$('img').width("auto");
}
}
sth like this?, although this is pure css, not jquery included, might not be suit in your case..
body {
margin-top:20px
}
.col-xs-3 {
margin: 5px 0;
width: 500px;
height:120px
}
.col-xs-3 > div {
width: 100%;
height: 120px;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
JsFiddle
I'm trying to make a gallery using divs that change their height when you click on them. Ideally, this would include animation to smoothly expand the div's height. There will be several of each div on each page, so it needs to just expand that section.
It's actually supposed to turn out something like the news section on this page: http://runescape.com/
I'd like to do it with JavaScript/jQuery if possible.
$('div').click(function(){
$(this).animate({height:'300'})
})
Check working example at http://jsfiddle.net/tJugd/
Here's the code I ended up using:
JS:
document.getElementById("box").addEventListener("click", function() {
this.classList.toggle("is-active");
});
CSS:
#box {
background: red;
height: 100px;
transition: height 300ms;
width: 100px;
}
#box.is-active {
height: 300px;
}
HTML:
<div id="box"></div>
Fiddle:
https://jsfiddle.net/cp7uf8fg/
try
$('div').toggle(function(){
$(this).animate({'height': '100px'}, 100);
}, function(){
$(this).animate({'height': '80px'}, 100);
});
DEMO
jQuery rules. Check this out.
http://api.jquery.com/resize/
The complete solution:
Both spacer DIV and Margin or Padding on content DIV works but best to still have a spacer DIV.
Responsive design can be then applied to it in your CSS file.
This is mutch better as with JAVA the screen would flicker!
If you use a grid system there will be a media query part there you need to include your settings.
I use a little spacer on HD screen while its increasing till mobile screen!
Still if you have breadcrumb in header multiple lines can be tricky, so best to have a java but deferred for speed resons.
Note that animation is for getting rid of flickering of screen.
This java then would only fire if breadcrumb is very long otherwise single CSS applied via the grid and no flickering at all.
Even if java fired its doing its work via an elegant animation
var header_height = $('#fixed_header_div').height();
var spacer_height = $('#header_spacer').height() + 5;
if (header_height > spacer_height) {
$('#header_spacer').animate({height:header_height});
};
Note that I have applied a 5px tolerance margin!
Ho this helps :-)
I know this is old, but if anyone seems to find their way here. #JacobTheDev answer is great and has no jQuery! I have added a little more for use cases where the event is not being assigned at the same point your toggling the css class.
HTML
<div id='item' onclick='handleToggle()'> </div>
JS
handleToggle(event){
document.getElementById(event.target.id).classList.toggle('active')
}
CSS
#item {
height: 20px;
transition: 1s;
}
.active {
height: 100px;
}
I have a TinyMCE that is set over a TextArea, and I want this editor area to ocuppy all the space of its parent div, all times.
I have a JS function that get the current space and set the textarea.style.height to it, but when I enables TinyMCE it seems to stop working.
Also, the textarea has width: 100%; it doesn't resize by HTML rendering when it's using TinyMCE too.
Any ideas?
Nowadays, you should use the autoresize plugin that comes with tinyMCE. You will have to call tinyMCE like this (jQuery version):
$('.tinymce').tinymce({
theme : 'advanced',
plugins : 'autoresize',
width: '100%',
height: 400,
autoresize_min_height: 400,
autoresize_max_height: 800,
});
I made the experience, that it may be helpful to manually call the resizing in the init_instance_callback to provide the correct height on init. Add this parameter to the passed options, if you need this:
init_instance_callback: function (inst) { inst.execCommand('mceAutoResize'); }
The point is that TinyMCE generates an iframe in the place of the textarea, with this ID: originalID+"_ifr", and a table originalID+"_tbl" for holding the controls and the editor area.
To make fluid width:
document.getElementById(id+'_tbl').style.width='100%'
To make fluid height:
Change dinamically document.getElementById(id+'_ifr').style.height to the height you want, through JS.
This is the script I'm using for this:
function toScreenHeight(id, minus) {
var height;
if (typeof(window.innerHeight) == "number") //non-IE
height = window.innerHeight;
else if (document.documentElement && document.documentElement.clientHeight) //IE 6+ strict mode
height = document.documentElement.clientHeight;
else if (document.body && document.body.clientHeight) //IE 4 compatible / IE quirks mode
height = document.body.clientHeight;
document.getElementById(id).style.height = (height - minus) + "px";
}
You can use the code and function calls inside onload and onresize body events.
in tinymce 3.4.6,
set
width:'100%'
in init option will solve the problem.
If you're doing tiny MCE dynamically via JS, you can run into timing issues where the MCE editor is not yet available for style adjustments. To combat this, you can use an old school timeout.
In this example, I'm using a "j" namespace for JQuery. If your editor is in a fluid div that changes size, you may want include this in a $(window).resize(function() { }); listener.
setTimeout(function(){
$j('.mceEditor').css('width','100%').css('minHeight','240px');
$j('.mceLayout').css('width','100%').css('minHeight','240px');
$j('.mceIframeContainer').css('width','100%').css('minHeight','240px');
$j('#'+[INSERT TEXTAREA ID HERE]+'_ifr').css('width','100%').css('minHeight','240px');
},500)
None of the above were working for me in TinyMCE v4, so my solution was to calculate the height based on the toolbars/menu bar/status bar, and then set the height of the editor, taking those heights into consideration.
function resizeEditor(myHeight) {
window.console.log('resizeEditor');
myEditor = getEditor();
if (myEditor) {
try {
if (!myHeight) {
var targetHeight = window.innerHeight; // Change this to the height of your wrapper element
var mce_bars_height = 0;
$('.mce-toolbar, .mce-statusbar, .mce-menubar').each(function(){
mce_bars_height += $(this).height();
});
window.console.log('mce bars height total: '+mce_bars_height);
myHeight = targetHeight - mce_bars_height - 8; // the extra 8 is for margin added between the toolbars
}
window.console.log('resizeEditor: ', myHeight);
myEditor.theme.resizeTo('100%', myHeight); // sets the dimensions of the editable area
}
catch (err) {
}
}
}
In my case, I wanted the editor window to match the width and height of the actual window, since the editor would come up in a popup. To detect changes and resize, I set this to a callback:
window.onresize = function() {
resizeEditor();
}
With version 4 and the option to use flexbox layout in the browser I did the following to get a full width,height editing experience of the parent div.
It should be easy to put the css into a file if you prefer adding it to your existing styles.
var css = '.tinycme-full .mce-edit-area {display:flex;flex-flow:column;} .tinycme-full .mce-edit-area iframe {flex:1 1 auto;} .tinycme-full {height:100%;} .tinycme-full .mce-tinymce.mce-container { width:100%;height:100%;border:0; } .tinycme-full .mce-panel{border:0} .tinycme-full .mce-container-body.mce-stack-layout {display: flex; flex-flow: column;height: 100%;} .tinycme-full .mce-stack-layout-item{ flex: 0 0 auto;} .tinycme-full .mce-edit-area{flex:1 1 auto;} ',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet["cssText"] = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
The idea is that it make all the needed divs take up as much column space as needed to fill the parent 100% and its done by putting a div around your textarea: <div class="tinycme-full"> <textarea ... /></div>
No jquery or other dependencies are needed andd it now fills the parent 100%.
I had the same problem, after reading this thread I ended up with this code
init_instance_callback: function (inst) {
setTimeout(function () {
document.getElementById(inst.id + '_ifr').style.height= (document.getElementById("theContainerDiv").offsetHeight-85) + 'px';
},1000);
},
I resize the "_ifm" element instead of the "_tbl", since resizing the "_tbl" didn't resize the edit area for me. Then I leave some space for the toolbar and statusbar by making the "_ifr" 85 pixels shorter then the container div.
I had to use setTimeout to make it work, maybe because I have an animation that displays the container element.
I'm using pure css solution to achieve this (tinyMCE 4.0.20).
Set iframe height to 100%:
tinymce.init({
height: '100%'
})
Add styles to auto-resize iframe container:
.mce-tinymce { height: auto; width: 100%; position: absolute; left: 0; top: 0; bottom: 0; }
.bq-editor .mce-container-body { height: 100%; }
.bq-editor .mce-edit-area { position: absolute; top: 57px; bottom: 0; width: 100%; height: auto; }
Note: I have one toolbar line, and top: 57px; in .bq-editor .mce-edit-area is toolbar padding.
SyCoDeR is right but I followed a slightly different path though probably with the same results.
/*Container, container body, iframe*/
.mce-tinymce, .mce-container-body, #code_ifr {
min-height: 100% !important;
}
/*Container body*/
.mce-container-body {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
/*Editing area*/
.mce-container-body .mce-edit-area {
position: absolute;
top: 69px;
bottom: 37px;
left: 0;
right: 0;
}
/*Footer*/
.mce-tinymce .mce-statusbar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
Revised because TinyMCE changes the id's with menu/toolbar additions or deletions. This works no matter what you do with it.
This is an old question, but apparently it still drags a lot of attention nowadays (Second half of 2020).
Sadly, with the release of the TinyMCE v5, most of the workarounds I found simply do not work anymore. I am sure they worked once, but every TinyMCE release seems to bring new "constrainings" that cripple those workarounds...
Without making it a discussion, I believe it is the cost of evolution. For an old product like the TinyMCE, it is incredible to see it is still around and kicking, staying way above the competition. It is by far one of the most efficient and flexible solutions for all environments, including mobile and for those new languages and frameworks that born since (which seems to be a trend lately, with new ones coming out of the blue every day).
So, with that in my mind, and after so many (failed) attempts to make most of the proposed solutions work, I decided to dig into the source code (TinyMCE v5.4) to better understand it. What I found was a much superior product overall, and that the solution everyone has been looking for is much simpler to implement than I was anticipating.
With no further delay, here my solution that simply works. It implements an editor that takes the entire document area (or whatever area you want), which WILL resize with the browser, requiring NO script, NO hack, and NO trick that could cause cross-browsing issues. Here's how:
Give to your <html> and <body> DOM objects the missing properties of size and adjust the spacing accordingly to your needs:
html, body {
width : 100%;
height : 100%;
margin : 0 !important;
padding : 0 !important;
overflow : hidden; /* Required if you want to have the editor taking the entire page. */
/* Otherwise, set as you need it. */
}
TinyMCE suggests the <textarea> to be embedded inside a <form> object. Regardless if you use it as suggested or not, simply give to it and ID and the following CCS properties (in my case, it is set as <form method="post" id="editorBase">):
#editorBase {
display : block !important;
width : 100% !important;
height : 100% !important;
}
In the TinyMCE Init method, add or modify the following settings:
tinymce.init({
// Required Settings:
width : '100%', // Note value is set as "string".
height : '100%', // Note value is set as "string".
resize : false, // Suggestion: disable the statusbar resizing. :)
// Suggested Settings:
toolbar_sticky : true, // Keep the menu and tollbar in a fixed position .
toolbar_location : 'top', // You can try 'top', 'bottom' or 'auto'.
toolbar_mode : 'floating', // It is simply a button behavior settings.
// Options are: 'floating', 'sliding', 'scrolling', or 'wrap'.
});
Yet in the TinyMCE Init settings, find the plugins item and remove the autoresize option from it (it is the most important step of all!).
Done! Try and test it! (YES! It is all done!)
With those simple adjustments you can set the editor to fit any design. Feel free to adjust it as needed. Just don't forget to set the width and the height properties in the TinyMCE Init settings as strings, and keep it consistent with the CSS settings for the <form>.
The reason to use strings in the width and height properties of the TinyMCE Init settings instead of numeric values is to allow you to use "%", "em", "pt", etc... Otherwise, the presented solution would never work.
Another trick to make it even more neat is to set the editor as borderless skin (a feature only present in the "professional" version of TinyMCE). No, it is not a hack, it is a siple adjustment to the CSS and totaly allowed by TinyMCE's EULA and Licensing. Simply add the following CSS to your page Stylesheet and it enjoy a borderless editor for free:
.tox-tinymce { border:none !important; }
Could not be easier than that.
Happy coding!
The wrapper of iframe (its ID finish by _ifr) is the first parent of span that it has application as role .
Thus, To get the wrapper :
$('span[role=application]').parents(':eq(0)')
So to Resize height:
$('[id$=_ifr]').css('height',$('span[role=application]').parents(':eq(0)').css('height'))
To resize width
$('[id$=_ifr]').css('width',$('span[role=application]').parents(':eq(0)').css('width'))
None of these solutions worked 100% for me. I needed the height to adjust on initialization and during edits. What I did is grab the height of the HTML element in the iFrame, and then applied the height to the iFrame with an extra 100px.
Here's my solution: (added img max-width for responsive images)
on initialization
setup: function(editor) {
editor.on('init', function (e) {
$("#editor_textarea_ifr").contents().find('img').css("max-width","100%");
iframeHeight = $("#editor_textarea_ifr").contents().find("html").height();
$("#editor_textarea_ifr").css("height",iframeHeight + 100);
});
},
on node change (edits)
init_instance_callback: function (editor) {
editor.on('NodeChange', function (e) {
$("#editor_textarea_ifr").contents().find('img').css("max-width","100%");
iframeHeight = $("#editor_textarea_ifr").contents().find("html").height();
$("#editor_textarea_ifr").css("height",iframeHeight + 100);
});
}