Creating img element and appending to dom has no termination - javascript

I've got a pretty complicated DOM structure already and I'd like to eliminate the possibility of unterminated image elements causing issues.
Looking at the simplest case:
var prettyPicture = document.createElement("img");
//Add properties...
container.appendChild(prettyPicture );
Works fine, but when I insepct the dom I see the img element without a terminating slash such as <img/>
<img id="iamge-6816177" src="_site/images/detail/6816177.png">
No issues in the simple layout view, but when I look at a view with tons of these elements, random ones, even similar images within the same parent nodes do not render, though their nodes are in the dom inspector. Would missing termination cause any issues with the tree?

The closing tag of an img element is entirely optional - this won't cause you problems in any browser. So much so, in fact, that in HTML5 you're now not supposed to include the /> in img elements at all.
Also, what you see when you inspect the DOM is just how your inspector chooses to display elements with no closing tag - you can be sure that createElement() and appendChild() are generating valid HTML, as you're working directly with the DOM rather than providing text for the browser to parse into DOM objects.

If you're concerned about
<img id="iamge-6816177" src="_site/images/detail/6816177.png">
instead of
<img id="iamge-6816177" src="_site/images/detail/6816177.png"/>
then there is no worry : the days of the painful XHTML have ended and HTML5 confirms that you shouldn't write XML-style self-closing tags.
From the spec :
Void elements only have a start tag; end tags must not be specified
for void elements.
[...]
Void elements
area, base, br, col, command, embed, hr, img, input,
keygen, link, meta, param, source, track, wbr
It's bad practice to clutter your code with ending tags. HTML isn't XHTML.

From http://www.w3schools.com/tags/tag_IMG.asp
In HTML the <img> tag has no end tag.
In XHTML the <img> tag must be properly closed.
In all cases, the browser won't care.

No this should not cause any issues. I would just ignore it as this will not harm w3.org compliance because DOM elements are generated dynamically.

Related

Is it bad idea to inline CSS mid page? [duplicate]

