I am using NgStyle to dynamically set the background image of a container in angular 4.
This site: Says the proper syntax is the following
[ngStyle]="{'background-image': venueobject.groupphoto[0]}">
or
[ngStyle]="{'background-image': 'venueobject.groupphoto[0]'}">
I also saw turning the whole thing into a string:
[ngStyle]="'background-image': 'url(' + 'venueobject.groupphoto[0]'+ ')'">
and
[ngStyle]="'background-image: url(' + venueobject.groupphoto[0] + ')'">
but I keep not getting it. The page is rendering so my html is not broken, but the image is not showing.
This is currently not yay and I am trying to make it yay.
Please help me make it yay
Hugs and kisses
You can try the following:
In your ts file:
import { DomSanitizer } from '#angular/platform-browser';
constructor(private sanitizer: DomSanitizer) { }
getBackgroundImg() {
// replace the path to your image here
const img = 'assets/img/wall.png';
const style = `background-image: url(${img})`;
// this is to bypass this warning 'WARNING: sanitizing unsafe style value background-image: url(assets/img/wall.png) (see http://g.co/ng/security#xss)'
return this.sanitizer.bypassSecurityTrustStyle(style);
}
In your html file:
<div [style]="getBackgroundImg()"></div>
You will also need to set the width and height of the div to see the image.
Related
My app in Ionic 4 but I can’t understand how to customize components.
And i want to display alignment position top right corner.
I have tried in global.css file as well as component.css file , but didn't any luck.
async getNotifications() {
const popover = await this.popoverController.create({
component: NotificationComponent,
// event: ev,
cssClass: 'notificationCSS',
translucent: true
});
return await popover.present();
}
In notificationCSS :
.notificationCSS{
top: 0px !important;
right: 0px !important;
}
Ref. Url
I had a similar problem in ionic for dynamically (maybe not exactly correct in angnular world) rendered html elements. My component css file didn't pick up the classes that I was targetting. However global.css did. I would try put your css in global again.
When I dynamically change img's src attribute, old image is displayed while loading a new one.
I have a component which displays some data: text and image. On click the underlying data is changed (i.e. new data from server). Once click, text is changed immediately, but component displays old image while new one is loaded. When new image is loaded, then it is visually displayed which can take noticeable amount of time.
In real application one can have product details and changing products on button click. All data is replaced immediately but not image.
Problem exists when the component is not destroyed (reused).
I've already tried clear image src after click, but it not worked.
I have simple binding in template
img [src]="img.url" style="width: 300px; height: 300px">
<p>{{ img.text }}</p>
and image change on click
this.img = this.images[1];
You can see sample app here https://stackblitz.com/edit/angular-cojqnf
Is this possible to take more control of this image change process? It would be great to clear image on click and wait for new one with empty background for example.
I hacked around a little with your stackblitz demo, I basically wrapped your code in an ImageGhostDirective to make it reusable. The directive listens to any changes on the src attribute using a MutationObserver to change the style. Using a HostListener on the 'load' event, it reverts the styles back to normal. I start with an opacity of 0 for the first load, followed by an opacity of 0.2 between successive image changes, but this is completely arbitrary and could be replaced by a spinner or any kind of placeholder...
Here is the link to the stackblitz: https://stackblitz.com/edit/angular-image-ghost-directive
<img [src]="'https://loremflickr.com/300/300?random=' + index"
style="width: 300px; height: 300px" imgGhost>
#Directive({
selector: 'img[imgGhost]'
})
export class ImageGhostDirective implements OnDestroy {
private changes: MutationObserver;
constructor(private elementRef: ElementRef) {
this.changes = new MutationObserver((mutations: MutationRecord[]) =>
mutations.filter(m => m.attributeName === 'src').forEach(() => this.opacity = 0.2)
);
this.changes.observe(this.elementRef.nativeElement, {
attributes: true,
childList: false,
characterData: false
});
}
ngOnDestroy(): void {
this.changes.disconnect();
}
#HostBinding('style.display') display = 'block';
#HostBinding('style.opacity') opacity = 0;
#HostListener('load')
onLoad(): void {
this.opacity = 1;
}
}
It is also possible to tell Angular to automatically attach this directive to every img element by using the img:not([imgGhost]) selector in the directive decorator. That way, you don't have to manually place the directive on every image in your app.
Hope this is useful.
Finally I achieved what I want by leveraging (load) event on img and [ngStyle].
In template I added load handler and style:
<img [src]="img.url" style="width: 300px; height: 300px" (load)="loaded()"
[ngStyle]="{'display': imgVisible ? 'block' : 'none'}">
In back-end:
imgVisible = true;
and when changing data, also hide image:
this.imgVisible = false;
next, when image is loaded, show the image (be careful! when old and new images have the same URL, this event is not raised; if it is the case you need to conditionally hide image)
loaded(): void {
this.imgVisible = true;
}
Complete code for solution: https://stackblitz.com/edit/angular-ewptj7
I'm not a big fan of this kind solutions. It could be difficult to apply when you have more images.
All better solution are welcome.
This question already has answers here:
Angular 2 - innerHTML styling
(11 answers)
Closed 5 years ago.
I am passing html as innerHtml to my view. Below is my view
<div [innerHTML]="someHtmlCode"></div>
if I pass the below code, it is working fine.
this.someHtmlCode = "<div><b>This is my HTML.</b></div>"
if I pass the below code which contains color, it is not working.
this.someHtmlCode = '<div style="background-color: blue;"><b>This is my HTML.</b></div>';
This behavior you're getting is normal. The class added to innerHTML is ignored because by default the encapsulation is Emulated. Which means Angular prevents styles from intercepting inside and outside of the component.
You should change the encapsulation to None in your component.
This way, you'll be able to define classes wherever you want: inside styles or in a separate .css, .scss or .less style-sheet (it doesn't matter) and Angular will add them to the DOM automatically.
import { Component, ViewEncapsulation } from '#angular/core';
#Component({
selector: 'example',
styles: ['.demo {background-color: blue}'],
template: '<div [innerHTML]="someHtmlCode"></div>',
encapsulation: ViewEncapsulation.None,
})
export class Example {
private someHtmlCode = '';
constructor() {
this.someHtmlCode = '<div class="demo"><b>This is my HTML.</b></div>';
}
}
I was also facing the same issue but after reading this below link I figured out the solution and it was done without using pipes
Hope this will help you.
https://netbasal.com/angular-2-security-the-domsanitizer-service-2202c83bd90
Instead of an inline style, I put the style in a class.
Not sure if using class is an option for you or not, but here's a Plunker demo.
HTML:
this.someHtmlCode = '<div class="demo"><b>This is my HTML.</b></div>'
CSS:
.demo{
background-color: blue;
}
Define the class demo at the root css file, usually it's called styles.scss.
I am using react-boilerplate (3.4.0) with react-router internally for the routing.
I have tried to create a Link with : < a href="#anchor-tag" >< /a >
When I click on it I expect to scroll to the div with id=anchor-tag
It just scroll to the top of the page, even if I use a Link component instead of a < A > tag. Does we have to care about use < A > or < Link > ?
How should we create anchor tag in react-router ?
This might be a while late but what you can do is add this to your component:
import ReactDOM from 'react-dom';
... some more codez...
componentDidUpdate() {
const anchor = this.props.location.hash.replace('#', '');
if (anchor) {
const domElement = ReactDOM.findDOMNode(this.refs[hash]);
if (domElement) {
domElement.scrollIntoView();
}
}
}
and then on your actual element that you want to navigate to, you need to add the ref attribute, like this:
<h1 ref="my-anchor">Hello World</h1>
The link element is going to look just like a regular link:
<a href="/about#my-anchor>Go To Anchor</a>
Or with react-router:
<Link key="my-anchor" to="/about#my-anchor">Go To Anchor</Link>
This works with react-router 2.6.1 - not sure about later versions at this point.
Hope this helps!
Improved answer above:
componentDidMount() {
const anchor = this.props.location.hash;
if (anchor) {
const domElement = document.querySelector(anchor);
if (domElement) {
domElement.scrollIntoView();
}
}
}
I highly recommend to use the package from Rafael Pedicini called react-router-hash-link.
Live example right there. It's working well and the code is clean.
I want to add a background image on Facebook's react.js my-app. I can do this by setting a background image to a div element. But my div only covers half of the page. Which is why my image is not fulling occupying the page.
Instead, I want to do this on a body element. But how to add a body element and set a background image to it?
I tried this, but its not working in App.js file of my-app
<body background="http://i.imgur.com/DaNQJ6I.jpg"></body>
[EDITED]
Css-tricks.com provides a quite cool solution of the full page images:
https://css-tricks.com/perfect-full-page-background-image/
I used this example for my React implementation with the useEffect (https://reactjs.org/docs/hooks-effect.html).
Note: background-size replaced by backgroundSize when the style is setted.
import React, { useEffect } from "react";
import img from "./test.jpg";
export default function App() {
useEffect(() => {
document.body.style.background = `url('${img}') no-repeat center center fixed`;
document.body.style.backgroundSize = "cover";
document.body.style.webkitBackgroundSize = "cover";
}, []);
return <div className="App"></div>;
}
Try using style:
<body style={ bodyStyle }></body>
And bodyStyle should look like:
var bodyStyle = { backgroundImage: 'url(http://i.imgur.com/DaNQJ6I.jpg)' };
For some reason, I cannot add a background image on app.js or app.css files of react framework. However, I tried to do it on index.html. This worked perfectly to me.
So, please add background images on index.html If you are unable to do it in app.js or app.css.
And also, future readers, If you have found a way to do it, feel free to answer the question, thanks!!
This works for me. The actual work is done in componentDidMount(). So technically, you could add this on about any component. Like, you could put it on a navbar or even in the layout.
For my projects, I created a component. Add it to your layout (or where ever) and it should work.
Good luck!
export default class BodyStyle extends Component {
componentDidMount() {
const { style } = this.props;
var body = document.getElementsByTagName( "body" )[ 0 ];
for ( var key in style ) {
body.style[ key ] = style[ key ];
}
}
render() {
return <span ref="BodyStyle"/>;
}
};