Add font awsome icons to a JavaScript file - javascript

I have created a webpage with this layout:
<html>
<head>
<title>My Website</title>
<script src="Link to Font Awesome Kit Code" crossorigin="anonymous"></script>
<script src="header.js" type="text/javascript" defer></script>
</head>
<body>
<header-component></header-component>
</body>
</html>
I have created a JavaScript file named "header.js" with this layout:
const headerTemplate = document.createElement('template');
headerTemplate.innerHTML = `
<p>This font awesome icon has been put on this webpage using JavaScript</p>
<i class="fa-solid fa-envelope"></i>
`
class Header extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
const shadowRoot = this.attachShadow({ mode: 'closed' });
shadowRoot.appendChild(headerTemplate.content);
}
}
customElements.define('header-component', Header);
The paragraph tag showed up correctly.
I also expected the font awesome icon to show up correctly, as the script tag to font awesome has been written in the head of the HTML document. However, no icon has showed up. I have also tried to write the script tag at the top of the JavaScript document, as well as inside the innerHTML of the JavaScript document. However, this has not resulted in the font awesome icon showing. Instead, the output remains the same.
I wrote the 'i' tag inside the HTML document, to test if the error was inside the HTML code, rather than the JavaScript. However, inside the HTML document, the 'i' tag worked correctly.

Related

D3.js - Add elements in HTML - <script></script> location

