I am using the functionality from the "Thumbnail Grid with Expanding Preview" tutorial (like everyone else it would seem O_o) I have it all working pretty much the way I want, except that instead of div.og-expanded expanding to the full height of the page, I'd like div.og-expanded to expand only to the size of the content within the container instead.
I'm using the latest code from Github.
The height of div.og-expanded seems to be controlled by calcHeight : function in grid.js
calcHeight : function() {
var heightPreview = winsize.height - this.$item.data( 'height' ) - marginExpanded,
itemHeight = winsize.height;
if( heightPreview < settings.minHeight ) {
heightPreview = settings.minHeight;
itemHeight = settings.minHeight + this.$item.data( 'height' ) + marginExpanded;
}
this.height = heightPreview;
this.itemHeight = itemHeight;
},
setHeights : function() {
var self = this,
onEndFn = function() {
if( support ) {
self.$item.off( transEndEventName );
}
self.$item.addClass( 'og-expanded' );
};
this.calcHeight();
this.$previewEl.css( 'height', this.height );
this.$item.css( 'height', this.itemHeight ).on( transEndEventName, onEndFn );
if( !support ) {
onEndFn.call();
}
},
As I said, instead of using the window size to get the height, I'd like to base it off of the content height of div.og-expander-inner. I saw a similar question "Expanding preview (calcHeight : function)" The solution calculated the height based on the content of (what is essentially) div.og-fullimg or div.og-details whichever is taller. This is a decent solution as it took the responsiveness of the content into consideration, which is important to me. Unfortunately, I couldn't sort out how to apply this solution to the original source code.
Any help here would be greatly appreciated.
Related
I am building a website with Foundation 6 using CSS instead of SCSS. I'm using the responsive off-canvas drill-down menu on small screens, and by default, the off-canvas menu width is 250px.
Problem: I would like this to be the full width of the browser window instead.
Setting the Width
I have used JavaScript to dynamically set the .off-canvas.position-right width to the width of the window, and right to the negative width of the window. I've also set the .off-canvas .drilldown max-width to the width of the window.
This works well, and here's how I did it:
function setOffCanvasWidth() {
var windowWidth = window.innerWidth,
offCanvasRight = document.querySelector( '.off-canvas.position-right' ),
isDrilldown = document.querySelector( '.off-canvas .is-drilldown' );
offCanvasRight.style.width = windowWidth + "px";
offCanvasRight.style.right = "-" + windowWidth + "px";
isDrilldown.style.maxWidth = windowWidth + "px";
}
setOffCanvasWidth();
I'm happy with this part, but it only solves half of the problem.
Moving the Off-Canvas
In addition to dealing with the width of the menu, .is-open-right is moving everything over by -250px using transform: translateX().
I tried including these lines in my function to set the transform: translateX() value to the negative width of the window:
var offCanvasWrapperInner = document.querySelector( '.off-canvas-wrapper-inner.is-off-canvas-open.is-open-right' );
offCanvasWrapperInner.style.transform = "translateX(-" + windowWidth + "px)";
But this didn't work. I think it has to do with the fact that .off-canvas-wrapper-inner doesn't have the class .is-open-right when the window loads. That class is added dynamically after clicking the hamburger toggle button, which has a class of .menu-icon. So I tried adding a click event listener, but it still doesn't work.
Here is my JS code in its entirety:
function setOffCanvasWidth() {
var windowWidth = window.innerWidth,
offCanvasRight = document.querySelector( '.off-canvas.position-right' ),
isDrilldown = document.querySelector( '.off-canvas .is-drilldown' ),
menuIcon = docuemnt.querySelector( '.menu-icon' ),
offCanvasWrapperInner = document.querySelector( '.off-canvas-wrapper-inner.is-off-canvas-open.is-open-right' );
offCanvasRight.style.width = windowWidth + "px";
offCanvasRight.style.right = "-" + windowWidth + "px";
isDrilldown.style.maxWidth = windowWidth + "px";
menuIcon.addEventListener( 'click', function() {
offCanvasWrapperInner.style.transform = "translateX(-" + windowWidth + "px)";
} );
}
setOffCanvasWidth();
Where Am I Going Wrong?
I'm not looking for anyone to code the solution for me, necessarily, but any feedback and direction on how I might set the .is-open-right translateX value would be very helpful.
Here is the entire project code: https://github.com/paulshryock/paulshryock/releases/tag/v0.0.1
Here is a live demo: https://paulshryock.github.io/paulshryock/
Use a translateX value of -100%. Percentage transformations are based on the element's dimensions, so 100% would be equal the element's width. At this point no JavaScript would be needed.
On that note, I would recommend setting the menu's left to 100% instead of setting right to the negative width.
I am trying to set the margin of my wrapper dynamically. Here is my JavaScript code:
var w = window.innerWidth;
if (w > 800) {
var margin = (w - 800) / 2;
$('.ui-page').css('margin-left', margin);
var output = $('.ui-page').css('margin-left');
$('.ui-footer').css('margin-left', margin);
$('.ui-header').css('margin-left', margin);
alert(output);
}
But when I open the page, the alert says undefined !?
In addition to my previous answer, which shows it working, there is this fail-safe.. this is a different approach that must always work. I suspect your page is not loaded when the code is run:
http://jsfiddle.net/digitalextremist/xfVdL/1/
$( document ).ready( function() {
var w = window.innerWidth;
var maxWidth = 300
if ( w > maxWidth ) {
var margin = (w - maxWidth) / 2;
$('.ui-page').css('margin-left', margin);
var output = $('.ui-page').css('margin-left');
$('.ui-footer').css('margin-left', margin);
$('.ui-header').css('margin-left', margin);
alert( output );
}
});
Or, if you use jQuery Mobile:
$( document ).on( 'pagebeforeshow', function( event ) {
var w = window.innerWidth;
var maxWidth = 300
if ( w > maxWidth ) {
var margin = (w - maxWidth) / 2;
$('.ui-page').css('margin-left', margin);
var output = $('.ui-page').css('margin-left');
$('.ui-footer').css('margin-left', margin);
$('.ui-header').css('margin-left', margin);
alert( output );
}
});
It is critical that you let the page load first before testing sizes as you are doing.
What you are doing is correct, but jQuery and jQuery Mobile render the page in stages. To make sure you take your measurement of .ui-page at the right time, once everything is properly loaded by jQuery or jQuery Mobile, you need to make sure it all rendered first, which means you need to use $( document ).on( 'pagebeforeshow' ) for jQuery Mobile, or $( document ).ready() for jQuery itself. These make sure your code runs after the page is fully rendered. Before that, your measurements will be wrong! And before that, .ui-page might not even exist yet, if it is added by jQuery Mobile.
Here is more information for you:
When should I use jQuery's document.ready function?
jQuery: Why use document.ready if external JS at bottom of page?
http://learn.jquery.com/about-jquery/how-jquery-works/
http://www.w3schools.com/jquerymobile/event_pagebeforeshow.asp
http://jquerymobile.com/demos/1.1.0/docs/api/events.html
Try setting the margin with a unit; something like:
$('.ui-page').css('margin-left', margin + 'px');
Also, you can use margin: 0 auto; to have your div's center themselves within the page. See MDN for some details.
It looks like your query for .ui-page is returning no elements.
Therefore, when trying to retrieve the margin-left property, it returns undefined.
Try checking whether whether .ui-page actually exists on the page.
A quick way to do this:
if ( $('.ui-page').length > 0 ) alert('.ui-page exists!');
What version of jQuery are you using? And what browser?
Without changing your code really at all, it works fine under version 1.10.1
( It also works under every other version... on Chrome and Firefox )
See what I mean? http://jsfiddle.net/digitalextremist/xfVdL/
So, it does work... No "px" required.
I'm trying to get the div width and height as the user changes it and submit that number to another page. I can't seem to figure out how to get the width and height though.
<script>
$(function() {
$( "#set div" ).draggable({
stack: "#set div",
preventCollision: true,
containment: $('#main_content'),
stop: function(event, ui) {
var mydiv = document.getElementById("set");
var pos_x = ui.offset.left;
var pos_y = ui.offset.top;
var width = mydiv.style.width; ----THIS DOESN'T WORK
var height = mydiv.style.height; ----THIS DOESN'T WORK
var window_width = window.innerWidth;
var window_height = window.innerHeight;
var need = ui.helper.data("need");
console.log(pos_x);
console.log(pos_y);
console.log(width);
console.log(window_width);
console.log(need);
//Do the ajax call to the server
$.ajax({
type: "POST",
url: "updatecoords.php",
data: { x: pos_x, y: pos_y, need_id: need, width: width, height: height, window_width: window_width, window_height: window_height}
}).done(function( msg ) {
alert( "Data Saved: " + msg );
});
}
});
});
</script>
What's the proper way to do this?
It's quite wrong to use ele.style.width to get the element's width!!!!!!
In native JavaScript, you can get a element's CSS through two ways:
Standard Method
window.getComputedStyle(ele)
For example,
var ele = document.getElementById("content"), // Do not use #
eleStyle = window.getComputedStyle(ele);
/* Below is the width of ele */
var eleWidth = eleStyle.width;
IE(IE 8 And Before)
element.currentStyle
For example,
var ele = document.getElementById("content"), // Do not use #
eleStyle = ele.currentStyle;
/* Below is the width of ele */
var eleWidth = eleStyle.width;
Why Not Use ele.style?
ele.style is just get the attribule style of ele. If you use ele.style.width, you just get the width of ele.style, not the real width of ele.
If you have done something like:
ele.style.width = "55px"
You get "55px" when using ele.style.width. If you haven't, you will get undefined.
How To Do In jQuery?
Use $ele.width() (if you want the "exact" width, use $ele.outWidth()), jQuery has done everything for you.
In plain vanilla JavaScript use
var width = mydiv.offsetWidth;
var height = mydiv.offsetHeight;
This will give you numeric values, or
var width = mydiv.offsetWidth + 'px';
var height = mydiv.offsetHeight + 'px';
If you want them in "CSS" format.
Since you're already using jQuery, you can just do:
var width;
if (need == 1) {
width = $("#web").width();
} else {
width = $("#set").width();
}
Since you're using jQuery, you'll probably want to know about the following:
$('#id').outerWidth()
$('#id').outerWidth(true)
These will come in very handy. This allows you to find the total width of the div (padding, border, width and (optional argument) margin).
http://api.jquery.com/outerWidth/
I'm trying to resize an iframe dynamicly to fit its content. To do so I have a piece of code:
$("#IframeId").height($("#IframeId").contents().find("html").height());
It doesnt work. Is it because of cross-domain issue? How do I get it to fit? Please take a look at Fiddle: JsFiddle
ps I have set the html and body of the link height:100%;
You just need to apply your code on the iframe load event, so the height is already known at that time, code follows:
$("#IframeId").load(function() {
$(this).height( $(this).contents().find("body").height() );
});
See working demo . This demo works on jsfiddle as I've set the iframe url to a url in the same domain as the jsfiddle result iframe, that is, the fiddle.jshell.net domain.
UPDATE:
#Youss:
It seems your page for a strange reason don't get the body height right, so try using the height of the main elements instead, like this:
$(document).ready(function() {
$("#IframeId").load(function() {
var h = $(this).contents().find("ul.jq-text").height();
h += $(this).contents().find("#form1").height();
$(this).height( h );
});
});
Not sure why #Nelson's solution wasn't working in Firefox 26 (Ubuntu), but the following Javascript-jQuery solution seems to work in Chromium and Firefox.
/**
* Called to resize a given iframe.
*
* #param frame The iframe to resize.
*/
function resize( frame ) {
var b = frame.contentWindow.document.body || frame.contentDocument.body,
cHeight = $(b).height();
if( frame.oHeight !== cHeight ) {
$(frame).height( 0 );
frame.style.height = 0;
$(frame).height( cHeight );
frame.style.height = cHeight + "px";
frame.oHeight = cHeight;
}
// Call again to check whether the content height has changed.
setTimeout( function() { resize( frame ); }, 250 );
}
/**
* Resizes all the iframe objects on the current page. This is called when
* the page is loaded. For some reason using jQuery to trigger on loading
* the iframe does not work in Firefox 26.
*/
window.onload = function() {
var frame,
frames = document.getElementsByTagName( 'iframe' ),
i = frames.length - 1;
while( i >= 0 ) {
frame = frames[i];
frame.onload = resize( frame );
i -= 1;
}
};
This continually resizes all iframes on a given page.
Tested with jQuery 1.10.2.
Using $('iframe').on( 'load', ... would only work intermittently. Note that the size must initially be set to 0 pixels in height if it is to shrink below the default iframe height in some browsers.
What you can do is the following:
Within the iFrame use document.parent.setHeight(myheight) to set the height within the iFrame to the parent. Which is allowed since it is a child control. Call a function from the parent.
Within the parent you make a function setHeight(iframeheight) which resizes the iFrame.
Also see:
How do I implement Cross Domain URL Access from an Iframe using Javascript?
Just do it on the HTML tag, works perfect
$("#iframe").load(function() {
$(this).height( $(this).contents().find("html").height() );
});
As the answer to the question use an already outdated jquery (load has been deprecated and replaced with .on('load',function(){}), below is the latest code for the answer in the question.
Note that I use the scrollHeight and scrollWidth, which I think will load much nicer than using Height and Width like the answer provided. It will totally fit, without scroll anymore.
$("#dreport_frame").on('load',function(){
var h = $('#dreport_frame').contents().find("body").prop('scrollHeight');
var w = $('#dreport_frame').contents().find("body").prop('scrollWidth');
$('#dreport_frame').height(h);
$('#dreport_frame').width(w);
})
Adjust height of an iframe, on load and resize, based on its body height.
var iFrameID = document.getElementById('iframe2');
var iframeWin = iFrameID.contentWindow;
var eventList = ["load", "resize"];
for(event of eventList) {
iframeWin.addEventListener(event, function(){
if(iFrameID) {
var h = iframeWin.document.body.offsetHeight + "px";
if(iFrameID.height == h) {
return false;
}
iFrameID.height = "";
iFrameID.height = iframeWin.document.body.offsetHeight + "px";
}
})
}
At end, I come with this cross-domain solution that work also for resize...
(resize not triggering : Auto resize iframe height when the height of the iframe contents change (same domain) )
Iframe :
(function() {
"use strict";
var oldIframeHeight = 0,
currentHeight = 0;
function doSize() {
currentHeight = document.body.offsetHeight || document.body.scrollHeight;
if (currentHeight !== oldIframeHeight) {
console.log('currentHeight', currentHeight);
window.parent.postMessage({height:currentHeight}, "*");
oldIframeHeight = currentHeight;
}
}
if (window.parent) {
//window.addEventListener('load', doSize);
//window.addEventListener('resize', doSize);
window.setInterval(doSize, 100); // Dispatch resize ! without bug
}
})();
Parent page :
window.addEventListener('message', event => {
if (event.origin.startsWith('https://mysite.fr') && event.data && event.data.height) {
console.log('event.data.height', event.data.height);
jQuery('#frameId').height(event.data.height + 12);
}
});
I have posted a video explaining my problem.
Sorry for the slow frame rate.
When I shrink the window too fast, the Masonry jQuery plugin seems to be too slow to keep up and therefore breaks the layout when the browser is resized too quickly. Some of the items fall below the footer, and it looks obviously wrong.
When I reload the page, as seen in the video, the layout returns to normal.
I think it is a problem is smartresize
Here is the demo page:
http://test.davewhitley.com/not-wp/isotope_test/index.php
This page successfully does it:
http://tympanus.net/codrops/collective/collective-2/
the javascript:
jQuery(document).ready(function($) {
var CollManag = (function() {
var $ctCollContainer = $('#ct-coll-container'),
collCnt = 1,
init = function() {
changeColCnt();
initEvents();
initPlugins();
},
changeColCnt = function() {
var w_w = $(window).width();
if( w_w <= 600 ) n = 2;
else if( w_w <= 768 ) n = 3;
else n = 4;
},
initEvents = function() {
$(window).on( 'smartresize.CollManag', function( event ) {
changeColCnt();
});
},
initPlugins = function() {
$ctCollContainer.imagesLoaded( function(){
$ctCollContainer.masonry({
itemSelector : '.ct-coll-item',
columnWidth : function( containerWidth ) {
return containerWidth / n;
},
isAnimated : true,
animationOptions: {
duration: 300
}
});
});
$ctCollContainer.colladjust();
$ctCollContainer.find('div.ct-coll-item-multi').collslider();
};
return { init: init };
})();
CollManag.init();
});
I had the same issue. I used bindResize on windows resize. I found this solution on their website
Masonry Methods
bindResize is at masonry.pkgd
$container.masonry({
itemSelector: '.container'
});
$(window).resize(function () {
$container.masonry('bindResize')
});
Great work by the way.
At certain points, yes, the layout goes a little crazy. Surely this is just down to the way browsers handle percentage widths + masonry. Great little tip below:
Make your container smaller, but your images larger.
.mycontainer { width: 24%; )
.mycontainer img { width: 101%; height: auto; )
http://metafizzy.co/blog/beyonce-seamless-fluid-image-masonry/