Appending to InnerHtml without rest of contents flicking - javascript

I have a div element with some formatted images. On user request, I load additional images asynchronously, without postback, and append the result (formatted HTML for new images) to the div element using JavaScript:
function onRequestComplete(result) {
var images = document.getElementById('images');
images.InnerHtml += result;
}
All is okay, except that part when images in the panel loaded previously flicker after the HTML is appended. As far I understand, the panel is reconstructed, not just new HTML is appended to its bottom. So it isn't web 2.0 behavior.
How can it be done without flicking? Thanks in advance.

Use the dom method of adding them:
var div = document.createElement('div');
div.innerHTML= result;
document.getElementById('images').appendChild(div);
Or if you really want to do it the right way, create an dom element for each image and then append them. This also has the benefit of preloading the images.
Or just use jQuery. ;)

Using the += operator is the same as:
images.innerHTML = images.innerHTML + result;
Which will re-render all your container, thus causing "flickering".
You should be able to have the same result appending new elements to the container, without having the flickering. For that, you will need the createElement and appendChild methods.
HTH!

When you append your content, you could tack on something like
<span class='endMarker'></span>
Then instead of just updating "innerHTML" like that, you'd look through the DOM inside the target, find the last <span> with class "endMarker", and then append new content after that. Without meaning to be a "use jQuery problem solved" person I will say that a library like that would make things a little easier. To append the content, you could drop it in a hidden div and then move it.

Make all images a single image, than use CSS positioning to show the desired section. The flickering is due to the loading of the new images.

Related

Append a whole footer into an HTML page thanks to JS

I'm currently learning JS following some tutorials on YouTube, for now my goal is to put some code on the bottom of the page. With a little bit of googling I think what I'm looking for is appending, but I don't find any example of how to append. I found an example of append but it seems like I can append only one element, but since I'm trying to append a whole responsive bootstrap footer, I'll need to append a div with divs in it with classes etc... Is append the right method to use? I can't place the footer in the page itself I only have access to JS that's why I try this way..
I don't know if I should give you the code I want to append, sorry to bother
If you have the whole footer with div children that have classes etc. append will work, and it works as such:
const mainContent = document.getElementById("main-content")
const footerElement = document.createElement("footer")
footerElement.innerHTML = '<footer> other divs with classes etc......</footer>'
mainContent.append(footerElement)
Basically, once you have your footer element defined however you need it, you can run the append function on your main content/wherever you want your footer to be at the bottom of, and the element will be added. Hope that helps.

Loading html into page using javascript

So I have this nice piece of javascript that will load local HTML files into my document for me on the fly, which is pretty cool.
function load_html(src) {
var html = document.createElement("object");
html.type = "text/html";
html.data = src;
document.getElementById("wrapper").appendChild(html);
}
I got the idea from the post here How do I load an HTML page in a <div> using JavaScript?.
The only problem with it is that it seems that the object tag that I create needs a default width and height, which I want it to wrap the size of it's containing elements, and the new elements that are within the object tag have their own set of css values instead of using the css value of the current page.
Does anyone know how to make the elements within my object get the css values from my current page?
Also, how can I make my object be the size of it's containing elements?
I'm sure there is an easy way to do it, but I haven't found much on object tags.

document.write to display content on same page.

I have a doubt with javascript document.write method. Mostly when I use document.write() it shows me the content written with the method in a different page. For instance, if I write the command like this, document.write("Hello, My name is Sameeksha"); then the execution of this line takes me to a different document on the same page. I want to be able to append the message on the same page, with other elements of the page. For example, if I have text boxes and buttons on the page and I want the text with document.write to appear under all the content of the page or on a particular section of a page. Please suggest what can be done to get the output in this way? As, this way it will be really easy to create dynamic HTML content.
Thank you so much for your time.
Regards,
Sameeksha Kumari
document.write is basically never used in modern Javascript.
Whan you do instead is to create explicit DOM elements and append them to the document in the place you want. For example
var x = document.createElement("div"); // Creates a new <div> node
x.textContent = "Hello, world"; // Sets the text content
document.body.appendChild(x); // Adds to the document
Instead of appending to the end you can also add child nodes to any existing node. For example:
function addChatMessage(msg) {
var chat = document.getElementById("chat"); // finds the container
var x = document.createElement("div");
x.textContent = msg;
chat.appendChild(x);
}
I'd say 6502 posted the more correct way to do it, but I think someone should mention innerHTML as well. First, give some element in your HTML body an id so you can reference it:
<div id="outputDiv">I'm empty.</div>
Then, either at the bottom of your document (at the end of the <body> tag), or any other time after the page is loaded, you can update the contents with innerHTML:
document.getElementById("outputDiv").innerHTML = "<h1>Hello!!!</h1>";
Here's a jsfiddle demonstrating this. This isn't as clean/correct/elegant as using the more standard DOM methods, but it's well supported. Sometimes quick and dirty is what you need!

Is it possible to make a change with jQuery and then immediately reverse that change?

