I would like to interact with the DOM immediately when the element becomes available. I can do this with a setInterval, but it won't work with Crossrider because the js that can interact with the DOM is only loaded once the DOM is ready. Any way to get aroind this?
Thanks
The current API doesn't officially support this feature at this time.
However, you're welcome to try our new appAPI.dom methods which work in Chrome and Firefox but are currently undocumented until they are officially released. The new methods are pretty self-explanatory, so I've listed them here with a brief description:
appAPI.dom.onDocumentStart.addJS(String jsCode, [Array siteList])This method adds the specified jsCode when the document starts to load. Optionally specify an array of strings/regex expressions (see http://docs.crossrider.com/#!/api/appAPI-method-isMatchPages for examples) specifying which URLs to add the code to.
appAPI.dom.onDocumentStart.addCSS(String cssRules, [Array siteList])This method adds the specified cssRules when the document starts to load. Optionally specify an array of strings/regex expressions (see http://docs.crossrider.com/#!/api/appAPI-method-isMatchPages for examples) specifying which URLs to add the CSS to.
you might want to check out the appAPI.dom.onDocumentStart object because it doesn't seem to be defined even when called after appAPI.ready(). This is the error I'm getting:
Uncaught TypeError: Cannot call method 'addCSS' of undefined
Thanks! Keep up the good work!
Related
I'm studying Javascript using Visual Code and every time a similar exercise that uses 'event' (the event shows in the code with the strikethrough like e̶v̶e̶n̶t̶) appears I can't complete it because of this annoying issue. In the description pop up a warning showing the issue ("event is deprecated ts(6385)"). I look out in the forums and stack over flow but I can not find any answer for this problem, only a few places says the lib dom and #deprecated, but I don't what to do.
Please, any way to help and learn to pass this problem out will be very useful.
function sayMyFirstName(element){
alert("My First name is..." + element.value)
}
function sayMyLastName(){
console.log(event)
}
It sounds like you're getting TypeScript validation for a simple JS project. There are several things you can try:
In your settings file (settings.json):
"typescript.validate.enable": false
... OR ...
In your .js source file(s):
/*tslint:disabled*/
A separate issue is why you're getting the "deprecation" warning in the first place. This is the reason:
https://developer.mozilla.org/en-US/docs/Web/API/Window/event
The read-only Window property event returns the Event which is
currently being handled by the site's code. Outside the context of an
event handler, the value is always undefined.
You should avoid using this property in new code, and should instead
use the Event passed into the event handler function. This property is
not universally supported and even when supported introduces potential
fragility to your code.
In other words, "event" should really be passed as an argument to a JS event handler. You shouldn't be using the global object; you shouldn't NEED to use the global object.
Here are a few good tutorials:
Introduction to events (MDN.com)
JavaScript Events
Strong suggestion:
If you're learning JavaScript, please make sure your study materials are up-to-date (definitely covering ES6!). This is a good book: Secrets of the JavaScript Ninja 2nd Edition
It looks to me that the TypeScript Validator is saying the implicit passing of event is deprecated. A simple fix would be to pass the event into the function as a parameter
function sayMyLastName(event){
console.log(event)
}
I'm migrating a lot of functionality from JS to Angular and found this issue a lot
You can use "window.event" to replace the deprecated "event".
You just need to open >Preferences: Open Workspace Settings (JSON) by Ctrl + Shift + P in VSCode then add this line to JSON file "editor.showDeprecated": false to disable a show deprecated in case if you only need to some workspace.
If you want to disable all workspace then use >Preferences: Open Settings (JSON) instead.
I'm using a framework which features auto-connecting to server on page load. I can disable it by passing options arguments, but the line that confuses me is this:
You can prevent this initial socket from connecting automatically by disabling io.sails.autoConnect before the first cycle of the event loop elapses.
My questions are:
When does the first cycle of the event loop elapses?
Is this behaviour the same across ALL modern (IE9+) browsers?
I have a bunch of scripts (in <body>) loading between the lib and my entry file. Does this affect when the first cycle elapses? EDIT: Yes, it does.
How can I ensure my code runs before the first cycle elapses?
Is this kind of implementation of auto-connect considered good practice?
The documentation for the source file is a little more explicit; it says "This can be disabled or configured by setting io.socket.options within the first cycle of the event loop."
Basically what's happening is that there exists within the library a setTimeout(fn, 0) call, which is idiomatic for starting a parallel process. However, in the JS standards it's explicitly stated that JS is single-threaded: in other words, even though setTimeout and setInterval are asynchronous they are not actually parallel in the sense that any of their code will be executing simultaneously with any other code. So they wait until the current function is over before they execute. This queueing mechanism is known as the JavaScript event loop.
I believe that what you are asked to do by the script author is to modify the source to include the relevant change, perhaps at the bottom of the file for your convenience.
It is also likely that a similar effect will be achieved by putting a <script> tag underneath the one that loads the given JS. This has not been explicitly standardized by HTML 4, but may be implicitly standardized in the new HTML 5 spec (it's a complicated interaction between different parts of the specs).
In terms of HTML5, it looks like the current specs say that there is a afterscriptexecute event and a load event which occur immediately after any remote script is loaded (or, if it's an inline script, the load event is scheduled as a task -- I am not sure when those occur). So you might be able to guarantee it without modifying the script by instead doing:
<script>
function do_not_autoload() { /* ... */ }
</script>
<script onload="do_not_autoload()" src="./path/to/sails.io.js"></script>
but I'm not sure what the compatibility table for script#onload is going to look like.
I made you a jsfiddle which can be used to grab a 'fingerprint' for different browsers to get an idea of what evaluation orders are out there in the wild. The * is the document.body.onload event. On my system it produces:
Firefox 32.0.3 : cafdbe*
Chrome 37.0.2062 : cafd*be
IE 11.0.9600 : cafd*be
In other words,
I am creating a Firefox extension, and one feature of it that I would like is the ability for the user to inject a script or stylesheet into a specific website, rather like Greasemonkey (except that this will only be for one site). I am adding some functions for the scripts to make use of, which I intended to add from the Content Script into the main (unsafe) window. On the MDN blog, it says that they have made changes to how it should be implemented, so I have based my code on the new implementation as advised in the post, so this is what I have:
var $jq = jQuery.noConflict();//Yes, I am also injecting jQuery at the same time
console.log("created jquery object"); //This works
exportFunction($jq, unsafeWindow, {defineAs: "$jq"});
console.log("This will never be called");
But execution of the script just stops, and in the console it prints Message: TypeError: window is null.
I am testing in Firefox 28 predominantly (I can't seem to get Firefox for Ubuntu to update beyond that right now, and a whole load of issues are forcing me to use Ubuntu in a VM for this), but in Nightly 31a1 (Win7) nothing is ever injected, including a hardcoded style (that works on FF28) so I will have to figure that out at some point. (The PageMod code is here:
var lttWorker = sdk.pageMod.PageMod({
include:["*"],
/*contentScriptFile: [sdk.data.url("jquery.large.js"), sdk.data.url("scripts/bootstrapper.js")],
contentScriptWhen: "ready",*/ //This is commented to test whether it was an issue with the script. It's not.
contentStyle: "#header_bar{background-color:green;}", //This is injected in FF28 but not 31
attachTo: ["existing", "top"],
onAttach: function(){desktopNotifications({title:"attached content worker", text:"The content worker has been successfully attached"})} //This is called in FF28 but not 31
});
lttWorker.on("error", function(){callError("pageWorker failed");}); //This never gets called. Ever.
if anybody is interested)
EDIT: I have now tried it on Firefox 30b and there are still a load of issues, although they seem to be slightly different to both FF28 and 31...
First of all: These new functions are supported in Firefox 30 and later. See #canuckistani answer.
The exportFunction API is way too limited to actually inject something like jQuery with all the complex objects being or containing DOM nodes. That simply won't fly with the structured-clone algorithm that is applied to arguments.
The API is meant as a way for add-ons to communicate with pages bi-directionally, and not to inject complex libraries.
Your best bet is actually creating a script tag using the DOM APIs and putting jQuery there.
I tried to create custom widget for my site. when I loaded page it says:
mixin #0 is not a callable constructor.
clsInfo.cls.prototype is undefined
I can't find any information about clsInfo, so I don't know what is it. maybe the problem that I use dojo from google:
and my own script is located on localhost. so when my dojo on page initializes something goes wrong with my script. I can't find any good info on dojo, maybe I search in wrong places?
please help me to resolve my problem
I ran into this when I was trying to override a dijit.Dialog so I could bind events to controls within it. We've yet to see if the binding part will work, but if you look at the source, this happens when one of the bases passed in as the second argument fails to resolve to an "[Object function]". In my case, I was passing a String in.
dojo.declare takes 3 arguments:
The name of the custom object "class" you're building
An array of base classes, parents to provide functionality (not the string names of those classes)
A hash of functions and declarations
So if I want to override dijit.Dialog, I have to do:
dojo.declare("myDialogType", [dijit.Dialog], {
function1() {/*Code*/},
function2() {/*Code*/}
}
I had ["dijit.Dialog"] as my second argument and that was the problem.
I strongly recommend using Web Inspector or Firebug with uncompressed local copies of the Dojo library rather than the CDN to figure out what's going on and debug these types of problems. Dojo's documentation is extensive but not complete in some areas and some behaviors have to be figured out by looking at what the code expects. That's not intended as a slight to the authors; once you get it going it's a pretty awesome product, and any documentation for volunteer work is appreciated.
Are you sure Dojo is loading? Did you put your code in a dojo.addOnLoad()? When using a CDN you sometimes run into issues with execution times. dojo.addOnLoad() will not only trigger when the DOM is loaded, it gets called when dojo resources have downloaded, such as dijit._Widget.
I've run into this problem when I screw up the order of my requires which makes _WidgetBase not what _WidgetBase really is. Seems like a simple spot to screw up.
I'm developing a site in javascript and jquery. Sometimes when I refresh I just get different random errors in firebug. What's the deal?
edit: I'm getting errors like a variable isn't defined, when clearly it is and working, and when i refresh again, the error is gone..
using Firefox V3.5.5 Firebug V.1.5.3 and I'm primarily working with jQuery 1.4.2
OK. While it's more or less impossible to give a reasonable solution to such a general question, I'll just add my 2 cents' worth:
One possible source of "undefined variable" errors comes from including several scripts, which may or may not always load and execute in the same order. If you define a variable in one script (let's call that script declare.js) and use it in another (let's say use.js), and use.js is executed before declare.js, then you will get such an error. If the scripts execute the other way around, everything will appear fine.
If you're interested in this very topic, have a look at e.g. Steve Souders' book Even faster web sites, published by O'Reilly. More specifically, look at the chapter about non-blocking script loading.
Most common cause is that you're trying to execute Javascript before the DOM is loaded and thus before all HTML elements are available in the DOM tree, which in turn may cause that simple calls like document.getElementById(id) and jQuery's $(selector) may return undefined elements. That it sometimes works is pure coincidence and a matter of timing.
You need to ensure that any Javascript/jQuery code which is supposed to be executed during page load and relies on the availability of the elements in the DOM tree, also really get executed after the DOM is loaded. In plain vanilla JS you can do so:
window.onload = function() {
document.getElementById(someId);
}
and in jQuery:
$(document).ready(function() {
$(someSelector);
});