Extending htmloptionscollection - javascript

I have a code to extend the htmloptionscollection object:
HTMLOptionsCollection.prototype.contains = HTMLOptionsCollection.prototype.contains ||
function(otherOption) {
for (var i = 0; i < this.length; i++) {
if (this[i].value === otherOption.value) {
return true;
}
}
return false;
};
It works well on firefoxa dn in Opera but does not work in IE9 and in Google Chrome it shows:
"Uncaught ReferenceError: HTMLOptionsCollection is not defined"
How can I solve this problem. Am I doing anything wrong? If I am, how can I solve it?

If you do something wrong then the wrong thing is that you assume that the whole DOM is supported by any browser. For example IE: I don't see any prototype for HTMLOptionsCollection on MSDN

Related

document.querySelectorAll("body") returning undefined

I am using the following codes in the console of the firefox DevTools to extract book names from https://bookauthority.org/books/best-problem-solving-books
Code 1
var selects=document.querySelectorAll("div.book-header-title a.book-title h2.main");
for (i = 0; i < selects.length; ++i) {
console.log (selects[i].innerText);
}
Code 2
var selects=document.querySelectorAll("div.book-header-title a.book-title h2.main");
console.log(selects)
Even the following code is not working
var selects=document.querySelectorAll("body");
console.log(selects)
It only says undefined. What can I do?
querySelectorAll works just fine. The problem resides in that the specific webpage on which you're executing the code, has overriden the window.console.log method and the new implementation apparently does not print arguments to the console, as its native implementation does.
You can see this by issuing window.console.log (without parentheses), which usualy prints something like ƒ log() { [native code] } (at least in Chrome).
There are hacks how to acquire the native implementation. See, for example, this post: https://stackoverflow.com/a/11129588/4005175
Example:
// restore window.console.log method
var f = document.createElement("iframe");
f.style.display = "none";
document.documentElement.appendChild(f);
window.console.log = f.contentWindow.console.log;
// print book titles
var selects=document.querySelectorAll("div.book-header-title a.book-title h2.main");
for (i = 0; i < selects.length; ++i) {
console.log (selects[i].innerText);
}

SCRIPT1003 error in IE

In my project, I make a require call to a js file to create an object of the file.
For example,
require(['directory/hello-js-file'], function(Hello){
var hello = new Hello();
hello.show();
});
After this block, Hello is undefined. In the IE console, I see this error message, 'SCRIPT1003: Expected ':' File: Function code (13), Line:2, Column:1'
The function looks like this:
function anonymous(){
return eval(arguments[0]);
}
I was able to narrow down this issue being originated from two functions (Contents have been modified but the logic is same.):
bindDetail: function($view){
var self = this;
var details = object.details; // object is a global variable
for(var i = 0; i < details.length; i++){
if(self.hasData(details[i])){
// doSomething
}
}
},
hasData(detail){
if(detail.data !== undefined && detail.data !== ""){
return true;
}
return false;
}
This issue only arises in IE. This works fine in Chrome.
Can someone please direct me to a solution? Thank you. I appreciate your help.
After posting the question, I realized that I was missing the :function tag to hasData. That resolved the issue. :)

Syntax error when using `get` in object property shorthand

This bit of code:
function get() {
console.log('get')
}
var obj = {
get
}
obj.get()
results in a SyntaxError: Unexpected token } in iojs and Chrom{ium,e} but works fine in Firefox.
Longhand, of course, works fine:
function get() {
console.log('get')
}
var obj = {
get: get
}
obj.get()
So does using a word other than get
function git() {
console.log('get')
}
var obj = {
git
}
obj.git()
Is this a bug in V8 or something else? What am I not getting here?
v8 hasn't made this available by default yet1; firefox (which doesn't use v8) has.
For now, you can transpile with babel.js.
1 It's available, but not in every runtime environment. In node.js, for example, you need to enable it with a --harmony_something flag.

Javascript: Basic for loop is not working

