I asked this question today and got some great answers (thanks to the guys who helped me out there :) ).
Now please have a look at the following code. I'm a 100% sure the resizing part works, but my if/else statement doens't work (I'm still a JS rookie). I also mentioned this in my previous topic, but someone said I should rather post a new question.
(The script should detect someones browser width, so it can resize the #fluidimage)
note: the resizing part works. Only the viewportwidth detection and the if/else statement isnt functional yet.
$(window).load ( function () {
function resizer (index, measurement) {
var imageresize = 80;
var viewportWidth = width();
if ((viewportWidth >= 1680)) {
imageresize = 100;
} else if ((viewportWidth <= 1680) && (viewportWidth > 1280)) {
imageresize = 80;
} else if ((viewportWidth <= 1280) && (viewportWidth > 1024)) {
imageresize = 60;
} else if ((viewportWidth <= 1024) ) {
imageresize = 40;
} else {
imageresize = 100;
}
this.wCall = (typeof this.wCall == "null") ? true : this.wCall ^ true;
return this.wCall ? Math.round (measurement * imageresize / 100) : measurement;
}
$("#fluidimage").width (resizer).height (resizer);
} );
Change:
var viewportWidth = width();
To:
var viewportWidth = $(window).width();
See it at jsFiddle.
Related
I have a webpage that when scrolled down, the text freezes when it reaches the last paragraph of text but the images keep on scrolling. I've got the implementation working but there is a lot of jank when scrolling with a mouse wheel, not so much if I click and drag the scroll bar.
Are there any optimizations I can make to this code to make work as intended or is there a different way to accomplish the same task?
window.addEventListener('scroll', function (e) {
window.requestAnimationFrame(keepTextStationary);
//keepTextStationary(); // Less janky, but still horrible
});
function keepTextStationary() {
var textRect = writtenContent.getBoundingClientRect();
var imageRec = images.getBoundingClientRect();
if (textRect.bottom < window.innerHeight && document.documentElement.scrollTop > 0) {
writtenContent.style.position = 'relative';
writtenContent.style.bottom = (225 - document.documentElement.scrollTop) + 'px';
if (imagesTop === undefined) {
imagesTop = imageRec.y;
}
} else {
writtenContent.style.bottom = (225 - document.documentElement.scrollTop) + 'px';
}
if (imageRec.y >= imagesTop) {
writtenContent.style.position = '';
}
}
Here is the site so you can see the problem.
https://bowerbankninow.azurewebsites.net/exhibitions/oscar-perry-the-pheasant
You are causing layout trashing every time you call getBoundingClientRect. Try debouncing your scroll events:
var lastScrollY = 0;
var ticking = false;
function keepTextStationary() {
var textRect = writtenContent.getBoundingClientRect();
var imageRec = images.getBoundingClientRect();
if (textRect.bottom < window.innerHeight && lastScrollY > 0) {
writtenContent.style.position = 'relative';
writtenContent.style.bottom = (225 - lastScrollY) + 'px';
if (imagesTop === undefined) {
imagesTop = imageRec.y;
}
} else {
writtenContent.style.bottom = (225 - lastScrollY) + 'px';
}
if (imageRec.y >= imagesTop) {
writtenContent.style.position = '';
}
ticking = false;
}
function onScroll() {
lastScrollY = document.documentElement.scrollTop;
requestTick();
}
function requestTick() {
if (!ticking) {
requestAnimationFrame(keepTextStationary);
ticking = true;
}
}
window.addEventListener('scroll', onScroll );
See this article for in-depth explanation: https://www.html5rocks.com/en/tutorials/speed/animations/
You dont.
Relocations / styling in javascript take place after the CSS has been loaded. Bad practise. What you can do, is make it animated to make it look less horrible.
Why is pure CSS not an option ?
I have this pop up window being centered by javascript using px. I need the box to be responsive so how can I adjust the script to calculate for percentages and not px. Is it possible? This current code allows me to produce an automatic pop up but it also has script that centers the pop using px. This is not responsive.
function toggle(div_id) {
var el = document.getElementById(div_id);
if ( el.style.display == 'none' ) { el.style.display = 'block';}
else {el.style.display = 'none';}
}
function blanket_size(popUpDivVar) {
if (typeof window.innerWidth != 'undefined') {
viewportheight = window.innerHeight;
} else {
viewportheight = document.documentElement.clientHeight;
}
if ((viewportheight > document.body.parentNode.scrollHeight) && (viewportheight > document.body.parentNode.clientHeight)) {
blanket_height = viewportheight;
} else {
if (document.body.parentNode.clientHeight > document.body.parentNode.scrollHeight) {
blanket_height = document.body.parentNode.clientHeight;
} else {
blanket_height = document.body.parentNode.scrollHeight;
}
}
var blanket = document.getElementById('blanket');
blanket.style.height = blanket_height + 'px';
var popUpDiv = document.getElementById(popUpDivVar);
popUpDiv_height=blanket_height/2-187.5;//200 is half popup's height
popUpDiv.style.top = popUpDiv_height + 'px';
}
function window_pos(popUpDivVar) {
if (typeof window.innerWidth != 'undefined') {
viewportwidth = window.innerHeight;
} else {
viewportwidth = document.documentElement.clientHeight;
}
if ((viewportwidth > document.body.parentNode.scrollWidth) && (viewportwidth > document.body.parentNode.clientWidth)) {
window_width = viewportwidth;
} else {
if (document.body.parentNode.clientWidth > document.body.parentNode.scrollWidth) {
window_width = document.body.parentNode.clientWidth;
} else {
window_width = document.body.parentNode.scrollWidth;
}
}
var popUpDiv = document.getElementById(popUpDivVar);
window_width=window_width/2-250;//200 is half popup's width
popUpDiv.style.left = window_width + 'px';
}
function popup(windowname) {
blanket_size(windowname);
window_pos(windowname);
toggle('blanket');
toggle(windowname);
}
This seems like an awful lot of javascript to display a popup dialog. You can accomplish this functionality with CSS/HTML alone, although many solutions will use HTML/CSS for the layout, and some javascript to show/hide the dialog.
I dont like to use javascript at all for the actual layout of the webpage, such as positioning elements. CSS was designed specifically for positioning and styling web elements, and it is generally more efficient than JS.
You may want to check out some of the many guides available online for HTML/CSS Modal Dialogs. These are done with minimal javascript.
Check out this one for starters
http://www.webdesignerdepot.com/2012/10/creating-a-modal-window-with-html5-and-css3/
Good luck
You really don't need JavaScript to center something - for that, we have CSS! To center something horizontally, simply use the following CSS on the element
margin: auto;
To center something vertically, you can use something like
top: 50%;
transform: translateY(-50%);
position:relative;
I am using this code to adjust the text size depending on the length of text inside the element title. This works great until the user adjusts the size of the browser. What can be done to allow the text size to be adjusted if the user's window is made smaller. Say for instance if window width is less than 600 pixels, than change font size.
How can this be made to on page load, do what the code does now - but also change font sizes when browser size is adjusted as well?
$(".title").css('font-size', function () { // get length of text for title and adjust font size
var $numWords = $(this).text().length;
if (($numWords >= 1) && ($numWords < 40)) {
return "26px";
}
else if (($numWords >= 40) && ($numWords < 60)) {
return "24px";
}
else if (($numWords >= 60) && ($numWords < 100)) {
return "22px";
}
else if (($numWords >= 100)) {
return "20px";
}
});
<div id="cont" style="font-family: Verdana; background-color: #ccc;">
<div id="textContent">fox jump over the lazy dog...fox jump over the lazy dog...fox jump over the lazy dog</div>
</div>
<script>
var textContainer = document.getElementById('cont');
var text = document.getElementById('textContent');
var textLength = text.innerText.length;
var firstLoadWidth;
if (textLength >= 1 && textLength < 40) {
cont.style.fontSize = '26px';
}
else if (textLength >= 1 && textLength < 60) {
cont.style.fontSize = '24px';
}
else if (textLength >= 1 && textLength < 100) {
cont.style.fontSize = '22px';
}
else if (textLength > 100) {
cont.style.fontSize = '20px';
}
window.addEventListener('load', function () {
firstLoadWidth = window.innerWidth;
});
window.addEventListener('resize', function () {
var getSize = window.innerWidth / firstLoadWidth;
getSize <= 1 ? text.style.fontSize = getSize + 'em' : text.style.fontSize = '1em';
}, false);
</script>
You can use jQuery's resize() function for that (http://api.jquery.com/resize/)
$(document).ready(function() {
onResize()
});
onResize = function() {
if(window.width() < 600){
// Do stuff
}
}
$(window).bind('resize', onResize);
You can measure the actual rendered size of the text like this:
var text = $(this).text();
var tmp = $("<div/>").css({position: "absolute"}).text(text);
$("BODY").append(tmp);
var width = tmp.width();
tmp.remove();
If you make sure your div is styled as it will be on the page (same font, weight, size), then this can tell you how big it will be. It should be possible to iterate this to search for a size that fits the available space (with some reasonable cutoff). This will be slow if you have hundreds or thousands of these on a page, but for a couple of titles it should be fine.
just use the percentage in your font-size
p {
font-size:200%;
}
the percentage is due to the width of the parent tags "div"
I am trying to scroll by highlighting text and dragging down. Now, as you are probably aware, this is standard, default behavior for a standard overflow: auto element, however I am trying to do it with some fancy scrollbars courtesy of jQuery jScrollPane by Kelvin Luck.
I have created a fiddle here: DEMO
basically as you can see, highlighting and scrolling works in the top box (the default overflow: auto box) but in the second it doesn't and, to compound matters, once you reach the bottom it INVERTS your selection!
So, my question(s) is(are) this(these): is there a way to fix this? If so, how?
UPDATE
I have been working on this quite a bit and have found a slight solution using setTimeout()
however, it doesn't work as intended and if anybody is willing to help I have forked it to a new fiddle here: jsFiddle
the code itself is:
pane = $('#scrolldiv2');
pane.jScrollPane({animateEase: 'linear'});
api = pane.data('jsp');
$('#scrolldiv2').on('mousedown', function() {
$(this).off().on('mousemove', function(e) {
rel = $(this).relativePosition();
py = e.pageY - rel.y;
$t = $(this);
if (py >= $(this).height() - 20) {
scroll = setTimeout(scrollBy, 400, 20);
}
else if (py < 20) {
scroll = setTimeout(scrollBy, 400, -20);
}
else {
clearTimeout(scroll);
}
})
}).on('mouseup', function() {
$(this).off('mousemove');
clearTimeout(scroll);
})
var scrollBy = function(v) {
if (api.getContentPositionY < 20 & v == -20) {
api.scrollByY(v + api.getContentPositionY);
clearTimeout(scroll);
} else if (((api.getContentHeight - $t.height()) - api.getContentPositionY) < 20 & v == 20) {
api.scrollByY((api.getContentHeight - $t.height()) - api.getContentPositionY);
clearTimeout(scroll);
} else {
api.scrollByY(v, true)
scroll = setTimeout(scrollBy, 400, v)
}
}
$.fn.extend({
relativePosition: function() {
var t = this.get(0),
x, y;
if (t.offsetParent) {
x = t.offsetLeft;
y = t.offsetTop;
while ((t = t.offsetParent)) {
x += t.offsetLeft;
y += t.offsetTop;
}
}
return {
x: x,
y: y
}
},
})
You just have to scroll down/up depending on how close the mouse is to the end of the div; is not as good as the native solution but it gets the job done ( http://jsfiddle.net/PWYpu/25/ )
$('#scrolldiv2').jScrollPane();
var topScroll = $('#scrolldiv2').offset().top,
endScroll = topScroll + $('#scrolldiv2').height(),
f = ($('#scrolldiv2').height() / $('#scrolldiv2 .jspPane').height())*5 ,
selection = false,
_prevY;
$(document).mousemove(function(e){
var mY;
var delta = _prevY - e.pageY;
if((e.pageY < endScroll && (mY = ((e.pageY - endScroll + 80)/f)) > 0) ||
(e.pageY > topScroll && (mY = (e.pageY - (topScroll + 80))/f) < 0)){
if(selection && (delta > 10 || delta < -10) )
$('#scrolldiv2').data('jsp').scrollByY(mY, false) ;
}
})
$('#scrolldiv2').mousedown(function(e){_prevY = e.pageY; selection = true ;})
$(window).mouseup(function(){selection = false ;})
BTW, the reason it inverts the selection is because it reached the end of the document, just put some white space down there and problem solved.
I really hate to say it, I know it's an issue even I ran into with the update to this plugin, but in the old plugin (seen here) it works just fine with basic call. So I just reverted my copy.
I have this very usefull little piece of javascript that centers mig div. By i would like to make it apply to 3 divs on the same site, without repeating the same piece of code 3 times.
Any ideas on how to do it?
Putting all 3 divs into 1 divs that takes care of it, is not and option.
<script type="text/javascript">
<!--
function getWindowHeight() {
var windowHeight = 0;
if (typeof(window.innerHeight) == 'number') {
windowHeight = window.innerHeight;
}
else {
if (document.documentElement && document.documentElement.clientHeight) {
windowHeight = document.documentElement.clientHeight;
}
else {
if (document.body && document.body.clientHeight) {
windowHeight = document.body.clientHeight;
}
}
}
return windowHeight;
}
function setContent() {
if (document.getElementById) {
var windowHeight = getWindowHeight();
if (windowHeight > 0) {
var contentElement = document.getElementById('outer');
var contentHeight = contentElement.offsetHeight;
if (windowHeight < 570) {
contentElement.style.position = 'relative';
contentElement.style.top = '30px';
}
else if (windowHeight - contentHeight > 0) {
contentElement.style.position = 'relative';
contentElement.style.top = ((windowHeight / 2) - (contentHeight / 2)) + 'px';
}
else {
contentElement.style.position = 'static';
}
}
}
}
window.onload = function() {
setContent();
}
window.onresize = function() {
setContent();
}
//-->
</script>
Regards Troels
You don't need to check if document.getElementById exists. It has been supported since the Roman Empire.
Pass the id or the actual element that has to be centered to your function. That removes the dependency on a fixed element (#outer) in your case and makes it more flexible. Also try to name your functions to be indicative of what they are actually doing. setContent is a very generic name and doesn't indicate the centering aspect anywhere.
function centerElementWithId(id) {
..
var contentElement = document.getElementById(id);
..
}
Then call it thrice,
centerElementWithId('outer')
centerElementWithId('secondDiv')
centerElementWithId('thirdDiv');