Javascript/Jquery flow text into divs - javascript

How do I flow a text stream from one div to the next? Each div has a fixed height and width and I need the data to be passed to the first, then if that is filled overflow to another etc. (The second etc. divs need to be dynamically created). Eventually the divs will be contenteditable, this is the page technique for a simple WYSIWYG style editor.
Please help...
JS Fiddle (note zoom in use on body)(I need to reflow on keyup/down, make pages and remove as necessary and be able to add in the middle)
function loadgo(){
run();
var h = document.getElementById('page'+(document.getElementById("pagecount").value-1)).offsetHeight;
document.getElementById("loadgo").value = h+1;
if (h > 1135){
var pagecount = document.getElementById("pagecount").value;
//$('body').append("<div class=page style='color:#F00' id='page"+pagecount+"' contenteditable>"+this.id+"</div>");
var objTo = document.body;
var divtest = document.createElement("div");
divtest.style.color = '#F00';
divtest.id = "page"+pagecount;
divtest.className = 'page';
divtest.contentEditable = "true";
divtest.innerHTML = "new div";
objTo.appendChild(divtest);
document.getElementById("page"+pagecount).focus();
document.getElementById("pagecount").value++;
zoomin();zoomout();
run();
}
}
function run(){
setTimeout(function() {
loadgo();
}, 500);
}
loadgo();

What you're looking for is called CSS Regions. This allows your text to flow through various containers placed on your site.
You can read about it on Adobe's site, and Apple has a nice WWDC video explaining how to implement it (starts at 8:40). Also check out the Editor's Draft.

Related

Javascript applied CSS3 transitions not working on new element

I'm using a mixture of CSS/JS to create some simple page slide transitions for new pages, that will eventually be loaded dynamically by AJAX, however on creation of the new element "main2" which has the necessary -webkit-transition etc. it does not slide in like it should, but simply appears. The previous page however slides out fine, using basically the same code.
As well as this, changing the slide in to after the animation for the previous page has finished like so:
function newPage() {
var newMain = document.createElement("div");
newMain.className = "main";
newMain.style.left = "100vw";
newMain.id = "main2";
newMain.style.zIndex = 1999;
newMain.style.background = "#AAA";
document.body.appendChild(newMain);
oldMain = document.getElementById("main");
oldMain.style.left = "-50vw";
setTimeout(function() {
newMain.style.left = "50vw";
oldMain.parentNode.removeChild(oldMain);
newMain.id = "main";
}, 1000);
}
makes it animate in, just not at the right time.
Any help would be appreciated, I'm sure it's just something glaringly simple that I've missed.
Demo: JSFiddle
Try this: http://jsfiddle.net/5raj05th/8/
I changed the code so you do trigger the transition by adding the style:
newMain.style.left = "100vw";
and later:
newMain.style.left = "0";

JavaScript page resizing

I know that you don't normally like doing things like this but I'm at University and have to do a project with several different stylesheets for the same page. I have been given JavaScript code to enable me to resize the page when the window is resized.
This code works however I am getting a peculiar effect on one of the stylesheets where the content div takes up most of the page when it shouldn't, this page has measurements in ems whereas my other stylesheets use px but I am supposed to use ems for at least one page. Although I could give my lecturer a reason for it being bigger I would prefer to fix the problem. The JavaScript code I am using is shown below:
function smoothresize() {
blockwidth = 59.4; /*This is in ems as per the lecturers request a well and is the size of the container div I created*/
minmargin = 0;
minsize = 10;
emwidth = (minmargin * 2) + blockwidth;
computeResize(emwidth, minsize, false)
}
function computeResize(wide, minsize, jerk) {
windowpixels = document.documentElement.clientWidth;
pixelsize = windowpixels / wide;
emsize = calculateEmsize(pixelsize, minsize, jerk);
b = document.getElementsByTagName('html')[0];
b.style.fontSize = emsize + "em";
}
function calculateEmsize(psize, minsize, jerk) {
if (psize > minsize) {
raw = psize;
}
else {
raw = minsize;
}
if (jerk) {
result = ((Math.floor(raw)) / 16);
}
else {
result = raw / 16;
}
return result
}
This is where I have Implemented the code in my XHTML:
<body onload="smoothresize()" onresize="smoothresize()">
I wouldn't be able to use jQuery as a solution to the problem either, I would only be able to modify the code given.
Any help in this matter Would be greatly appreciated
Check out jQuery's user interface plugin. It contains a "resizable" option; you ought to be able to add <script type="text/javascript">window.onload=function(){};</script> that loads the desired JQUI function upon page load.

