IE7 Queryselector not finding elements - javascript

if (!document.querySelectorAll)
document.querySelectorAll = function(selector) {
var head = document.documentElement.firstChild;
var styleTag = document.createElement("STYLE");
head.appendChild(styleTag);
document.__qsResult = [];
styleTag.styleSheet.cssText = selector+"{x:expression(document.__qsResult.push(this))}";
window.scrollBy(0, 0);
head.removeChild(styleTag);
var result = [];
for (var i in document.__qsResult)
result.push(document.__qsResult[i]);
return result;
}
var tabs = document.querySelectorAll(".tab");
var descriptionTabs = document.querySelectorAll(".descriptionTab");
var hireTabs = document.querySelectorAll(".hireTab");
var salesTabs = document.querySelectorAll(".salesTab");
var lazyImages = document.querySelectorAll(".lazy");
console.log(tabs.length);
console.log(hireTabs.length);
console.log(salesTabs.length);
console.log(descriptionTabs.length);
console.log(lazyImages.length);
<img class="imageThumbs lazy" src="">
<img class="imageThumbs lazy" src="">
<img class="imageThumbs lazy" src="">
<img class="imageThumbs" src="">
<div class="tabContainer">
<div class="descriptionTab tab">Description</div>
<div class="hireTab tab">HireTab</div>
<div class="salesTab tab">SalesTab</div>
</div>
I have a weird problem with IE, document mode 7.
The weirdest thing about it is that my functions work fine in document modes 5 and 8.
Certain elements are not being found. When I check the browser developers tools they are in there, in the HTML doc.
I can't see why those ones are incorrect in this particular version of IE and all others work fine.
Hopefully someone has an idea. Thanks in advance.
EDIT:
This is a seperate script soley for earlier versions of IE. I am using getElementsByClassName in the other script.
The script tag is at the bottom of the HTML page.
It works everywhere else except IE7.
EDIT: Change code to be a snippet.
EDIT: I have pinpointed the issue by stepping through.
styleTag.styleSheet.cssText = selector+"{x:expression(document.__qsResult.push(this))}";
This line seems to work on some elements and not others, so they are not getting pushed. As far as I can see there is not difference between
var descriptionTabs = document.querySelectorAll(".descriptionTab");
Which works and
var hireTabs = document.querySelectorAll(".hireTab");
Which doesn't.
FinalEdit(I give up): The Results seems to differ depending on what order the queryselectors are in.

After some digging, I found a solution on Github.
https://gist.github.com/Fusselwurm/4673695
(function () {
var
style = document.createStyleSheet(),
select = function (selector, maxCount) {
var
all = document.all,
l = all.length,
i,
resultSet = [];
style.addRule(selector, "foo:bar");
for (i = 0; i < l; i += 1) {
if (all[i].currentStyle.foo === "bar") {
resultSet.push(all[i]);
if (resultSet.length > maxCount) {
break;
}
}
}
style.removeRule(0);
return resultSet;
};
// be rly sure not to destroy a thing!
if (document.querySelectorAll || document.querySelector) {
return;
}
document.querySelectorAll = function (selector) {
return select(selector, Infinity);
};
document.querySelector = function (selector) {
return select(selector, 1)[0] || null;
};
}());
This works in all the earlier IE versions. I just replaced the polyfill I was using previously.

It's not supported, https://caniuse.com/#feat=queryselector
You can use alternatives like findElementById or findElementByClassName

Related

Tampermonkey userscript to scroll to first image with alt tag

