I have created pdf with header and footer. I want to hide header and footer from 1st and 2nd page in pdf.
So I have written below javascript code:
<script>
/* page counter */
function subst() {
var vars={};
var x=document.location.search.substring(1).split('&');
for (var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
for (var i in x) {
var y = document.getElementsByClassName(x[i]);
for (var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
if(vars['page'] == 1 || vars['page'] == 2){
// document.getElementById("header_content").innerHTML = "";
document.getElementById("header_content").style.border = '1px solid';
var element = document.getElementById("header_content");
element.classList.add("hidden");
}
}
}
</script>
Contents are hidden but it covers white space.
So how can I remove that white space from 1st and 2nd page?
What does the CSS class 'hidden' do?
You need to set display: none in there.
Sounds like you are using visibility: hidden instead.
Related
For example, after clicking on Hide button some items disappear
function hideItem() {
targList = document.getElementsByClassName("completed");
document.getElementsByClassName("completed")
if (targList) {
for (var x = 0; x < targList.length; x++) {
targList[x].setAttribute('style', 'display: none !important');
}
}
localStorage.setItem("autosave", targList);
}
But after refreshing the page style of items do not save. How to preserve this style of element after reloading web page?
You can't store DOM into localStorage. You'd have to save identifying code for each element. For example, id.
Then do the opposite after loading the page.
function hideItem() {
var targList = document.getElementsByClassName("completed");
var hidden_ids = []
for (var x = 0; x < targList.length; x++) {
targList[x].setAttribute('style', 'display: none !important');
hidden_ids.push(targList[x].id)
}
localStorage.setItem("autosave", JSON.stringify(hidden_ids));
}
function loadItem() {
var hidden_ids = Json.parse(localStorage.getItem("autosave") || '[]');
for (var x = 0; x < hidden_ids.length; x++) {
document.getElementById(hidden_ids[x]).setAttribute('style', 'display: none !important');
}
}
hideItem();
<div id="elem1" class="completed">hello</div>
<div id="elem2" class="not-completed">hello</div>
I'm trying to write some code in apps script to pull text from a text box in google slides and split it by paragraphs into new text boxes and I'm hitting a snag when I get to preserving lists. I haven't been successful in finding a simple way to get the listPreset from the paragraphs in the original text box to the paragraphs in their own text boxes.
I was able to use ListStyle() methods getGlyph() and isInList() successfully but unless I make a dictionary of which listPreset each glyph is in, I don't seem to able to retrieve the listPreset with any of the listed methods which I would need in order to fill into applyListPreset().
I'd love a getListPreset() function so I could just nab that from the original list. Is there something like that I'm missing?
Here is an example "before" condition.
Here is an example of the expected "after" condition.
Here is an example of what the "after" condition is when I am unable to duplicate the listStyle from the original text box into the new text boxes.
In the following example I copy the text from the original textbox and gather various attributes from it. I attempt to input the listStyle() information into the applyListPreset() method even though I know that's wrong. I just don't know how else to get the List Preset from the original text box.
FYI I've already had a bit of help with this already so it's not all my work.
function myFunction() { // get slides in the presentation
var slides = SlidesApp.getActivePresentation().getSlides();
var numberOfLogs = 5;
for (let slide of slides) { // get the objects on each slide
splitParagraphs(slide);
}
}
function splitParagraphs(slide){
slideShapes = slide.getShapes();
for(let shape of slideShapes){
var shapetype = shape.getShapeType();
if (shapetype == "TEXT_BOX"){ // checks to see if the object is a text box
createSplitShapes(shape, slide);
shape.remove();
}
}
}
function createSplitShapes(shape, slide){
var paragraphs = shape.getText().getParagraphs();
var oldHeight = shape.getHeight();
var width = shape.getWidth();
var newShapeHeight = oldHeight / paragraphs.length;
for (let [index, paragraph] of paragraphs.entries() ){ // make a textbox for each paragraph distributed vertically over the original textbox
createParagraphShapes(shape, index, paragraph, newShapeHeight, width, slide);
}
}
function createParagraphShapes(shape, index, paragraph, shapeheight, width, slide){
var text = paragraph.getRange();
var list = text.getListStyle().isInList();
var style = text.getListStyle();
var glyph = text.getListStyle().getGlyph();
var rawText = text.asString();
var textStyle = text.getTextStyle();
var fontsize = textStyle.getFontSize();
var fontfamily = textStyle.getFontFamily();
var fontweight = textStyle.getFontWeight();
var paragraphStyle = text.getParagraphStyle();
var alignment = paragraphStyle.getParagraphAlignment();
var lineSpacing = paragraphStyle.getLineSpacing();
var indent = paragraphStyle.getIndentStart();
var shapetop = shapeheight * index + shape.getTop();
if ( ! isBlank(rawText) ) {
var t = slide.insertTextBox(rawText);
t.setLeft(shape.getLeft());
t.setTop(shapetop);
t.setWidth(width);
var newTextStyle = t.getText().getTextStyle();
newTextStyle.setFontSize(fontsize);
newTextStyle.setFontFamilyAndWeight(fontfamily, fontweight);
var newParagraphStyle = t.getText().getParagraphStyle();
newParagraphStyle.setParagraphAlignment(alignment);
newParagraphStyle.setLineSpacing(lineSpacing);
newParagraphStyle.setIndentStart(indent);
if (list = true) {
t.getText().getListStyle().applyListPreset(style);
}
}
}
function paragraphLogs(paragraph, numberOfLogs){
if(numberOfLogs > 0){
console.log("\tWhat's in paragraphs?: ");
for (var k = 0; k < paragraph.length; k++){
console.log("\t\t" + ( paragraphs[k].getRange().asString() ) );
}
}
}
function isBlank(str){
return (!str || str.trim().length === 0);
}
Okay so I must create an infinite auto-scrolling horizontal image marquee using vanilla JS. I have the following code:
//if(painkiller<14){painkiller++;} else{painkiller=0;backup2()}
var speed = 5;
var exeggcute = true;
var painkiller = 0;
var marquix = document.getElementById("marquis");
var backup = "";
var coquus = 0;
for (var painkiller = 0; painkiller < 15; painkiller++) {
backup += "<img class='slide' src='" + ImgArray[painkiller].src + "' width='" + ImgArray[painkiller].width + "'>";
}
marquix.innerHTML = backup;
function riverflow() {
marquix.scrollLeft += 5;
if (marquix.children[0].getBoundingClientRect().left <= (marquix.children[0].width * -1)) {
marquix.appendChild(marquix.children[0]);
//marquix.getBoundingClientRect().left=0;
//marquix.children[0].style.transform="translateX(133px)"
}
}
//function backup2(){marquix.innerHTML=backup;}
setInterval('riverflow()', 50);
exeggcute = true;
<head>
<script>
var ImgArray = [];
for (var i = 0; i < 15; i++) {
ImgArray[i] = new Image();
ImgArray[i].src = "imgx/imagen" + (i + 1) + ".jpg";
ImgArray[i].width = 133;
}
</script>
</head>
<body>
<div id="marquis">
</div>
</body>
Basically I'm creating the image chain, then filling with it the innerHTML of a div, then assigning said div to a variable, and finally calling a repetitive function through setInterval(). Now, what that function does is a simple scroll to the left and - when the first image is completely out of the viewport - use appendChild to rip the first child element or img from the image chain then put it at the end of it. So no image overcharge is produced and the marquee uses the same 15 element once and again.
Here's my problem, though: when the appendChild function fires, the image that's out of the viewport is removed, however, the next image in line - as well as the rest of the chain - does not preserve its current position, and is instead forcefully scrolled to fill the gap left by the then-first image that's now at the end. Thus, the condition of the appendChild (which was the first children of the div being completely out of the viewport) becomes true and activates the function - leading the whole marquee to slide non-stop and out of control, as the appendChild is firing continuously.
How can I fix it?
Possible solutions:
You will need to reset the scrollLeft to 0 on the same moment that you switch the images.
You will need to add some element (another img for example at the begining) it could be all white or transparent. That image will be always there, before the firstone visible. When you remove the other image this auxiliar image need to be wider (change the width) to fill the gap, so add to its width the width of the removed image each time you remove one.
Or you can change the marginLeft of the leftmost image with marquix.children[0].style.marginLeft = n + "px";
That's what I came up with, but as I said, the translateX() parameter increases ad infinitum.
<script>
var ImgArray=[];
for (var i=0; i<15; i++){
ImgArray[i]= new Image();
ImgArray[i].src= "imgx/imagen"+(i+1)+".jpg";
ImgArray[i].width=133;
}
</script>
</head>
<body>
<div id="marquis">
<script>
//if(painkiller<14){painkiller++;} else{painkiller=0;backup2()}
var exeggcute= true;
var painkiller=0;
var marquix = document.getElementById("marquis");
var backup=""; var coquus=0;
for(var painkiller =0;painkiller<15;painkiller++){
backup+="<img class='slide' src='"+ImgArray[painkiller].src+"' width='"+ImgArray[painkiller].width+"'>";
}
marquix.innerHTML=backup;
var slidin=133;
function riverflow(){
marquix.scrollLeft+=10;
if (marquix.children[0].getBoundingClientRect().left<=(marquix.children[0].width*-1) && exeggcute){
marquix.appendChild(marquix.children[0]);
marquix.getBoundingClientRect().left=0;
for (var j=0; j<15; j++){
marquix.children[j].setAttribute("style","transform: translateX("+slidin+"px)")
}
slidin+=133;
}
}
//function backup2(){marquix.innerHTML=backup;}
setInterval('riverflow()',50);
exeggcute=true;
</script>
I am trying to write a script (because I can't find one that works) that will export all my separate layers, paths, etc to transparent png files. I have seen many scripts, but all of them do not export all the layers, etc. They seem to just try and export parent layers. So if there are sub layers, these are missed.
Here is my script:
var doc = app.activeDocument;
var counter = 0;
hideOrShowItems(doc, false);
// processLayers(doc);
// displayLayer(doc, true);
function hideOrShowItems(root, show) {
for(var i = 0; i < root.layers.length; i++) {
var layer = root.layers[i];
var pathCount = layer.pathItems.length;
var layerCount = layer.layers.length;
if (pathCount > 0) {
hideOrShowPaths(layer, show);
}
if (layerCount > 0) {
hideOrShowItems(layer, show);
}
layer.visible = show;
}
}
function hideOrShowPaths(root, show) {
for(var i = 0; i < root.pathItems.length; i++) {
root.pathItems[i].visible = show;
}
}
// -- Removed for brievety
When I run the script, the only thing that gets hidden is the top layer
All of the rest are untouched.
I put a counter in and did counter++ in the for loop of hideOrShowPaths and it counts 246, so I know it can see the paths and is actually trying to hide them, but they stay visible.
Has anyone done this before? Can I hide paths, groups, clips and export them all as pngs? or will I have to do this manually?
Looks like the flag you are looking for is hidden not visible.
var doc = app.activeDocument;
var root = doc.layers[0];
// just for testing purpose. Change the color
var newRGBColor = new RGBColor();
newRGBColor.red = 255;
newRGBColor.green = 255;
newRGBColor.blue = 255;
// make all items hidden
for (var i = 0; i < root.pathItems.length; i++) {
var item = root.pathItems[i];
item.hidden = true;
item.fillColor = newRGBColor; // just for testing
}
// now loop all pathItems
for (var i = 0; i < root.pathItems.length; i++) {
var item = root.pathItems[i];
item.hidden = !item.hidden; //make one visible
// export visible part
redraw();
item.hidden = !item.hidden; // hide it again
}
In your script you will need to hide every item first, then unhide one, export and hide it again.
I Hope that snippet helps with your problem
I've written a fairly simple script that will take elements (in this case, <p> elements are the main concern) and type their contents out like a typewriter, one by one.
The problem is that as it types, when it reaches the edge of the container mid-word, it reflows the text and jumps to the next line (like word wrap in any text editor).
This is, of course, expected behavior; however, I would like to pre-format the text so that this does not happen.
I figure that inserting <br> before the word that will wrap would be the best solution, but I'm not quite sure what the best way to go about doing that is that supports all font sizes and container widths, while also keeping any HTML tags intact.
I figure something involving a hidden <span> element, adding text to it gradually and checking its width against the container width might be on the right track, but I'm not quite sure how to actually put this together. Any help or suggestions on better methods would be appreciated.
Edit:
I've managed to write something that sort of works using jQuery, although it's very sloppy, and more importantly, sometimes it seems to skip words, and I can't figure out why. #content is the name of the container, and #ruler is the name of the hidden <span>. I'm sure there's a much better way to do this.
function formatText(html) {
var textArray = html.split(" ");
var assembledLine = "";
var finalArray = new Array();
var lastI = 0;
var firstLine = true;
for(i = 0; i <= textArray.length; i++) {
assembledLine = assembledLine + " " + textArray[i];
$('#ruler').html(assembledLine);
var lineWidth = $('#ruler').width();
if ((lineWidth >= $('#content').width()) || (i == textArray.length)) {
if (firstLine) { var tempArray = textArray.slice(lastI, i); }
else { var tempArray = textArray.slice(lastI+1, i); }
var finalLine = tempArray.join(" ");
finalArray.push(finalLine);
assembledLine = "";
if (lineWidth > $('#content').width()) { i = i-1; }
lastI = i;
firstLine = false;
}
}
return finalArray.join("<br>");
}
You could use the pre tag: Which displays pre-formatted text, or you could put the content into a div tag, set a fixed width, and script based upon that.
The best way (IMO) would be to add the whole word, but have the un-"typed" letters invisible. E.g:
H<span style="visibility: hidden;">ello</span>
He<span style="visibility: hidden;">llo</span>
Hel<span style="visibility: hidden;">lo</span>
Hell<span style="visibility: hidden;">o</span>
Hello
To make it easier, give the span a name, and delete it from the DOM each time.
A possible approach is to set p display inline (because default display-block will make p to consume all width even if it has just 1 character) and then as you 'type' check the element width.
Set a tolerance in px (25px for example) and once p's width reaches total available width minus width tolerance you insert <br />
I think this should work...
After playing with the code I edited into the question, I managed to get it working decently.
Code:
function formatText(html) {
var textArray = html.split(" ");
var assembledLine = "";
var finalArray = new Array();
var lastI = 0;
var firstLine = true;
for(i = 0; i <= textArray.length; i++) {
assembledLine = assembledLine + " " + textArray[i];
$('#ruler').html(assembledLine);
var lineWidth = $('#ruler').width();
if ((lineWidth >= $('#content').width()) || (i == textArray.length)) {
if (firstLine) { var tempArray = textArray.slice(lastI, i); }
else { var tempArray = textArray.slice(lastI+1, i); }
var finalLine = tempArray.join(" ");
finalArray.push(finalLine);
assembledLine = "";
if (lineWidth >= $('#content').width()) { i = i-1; }
lastI = i;
firstLine = false;
}
}
return finalArray.join("<br>");
}
Not perfect, but it'll do. Thanks, everyone.