Slide Out Panel that appends to a DIV

I'm attempting to create a slide out panel that appends to the container div within the header and footer of my page. I'm using Bootstrap for responsive, so the solution should ideally work with the media-queries contained within that package. I'm really at a loss on how to approach this because everything I've tried doesn't seem to work in some way or another.
This picture animates best what I'm trying to accomplish (sorry not a designer):
http://d.pr/i/DzQc+
What I've tried:
Pageslide - this is was the closest solution I've found so far. this appends the slide out panel to the body. As such it doesn't allow me to keep the slide out panel within the header/footer container of the page: http://srobbin.com/jquery-plugins/pageslide/
jQuery Mobile Panel Widget - I tried to hack and repurpose the jQuery mobile panel widget plugin to function as desired without any luck.
.append Function - I tried to animate the .append function but this didn't work with the responsive functions of bootstrap.
With that all said, do any of you have a suggestion on a plugin, function or implementation that may work? I'm not necessarily looking for a working piece of code, rather I'm looking for a direction that will work as I'm hoping.
Thanks!
Here is a popup container in a prototype pattern I built that you can create to any div. CSS it up to style to your liking
Useage:
InfoPopup.Create('YourDivID');
InfoPopup.Destroy();
InfoPopup.Bounce();
$(InfoPopup.YesBtn).fadeIn();
$(InfoPopup.NoBtn).fadeIn();
$(InfoPopup.ShowBtn).fadeIn();
Ect...
InfoPopup = {
YesBtn:'',
NoBtn:'',
ShowBtn:'',
IdlBtn:'',
HintText:'',
Create:function(target, contentId){
var infoImage = "";
var infoWrapperDiv = document.createElement('div');
infoWrapperDiv.id = 'infoWrapperDiv';
//min-max button
var minMax = document.createElement('img');
minMax.src = "images/minimize.png"
minMax.id = 'infoPopupMinMax';
minMax.setAttribute('onClick','InfoPopup.Shrink();');
infoWrapperDiv.appendChild(minMax);
//content
var contentDiv = document.createElement('div');
contentDiv.id = 'infoPopupContent';
contentDiv.innerHTML = '<span>Some Stuff Here</span>'
infoWrapperDiv.appendChild(contentDiv);
//YesNoButtons - append to infoWrapperDiv if needed in specific activity
//---- set custom onClick for the specific Activity in the switch
this.YesBtn = document.createElement('input');
this.YesBtn.id = 'infoBtnYes';
this.YesBtn.setAttribute('value','Yes');
this.YesBtn.setAttribute('type','button');
this.YesBtn.className = 'inputButton';
this.NoBtn = document.createElement('input');
this.NoBtn.id = 'infoBtnNo';
this.NoBtn.setAttribute('value','No');
this.NoBtn.setAttribute('type','button');
this.NoBtn.className = 'inputButton';
this.ShowBtn = document.createElement('input');
this.ShowBtn.id = 'infoBtnShow';
this.ShowBtn.setAttribute('type','button');
this.ShowBtn.setAttribute('value','Show');
this.IdlBtn = document.createElement('input');
this.IdlBtn.setAttribute('type','button');
this.HintText = document.createElement('div');
this.HintText.className = 'infoPopupHint';
switch(contentId){//Remove switch to just set up the content
case 1://on a 1 page web app the activity will dictate what content is presented
this.YesBtn.setAttribute('onClick','currentActivityObject.SaveVerification(1);');
this.NoBtn.setAttribute('onClick','currentActivityObject.SaveVerification(0);');
this.YesBtn.style.display = 'none';
this.NoBtn.style.display = 'none';
infoWrapperDiv.appendChild(this.YesBtn);
infoWrapperDiv.appendChild(this.NoBtn);
this.ShowBtn.setAttribute('onmousedown',"currentActivityObject.ShowAnswer(1);");
this.ShowBtn.setAttribute('onmouseup',"currentActivityObject.ShowAnswer(0);");
this.ShowBtn.className = 'inputButton infoBottomLeft';
this.ShowBtn.style.display = 'none';
infoWrapperDiv.appendChild(this.ShowBtn);
break;
case 2:
break;
}
infoWrapperDiv.appendChild(this.HintText);
$id(target).appendChild(infoWrapperDiv);
$('#infoWrapperDiv').animate({top:"78%"},'fast').animate({top:"80%"},'fast');
},
Shrink:function(){
$('#infoWrapperDiv').animate({top:"90%"},'fast').animate({top:"88%"},'fast');
var minMax = document.getElementById('infoPopupMinMax');
minMax.setAttribute('onClick','InfoPopup.Grow();')
},
Grow:function(){
$('#infoWrapperDiv').animate({top:"78%"},'fast').animate({top:"80%"},'fast');
var minMax = document.getElementById('infoPopupMinMax');
minMax.setAttribute('onClick','InfoPopup.Shrink();')
},
Bounce:function(){
$('#infoWrapperDiv')
.animate({top:"90%"},'fast')
.animate({top:"80%"},'fast');
},
Destroy:function(){
var infoWrapperDiv = $id('infoWrapperDiv');
if(infoWrapperDiv){
infoWrapperDiv.parentNode.removeChild($id('infoWrapperDiv'));
}
}
};