I have a pretty specific scenario where I would like to select all elements with jQuery, make a CSS change, save the elements, then reverse the change I made.
The Goal
I created a jQuery plugin called jQuery.sendFeedback. This plugin allows the user to highlight areas of the screen, as shown in this demo. When they submit their feedback the plugin grabs all the HTML on the page and dumps it into a callback function. Like so:
$('*').each(function ()
{
$(this).width($(this).width());
$(this).height($(this).height());
});
var feedbackInformation = {
subject: $feedbackSubject.val(),
details: $feedbackDetails.val(),
html: '<html>' + $('html').html() + '</html>'
};
if (settings.feedbackSent)
settings.feedbackSent(feedbackInformation);
The callback function accepts this feedback information and makes an AJAX call to store the page HTML on the server (this HTML includes the red box highlights the user drew on the screen). When someone from tech support needs to view the user's "screen shot" they navigate to a page that serves up the stored HTML so the developer can see where the user drew their highlights on the screen.
My original problem was that different screen resolutions made the elements different sizes and the red highlights would highlight the wrong areas as the screen changed. This was fixed pretty easily by selecting all elements on the page and manually setting their height and width to their current height and width when the user takes the snap shot. This makes all the element sizes static, which is perfect.
$('*').each(function ()
{
$(this).width($(this).width());
$(this).height($(this).height());
});
The Problem
The issue with this is that when the plugin is done transmitting this HTML the page currently being viewed now has static heights and widths on every element. This prevents dropdown menus and some other things from operating as they should. I cannot think of an easy way to reverse the change I made to the DOM without refreshing the page (which may very well end up being my only option). I'd prefer not to refresh the page.
Attempted Solution
What I need is a way to manipulate the HTML that I'm sending to the server, but not the DOM. I tried to change the above code to pull out the HTML first, then do the operation on the string containing the HTML (thus not affecting the DOM), but I'm not quite sure what I'm doing here.
var html = '<html>' + $('html').html() + '</html>';
$('*', html).each(function ()
{
$(this).width($(this).width());
$(this).height($(this).height());
});
This did not work. So either I need to be able to manipulate the string of HTML or I need to be able to manipulate the DOM and undo the manipulation afterward. I'm not quite sure what to do here.
Update
I employed the solution that I posted below it is working beautifully now. Now I am wondering if there is a way to statically write all the css for each element to the element, eliminating the need for style sheets to be referenced.
I think you are mostly on the right track by trying to make the modifications to the HTML as a string rather than on the current page for the user.
If you check this post, you might also want to follow the recommendation of creating a temporary <div> on the page, cloning your intended content to the new <div> ensuring it is invisible using "display:none." By also putting a custom Id on the new <div> you can safely apply your static sizing CSS to those elements using more careful selectors. Once you have sent the content to the server, you can blow away the new <div> completely.
Maybe?
After much pain and suffering I figured a crude but effective method for reverting my modifications to the DOM. Though I hadn't gotten around to trying #fdfrye's suggestion of cloning, I will be trying that next to see if there is a mroe elegant solution. In the meantime, here is the new code in case anyone else can benefit from it:
$('*').each(function () {
if ($(this).attr('style'))
$(this).data('oldStyle', $(this).attr('style'));
else
$(this).data('oldStyle', 'none');
$(this).width($(this).width());
$(this).height($(this).height());
});
var html = '<html>' + $('html').html() + '</html>';
$('*').each(function () {
if ($(this).data('oldStyle') != 'none')
$(this).attr('style', $(this).data('oldStyle'));
else
$(this).removeAttr('style');
});
When I'm looping through every element and modifying the css, I log the original value onto the element as data. After I assign the DOM HTML to a variable I then loop through all elements again and restore the style attribute to its original value. If there was no style attribute then I log 'none' to the element data and then remove the style attribute entirely when looping through again.
This is more performance heavy than I wish it was since it loops through all elements twice; it takes a few seconds to finish. Not horrible but it seems like a little much for such a small task. Anyway, it works. I get a string with fixed-sized HTML elements and the DOM goes back to normal as if the plugin never touched it.

How to dynamically generate droppable/draggable/sortable div elements within a div?

Hello so I have to parts to this question:
I would like to be able to dynamically create div elements when a user performs an action (say, clicks a button a drags something into a droppable and create a new droppable). I'm using this code right now and it's successfully generating the css block:
function createDiv()
{
var divTag = document.createElement("div");
divTag.id = "slotclass";
divTag.className ="connect";
document.body.appendChild(divTag);
}
... though I'm not too sure how to make it droppable/draggable/sortable after this.
I'd like for the dynamically generated div element to appear within a div that has a specific id from the css stylesheet. However, when I use createDiv(), it generates it outside of the div brackets regardless of what things I've tried (such as not closing brackets or placing my button in this case within the div brackets).
If anyone could help out with these two areas, that would be so great! Many thanks.
Let say you want to make it sortable, initialize sortable after you append child:
$("#slotclass").sortable({ ... }); or $(divTag).sortable({ ... });
You appended your new div in the body. To make it simple, I use jQuery. Replace document.body.appendChild(divTag); with $('#yourtargetdiv').append($(divTag));

Categories