I use a training site, that has a lot of courses. It is rather annoying that it does not remember the scroll position of your last course. I am trying to write a tampermonkey userscript to scroll to the first image with an alt tag of "Not Started" but it does not seem to work.
Here is what I have tried so far
var myList = document.getElementsByTagName("img");
for(var i=0;i<myList.length;i++)
{
if(myList[i].alt == "Not Started")
{
var pos = myList[i].offsetTop;
}
}
window.scrollTo(0,pos);
Two things here:
var pos
if you declare (mention for the first time) the variable pos in a for loop, it won't work. You have to declare it before where the rest of the function can read it.
window.addEventListener('load', (event) => {
i'm not sure why but at least in the snippet below this was needed. Perhaps the js starts running before the window loads and therefore cannot set window.scrollTo. If you have any questions leave it in the comments.
window.addEventListener('load', (event) => {
var myList = document.querySelectorAll('img');
var pos;
for (var i = 0; i < myList.length; i++) {
if (myList[i].alt == "Not Started") {
pos = myList[i].offsetTop;
break;
}
}
window.scrollTo(0, pos);
});
<img src='https://placekitten.com/800/800'>
<img src='https://placekitten.com/800/800' alt='Not Started'>
<img src='https://placekitten.com/700/800' alt='Not Started'>

Hiding `AdSense` `div` by accessing site from referral

I'm really a newbie to everything around programming ok. So...
I want to hide an AdSense div when accessing from a specific source (for example: ?utm_source=www.test.com) for the time a user is still moving around on my site or 120 seconds after that.
PS: I'm in a partnership with another advertising company and I have to show their ads when visitors come through this referral.
I have an AdSense code:
<div class="td-all-devices">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Test -->
<ins class="adsbygoogle"
style="display:inline-block;width:300px;height:600px"
data-ad-client="ca-pub-0000000000000"
data-ad-slot="000000"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
I tried this, but AdSense keep showing in footer:
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++)
{
var pair = vars[i].split("=");
if (pair[0] == variable)
{
return pair[1];
}
}
return -1; //not found
}
if ( getQueryVariable('utm_source') == 'www.test.com' )
{
im.getAds(pozice);
var ads = 1;
document.getElementsByClassName("td-all-devices").style.display = 'none';
}
else
{
var ads = 0;
}
Can anyone help?
In here:
if ( getQueryVariable('utm_source') == 'www.test.com' )
{
im.getAds(pozice);
var ads = 1;
document.getElementsByClassName("td-all-devices").style.display = 'none';
}
document.getElementsByClassName returns an array of objects. Therefore you need to iterate through it to change the value of something in it. Well, you don't HAVE TO ITERATE through it... as long as you can specify which index of the collection you want to play with.
Something like this:
if ( getQueryVariable('utm_source') == 'www.test.com' )
{
im.getAds(pozice);
var ads = 1;
var theElements = document.getElementsByClassName("td-all-devices");
for(var i = 0; i < theElements.length; i++)
{
theElements[i].style.display = 'none';
}
}
else
{
var ads = 0;
}
document.getElementById() returns 1 element you could have modified using this
document.getElementById("whatever unique id").style.display = 'none';
document.getElementsByClassName() returns a collection of elements you could have modified like this
document.getElementsByClassName("whatever class name")[index position].style.display = 'none';
Since you are a self proclaimed newbie, I will invite you to discover the many Developer tools your preferred browser likely has to offer you. Most browsers have a console you can look at. The console will help you tremendously in troubleshooting your code. In console, you would have picked your problem almost instantly because you would have seen an entry like this:
TypeError: document.getElementsByClassName(...).style is undefined
In Firefox, with unmodified keyboard shortcuts, you can bring up the developers palette using ctrl + shift + s.

jQuery.attr('data-*') not work on IE8 (work on IE7) [duplicate]