I was working with the following tutorial of D3.js: https://www.tutorialspoint.com/d3js/index.htm.
My issue is as follows:
I'm aware of that the location inside the HTML is at the end of the . I mean, I usually put it here:
<body>
<!-- HTML code -->
<script>
<!-- JS code or external JS link -->
</script>
</body>
With this practice, what I'm looking is to run JS after the HTML content renders.
But! When I follow this practice using D3.js, what I discover is that D3.js renders what I add (using d3("html").append(something to append), after the script tags.
For example!
<!DOCTYPE html>
<head>
<title>D3.js Test</title>
</head>
<body>
<div class="div_test">
<h1>I want the D3.js content after this div (but not inside the div)</h1>
</div>
<script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
<script>
d3.select("html").append("p").text("I get this text after the script tags");
</script>
</body>
</html>
I'm getting the content as follows:
<!DOCTYPE html>
<html>
<head>
<title>D3.js Test</title>
</head>
<body>
<div class="div_test">
<h1>I want the D3.js content after this div (but not inside the div)</h1>
</div>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script>
d3.select("html").append("p").text("I get this text after the script tags");
</script>`
</body><p>I get this text after the script tags</p></html>
Questions!
Is the position of the tag correct?
Is there a possibility to keep the flow without adding a to anchor the expected new tag?
Thanks!!!
You can use selection.insert() to insert an element instead of appending it to the DOM. The second argument to that method determines where the newly created element is put into the DOM tree. If you just want to put it in front of the first <script> element you can do something like:
d3.select("body").insert("p", "script") // <-- insert before first <script>
If you need to place it after the <div>, no matter what the next element might look like, you can use the adjacent sibling combinator to select the sibling element directly following the <div> like so:
d3.select("body").insert("p", "div + *") // <-- insert before next element following div

Toggle function not working on font awesome. The event handler is getting removed on id by browser after first toggle

The hamburger icon toggles to times icon but the reverse does not happen. The event handler is removed from the svg tag with the same id after first click. No other code exists in js file.
$(document).ready(function() {
$('#menu-bar').click(function() {
$(this).toggleClass('fa-times');
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="menu-bar" class="fas fa-hamburger"></div>
The problem was with the fontawesome file all.js or all.min.js. The right files to be included when using font awesome for icons are:
<link rel="stylesheet" type="text/css" href="staticAssets/css/all.min.css">
<script type="text/javascript" src="staticAssets/js/fontawesome.min.js"></script>
Its better to include all the files downloaded for font awesome at one place, since the files also have relative paths, which might show up as errors in console.

How to use SyntaxHighlighter on dynamically loaded code blocks with Angular 6?

I am trying to add SyntaxHighlighter to my angular blog project. My articles have <pre> formatted code snippets and is loaded from database. This article HTML is then displayed in ArticleComponent template. This ArticleComponent itself is loaded when a particular route is triggered. But when I browse to this route and an article is loaded, the <pre> formatted codes are not highlighted at all. However, if I refresh the page, highlighting works well. Not sure where I am going wrong.
index.html
<head>
<meta charset="utf-8">
<title>My Blog</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="./assets/css/foundation.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css" />
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css" />
</head>
<body>
<app-root></app-root>
<script type="text/javascript" src="./assets/js/jquery.js"></script>
<script type="text/javascript" src="./assets/js/what-input.js"></script>
<script type="text/javascript" src="./assets/js/foundation.js"></script>
<script>
$(document).foundation();
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js" type="text/javascript" ></script>
<script type="text/javascript">
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all()
</script>
</body>
article.component.html
<div class="cell">
<span [innerHTML]="article"></span>
</div>
article.component.ts
export class ArticleComponent implements OnInit {
public article = '';
public title = '';
constructor(private _route: ActivatedRoute, private _articleService: ArticleService) {
}
ngOnInit() {
const articleId: string = this._route.snapshot.paramMap.get('id');
const allArticles = this._articleService.getArticles();
const selectedArticleMetaData = allArticles.find(x => x.id === parseInt(articleId, 10));
this.title = selectedArticleMetaData.title;
this._articleService
.getArticleHtml(selectedArticleMetaData.id)
.subscribe((article: string) => {
this.article = article;
});
}
}
I checked the HTML DOM elements and I am able to verify that the article that is loaded without refresh has all its <pre> blocks as raw code. But when SyntaxHighlighter is actually working in case of refresh, these <pre> tags are all converted to div elements with proper style classes.
Looks like when when articles are loaded through binding, SyntaxHighlighter is unable to process the <pre> tags. Any idea how to fix this ? Also any idea why it works when I refresh this page ? In either case, the article is loaded through binding.
The SyntaxHighlighter.all() method which highlights all html with <pre> tag, is called only once i.e. when the page is loaded because you included it in the script tag of index.html. When this method is called, it will highlight all available <pre> on the page.
When you go to a route, the SyntaxHighlighter.all() function needs to be called which will highlight the new generated tags or text inside that tag.
When you refresh the page, <pre> tags are available on the page html when SyntaxHighlighter.all() is called which is the reason, it is highlighting correctly.
So for articles that are loaded through binding, call SyntaxHighlighter.all() in logic once to highlight your <pre> tags.
You need to choose the right event, where it should be called in your component and also, you need the define a variable at the top of your component below your import statements so that tslint should let you use that variable in your component i.e. declare var SyntaxHighlighter
Solved it. Answering it here as it might be helpful to some one else.
SyntaxHighlighter.all() method registers a Highlight method to windows.load event. Hence this method is only triggered on page load and never later. This solves the mystery of why highlighting worked during page refresh and not when angular routing is triggered.
The fix is to trigger a window.load event after article is loaded in the DOM. There are better ways to do this, but here is the most straight forward way to do this. Update article.component.ts to include the code to trigger window.load event.
this._articleService
.getArticleHtml(selectedArticleMetaData.id)
.subscribe((article: string) => {
this.article = article;
this.loading = false;
// trigger window.load event after 500 ms of binding the article property
setTimeout(() => {
window.dispatchEvent(new Event('load'));
}, 500);
});

hide body until external resources(loaded asynchronously) load

So, I have various external resources like google material icons and so on which are loaded using the link and script tags:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
How can I hide the body until all these resources(loaded via link and script) are loaded completely? Can I do this using custom directives? And also, I am NOT using jQuery.
EDIT:
The reason I want this is that google's material design icons are included in the following way:
<i class="material-icons">
visibility
</i>
So, while the material icons css is still loading, I can see all these icon texts, 'visibility' in my case on the screen in their textual form. And, only when the css loads, does the text translate to icon form. I'll add a screenshot soon.
Hide your body in our CSS, and show it when the event DOMContentLoaded is triggered
JAVASCRIPT
document.addEventListener("DOMContentLoaded", function(event) {
document.body.style.display = 'block';
});
CSS
body {
display:none;
}
Just add display:none for body tag in header :-
<html>
<head>
<style>
body{
display: none;
}
</style>
/* Load all your external CSS and JS */
</head>
<body>
<script>
$(document).ready(function(){
$(body).css("display", "block");
})
</script>
</body>
</html>
It may help you.
Using this: https://github.com/typekit/webfontloader
Will output a class to HTML tag while loading fonts, this way:
.wf-loading
.wf-active
.wf-inactive
.wf-<familyname>-<fvd>-loading
.wf-<familyname>-<fvd>-active
.wf-<familyname>-<fvd>-inactive
With that you can do anything from html > to any other tag, body for example, so:
.wf-loading body{display:none;}
.wf-active body{display:block;}
Also you have callbacks to use via js, take a look, it´s working: http://fiddle.jshell.net/m2d6k8er/ it´s just a very basic example of course.
Edit 2
OP's issue concerning loading external scripts may need further testing with async and defer attributes. The following links will help in that direction:
Async and Defer (non-blocking JavaScript with HTML5)
JavaScript Execution Order; Asynchronous JavaScript
Promises - Thinkster
In 3 Minutes, JavaScript Loading of Scripts
MDN
Deep dive into the murky waters of script loading
Here's the JS equivalent of Harsh's code (if placed at the closing </body> tag):
EDIT 1
delayedBy(ms) is triggered by the onload event of <body>. You can adjust the delay.
function delayedBy(ms) {
setTimeout('visible()', ms);
}
function visible() {
var body = document.getElementsByTagName("body")[0];
body.style.visibility = "visible";
}
body {
visibility: hidden;
}
<body onload="delayedBy(1000);">
<h1>Here I am!</h1>
</body>

How to replace custom HTML tag with another tag, using the same content?

Is it possible to create your own text contents (text between the HTML tags) of my custom HTML tags?
I used this code:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script>
$(document).ready(function () {
$("eg").replaceWith("<h2>Put the text content of eg here</h2>");
});
</script>
</head>
<body>
<eg>My text</eg>
</body>
</html>
Between the <h2> tags (don’t think I should only use <h2> tags without JS) in my JavaScript code, any text can be placed that I like to have.
Example: <eg>I can type any text here but it’ll be still in h2 tag settings</eg>.
What should I write between <eg></eg> in JS to have any <h2> text content that will be written in my HTML code?
If you want to replace the <eg>Test</eg> with <h2>Test</h2> then you can just do this: $("eg").replaceWith("<h2>" + $("eg").html() + "</h2>");.
Here is an example: http://plnkr.co/edit/urd69pJSXQngGIsYYSjq
If I'm understanding correctly, you just want to append an element to the DOM, so you can just use the html method as follows:
$("eg").html("<h2>Any text can be placed here</h2>");
Have a look at the docs if you need more info.
Note: You closed but didn't open your body tag.
Replace:
</body>
With something like:
<body> <eg> Your custom content is between body tags now </eg> </body>
And you also have two HTML tags, remove the second
<html>
No. It wouldn't be HTML anymore.
However, if you wrote xHTML (which is a form of XML), then you could extend the DOM with your own elements. But that would be XML, not HTML.
And if you tried adding custom elements to a page, browsers wouldn't know what to do with them. Even if some browsers might display them, it's a very bad idea. Use a class name instead.
Creating and using custom tags is a bad idea. It should be avoided.
You are probably looking for this:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script>
$(document).ready(function () {
$("#my_h2").html("<h2>Any text can be placed here</h2>");
});
</script>
</head>
<h2 id="my_h2"></h2>
</body>
</html>
For more, read-up on CSS selectors. (They are the same as jQuery selectors.)
Hope this helps.

Categories

Resources