I am trying to give my container element height and width via jQuery .css() but my code is setting it as window height and width. Can anyone please tell me why is the code not working?
Below is the code:
$(document).ready(function () {
var H = $(window).height();
var W = $(window).width();
var h = W / 1.625;
var w = H * 1.625;
if (w > W) {
$("#container").css("height", h + 'px').css("maxWidth", W + 'px;');
else {
$('#container').css("maxHeight", H + 'px').css("width", w + 'px;');
}
});
Your if statement is missing a }, so won't work in the first place. Change:
if(w>W)
{
$("#container").css("height", h+'px').css("maxWidth", W+'px;');
else
...
To:
if(w>W)
{
$("#container").css("height", h+'px').css("maxWidth", W+'px;');
}
else
...
Also as you're setting multiple CSS properties, you can combine these into one CSS method by passing the properties in as an object:
if (w>W)
{
$("#container").css({height:h, maxWidth:w});
}
...
jQuery sorts out the px for you in most cases. See jQuery's css() documentation for more info. :)
You're missing a closing brace } on the if, so your code should look like,
if (w > W) {
$("#container").css("height", h + 'px').css("maxWidth", W + 'px;');
}
else {
$('#container').css("maxHeight", H + 'px').css("width", w + 'px;');
}
You could improve your code readability by, passing your css properties as a part of an object, as opposed to chaining, as adding many properties is rather helpful when you pass them as an object.
if (w > W) {
$("#container").css({
"height": h + 'px',
"max-width": W + 'px'
});
}
else {
$("#container").css({
"max-height": H + 'px',
"width": w + 'px'
});
}
Related
I have a selection on a canvas, that I can drag and resize when it´s there.
I also can make it visible when I drag on the empty canvas.
But how do I make it visible and instantly have the bottom-right corner "in my hand" (for resizing); i.e. can I pass the drag event from the canvas to a resize event on the selection?
Is there a way with jQuery or do I have to make my own?
<div id="canvas" style="position:relative;width:500px;height:500px"
draggable="true" onDragStart="initSelection(event)">
<div id="selection" style="border:1px dashed gray;position:absolute;display:none"></div>
</div>
$('#selection').draggable({containment:'parent'}).resizable({containment:'parent'});
function initSelection(e){
if ('none'==$('#selection').css('display'))
{
var q=$('#canvas').offset();
$('#selection')
.css('left', e.clientX-q.left)
.css('top', e.clientY-q.top)
.css('width',10).css('height',10)
.css('display','block')
;
}
}
I think I see what you're trying to do.
Testing here: jsfiddle.net/Twisty/vkLjn0gL
I think you need to take one route or the other, not both at once.
resize the div with CSS based on the mousedown / mouseup events and
mouse x and y.
make it resizable up front and enable/start the resize
event tied to the mousemove until done and then make it draggable
I got this far when you posted that you found an answer: https://jsfiddle.net/Twisty/vkLjn0gL/5/
$(function() {
$("#canvas").on("dragstart", initSelection);
$("#canvas").on("mousemove", resize);
$("#canvas").on("mouseup", function() {
allowResize = false;
});
var allowResize = false;
/*
$('#selection').draggable({
containment: 'parent'
}).resizable({
containment: 'parent'
});
*/
function initSelection(e) {
if ('none' == $('#selection').css('display')) {
var q = $('#canvas').offset();
$('#selection')
.css('left', e.clientX - q.left)
.css('top', e.clientY - q.top)
.css('width', '10px').css('height', '10px')
.css('display', 'block');
allowResize = true;
}
}
function resize(e) {
if (allowResize) {
//console.log("MouseMove: ", e);
var w = $("#selection").width(),
h = $("#selection").height(),
q = $("#canvas").offset(),
px = 0,
py = 0;
px = e.clientX - q.left;
py = e.clientY - q.top;
console.log("Width: ", (w + px), " Height: ", (h + py));
$("#selection").css({
width: (w + px) + "px",
height: (h + py) + "px"
});
}
}
});
Update 1
Few fixes to mouse tracking:
https://jsfiddle.net/Twisty/vkLjn0gL/6/
function resize(e) {
if (allowResize) {
//console.log("MouseMove: ", e);
$("#canRes").html(allowResize);
$("#cx").html(e.clientX - $("#canvas").offset().left);
$("#cy").html(e.clientY - $("#canvas").offset().top);
$("#ox").html($("#selection").width());
$("#oy").html($("#selection").height());
var w = $("#selection").width(),
h = $("#selection").height(),
q = $("#canvas").offset(),
o = $("#selection").position();
px = 0,
py = 0;
if (w > $("#canvas").width() + q.left) {
return false;
}
if (h > $("#canvas").height() + q.top) {
return false;
}
px = e.clientX - q.left - o.left;
py = e.clientY - q.top - o.top;
$("#selection").css({
width: px + "px",
height: py + "px"
});
}
}
Update 2
I think this will do all that you wanted if you're still looking: https://jsfiddle.net/Twisty/vkLjn0gL/7/
Updated to selection after mouseup
$("#canvas").on("mouseup", function() {
allowResize = false;
$("#canRes").html(allowResize);
$("#selection").draggable({
containment: 'parent'
})
.resizable({
containment: 'parent'
});
});
Update 3
Added the drag handle on initial sizing: https://jsfiddle.net/Twisty/vkLjn0gL/10/
The problem is therein, that element.style.width returns a string, and not a number.
I want to do increase the width like so:
element.style.width += 100;
, but it remains the same. My solution is to take one of the long ways:
element.style.width = element.offsetWidth + 100;
element.style.width = parseInt(element.style.width) + 100;
(Thankfully, it doesn't require + 'px')
Is there a better way to do this?
You can do so:
var computedStyles = window.getComputedStyle(element, null);
var width = window.parseInt(computedStyles.width, 10);
element.style.width = (width + 100) + 'px';
or with jQuery you can do like this:
$(element).css("width", "+=200");
See more about it http://api.jquery.com/css/
You could also try this, though it is not particularly apposite or compact;
element.setAttribute("style","width:" + (element.offsetWidth + 100) + "px");
A fiddle example
I want to calculate the size of an element depending on the window size.
This code works:
var photoHeight = function() {
return {
'height' : ($(window).height() / 15) + 'px'
}
}
$(document).ready(function() {
var $obj = $('#photo');
var photoCss = photoHeight();
$obj.css( photoCss );
$(window).resize(function () {
$obj.css( photoCss );
});
});
But i need to subtract instead of divide.
If i change
'height' : ($(window).height() / 15) + 'px'
to
'height' : ($(window).height() - 15) + 'px'
The value seems to be 'undefined' and no .css is applied.
The full calculation should be something like this:
'height' : ($(window).height() - $('#page-header').outerHeight() - $('#page-footer').outerHeight() - 50) + 'px'
You don't need the photoHeight() function (it's simpler without):
$(document).ready(function() {
var $obj = $('#photo');
$obj.css("height", $(window).height() / 15);
$(window).resize(function () {
$obj.css("height", $(window).height() / 15);
});
});
Also note: if you set a variable photoCSS to photoHeight(), it won't change, even when the window resizes. If you want to use a function, go with something like $obj.css(photoHeight());
I'm looking for an effect very similar to this:
http://jsfiddle.net/G5Xrz/
function rnd(max) { return Math.floor(Math.random()*(max+1)) }
function showImage(container, maxwidth, maxheight, imgsrc, imgwidth, imgheight) {
var id = "newimage" + rnd(1000000);
$(container).append(
"<img id='" + id + "' src='" + imgsrc +
"' style='display:block; float:left; position:absolute;" +
"left:" + rnd(maxwidth - imgwidth) + "px;" +
"top:" + rnd(maxheight - imgheight) + "px'>");
$('#' + id).fadeIn();
return id;
}
setInterval(
function() {
showImage("#container", 400, 600,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
But i'd prefer a flexible layout, ie images not bound by a div with predefined height and width, instead responding to the dimensions of the browser.
The following piece of code seems to have a more appropriate way of generating the random positions:
http://jsfiddle.net/Xw29r/15/
function makeNewPosition(){
// Get viewport dimensions (remove the dimension of the div)
var h = $(window).height() - 50;
var w = $(window).width() - 50;
var nh = Math.floor(Math.random() * h);
var nw = Math.floor(Math.random() * w);
return [nh,nw];
}
function animateDiv(){
var newq = makeNewPosition();
var oldq = $('.a').offset();
var speed = calcSpeed([oldq.top, oldq.left], newq);
$('.a').animate({ top: newq[0], left: newq[1] }, speed, function(){
animateDiv();
});
};
However I'm very much a beginner with javascript and I don't know how to combine the two.
Can anyone help?
Thanks
Take this part from the second code:
// Get viewport dimensions (remove the dimension of the div)
var h = $(window).height() - 50;
var w = $(window).width() - 50;
and use those variables h and w with the browser height and width (minus 50) as the appropriate parameters in this part of the first code:
setInterval(
function() {
showImage("#container", 400, 600,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
Also, the first code has this HTML:
<div id="container" style="width:400px; height:600px; background: green; position:relative"></div>
That hard-codes the height and width at pixel values. You can use a CSS percentage value to make the width respond to the parent container's size. However, you will need JS to set the height properly; a percentage for the height does nothing
Putting that all together (and removing the "minus 50" part), you get this:
jsFiddle demo
<div id="container" style="width:100%; height:100px; background: green; position:relative"></div>
function adjustContainerHeight(height) {
$('#container').height(height);
}
adjustContainerHeight($(window).height());
setInterval(
function() {
var h = $(window).height();
var w = $(window).width();
adjustContainerHeight(h);
showImage("#container", w, h,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
This updates the height of the container when the page is first loaded, and once again whenever the random image is placed. More robust code would have a separate height-adjusting event handler that updates the height whenever the page size changes.
I have a simple function that sets the width of a bar based on an argument.
And I call the function on .each with jQuery.
The console logs the statement correctly, showing me it seems to work. However, the style seems to be overridden by the last value found.
Here is the function:
function barGraph(innerWidth, barWidth) {
innerWidth = parseInt(innerWidth) * .01 || .50;
barWidth = parseInt(barWidth) || 267;
// find percentage of total width
var innerWidth = Math.floor(innerWidth * barWidth);
var $innerBar = $('.slider-box div');
$innerBar.css('width', innerWidth + 'px');
console.log("Width should be: " + innerWidth + 'px');
}
then i call the function on each with jQuery:
$(document).ready(function() {
var $innerBar = $('.slider-box div');
$innerBar.each(function(index) {
var newWidth = $(this).attr("data-bar-width");
barGraph(newWidth, 267);
});
});
the console log shows 10 times, with all appropriate widths. However, the style for all is the same as the last width.
Can someone help explain how I get the function to set the width of the currently selected div?
Thanks so much in advance,
Adam.
Let's break it down
$(document).ready(function() {
var $innerBar = $('.slider-box div');
// going to call the barGraph function on each matching element
// so far, so good
$innerBar.each(function(index) {
var newWidth = $(this).attr("data-bar-width");
barGraph(newWidth, 267);
});
});
Then in barGraph
function barGraph(innerWidth, barWidth) {
innerWidth = parseInt(innerWidth) * .01 || .50;
barWidth = parseInt(barWidth) || 267;
// find percentage of total width
var innerWidth = Math.floor(innerWidth * barWidth);
// getting all the matching elements (again)
var $innerBar = $('.slider-box div');
// setting the width of each matched element to
// the innerwidth calculated in this barGraph call.
$innerBar.css('width', innerWidth + 'px');
console.log("Width should be: " + innerWidth + 'px');
}
So, the barGraph function is run as many times as there are matched elements in $('.slider-box div'), but each run sets the width of all matched elements. In effect, the last run will set the width of all matched elements to whatever the innerWidth is calculated to be on the last run. Is that what you want to happen?
What is more likely is perhaps something like this
$(function() {
var $innerBar = $('.slider-box div');
// going to call the barGraph function on each matching element
// so far, so good
$innerBar.each(function(index) {
var bar = $(this),
newWidth = bar.attr("data-bar-width");
barGraph(bar, newWidth, 267);
});
function barGraph(bar, innerWidth, barWidth) {
innerWidth = parseInt(innerWidth, 10) * .01 || .50;
barWidth = parseInt(barWidth, 10) || 267;
innerWidth = Math.floor(innerWidth * barWidth);
bar.css('width', innerWidth + 'px');
console.log("Width should be: " + innerWidth + 'px');
}
});
If the barGraph function is not used outside of the each call, then I might be inclined to move the function body inside of the anonymous function passed to each or modify barGraph function to be the function passed to each i.e.
$(function() {
$('.slider-box div').each(barGraph);
function barGraph(index, element) {
var bar = $(this),
newWidth = bar.attr("data-bar-width");
newWidth = parseInt(newWidth , 10) * .01 || .50;
newWidth = Math.floor(innerWidth * 267);
bar.css('width', newWidth + 'px');
console.log("Width should be: " + newWidth + 'px');
}
});
the problem is in here, have a look at your barGraph function:
var $innerBar = $('.slider-box div'); //here you choose all divs inside .slider-box
$innerBar.css('width', innerWidth + 'px'); //and set the width for all of them
change the barGraph function:
function barGraph(innerWidth, barWidth) {
innerWidth = parseInt(innerWidth) * .01 || .50;
barWidth = parseInt(barWidth) || 267;
// find percentage of total width
var innerWidth = Math.floor(innerWidth * barWidth);
var $innerBar = $('.slider-box div');
$innerBar.each(function(index){
$(this).css('width', innerWidth + 'px');
});
console.log("Width should be: " + innerWidth + 'px');
}
this may happen bacause on last barGraph() call you set all $('.slider-box div');
with last value you read into the each()
what if you try something like this
function barGraph(el, innerWidth, barWidth) {
...
el.css('width', innerWidth + 'px');
console.log("Width should be: " + innerWidth + 'px');
}
$(document).ready(function() {
var $innerBar = $('.slider-box div');
$innerBar.each(function(index, el) {
var newWidth = $(el).attr("data-bar-width");
barGraph($(el), newWidth, 267);
});
});
in this approach I passed a jQuery reference to each element, to the barGraph() function. It's also less expensive than before, since you always create a jQuery reference to a div collection.
In your barGraph function you select all instances of .slider-box div and set the width. You only want to set the one you are currently working with.
function barGraph($bar, innerWidth, barWidth) {
innerWidth = parseInt(innerWidth) * .01 || .50;
barWidth = parseInt(barWidth) || 267;
// find percentage of total width
var innerWidth = Math.floor(innerWidth * barWidth);
$bar.css('width', innerWidth + 'px');
console.log("Width should be: " + innerWidth + 'px');
}
by passing the bar into barGraph during the loop.
$(document).ready(function() {
var $innerBar = $('.slider-box div');
$innerBar.each(function(index) {
var $bar = $(this)
, newWidth = $bar.attr("data-bar-width");
barGraph($bar, newWidth, 267);
});
});
You may also want to move the selection of the width into the barGraph function to keep things clean.
Like most of jQuery's functions, css() works on collections as well as on single elements. Since $('.slider-box div') returns a collection, the CSS rule will be applied to all of the divs on every iteration of the each loop. So for 10 divs, barGraph will be called 10 × 10 = 100 times. And because the divs stay in the same order, the newWidth of the last div will be applied to all of the divs.
To apply the newWidth only to the current element in the each loop, you could keep all your logic inside that function:
var $innerBar = $('.slider-box div');
$('.slider-box div').each(function(index, element) {
var $this = $(this);
var innerWidth = ($this.attr("data-bar-width") / 10) || 0.5;
var barWidth = 267;
innerWidth = Math.floor(innerWidth * barWidth);
$this.css('width', innerWidth); // Note: no need to append 'px'; jQuery
});
This works pretty well as long as the logic is simple (a couple of lines at most) and you don't need to use it elsewhere. But when your code gets a bit more complex, you might want to brake it out into a separate function. Since you had already done this, let's look at some other solutions.
Two common solutions:
Eiter: pass the current element as a parameter of the function;
or: make it into a jQuery plugin.
The first is pretty simple:
function barGraph(element, innerWidth, barWidth) {
var $this = $(element);
// et cetera
}
// Call like this:
$('.slider-box div').each(function(index) {
var newWidth = $(this).attr("data-bar-width");
barGraph(this, newWidth, 267);
});
Like I said: simple. But it's not very neat, is it? The second solution is a bit more elegant:
$.fn.barGraph = function(barWidth) {
var $this = this; // `this` is already a jQuery object
var innerWidth = ($this.attr("data-bar-width") / 10) || 0.5;
barWidth = barWidth || 267;
innerWidth = Math.floor(innerWidth * barWidth);
$this.css('width', innerWidth);
};
// Use like this:
$('.slider-box div').each(function(index) {
$(this).barGraph(267);
});
And that's how easy it is to write your own jQuery plugin! Of course, it can use a little work, like a more descriptive name and support for chainability.