This has gotten so far,that I will sum up what we found out:
Inside the event handler the attribute src cannot be read in IE8 (FF works fine), neither with jQuery nor with usual javascript
The only way to get the data was to get it outside the handler, write it to an array and read it afterwards from the inside of the handler
But there was still no possibility to write to src (neither jQuery nor javascript worked - only for IE 8)
I've got it working by writing the img elemts themselves to the document, but the reason behind this problem is no solved
The snippet we have is used twice.
The old code
<script type="text/javascript">
jQuery(document).ready(function() {
//...
//view entry
jQuery('.blogentry').live('click',function(){
// Get contents
blogtext = jQuery(this).children('.blogtext').html();
blogauthor = jQuery(this).children('.onlyblogauthor').html();
blogtitle = jQuery(this).children('.blogtitle').html();
profileimage = jQuery(this).children('.profileimage').html();
imgleft = jQuery(this).children('.Image_left').attr('src');
imgcenter = jQuery(this).children('.Image_center').attr('src');
imgright = jQuery(this).children('.Image_right').attr('src');
// Write contents
jQuery('#bild_left').attr('src', imgleft);
jQuery('#bild_center').attr('src', imgcenter);
jQuery('#bild_right').attr('src', imgright);
jQuery('.person').attr('src', profileimage);
jQuery('#g_fb_name').html(blogauthor);
jQuery('#g_titel').html(blogtitle);
jQuery('#g_text').html(blogtext);
//...
});
//...
// Change entry
jQuery('.blogentry').each(function(){
entryindex = jQuery(this).attr('rel');
if (entry == entryindex)
{
// The following works fine (so 'children' works fine):
blogtext = jQuery(this).children('.blogtext').html();
blogauthor = jQuery(this).children('.onlyblogauthor').html();
blogtitle = jQuery(this).children('.blogtitle').html();
profileimage = jQuery(this).children('.profileimage').html();
// This does not work - only in IE 8, works in Firefox
imgleft = jQuery(this).children('.Image_left').attr('src');
imgcenter = jQuery(this).children('.Image_center').attr('src');
imgright = jQuery(this).children('.Image_right').attr('src');
//alert: 'undefined'
alert(jQuery(this).children('.Image_center').attr('src'));
//...
}
}
//...
});
</script>
The new code
Please see my own posted answer for the new code.
UPDATE:
This does not work if called inside of the click event!!!
jQuery('.Image_left').each(function(){
alert(jQuery(this).attr('src'));
});
SOLUTION TO GET THE IMAGE DATA:
relcounter = 1;
imgleft_array = new Array();
jQuery('.Image_left').each(function(){
imgleft_array[relcounter] = jQuery(this).attr('src');
relcounter++;
});
relcounter = 1;
imgcenter_array = new Array();
jQuery('.Image_center').each(function(){
imgcenter_array[relcounter] = jQuery(this).attr('src');
relcounter++;
});
relcounter = 1;
imgright_array = new Array();
jQuery('.Image_right').each(function(){
imgright_array[relcounter] = jQuery(this).attr('src');
relcounter++;
});
//... inside the eventhandler (entryindex = 'rel' of blogentry):
imgleft = imgleft_array[entryindex];
imgcenter = imgcenter_array[entryindex];
imgright = imgright_array[entryindex];
This works because it is not called inside the event handler and the sources are saved beforehand
BUT! I still cannot write the data, which is my aim:
jQuery('#bild_left').attr('src', imgleft);
jQuery('#bild_center').attr('src', imgcenter);
jQuery('#bild_right').attr('src', imgright);
UPDATE!!!
This is just crazy, I tried to write the data via usual javascript. This also works in FF, but no in IE8. Here really is some serious problem witt the attribute src:
document.getElementById('bild_left').src = imgleft;
document.getElementById('bild_center').src = imgcenter;
document.getElementById('bild_right').src = imgright;
alert(document.getElementById('bild_left').src);
This works in FF, but not in IE8, the attribute src remains undefined after writing! This seems to be not a jQuery problem at all!
children looks for immediate child elements only where as find looks for all the elements within it until its last child element down the dom tree. If you are saying find is working that means the element you are looking is not its immediate children.
Try to alert this jQuery(this).children('#Image_center').length see what you get.
FYI. Even when any element is not found jQuery will return an emtpy object it will never be null. So alert an emtpy object will always give you [object Object]. You should alwasy check for the length property of the jQuery object.
Try this
alert(jQuery(this).find('#Image_center').length);//To check whether element is found or not.
Bing Bang Boom,
imgright = jQuery(".Image_right",this).attr('src');
And why don't you easily use one working?
alert(jQuery(this).children('#Image_center').attr('src'));
change children to find
alert(jQuery(this).find('#Image_center').attr('src'));
It is probably the easiest solution, and when it work, why wouldn't you use it?
the problem is not in the attr('src') but in something else. The following snippet works in IE8:
<img id="xxx" src="yrdd">
<script type="text/javascript">
alert($('#xxx').attr('src'));
</script>
But if you for example change the the text/javascript to application/javascript - this code will work in FF but will not work in IE8
This has gotten so far,that I will sum up what we found out:
Inside the event handler the attribute src cannot be read in IE8 (FF works fine), neither with jQuery nor with usual javascript
The only way to get the data was to get it outside the handler, write it to an array and read it afterwards from the inside of the handler
But there was still no possibility to write to src (neither jQuery nor javascript worked - only for IE 8)
I've got it working by writing the img elemts themselves to the document, but the reason behind this problem is no solved
The new code
relcounter = 1;
imgleft_array = new Array();
jQuery('.Image_left').each(function(){
imgleft_array[relcounter] = jQuery(this).attr('src');
relcounter++;
});
relcounter = 1;
imgcenter_array = new Array();
jQuery('.Image_center').each(function(){
imgcenter_array[relcounter] = jQuery(this).attr('src');
relcounter++;
});
relcounter = 1;
imgright_array = new Array();
jQuery('.Image_right').each(function(){
imgright_array[relcounter] = jQuery(this).attr('src');
relcounter++;
});
//view entry
jQuery('.blogentry').live('click',function(){
// Get contents
entryindex = jQuery(this).attr('rel');
blogtext = jQuery(this).children('.blogtext').html();
blogauthor = jQuery(this).children('.onlyblogauthor').html();
blogtitle = jQuery(this).children('.blogtitle').html();
profileimage = jQuery(this).children('.profileimage').html();
imgleft = imgleft_array[entryindex];
imgcenter = imgcenter_array[entryindex];
imgright = imgright_array[entryindex];
// Write contents
jQuery('#entryimages').html('');
jQuery('#entryimages').html('<img class="rotate" width="132" height="138" id="bild_left" src="'+imgleft+'" /><img class="rotateright" width="154" height="162" id="bild_center" src="'+imgcenter+'" /><img class="rotate" width="132" height="138" id="bild_right" src="'+imgright+'" />');
jQuery('.person').attr('src', profileimage);
jQuery('#g_fb_name').html(blogauthor);
jQuery('#g_titel').html(blogtitle);
jQuery('#g_text').html(blogtext);
});
So I am just not using .attr('src') in the event handler....
Try to make a delay:
jQuery(document).ready(function() {
setTimeout(function () {
jQuery('.blogentry').each(function(){
// your code...
});
}, 100); // if doesn't work, try to set a higher value
});
UPDATE
Hope, this code will work.
$('.blogentry img').each(function(){
alert( $(this).attr('src') );
});
UPDATE
I'm not sure, but maybe IE can't read classes with uppercase first letter...
Try to change ".Image_center" to ".image_center"
UPDATE
Check your code again. You definitely have some error. Try this jsfiddle in IE8, attr('src') is showed correctly. http://jsfiddle.net/qzFU8/
$(document).ready(function () {
$("#imgReload").click(function () {
$('#<%=imgCaptcha.ClientID %>').removeAttr("src");
$('#<%=imgCaptcha.ClientID %>').attr("src", "Captcha.ashx");
});
});

Unable to parse onClick text using DOM

All that I have read says to use the element.onclick property, but that doesn't seem to be working in my situation. I'm trying to parse the number: 629216818 and set it to a varialbe: fbid. This is a Greasemonkey script, so the HTML can't be edited directly. I'm no pro, so I may be just doing something stupid, but here is my HTML and Javascript:
<div id="petRightContainer">
<a title = "Pet trainer bonus: Your companion will level 5% faster." href="setup.php?type=companion&gtRandom=8167343321487308">
<div class="petRight" style="background-image:url(/fb/res/gui4/companion/cu_sith.jpg)"></div>
</a>
<div class="petRightLevel">
Dog
</div>
etc.
<script type="text/javascript">
fbid = 0;
fbidRegex = /\d{3,}(?=&fromWall=1)/;
if ( document.getElementsByClassName("petRightLevel")[0]){
element = document.getElementsByClassName("petRightLevel")[0].firstChild;
codeStore = element.onclick;
fbid = fbidRegex.exec(codeStore);
document.write("it is working ");
}
document.write(fbid);
</script>
The problem is in this line:
element = document.getElementsByClassName("petRightLevel")[0].firstChild;
If you are using Firefox and other browsers which support document.getElementsByClassName and in your HTML, there are spaces between <div class="petRightLevel"> and
<a href="#" onClick= ...>
, the firstChild is actually a text node not the link. All you need to do is remove the spaces and/or line break in between the two elements.
If you are using IE, the problem is still at the same line of the javascript because IE doesn't support document.getElementsByClassName up until version 8.
Update: The following javascript code work for all the browsers I tested without touching HTML:
<script type="text/javascript">
fbid = 0;
fbidRegex = /\d{3,}(?=&fromWall=1)/;
var divs = document.getElementsByTagName("div");
var link = null;
for (var i=0;i<divs.length;i++)
{
if(divs[i].getAttribute("class") ==="petRightLevel")
{
link = divs[i].getElementsByTagName("a")[0];
break;
}
}
if (link){
codeStore = link.onclick;
fbid = fbidRegex.exec(codeStore);
document.write("it is working ");
}
document.write(fbid);
</script>
If you only need to get the anchors, it would be much simpler than this.
I think this might work for you.
<script type="text/javascript">
fbid = 0;
fbidRegex = /\d{3,}(?=&fromWall=1)/;
if(document.getElementsByClassName("petRightLevel")[0]){
element = document.getElementsByClassName("petRightLevel")[0].firstChild;
// callback function to execute when the element onclick event occurs.
codeStore = element.onclick = function(){
fbid = fbidRegex.exec(codeStore);
document.write("it is working ");
document.write(fbid);
}
}
</script>

Javascript error: Object Required in ie6 & ie7

I have a javascript function (epoch calendar) which displays a calendar when focus is set on certain text boxes. this works fine in ie8, ff (all versions as far as I can test), opera etc but doesn't work in ie7 or previous.
If i have it set up in a blank html test page it will work so I'm fairly sure it's a conflict with my css (provided to me by a designer).
I've traced the error to these lines of code -
Epoch.prototype.getTop = function (element) //PRIVATE: returns the absolute Top value of element, in pixels
{
var oNode = element;
var iTop = 0;
while(oNode.tagName != 'BODY') {
iTop += oNode.offsetTop;
oNode = oNode.offsetParent;
}
return iTop;
};
Epoch.prototype.getLeft = function (element) //PRIVATE: returns the absolute Left value of element, in pixels
{
var oNode = element;
var iLeft = 0;
while(oNode.tagName != 'BODY') {
iLeft += oNode.offsetLeft;
oNode = oNode.offsetParent;
}
return iLeft;
};
More specifically, if i remove the actual while loops then the calendar will display OK, just that its positioning on the page is wrong?
EDIT
Code below which sets 'element'
<script type="text/javascript">
window.onload = function() {
var bas_cal, dp_cal, ms_cal;
dp_cal = new Epoch('epoch_popup', 'popup', document.getElementById('<%=txtDateOfDiag.ClientID%>'));
dp_cal = new Epoch('epoch_popup', 'popup', document.getElementById('<%=txtDOB.ClientID%>'));
};
</script>
Note: I am using asp.net Master pages which is why there is a need for the .ClientID
EDIT
A further update - I have recreated this without applying css (but including the .js file provided by the designer) the code still works fine which, there must be some sort of conflict between the CSS and my JavaScript?
That would lead me to believe that the tagName does not match, possibly because you have it in upper case. You might try while(!oNode.tagName.match(/body/i)) {
what happens if you add a line of debug code like this:
var oNode = element;
var iLeft = 0;
alert(oNode);
This might give different results in different browsers; I think it may be NULL for IE.
You may want to have a look at the code that provides the value of the 'element' parameter to see if there's a browser-dependant issue there.

Categories