I have below method which is working fine in IE but I am getting the following error:
TypeError: hdnButton .click is not a function
when I use it in Firefox.
function PopupTest() {
var hdnButton = document.getElementById('div_btn').firstChild;
hdnButton.click();
}
Could anyone suggest how to get over this issue? I am not able to find any solution for it.
My guess (since you've shown no html) is that you have some white space (perhaps a line break) which IE is ignoring, but which FF is returning as a text node. If so, you should be able to skip over it with something like:
function PopupTest() {
var hdnButton = document.getElementById('div_btn').firstChild;
while (hdnButton.nodeType === 3)
hdnButton = hdnButton.nextSibling;
hdnButton.click();
}
...which works by using the .nodeType property to test whether the .firstChild is a text node (3 means text node; for more information see MDN). If it is, it takes the next sibling and tests its .nodeType, and so on until it finds an element that isn't a text node. (Of course this assumes there will be one.)
Alternatively if you know what tag the (non text node) first child should be you could select it on that basis, e.g., if it's actually a <button> element:
hdnButton = document.getElementById('div_btn').getElementsByTagName("button")[0];
hdnButton.click();
Or if you don't need to support IE<=7:
document.querySelector("#div_btn > :first-child").click();
Check if document.getElementById('div_btn').firstChild;
if it exists, maybe there is another error such a whitespace, or you are calling PopupTest() before the DOM is loaded.
Try:
<body onload="PopupTest()">
Related
EDIT:
JSFIDDLE here. I am trying to mirror DESKTOP 1 to MOBILE 1 elements (same for #2) in the fiddle. The error is shown in console.
Got to DESKTOP 1 and select NEW RATE from the list. Have the console opened to see the issue. Thanks!
I get an element from my layout with this command:
var eqTaxSelect = $('table#mob-tab-' + num).find('select.tax_rate').get();
I then try to toggle it:
toggleField($(eqTaxSelect), $(eqTaxSelect).nextElementSibling); <-- FAILS
function toggleField(hideObj, showObj) {
hideObj.style.display = 'none'; <-- FAILS HERE
showObj.style.display = 'inline';
showObj.focus();
}
with:
Uncaught TypeError: Cannot set property 'nextElementSibling' of undefined
What am I doing wrong when assigning the element to my variable? This function works for this inside click event listeners for example.
Thanks!
The HTML I am toggling came from this forum, essentially a select with a hidden input so new entries can be added as well as using an entry from the options list.
What am I doing wrong when assigning the element to my variable?
You are passing jQuery() objects, where toggleField expects DOM elements. jQuery() does not have a .nextElementSibling method. Remove calls to jQuery() at
toggleField($(eqTaxSelect), $(eqTaxSelect).nextElementSibling);
replace with
toggleField(eqTaxSelect, eqTaxSelect.nextElementSibling);
to pass DOM elements to toggleField.
test with
console.log(eqTaxSelect)
see on inspector (CTRL+SHIF+I CHROME). if this is ok,
just do this
toggleField(eqTaxSelect, eqTaxSelect.nextElementSibling)
withouth "$"
The reason why your statement
toggleField(eqTaxSelect, eqTaxSelect.nextElementSibling);
fails is because of the way you are populating the eqTaxSelect
var eqTaxSelect = $('table#mob-tab-' + num).find('select.tax_rate').get();
It should be modified as
var eqTaxSelect = $('table#mob-tab-' + num).find('select.tax_rate').get(0);
reason being, get() without an index returns an array and the way you are operating, you are expecting an single dom element.
jQuery documentation for get()
I noticed this after a user reported the behavior since it was working fine on Chrome, Firefox and IE8+. However in IE7 the following selectors:
$('#parentjobs option')
$('#parentjobs option:not(:contains("new"))')
throw this error:
Error: Unable to get value of the property '0': object is null or undefined
Which points to line 5126 on jquery-1.8.3:
context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];
I don't have IE7 installed but I can reproduce the error when I switch the document mode and browser mode to IE7 on the IE debug page (F12)
Any ideas what might be going wrong?
I'm not sure what the problem is, but something that might make it work cross-browser, in a different way, is to use filter:
$("#parentjobs").find("option").filter(function () {
return $(this).text().indexOf("new") === -1;
});
Which says "only include the <option> elements that don't contain the text 'new'"...and should do the same as your original selector.
filter includes/excludes elements based on the result of the return. If true is returned, the element is left in the list. If false is returned, the element is removed from the list.
Using .text() is the same as what :contains() looks at, and === -1 means the text isn't found.
It might just be me, but I like to be more explicit with selecting elements, staying away from long selectors (especially pseudo selectors) and using jQuery methods instead. Although this might make your selections a little slower (not allowing jQuery to optimize native browser methods), it's easier to debug and looks cleaner to me than a big string (and hopefully works for you in all browsers).
Reference:
http://api.jquery.com/filter/
Found out that in IE7 and below getElementById is not case-sensitive which was the cause of my problem.
http://msdn.microsoft.com/en-us/library/ie/ms536437(v=vs.85).aspx
In IE8 Standards mode, getElementById performs a case-sensitive match on theID attribute only.
In IE7 Standards mode and previous modes, this method performs a case-insensitive match on both the ID and NAME attributes, which might produce unexpected results.
http://jsfiddle.net/DerNalia/zrppg/8/
I have two lines of code that pretty much do the same thing
var doesntbreak = $j("hello");
var breaks = $j(" ");
The first one doesn't error, but the second one throws this
Syntax error, unrecognized expression:
should'nt they both behave the same?
any insight as to how to solve this?
in the actual method I'm using, ele is from the Dom, so it could eb a text node, or any other kind of node.
UPDATE:
the input to the function that I'm using that I noticed this takes selection from the dom.
updated example: http://jsfiddle.net/DerNalia/zrppg/11/ <- includes html markup.
So, I guess, my question is, how do I test if something is JUST a text node? and doesn't contain any markup?
In general, you cannot create standalone text nodes with the jQuery function. If a string isn't obviously HTML, it gets treated as a selector, and is not recognized by jQuery as a valid selector.
Assuming you want to parse arbitrary strings (which may have HTML tags or not), I suggest something like var result = $('<div></div>').html(' ').contents();. Place your your HTML or text string in a div to parse it and then immediately extract the parsed result as a jQuery object with the list of elements. You can append the resultant list of elements with $(parentElem).append(result);
try this:
function isTextNode(node){
div=document.createElement('div');
div.innerHTML=node;
return $(div).text()==$(div).html();
}
And " " is'nt a valid selector if you want to find a elements containing some text you must use the :contains selector http://api.jquery.com/contains-selector/
Internet Explorer (older versions at least) don't have built in "querySelector" functions, so the Sizzle engine has to do the work directly. Thus, the slightly different tolerances for bogus input can cause differences in error reporting.
Your selector expression " " is equally invalid in all browsers, however. The library is not obliged to quietly accept anything you pass it, so perhaps you should reconsider your application design.
If you want to check for entities, you could use a regular expression if you're confident that it's just a text node. Or you could get the contents with .text() instead of .html().
So, I have to thank Apsillers and Rolando for pointing me in the right direction. Their answers were very close, but gave me the information I needed.
This is what I ended up using:
TEXT_NODE = 3;
objectify = function(n) {
return $j("<div></div>").html(n).contents();
}
function textOnly(n) {
var o = objectify(n);
for (var i = 0; i < o.length; i++) {
if (objectify(o[i])[0].nodeType != TEXT_NODE) {
return false
}
}
return true;
}
And here is a jsFiddle with some test cases, that neither of the original code submissions passed.
to pass, it needed to handle this kind of input
"hello" // true
"hello<b>there</b>" // false
"<b>there</b>" // false
" " // false
Not actual answer, but may help someone with similar issue as mine and loosely related to this question. :)
I was getting same issue today, so fixed by removing
Changed:
var breaks = $j(" ");
to:
var breaks = $j(" ".replace(/&.*;/g, ""));
Here I am removing , < etc...
Note: value at is dynamic for me, so it can be anything.
I have encountered a very strange bug in Firefox.
I have a javascript function in an external file that works perfectly on regular complexity websites. However I have been putting together a few demonstration examples and come across something odd.
With html formatted like this (in an editor):
<div><p>Q: Where's the rabbit?</p><p class="faq_answer">A: I don't know, honest</p></div>
The Javascript works as expected.
However when like this:
<div>
<p>Q: Where's the rabbit?</p>
<p class="faq_answer">A: I don't know, honest</p>
</div>
It fails at this line:
elementsList[i].parentNode.firstChild.appendChild(finalRender.cloneNode(true));
Why on Earth would formatting of html cause anything at all?
It is not a bug. The DOM has not only element nodes, but also text nodes [docs] (among others). In this example:
<div>
<p>Q: Where's the rabbit?</p>
you have at least two text nodes:
One between the <div> and the <p>, containing a line-break.
One text node inside the <p> element node, containing the text Where's the rabbit?.
Thus, if elementsList[i].parentNode refers to the <div> element,
elementsList[i].parentNode.firstChild
will refer to the first text node.
If you want to get the first element node, use
elementsList[i].parentNode.children[0]
Update: You mentioned Firefox 3.0, and indeed, the children property is not supported in this version.
Afaik the only solution to this is to loop over the children (or traversing them) and test whether it is a text node or not:
var firstChild = elementsList[i].parentNode.firstChild;
// a somehow shorthand loop
while(firstChild.nodeType !== 1 && (firstChild = firstChild.nextSibling));
if(firstChild) {
// exists and found
}
You might want to put this in an extra function:
function getFirstElementChild(element) {
var firstChild = null;
if(element.children) {
firstChild = element.children[0] || null;
}
else {
firstChild = element.firstChild;
while(firstChild.nodeType !== 1 && (firstChild = firstChild.nextSibling));
}
return firstChild;
}
You can (and should) also consider using a library that abstracts from all that, like jQuery.
It depends on what your code is actually doing, but if you run this method for every node, it would be something like:
$('.faq_answer').prev().append(finalRender.cloneNode(true));
(assuming the p element always comes before the .faq_answer element)
This is the whole code, you wouldn't have to loop over the elements anymore.
Because you have a text node between <div> and <p>.
As usual, the assumption of a browser bug is incorrect: this is, instead, a programmer bug!
Couldn't one achieve it by using ParentNode.children instead?
I recently have discovered a warning happening in Firefox that says
Warning: Unknown pseudo-class or pseudo-element 'hidden'
Here is page http://eleven23.net/eleven23/beta/work/web/lounge22.php
And the warning happens when it gets to the part of javascript that has img:hidden
$('img:hidden').eq(0).fadeIn(500);//fades in the hidden images one by one
i++;//add 1 to the count
So Im wondering if anyone has an idea on how to resolve this warning.
Thanks!
The first step is to really stop the repeated calling of doThis() via setInterval which at the moment doesn't happen. Thus the warning appears every 500ms.
Change
$(document).ready (function() {
var int = setInterval("doThis(i)",500);
});
to
$(document).ready (function() {
int = setInterval("doThis(i)",500);
});
Else your call to clearInterval(int) won't do anything as you declared var int twice and try to clear the "outer" int which isn't the interval.
After this fix only 4-5 of this warning should remain in your console.
Now to your error. There isn't much you can do to stop this error from appearing exactly that many times you call doThis().
jQuery uses Sizzle internally as selector engine. And in some cases Sizzle tries to use (on browsers supported) the querySelectorAll() function to find the elements matching your selector.
Now AFAIK is hidden not a valid CSS selector thus although Firefox supports the call to querySelectorAll() it correctly fails after encountering an unknown selector. jQuery catches the error and then does the selection of image:hidden itself.
If you don't want to see this error at all you can use a different jQuery syntax which in this case would stop Sizzle from trying to attempt to use querySelectorAll().
Change
$('img:hidden').eq(0).fadeIn(500);
to
$('img:hidden', $('div#content_wrapper')).eq(0).fadeIn(500);
But I don't advise you to do this as it doesn't really get you much only 4-5 warnings less in your console.
Unfortunately this is a bug within JQuery itself. See: http://docs.jquery.com/Selectors/hidden
Check firebug, even on their example page you get this same warnring. It referes to a non-existing CSS pseudo-class :hidden. Where you are using $('img:hidden')