I have created a reusable web component and for this question's sake, let's call it <custom-el>. To invoke this custom element's implementation, I am writing it in my template files as following <custom-el class="container-for-custom-tag"></custom-el> and in the component, I am adding the children to this tag. When the browser engine finds out this tag, my component gets invoked and it adds children to this tag.
To make it work in IE 11, I have used document-register-element polyfill and it transpiles the file successfully. I don't get any errors in IE 11 when I load this transpiled file. But since the tag is also not recognized in IE11, nothing renders in UI. What am I doing wrong here?
I tried using babel plugins as well, I get the same result. The file gets transpiled but nothing renders in UI because of the tag.
Now, I have a solution in mind to invoke the web component on demand instead of it getting invoked because of the HTML tag. But I really want to know is there anything else which can be done to solve it. I saw on GitHub page of document-register-element that they have also put the custom tag in the HTML page in the examples but how is it working for them that I am not sure of.
This is how I am defining my custom Element:
class CustomEl extends HTMLElement {
// Inside this I render the child elements
// This HTML gets appended to the custom-el as children:
//<div class="text-container">20</div>
// I m not using shadow root
}
// Here I define the custom element
customElements.define('custom-el', CustomEl);
This is how I have invoked it:
// The following code goes in the template HTML file
<div class=“wrapper-container”>
<custom-el id="js-custom-el-conatiner”></custom-el>
<div>
When I load it in the browser, I get the following output in the browser inspector:
<div class=“wrapper-container”>
<custom-el id="js-custom-el-conatiner” >
<div class="text-container">20</div>
</custom-el>
<div>
For IE, I have required polyfill/document-register-elementin this file as per the github page documentation. class CustomEl extends HTMLElement gets compiled and I don't get any syntax error or any kind of error in the file. But since the HTML tag is still <custom-el> which invokes the implementation, it doesn't get invoked because that element is not recognized by IE browser engine.
It's not JS issue here - you have proved the custom element does its job and makes it into DOM. Now, make sure you have applied CSS to that element, basically telling browser how to render it. Start with basic display property. Without JSFiddle or CodePen or anything to play with it's hard to tell you the exact issue. Most of the times it's the problem to get a custom element into IE11 due to the fact it does not support ES6 constructs that are needed and one has to rely on polyfills like https://github.com/webcomponents/polyfills/tree/master/packages/webcomponentsjs
Related
So I currently have a tampermonkey script that runs when it's on https://code.org/projects/applab/* which is where I want it. However whenever I run my code to remove the attr 'style' of the grandparent and parent of the specified element nothing happens.
Even though when I ran a test of this jQuery on w3's interpreter it worked...
$(document).ready(function() {
$("body").append(themeChangesCss);
$("#screenSelector").parent().parent().removeAttr('style');
$("#screenSelector").parent().removeAttr('style');
$("#runButtonWrapper").parent().parent().removeAttr('style');
$("#runButtonWrapper").parent().removeAttr('style');
});
You can also view the whole script here : https://sourceb.in/vdZOU1B7fq
You should probably start by logging the element you're trying to change to console. It is quite possible, that the web app changes the style AFTER your script executes. In that case, your changes will not have any effect.
If that is the case, read up on Mutation Observer, which allows you to execute code any time something changes the style attribute on the elements you want to clear.
I have tested your code and it indeed does work as it should on my test document. I couldn't find how should I test your code on the website you linked.
I have some div:
<div id='dialog'></div>
Now I want to load into this div an external html file and use its js functions.
I know I can load it using jQuery.Load() and it works fine, the problem is that I want to use the html js functions.
The main problem is that I have several divs which I load this html file into them and I want that when I'm activating js function it will only work on the specific div.
Pass parameter to view that you are loading that will indicate container of the loaded view:
jQuery.Load(url, { containerId: 'dialog' })
I remember I had the problem back when jQuery1.4 was issued. In that version, .load() suddendly began stripping out the js when a target container was specified.
What I did at that time :
separate html and js in different files (let's say myhtml.html and myjs.js ), or views
have my js file act as a js module, with a public entry point function (say initContent) taking a jQuery element as a parameter
have an invisible link in myhtml.html, namely
after loading myhtml.html into my target div, search for $('a.dynamicJs') in my target div to extract js url, and entry point function from the href
if the js had not previously been loaded, dynamically load the js into the page trhough an ajax call
dynamically call the entry point function with the target div as parameter
This also worked with css.
It required some time to tweak it on all navigators (limited number of css sections on IE, different way to dynamically call a function), and I ended with much more code I expected in the first place. It also required a lot of refactoring of my html/js modules (but I must confess I ended having a code that was really cleaner)
I'm sure there are frameworks that handle this kind of situation way better by now. But this is what I came up with at that time.
Hope this will help
When I load a page, there is a style attribute that has been added to the <body> tag that is not there in my templates. How do I discover what javascript has modified it?
Just to be clear, the body tag is now:
<body class="home page" style="margin-top: -43px;">
So the style is not coming from a style sheet. While the template does not include the "style=" bit at all. So I'm pretty sure that some running javascript is modifying the body tag.
I have both Firefox/Firebug and Chrome Inspector available to me. I have tried right clicking on the body tag in "HTML"/"Elements" view and choosing "break on attributes modification" but the change has happened by the time I can do that, and the break point does not survive a page reload.
I'm using Django and jQuery in case that alters the answer.
I currently use an extension of Firebug called FireDiff you can file its homepage here: http://www.incaseofstairs.com/firediff/
You could use mutation observers.
Try adding this code as the first thing that gets executed on page load:
var target = document.querySelector('body'),
observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
debugger;
});
});
observer.observe(target, { attributes: true });
As a side note, it'd be great if that particular kind of breakpoints survived page reload.
There is the possibility it is added server side too. If you search your source files for the stylesheet name it should appear in either a JavaScript or a Python file. i.e. grep for "mystylefile.css"
You could disable JavaScript and see if it is still added if you want to narrow it down.
Update
Finding what added the margin-top to the element will be harder! You could search your JavaScript files for "margin-top" and see how many results you get back - or add the JavaScript files one by one until one causes it to be added.
I'm very new to javascript, so this is confusing me. All of the settings charm tutorials only show how to put the controls into the settings charm, but none of them say how to find the information gotten in them.
I tried to do one of these (like I do in the main program):
var muteToggle = document.GetElementById("Mute");
where "Mute" is the id in the separate html file.
muteToggle just ends up being null all of the time. I tried putting it after
WinJS.UI.ProcessAll().then(function completed() {...
but that didn't work either. Everything else is the same as in this page: http://msdn.microsoft.com/en-us/library/windows/apps/hh780611.aspx
Make sure you're doing it in the ready function of the js file that is referenced from your settings HTML. Try opening the JavaScript console or QuickWatch while broken at that line and also look at the DOM Explorer to see if you can find your toggle control. You should be able to access it though. Also, try element.getElementById instead of document.getElementById. Either should work actually, but as long as you're troubleshooting. Good luck.
Your problem is that you are trying to get a reference to the HTML element from the code running during the app activation. Although that piece of code may define the HTML to be loaded for a settings pane, it does Not actually load the HTML into the DOM. You just simply can't get the instance from that location.
What you need to do is have the settings flyout have its own js file that implements IPageControlMembers. In particular, you need to implement the ready method. This method is called once all the HTML and controls are loaded for the page, including your toggle. The link has an example of how to do this.
Also see:
WinJS.UI.Pages.define
Using single page navigation
I am just starting out with Windows 8 development using HTML/JS. I've spent the last few months immersed in jQuery development for apps targeting vehicle head-units and televisions.
Jumping into this, I thought the transition would be simple. I have the design and structure of my site all figured out for the most part and was hoping to follow some of the practices I had been using for my previous work.
That is, I want to essentially create a single page app. The main default.html file will house the top navigation/title and one other div. The other div will be used to load in all the other pages, all separate HTML files within the project.
All of the global functions and major functionality will reside in a javascript file, application.js. Then any page-specific javascript will reside at the top of each HTML file.
I'm quickly realizing that this is a problem. Using jQuery.load() to load in my pages causes security errors in my app.
JavaScript runtime error: Unable to add dynamic content. A script attempted to inject dynamic content, or elements previously modified dynamically, that might be unsafe. For example, using the innerHTML property to add script or malformed HTML will generate this exception. Use the toStaticHTML method to filter dynamic content, or explicitly create elements and attributes with a method such as createElement.
I was really hoping to avoid having to learn a bunch of Microsoft-specific stuff. I think it's great that they've provided a lot of tools and what not, and maybe I just haven't used them enough, but everything just feels too rigid for me and for what I'm trying to do or can already be accomplished with jQuery. I'm one who likes to know EXACTLY what is happening and have full control over it.
Also looking through the templates and sample projects, I really don't like all the repeated code. For instance, every single HTML file declaring all the same references. I want to write my references and sections like my title bar just once, and not have to copy/paste that code all over my project.
Is there a way to do things the way I was hoping, and create a single page app? Do they have their own substitute for jQuery's .load()?
Any help pointing me in the right direction would be much appreciated!
EDIT 8/14/2012:
I have tried using the fix from this question:
Using jQuery with Windows 8 Metro JavaScript App causes security error
This gets rid of the security warning and I can load in HTML using jQuery.load(). However, looking at DOM explorer, my HTML is being stripped of my scripts.
I have also tried wrapping my .load() call inside of MSApp.execUnsafeLocalFunction(), but yet again my file still gets stripped of all scripts. What gives?
I fixed by simply changing the line of jQuery that was causing the error.
jQuery-1.8.0, line 5566:
append: function () {
return this.domManip(arguments, true, function (elem) {
if (this.nodeType === 1 || this.nodeType === 11) {
self.appendChild(elem); // problem line
}
});
},
Changed to:
append: function () {
return this.domManip(arguments, true, function (elem) {
if (this.nodeType === 1 || this.nodeType === 11) {
var self = this;
MSApp.execUnsafeLocalFunction(function () {
self.appendChild(elem);
});
}
});
},
There is a "formal" way to do what you are seeking.
WinJS.Navigation is provided to support "single page apps". For example, the default.html would contain a markup that would represent where the dynamically loaded page content would go:
<div id="contenthost"
data-win-control="Application.PageControlNavigator"
data-win-options="{home: '/pages/home/home.html'}">
</div>
In the example above, the actual content page loaded is at /pages/home/home.html
In event handlers, you can simply do the following to load or navigate to another page:
WinJS.Navigation.nav("/pages/other/page.html");
True, it is not jQuery, but it works great :)
Depending on your app, if you are not intending to access any WinRT components, you can navigate your page to ms-appx-web which will change the security policy around the page, but you can't specify this from start up. You would have to do a navigate, and leverage that new securyt context.
The other option you have it to wrap the calls to JQuery with msWWA.execUnsafeLocalFunction function, which will enable all that unsafe code be pushed into the DOM