d3.style won't set width of HTML element - javascript

This one is fairly simple, but very weird:
var dims = this.placeholder.node().getBoundingClientRect();
this.mapContainer = d3.select('body').append('div')
.classed('map-container', true)
.style({
position : 'absolute',
width : dims.width,
height : dims.height,
top : dims.top,
left : dims.left
});
dims.width, dims.height, etc. return non-zero values, but the div that I get is just plain <div class="container" style="position:absolute;"></div>
I can set other style values in the console (d3.select('.map-container').style({color:'red','background-color':'blue'}) works fine), but setting width d3.select('.map-container').style({width:30,top:40}) does nothing at all.
Here's a straight jsbin where it also doesn't work: http://jsbin.com/gequrasivo/1/edit?html,js,output
What's going on here?

It's because CSS style values require a unit.
this.mapContainer = d3.select('body').append('div')
.classed('map-container', true)
.style({
position : 'absolute',
width : dims.width + 'px',
height : dims.height + 'px',
top : dims.top + 'px',
left : dims.left + 'px'
});
works fine.

Related

add up positions from css in javascript

I am trying to code a little game and therefore trying to move an object in a certain area. To get somewhat of a border I am trying to add up positions. However I will simplify this for you and this is what does not work: (in JS)
parseInt( $('#w'+w ).css( 'top' ) + $('#w'+w ).css( 'height' ) )
this should just add up the top position with the height of this element. When I print this out it will tell me it is 100. But when I print height and top without adding them up its height = 500 and top = 100 ( This is how it is in the css code ).
If i swap height and top and add this up the result is 500, so the first element. I got similar calculations, which fit. Any suggestions what went wrong in my code?
You are probably concatenating strings:
// $('#w' + w).css('top') returns the string "100px"
// $('#w' + w).css('height') returns the string "500px"
parseInt("100px" + "500px") // 100
parseInt("500px" + "100px") // 500
I suggest that you change your code to this:
parseInt($('#w' + w).css('top')) + parseInt($('#w' + w).css('height'))
for top use position:
var position = $('#w'+w ).position();
console.log( "left: " + position.left + ", top: " + position.top );
for height or width use jQuery width() and height():
console.log( "width: " +$('#w'+w ).width() + ", height: " + $('#w'+w ).height() );

Responsive DIVs overlaying on "background-size: contain" - solve the issue where the alert fires