Is there any reason why the following would not work:
for (i=0;i < someArray.length;i++) {
if (someArray[i].indexOf("something") !== -1) {
//do something here
}
}
The most basic "for" loop possible. But it doesn't work. On the first line (declaration of the loop, not inside the loop), I get "Uncaught reference error; i is not defined."
I have this page open in one Chrome tab, and another earlier version of the page open in another tab. In the other tab, this loop works just fine; in the first tab, this code throws an error.
EDIT - July 2 2015
The response about strict mode was helpful. After reading up a bit and going through the code I've got a handle on what's going on.
The confusing bit was that both versions of the code look like this, with some minor differences (requirejs module):
define(
'viewModels/someViewModel',
['dependency1', 'dependency2', 'dependency3'],
function(dep1, dep2, dep3) {
"use strict";
function SomeViewModel(arg1, arg2) {
var self = this;
self.initialize();
self.removeRefinement = function(refinementString) {
var refinementArray = refinementString.split("&");
for (i=0;i < navigationArray.length;i++) { //<-- error
}
}
}
}
);
One version throws the reference error. One doesn't.
This is a large web application with many other pages and Javascript files. The only thing I could think of was that in one version of the code, maybe i had been inadvertently globally defined somewhere else in the app, where strict mode wasn't enabled. After running to the breakpoint and checking "window" I see that's exactly what's happening.
Thanks =D
If you are in strict mode, you'll get the error Uncaught reference error; i is not defined. If you're not in strict mode, you won't get the error.
This will throw the error
'use strict'
var someArray = ['aaa', 'bbb', 'ccc'];
for (i=0;i < someArray.length;i++) {
console.log(i)
if (someArray[i].indexOf("something") !== -1) {
//do something here
}
}
This won't
var someArray = ['aaa', 'bbb', 'ccc'];
for (i=0;i < someArray.length;i++) {
console.log(i)
if (someArray[i].indexOf("something") !== -1) {
//do something here
}
}
when you declare a variable it must be declared like this var i = 0;
a for loop looks like this:
JavaScript
for(var i = 0; i == 10; i++)
{
}

How to trace Javascript events (Stack Trace )?

In any programming language, I can trace any function and know which function is called by other. But in Javascript , I don't know how, since the code is not written by me and Firebug does not give this feature - as far as I know.
An example :
I want to display the function names of each function that is called when clicking on XYZ Element, and display them in order.
Found this: A javascript stacktrace in any browser, James says they have a github account now
function printStackTrace() {
var callstack = [];
var isCallstackPopulated = false;
try {
i.dont.exist+=0; //doesn't exist- that's the point
} catch(e) {
if (e.stack) { //Firefox
var lines = e.stack.split('\n');
for (var i=0, len=lines.length; i<len; i++) {
if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
callstack.push(lines[i]);
}
}
//Remove call to printStackTrace()
callstack.shift();
isCallstackPopulated = true;
}
else if (window.opera && e.message) { //Opera
var lines = e.message.split('\n');
for (var i=0, len=lines.length; i<len; i++) {
if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
var entry = lines[i];
//Append next line also since it has the file info
if (lines[i+1]) {
entry += " at " + lines[i+1];
i++;
}
callstack.push(entry);
}
}
//Remove call to printStackTrace()
callstack.shift();
isCallstackPopulated = true;
}
}
if (!isCallstackPopulated) { //IE and Safari
var currentFunction = arguments.callee.caller;
while (currentFunction) {
var fn = currentFunction.toString();
var fname = fn.substring(fn.indexOf("function") + 8, fn.indexOf('')) || 'anonymous';
callstack.push(fname);
currentFunction = currentFunction.caller;
}
}
output(callstack);
}
function output(arr) {
// Output however you want
alert(arr.join('\n\n'));
}
You can see the stack trace of any error with the stack() function call (on Firefox). Creating a simple function to print a stack trace could look like this:
function getStackTrace() {
try {
unusedVariable++; // This creates an error we can trace
}
catch (e) {
return e.stack;
}
}
Other browsers have different ways of printing the stack trace, but this should get you what you need for Firefox.
Hope this helps.
DynaTrace AJAX has some of the features like that. Not exactly what you are looking for but gives you the events and functions bound on an element and helps your troubleshooting. Had a free download, check it.
If you simply want to debug your code, your best option is to get a debugger plug-in for your browser. The Firebug plug-in does provide stack traces. (see here)
If you want to do it from within your code, there is no standard language feature of JavaScript that allows you to do this. Different browsers may implement non-standard extensions, but you shouldn't rely on them.
As "Casablanca" mentions... please note from the site of the aforementioned js-stack-trace (
http://www.eriwen.com/javascript/js-stack-trace/ ) that in FireFox and Chrome:
Obvious easy way: Firebug, Chrome Dev Tools, Dragonfly etc.
You can easily get a stack trace at any time by calling
console.trace() in your Javascript or in the Firebug console.
Since it sounds like you want to inspect the stack and take pieces of the information (the function names), sounds like you need
stackinfo
which was built exactly for that purpose.

Categories