Apply CSS dynamically in Angular app - css

In my angular application, i load URLs inside an iframe dynamically, i want to apply custom.css to the loaded url once the url is loaded inside an iframe.
I have tried it using ng-init with angular-css-injector function in iframe. It works, but the css is not applied. Probably it is getting called in the initial stage. Is there any angular feature to apply the function once the url is loaded in iframe?
Here is the code
HTML:
<iframe frameborder='0' ng-src="{{trustSrc(selected.imgurl)}}" ng-init="applyCSS()" frameborder="0" allowfullscreen>
</iframe>
App.js:
var routerApp =angular.module('DiginRt', ['ngMaterial','angular.css.injector'])
routerApp.controller('AppCtrl', ['$scope', '$mdSidenav','$sce', 'muppetService', '$timeout','$log', 'cssInjector',function($scope, $mdSidenav,$sce, muppetService, $timeout, $log,cssInjector) {
$scope.applyCSS = function() {
cssInjector.add("style.css");
console.log("loaded css dynamically");
}
Here is the plunker

The thing which you are trying is appending CSS to own page, and appending css do parent document would not be applied to the child document which is created by iframe (Iframe creates child document after src has been loaded into the DOM).
Simply you can not do this. You can dynamically add the style dynamically inside iFrame unless the domain of both be same.(Refer this SO Answers for add url for same domain)
By looking at your code it don't looks like your are trying to load different domain inside iframe on your domain.
Possible work around would be, you could pass one more query parameter inside url & maintain css code on the site which you want to load it inside your iframe on basis of query parameter.(use yepnope.js to load js conditionally)

Related

iframe cross-domain access with JavaScript

I have a simple HTML page with an iframe. I set its src to another HTML
file and I can change the style of any chosen element at will using code
like this (a basic example):
function elementStyle()
{
var iFrame = document.getElementById( "iFrame" );
var element = iFrame.contentWindow.document.getElementsByTagName(
"table" )[0];
element.style.color = "#ff0000";
}
However the src of the iframe must be an external URL and cross-domain
restriction prevents me from accessing its elements. I have no control
over its content so I can't use postMessage() because I can't receive
any message posted.
Any ideas of a way to get round this?
Note: it must work for anyone with any browser so musn't use any special
methods (like jQuery, CORS etc).
Thanks

How to access <div> elements outside the <body> tag?

I made a script that connects to a WP video plugin and generates a floating menu over it. The script works fine inside the WP page but it does not work when I use the plugins SHARE&EMBED function when it generates a link to my video that is used to incorporate it into another page structure. When embedding the into the outside webpage my custom Js script does not work. Better to say it works because my js and css files get connected to the head of the new page and the menu is present inside the structure of the page but it is covered by the new div elements generated by the plugin.
WordPress video plugin that I use generates an iframe tag. When I examine the page in which I embed the link to the video, in developer mode, I see that the is placed inside a tag that is outside the page's tag. When I try to access the Iframe tag with document.getElementsByTagName("iframe") or by its' id I get an error message that the element does not exist. I tried to use "document.addEventListener('DOMContentLoaded',..." and "if(window.fwduvpPlayer0)..." but it still i can not access the the tag with my video.
document.addEventListener('DOMContentLoaded', function displayMenuBtnOverVideo() {
generateMainMenuButton1();``
if (window.fwduvpPlayer0 && document.getElementsByTagName("iframe") != null) {
shareAndEmbed();
}
});
document.addEventListener('DOMContentLoaded', function displayMenuBtnOverVideo() {
generateMainMenuButton1();``
if (window.fwduvpPlayer0 && document.getElementsByTagName("iframe") != null) {
shareAndEmbed();
}
});
function shareAndEmbed() {
let getIFrameDiv = document.document.getElementById("fwduvpPlayer0youtube");
getIFrameDiv.insertAdjacentHTML("beforebegin",
`<div class="show-menu top-left" id="menuBtnDiv1">
<button class="btn btn-sm" id="menuBtn" onclick="videoOverlayMenuGenerator1()">
<span class="iconify" data-icon="whh:menu" data-inline="false"></span><span class="menu-button-title"> MENU emb</span>
</button>
</div>`
);
The idea is that I want my script to access he iFrame tag by its' id and include before it the div tag with the code for my custom menu.
You are selecting the document property within document. That property does not exist.
let getIFrameDiv = document.document.getElementById("fwduvpPlayer0youtube");
Maybe you tried to get the <html> tag which is the documentElement property in document.
documentElement only has three methods to select elements.
getElementsByClassName
getElementsByTagName
getElementsByTagNameNS
In order to access to a element that is not into the tag, you can try to use this options:
window.parent.document.getElementById()
OR
window.top.document.getElementById()
Maybe, with this you would can to access to this elements.
I hope that this, help you.
Regards

Expose specific element in ShadowDom to external JS using document.getElementById

I have a v0/Polymer 1 web component that I am upgrading to v1/Polymer 2. This web component dynamically builds a URI that loads an external JavaScript file. The external JavaScript file runs and loads an <iframe> into a <div> of my component. This external JS contains document.getElementById to load the <iframe> into the specified <div>.
I have searched and haven't found a way to force the <div> element to be exposed/placed in the shady DOM. I have read that if I design the component without a shadow DOM nothing will be displayed.
Is there anyway I can update this to web components v1/Polymer 2 with the external script (third party) still using document.getElementbyId to modify a <div> inside the web component?
UPDATE
I have found that I can force webcomponents to use the shadow dom using <script>window.ShadyDOM = { force: true };</script> or <script src="/bower_components/webcomponentsjs/webcomponents-lite.js" shadydom></script> however I still cannot access the element by ID and I do not want to force all other webcomponents to use the shady DOM. Still looking for possibilities.
What I had to do was put a <slot></slot> inside my Web Components template. When I declare the custom element, I have to nest a <div> inside of it like so: <custom-element><div></div></custom-element> which I am doing using this.appendChild() where this is the custom element. The <div> inside my element can now be accessed by document.getElementById() once it is assigned an id attribute.

AJAX: is the new loaded content using the same css file?

When I load content with AJAX, is this content supposed to automatically use the preloaded main page css style ?
For example, if I load a <span class="smallText">hello</span> with AJAX.
Is this new HTML using the default.css file with
.smallText {
font-size:6px;
}
?
when I load content with AJAX, is this content supposed to automatically use the preloaded main page css style ?
Yes. The HTML is injected into the context of the current page, and subject to all its CSS rules.
Yes it will use the CSS of the page it's loaded in.

Apply "onclick" to all elements in an iFrame

How do I use the JavaScript DOM to apply onclick events to links inside of an iframe?
Here's what I'm trying that isn't working:
document.getElementById('myIframe').contentDocument.getElementsByTagName('a').onclick = function();
No errors seem to be thrown, and I have complete control of the stuff in the iframe.
Here is some code to test and see if I can at least count how many div's are in my iframe.
// access body
var docBody = document.getElementsByTagName("body")[0];
// create and load iframe element
var embed_results = document.createElement('iframe');
embed_results.id = "myIframe";
embed_results.setAttribute("src", "http://www.mysite.com/syndication/php/embed.php");
// append to body
docBody.appendChild(embed_results);
// count the divs in iframe and alert
alert(document.getElementById("myIframe").contentDocument.getElementsByTagName('div').length);
It is possible for an iFrame to source content from another website on a different domain.
Being able to access content on other domains would represent a security vulnerability to the user and so it is not possible to do this via Javascript.
For this reason, you can not attach events in your page to content within an iFrame.
getElementsByTagName returns a NodeCollection, so you have to iterate throgh this collection and add onclick handler to every node in that collection. The code below should work.
var links = document.getElementById('myIframe').contentDocument.getElementsByTagName('a');
for(var i=0;i<links.length;++i)links[i].onclick=function(){}
also make sure, you run this code after the frames' content is loaded
embed_results.onload=function(){
// your code
}

Resources