Problem:
I am using a background-size: contain image with DIVs overlaying on top, and I want them to stay stationary relative to the scale and aspect ratio of the image.
It works, but for a small issue wherein the browser's width is less than the background image's. When this happens, you can see the overlay DIVs (.navbar and #home, respectively) begin to slide out of place, only to immediately snap back to their correct positions once the browser corrects itself.
I've written up a Fiddle that contains an alert. The alert fires when the browser width is less than the background image width. You will need to resize your browser window horizontally to get it to trigger. You can comment out the alert to observe the DIV shifting.
What is causing this, and how can I prevent it?
Code:
var width = $('.bg').width();
var height = $('.bg').height();
var imgWidth = width > height ? 350/325 * height : width;
var imgHeight = height > width ? 325/350 * width : height;
var imgTop = imgHeight * .75 + ((height - imgHeight) / 2);
$('.navbar').css({
'width': imgWidth,
'height': imgHeight * .15,
'top': imgTop + 'px'
});
$(window).on("resize", function() {
width = $('.bg').width();
height = $('.bg').height();
imgWidth = width > height ? 350/325 * height : width;
imgHeight = height > width ? 325/350 * width : height;
imgTop = imgHeight * .75 + ((height - imgHeight) / 2);
if (width < imgWidth) {
//alert(width + 'x' + height + ', ' + imgWidth + 'x' + imgHeight);
}
$('.navbar').css({
'width': imgWidth,
'height': imgHeight * .15,
'top': imgTop + 'px'
});
});
It jumps because:
You have a rectangular image--350px X 325px. So this means width === 350px and height === 325px.
You are checking whether width > height and height > width in these two lines:
imgWidth = width > height ? 350/325 * height : width;
imgHeight = height > width ? 325/350 * width : height;
i.e. You are checking whether the width (which starts out at 350px) is greater than height (325), and whether height (325) is greater than width (350).
Taking the second example: The height will not be greater than the width until after you've shrunk the window horizontally 25px (350 - 325) beyond the point where the image starts to shrink. And so, for those first 25px, the height isn't recalculated because height > width is still false.
The easiest remedy for this is simply to check against the offset--check whether width - 25 > height and whether height + 25 > width:
imgWidth = width - 25 > height ? 350/325 * height : width;
imgHeight = height + 25 > width ? 325/350 * width : height;
JSFiddle Here
Also, for what I think is cleaner code, though a more complex fix, check out this fiddle Here

Rotating Images w/jQuery... But Resizing Isn't Working

I have an image that needs to be rotated. This image is oriented either landscape or portrait.
I have an HTML5 form to accept the degrees of rotation with a step 90 each click. When this value changes, the image should rotate and resize. It should always be 770px wide, but can be as tall as it needs to be.
I've written the following event handler, but it doesn't work the way I'd expect.
Use Case: When the image is portrait, it's initial values are 770x1027 (w x h). When rotating it 90 degrees, I would expect the below function to rotate the image, set the width = 1027 and height = 770. But what I'm seeing is that both width and height are being set to 770. What am I not seeing?
$("#degrees").change(function(){
var element$ = $("#photo-submission"),
w = element$.width(),
h = element$.height(),
deg = $(this).val();
element$.removeAttr("style").attr({
"style": "-webkit-transform:rotate("+ deg +"deg); width: "+ h +"px; height: "+ w + "px;"
})
});
You seem to have switched your width and height.
element$.removeAttr("style").attr({
"style": "-webkit-transform:rotate("+ deg +"deg); width: "+ w +"px; height: "+ h + "px;"
})
How about trying it with the jQuery method actually made for changing CSS properties, that way it would be easier to keep track of your variables and place them in the right places :
$("#degrees").change(function(){
var el = $("#photo-submission"),
w = el.width(),
h = el.height(),
deg = this.value;
el.css({
'-webkit-transform' : 'rotate(' +deg+ 'deg)',
width : w,
height : h
});
});
FIDDLE
The real advantage of this is that you don't have to set the width and height to what it already is, which is basically what you're doing, so this is enough
$("#degrees").change(function(){
$("#photo-submission").css({
'-webkit-transform' : 'rotate(' + this.value + 'deg)'
});
});

fancybox is not centered

I am using fancybox 1.3.4 to show some content in popup, but the popup is not centered in browser how to fix it?
html code:
<a class="clickMe" title="" message="Last Updated: 10/1/2013">Privacy Policy</a>
js code:
$("body").on("click", ".clickMe", function(){
showAlertSized($(this).attr("title"), $(this).attr("message"), $(this).attr("width"), $(this).attr("height"));
});
function showAlertSized(title, msg, width, height) {
debugger;
if(width === undefined){
//width = 965;
width = '95%';
}
if(height === undefined) {
//height = 700;
height = '95%';
}
var content = '<h1>' + title + '</h1>' +
'<p class="msg">' + msg + '</p>' +
'<div class="fancy-btns"><input type="button" value="" onclick="closeAlert()" class="fancy-ok-btn" /></div>';
$.fancybox({
'content': content,
'hideOnOverlayClick': false,
'overlayOpacity' : 0.7,
'overlayColor' : '#777',
'width': width,
'height': height,
'autoDimensions': false,
'autoSize': false
});
}
here is the screenshot
your width and height are set to 95% of the viewport so by logic you have 5% width and height unaccounted for. Try adding 'margin': 2.5% to your fancybox initialisation call, this should put a 2.5% margin on all 4 sides of your fancybox, making it perfectly centered. Unfortunately I am unable to test this or provide a coded example, but theoretically it should work!

Fluid Width Slider

I am making a website here: argit.bounde.co.uk
I have followed a tutorial on making a slider and it works on the principle of having a ul of a big width and then the li's floated. This is then all concealed by a div which has overflow: hidden. Then have jquery which animates the margin-left = imgWidth
The rest of my site is fluid width and so obviously I need the slider to follow along other wise it looks a bit silly. At the moment I have given the li's a set width with jquery and then have img's as 100%. This solution is okay, but falls apart when the device doesn't support jQuery so I would prefer a more robust method. I cant set the ul to 100% as then the images no longer are in a line and they simple stack underneath each other
Can anyone think of a way I could achieve this?
Full slider jQuery here:
var current = 1;
function slider () {
var sliderUl = $('div#slider ul'),
imgs = sliderUl.find('img'),
imgWidth = imgs.width(),
imgLength = imgs.length,
totalImgsWidth = imgLength * imgWidth;
var direction = $(this).data('dir'),
loc = imgWidth;
if( direction == 'next') {
++current;
} else {
--current;
}
if( current === 0) {
current = imgLength;
loc = totalImgsWidth - imgWidth;
direction = 'next';
} else if ( current - 1 === imgLength ) {
current = 1;
loc = 0;
}
transition(sliderUl, loc, direction);
};
function transition( container, loc, direction ) {
var ease;
var unit;
if (direction && loc !== 0) {
unit = (direction === 'next') ? '-=' : '+=';
}
container.animate({
'margin-left': unit ? (unit + loc) : loc
})
};
I've linked to a fiddle of a plugin I programmed that does this. The requirements are that the parent container has position: relative, and to a lesser extent overflow: hidden and that it is called after images are loaded. Feel free to take the code and learn from it.
http://jsfiddle.net/dhQk/35K8X/7/show/
JS
$.fn.fitToParent = function (type, align) {
type = typeof type === 'undefined' ? 'fit' : type;
align = typeof align === 'undefined' ? 'center' : align;
return this.each(function () {
var $this = $(this);
var $parent = $(this).parent();
if ($this.is('img')) {
$this.css({
'position': 'absolute',
'width': '100%',
'height': 'auto'
}).css({ //Allow Height to adjust
'left': '',
'margin-left': '',
'top': align == 'center' ? '50%' : (align == 'left' ? '0px' : ''),
'bottom': '',
'margin-top': align == 'center' ? (-$this.height() / 2) + 'px' : ''
});
//Size by height depending on sizing type
if (($this.height() > $parent.height() && type === 'fit') || ($this.height() < $parent.height() && type === 'fill')) {
$this.css({
'width': 'auto',
'height': '100%'
}).css({ //Allow Width to adjust
'top': '',
'margin-top': '',
'left': align == 'center' ? '50%' : (align == 'left' ? '0px' : ''),
'right': align == 'right' ? '0px' : '',
'margin-left': align == 'center' ? (-$this.width() / 2) + 'px' : ''
});
}
if (type === 'none') {
$this.css({
'width': '',
'height': ''
}).css({ //Allow Width to adjust
'top': '50%',
'bottom': '',
'margin-top': (-$this.height() / 2) + 'px',
'left': align == 'center' ? '50%' : (align == 'left' ? '0px' : ''),
'right': align == 'right' ? '0px' : '',
'margin-left': align == 'center' ? (-$this.width() / 2) + 'px' : ''
});
}
}
});
};
To explain the logic, all it does is sets the width to 100% and checks if it's height is greater, if it isn't then width 100% is fine. If not it switches it to height 100%. On images if one size attribute is set then the other one resizes accordingly. After the size logic is complete. it just centers the image using position absolute and margining.
You can detect does device support jQuery:
$('html').addClass('jQuery');
And then use specific css styles for this class:
.jQuery li {
/* some style */
}
If class 'jQuery' setted then device support jQuery.
The simplest method would be to not float the your panels (li's) and set them to be 100% width of the wrapping div. Then when the user navigates, position the next panel out of view to the right at 100% margin, then animate it to 0 margin while you animate the previous panel to -100% margin. Do the opposite when the user selects the previous panel. I don't think this method works well in older IE, but I could be mistaken.
Alternatively, you can bind to the window resize event (it would be best to throttle the event) and resize the panels and any saved widths/heights

Categories

Resources