Normally css files are put inside <head></head>, what if I put it inside <body></body>, what difference will it make?
Just to add on to what jdelStrother has mentioned about w3 specs and ARTstudio about browser rendering.
It is recommended because when you have the CSS declared before <body> starts, your styles has actually loaded already. So very quickly users see something appear on their screen (e.g. background colors). If not, users see blank screen for some time before the CSS reaches the user.
Also, if you leave the styles somewhere in the <body>, the browser has to re-render the page (new and old when loading) when the styles declared has been parsed.
The most recent versions of the HTML spec now permits the <style> tag within body elements. https://www.w3.org/TR/html5/dom.html#flow-content
Also the scoped attribute which used to be prerequisite to have a style tag in the body is now obsolete.
This means, that you can use the style tag everywhere you want, the only implications are decreased page performance due to possible reflows/repaints once the browser hits styles further down in the page tree.
Obsolete answer:
The <style> tag isn't allowed within <body> according to the w3 specs. (You can, of course, apply inline styles via <div style="color:red"> if necessary, but it's generally considered poor separation of style & content)
Putting CSS in body means it is loaded later. It is a technique some use to let the browser start drawing the interface faster (i.e., it removes a blocking step). This is important for user experience on SmartPhones.
I do my best to keep one small css on the <head> and I move the rest at the bottom. For example, if a page uses JQuery UI CSS, I always move it at the bottom of the <body>, just before the links to JQuery javascript. At least, all the non Jquery item can already be drawn.
Head is designed for (Quoting the W3C):
"information about the current
document, such as its title, keywords
that may be useful to search engines,
and other data that is not considered
document content"
See the Global structure of an HTML document. As CSS is not document content, it should be in the head.
Also every other Web developer will expect to see it there, so don't confuse things by putting it in the body, even if it works!
The only CSS you should put in the body is inline CSS, though I usually avoid inline styles.
The standards (HTML 4.01: the style element) clearly specifies that the style tag is only allowed inside the head tag. If you put style tags in the body tag the browsers will try to make the best of it anyway, if possible.
It's possible that a browser would ignore a style tag in the body if you specify a strict document type. I don't know if any current browser does this, but I wouldn't count on all future versions to be so relaxed about where you place the style element.
Although the style tag is not allowed in the body, the link tag is, so as long as you are referencing an external stylesheet, all browsers should render and use the CSS correctly when used in the body.
Source: https://html.spec.whatwg.org/multipage/semantics.html#the-link-element
In addition to earlier answers, though putting a style code block inside the element may work in modern browsers (though that still doesn't make it right), there's always a danger, particularly with older browsers that the browser will render the code as text unless the style section's included within a CDATA section.
Of course the other thing with putting it inside the element, other than inline styles, is that as it doesn't meet with the W3C HTML/XHTML specs is that any page with it within the body will fail on the W3C validator. It's always easier to bug-hunt unexpected display problems if all your code is valid, making it easier to spot mistakes. An invalid HTML element can adversely effect the rending of any and all element beyond where it occurs in the code, so you can get unexpected effects having elements in places where they shouldn't be, because when a browser finds an invalid element, it just makes it's best guess as to how it should display it, and different browsers may make different decisions in how they render it.
Whether you use a transitional or a strict doctype, it would still be invalid according to the (X)HTML specs.
Two conflicting answers:
From MDN page on link tag:
A <link> element can occur either in the <head> or <body>
element, depending on whether it has a link type that is body-ok. For
example, the stylesheet link type is body-ok, and therefore a
<link rel="stylesheet"> is permitted in the body. This isn't however
best practice; it makes more sense to separate your <link> elements
from your body content, putting them in your head.
From CSS The Definitive Guide (4th Edition/2017) page 10
To successfully load an external stylesheet, link must be placed inside the head element but may not be placed in any other element.
You would actually defeat the purpose of using CSS by putting the styles in the body. The point would be to separate content from presentation (and function). This way, any changes to style can be done in the stylesheet, not in the content. Once you use the inline style method, every page that has inline styling needs to changed one by one. Tedious, and risky since you could miss a page or three, or ten.
Using a stylesheet, you only need to change the stylesheet; the changes propagate automagically to every HTML page that links to the stylesheet.
neonble's point is also another great reason; if you mess up the HTML by adding CSS inline, rendering becomes a problem. HTML doesn't throw exceptions to your code. Instead it goes out and renders it the best way it can, and moves on.
Adhering to web standards by using a stylesheet makes for a better website. And when you need help because things on your page aren't exactly that way you want them, placing your CSS in the head as opposed to the body makes for much better troubleshooting by yourself and for anyone you ask for help from.
The difference is.
The loading of the page is asynchronous, so if you have external stylesheet it will load the css file immediately when it reach the link tag, that is why it is good to have at the top in head.
What difference will it make?
Pros: Sometimes easier to apply certain attributes in certain places, especially if code is being generated on the fly (such as building via php and each of a dynamically sized list needs its own class... such as for item timings for transforms).
Cons: Slightly slower, may not work someday in the distant future.
My General opinion on it:
Don't do it it you don't have to, but if you do have to, don't lose any sleep over it.
Putting the <style> in the body works well with all modern browsers.
I had been using this in eBay.
If it works, don't kick it.

What is the meaning of "target element is not a descendant of root"?

I got the following warning in the Chrome's console:
"IntersectionObserver.observe(target): target element is not a descendant of root."
What is the meaning of this? How could I find the reason for it, in order to fix it?
This warning appeared for me too. Chrome Debugging tool did not like an attribute in an element. I found the offending attribute by cutting out chunks of html and reloading the page until I narrowed it down to a single attribute.
for me it was this muted attribute...
Hope this helps.
I got this warning when I was creating a HTMLVideoElement in JS, but not adding it to the body of the document, before playing it to extract the first frame image.
I worked around it by setting its display to none, appending the node as a child of the body, and in a later promise removing the element from the body.
So, I'd check if you're creating any DOM elements in JS, and not adding them to the body of the HTML document.

Is there a way to intercept and block image loading from <img> elements?

Background
I have created a Javascript decoder for the FLIF image format. Since it's a new format and browsers don't support it yet (if ever), we want to create a poly-fill for it in JS.
We have one basic version already working. It queries for canvas elements and renders the FLIF image on to it.
However, for users that don't have Javascript enabled, the solution doesn't work. They see a blank canvas.
Question
We were wondering if there is a way to allow <img> elements to be specified in the HTML as a fall-back, but block them from loading via javascript, so that we can replace them with our FLIF canvas?
I have tried adding various event listeners, such as DOMContentLoaded, and removing the <img> elements in them, but by that time it is too late; the browser starts fetching the image.
You cannot stop a standard image element from being requested in this case, as it's necessary to know that such an element exist before you can access it. Although you can remove/hide/etc the element as soon as possible, from the users end the image would of never been shown. For example:
<img id="foo" src="..." />
<script>
document.getElementById("foo").remove();
</script>
You can't block an existing <img> tag from making the request for the resource set in src simply because the element has to exist before you can target it with script and by then the request has been made.
Note: Since 99% of the web requires script enabled anymore you could wrap the <img>'s in <noscript> tags
You could place the <img> tags inside a <noscript> block.
I just did a test with Chrome, and it doesn't try to load the images inside the block (unless Javascript is disabled, of course). I don't know if every browser works the same way, though, some of them might still try to download the images.
I find this a bit hacky, but another choice is to add some extra info to the img tags, and then add some CSS from your poly-fill to avoid the images being showed.
Example HTML:
<img src="image.png" data-polyflif-src="image.flif">
Example CSS generated inside the poly-fill:
// Add CSS to avoid images marked as flif being showed
document.write("<style>img[data-polyflif-src]{display:none;}</style>");
// Once DOM is loaded generate the canvas element and content after every img tag (optionally remove the img or whatever)
...

Is there a way to only replace the innerText of all elements on a page?

Background
Based on today's XKCD I created the below script:
javascript:var a=document.getElementsByTagName('body')[0].innerHTML;a=a.replace(/Program(\w\w+)*/gmi,'curse').replace(/language/gmi,'word');
If you go to a site (e.g. http://en.wikipedia.org/wiki/Programming_language) and paste the above code (re-adding the javascript: if required) this performs a regex replace on the document's content, whilst preserving most formatting, creating some fun reading.
However, the look of the site is affected; presumably because I'm replacing innerHTML rather than just innerText (I guess; though not sure).
I can't simply replace innerText as all elements include their child's innerText in their own; doing this on the body element would remove all formatting, and doing it on every element would duplicate huge amounts of content.
Question
Is there a way to iterate through all nodes in an HTML document, via (minimal) javascript, replacing words in their immediate child text values whilst preserving their remaining content?
The Javascript that you have doesn't change the page at all. It reads the content of the body into a string, then changes the string. That doesn't affect the content.
The reason that the page changes is that the value of the script is the value of the string, so that is used as content for a new page. As that is just a HTML snippet without the head tag where all the styles and scripts are defined, you get an unstyled page with just the content.
If you want to change the page, you should put the string back as content in the body, then use void(0); as the last statement to prevent the creation of a new page:
javascript:var a=document.getElementsByTagName('body')[0].innerHTML;a=a.replace(/Program(\w\w+)*/gmi,'curse').replace(/language/gmi,'word');document.getElementsByTagName('body')[0].innerHTML=a;void(0);

Possible to create custom "DOMs" by loading HTML from string in Javascript?

I'm trying to parse HTML in the browser. The browser receives 2 HTML files as strings, eg. HTML1 and HTML2.
I now need to parse these "documents" just as one would parse the current document. This is why I was wondering if it is possible to create custom documents based on these HTML strings (these strings are provided by the server or user).
So that for example the following would be valid:
$(html1Document).$("#someDivID")...
If anything is unclear, please ask me to clarify more.
Thanks.
var $docFragment = $(htmlString);
$docFragment.find("a"); // all anchors in the HMTL string
Note that this ignores any document structure tags (<html>, <head> and <body>), but any contained tags will be available.
With jQuery you can do this:
$(your_document_string).someParsingMethod().another();
You can always append your html to some hidden div (though innerHTML or jQuery .html(..)). It won't be treated exactly as a new document, but still will be able to search its contents.
It has a few side-effects, though. For example, if your html defines any script tags, they'll be loaded. Also, browser may (and probably will) remove html, body and similar tags.
edit
If you specifically need title and similar tags, you may try iframe loading content from your server.

Categories