Javascript Zoom on different tabs

I have made a simple zoom in and out function with button as well as mousewheel function. The main concept is to limit the maximum zoom level and minimum zoom level.
I have successfully made it in two ways
BIN 1
BIN 2
But i tried to make this in a tab section with unique ID or by class.
My script
var zoomLevel = 100;
var maxZoomLevel = 150;
var minZoomLevel = 50;
var initW=0,initH=0;
function zoom(zm) {
var img=document.getElementById("pic");
if(zm > 1){
if(zoomLevel < maxZoomLevel){
zoomLevel+=10;
}else{
return;
}
}else if(zm < 1){
if(zoomLevel > minZoomLevel){
zoomLevel-=10;
}else{
return;
}
}
img.style.width = (initW*zoomLevel/100)+"px";
img.style.height = (initH*zoomLevel/100)+"px";
img.style.marginLeft = ((initW-img.width)/2) + "px";
img.style.marginTop = ((initH-img.height)/2) + "px";
}
window.onload=function(){
var img=document.getElementById("pic");
initW=img.width;
initH=img.height;
img.onmousewheel=function(e){
e=e||window.event;
if(e.wheelDelta>=120) zoom(1.1);
else zoom(0.9);
};
if(/Firefox/.test(navigator.userAgent)){
img.addEventListener("DOMMouseScroll",function(e){
if(e.detail<0) zoom(1.1);
else if(e.detail>0) zoom(0.9);
e.preventDefault();
},false);
}
};
Here i am getting my element by using GetElementById to access my image tag is there any way to get access all the img tags in other tabs too.
I also tried getElementsbyClassName but its not working it just retrieving the nodeslist.
How can i access all three images here
Current BIN
you need to use different ID's
var img=document.getElementById("pic1");
var img=document.getElementById("pic2");`
You have assigned all three images the same id (id="pic"). You can't do that, ids must be unique.
If you change their ids, (ex: pic, pic2, pic3), and pass that in to your zoom function as an argument, then all the tabs will zoom.
So change the zoom function to look like this:
function zoom(zm, id) {
var img=document.getElementById(id);
...
}
And make your html look like this (just one for an example):
<div id="tabs-2">
<input type="button" value ="-" onClick="zoom(0.9, 'pic2')"/>
<input type="button" value ="+" onClick="zoom(1.1, 'pic2')"/>
<div id="thediv">
<img id="pic2" src="http://stereo-ssc.nascom.nasa.gov/beacon/t0193.jpg"/>
</div>
</div>
Now all three will zoom individually. Here's a jsbin showing it.
But, there's a bug. The variable you use to track the zoom state is being shared between the tabs. This means the "zoom limit" is not really enforced: you can just zoom one tab all the way down, then the next tab all the way up. Repeat this to make any of the images as big or as small as you want. I don't think this is what you want, but I'm going to leave it an exercise for you to fix.

How to improve image cross-fade performance?

I want to be able to do a cross fade transition on large images whose width is set to 100% of the screen. I have a working example of what I want to accomplish. However, when I test it out on various browsers and various computers I don't get a buttery-smooth transition everywhere.
See demo on jsFiddle: http://jsfiddle.net/vrD2C/
See on Amazon S3: http://imagefader.s3.amazonaws.com/index.htm
I want to know how to improve the performance. Here's the function that actually does the image swap:
function swapImage(oldImg, newImg) {
newImg.css({
"display": "block",
"z-index": 2,
"opacity": 0
})
.removeClass("shadow")
.animate({ "opacity": 1 }, 500, function () {
if (oldImg) {
oldImg.hide();
}
newImg.addClass("shadow").css("z-index", 1);
});
}
Is using jQuery animate() to change the opacity a bad way to go?
You might want to look into CSS3 Transitions, as the browser might be able to optimize that better than Javascript directly setting the attributes in a loop. This seems to be a pretty good start for it:
http://robertnyman.com/2010/04/27/using-css3-transitions-to-create-rich-effects/
I'm not sure if this will help optimize your performance as I am currently using IE9 on an amped up machine and even if I put the browser into IE7 or 8 document mode, the JavaScript doesn't falter with your current code. However, you might consider making the following optimizations to the code.
Unclutter the contents of the main photo stage by placing all your photos in a hidden container you could give an id of "queue" or something similar, making the DOM do the work of storing and ordering the images you are not currently displaying for you. This will also leave the browser only working with two visible images at any given time, giving it less to consider as far as stacking context, positioning, and so on.
Rewrite the code to use an event trigger and bind the fade-in handling to the event, calling the first image in the queue's event once the current transition is complete. I find this method is more well-behaved for cycling animation than some timeout-managed scripts. An example of how to do this follows:
// Bind a custom event to each image called "transition"
$("#queue img").bind("transition", function() {
$(this)
// Hide the image
.hide()
// Move it to the visible stage
.appendTo("#photos")
// Delay the upcoming animation by the desired value
.delay(2500)
// Slowly fade the image in
.fadeIn("slow", function() {
// Animation callback
$(this)
// Add a shadow class to this image
.addClass("shadow")
// Select the replaced image
.siblings("img")
// Remove its shadow class
.removeClass("shadow")
// Move it to the back of the image queue container
.appendTo("#queue");
// Trigger the transition event on the next image in the queue
$("#queue img:first").trigger("transition");
});
}).first().addClass("shadow").trigger("transition"); // Fire the initial event
Try this working demo in your problem browsers and let me know if the performance is still poor.
I had the same problem too. I just preloaded my images and the transitions became smooth again.
The point is that IE is not W3C compliant, but +1 with ctcherry as using css is the most efficient way for smooth transitions.
Then there are the javascript coded solutions, either using js straight (but need some efforts are needed to comply with W3C Vs browsers), or using libs like JQuery or Mootools.
Here is a good javascript coded example (See demo online) compliant to your needs :
var Fondu = function(classe_img){
this.classe_img = classe_img;
this.courant = 0;
this.coeff = 100;
this.collection = this.getImages();
this.collection[0].style.zIndex = 100;
this.total = this.collection.length - 1;
this.encours = false;
}
Fondu.prototype.getImages = function(){
var tmp = [];
if(document.getElementsByClassName){
tmp = document.getElementsByClassName(this.classe_img);
}
else{
var i=0;
while(document.getElementsByTagName('*')[i]){
if(document.getElementsByTagName('*')[i].className.indexOf(this.classe_img) > -1){
tmp.push(document.getElementsByTagName('*')[i]);
}
i++;
}
}
var j=tmp.length;
while(j--){
if(tmp[j].filters){
tmp[j].style.width = tmp[j].style.width || tmp[j].offsetWidth+'px';
tmp[j].style.filter = 'alpha(opacity=100)';
tmp[j].opaque = tmp[j].filters[0];
this.coeff = 1;
}
else{
tmp[j].opaque = tmp[j].style;
}
}
return tmp;
}
Fondu.prototype.change = function(sens){
if(this.encours){
return false;
}
var prevObj = this.collection[this.courant];
this.encours = true;
if(sens){
this.courant++;
if(this.courant>this.total){
this.courant = 0;
}
}
else{
this.courant--;
if(this.courant<0){
this.courant = this.total;
}
}
var nextObj = this.collection[this.courant];
nextObj.style.zIndex = 50;
var tmpOp = 100;
var that = this;
var timer = setInterval(function(){
if(tmpOp<0){
clearInterval(timer);
timer = null;
prevObj.opaque.opacity = 0;
nextObj.style.zIndex = 100;
prevObj.style.zIndex = 0;
prevObj.opaque.opacity = 100 / that.coeff;
that.encours = false;
}
else{
prevObj.opaque.opacity = tmpOp / that.coeff;
tmpOp -= 5;
}
}, 25);
}

Categories