I am currently having an issue with the getAttribute() method.
This currently works in IE8, but in IE11 I recieve the error Object doesn't support property or method 'getAttribute'.
The same issue happens when I use hasAttribute() at the same point.
The error is thrown when you reach if(discounts[j].getAttribute("id") == discountId), and if I try to console.log the id, I get Undefined.
I did manage to get it to work in IE11 by running in compatibility mode, but that is not an option.
This is the method I am currently using below.
if(discountsXml != null && discountsXml.documentElement != null) {
var invItems = discountsXml.documentElement.getElementsByTagName("invItem");
var invItemsCounter = invItems.length;
var i = 0;
for(i=0; i<invItemsCounter; i++) {
if(invItems[i].getAttribute("id") == invItemId) {
var discounts = invItems[i].childNodes;
var discountsCounter = discounts.length;
var j = 0;
for(j=0; j<discountsCounter; j++) {
if(discounts[j].getAttribute("id") == discountId) {
discount = true;
}
}
}
}
}
You didn't actually ask a question above so I'm not sure on the best answer,
But would it be possible for you to use the id property instead of the id attribute as is generally recommended?
invItems[i].id vs invItems[i].getAttribute("id")
http://www.w3schools.com/jsref/prop_html_id.asp
Related
Hi im using Angularjs for my project, There is nationality search drop down. I want to map which is typing on Input and filter it inside nationality JSON object. This part is working fine in other browsers except IE. There is console error "Object doesn't support property or method 'startsWith'". this is my code, Can i know how to add "String.prototype.startsWith" for this issue for my code.
$scope.searchNationality = function (data) {
var output = [];
if (data != "" && data != undefined) {
$scope.ShowNationalityDropDown = true;
for (var i = 0; i < $scope.nationalityList.length; i++) {
if ($scope.nationalityList[i].content.toLowerCase().startsWith(data.toLowerCase())) {
output.push($scope.nationalityList[i]);
}
}
$scope.nationalityListSearchResults = output;
} else {
$scope.ShowNationalityDropDown = false;
$scope.nationalityListSearchResults = [];
}
};
You can try changing from .startsWith to .indexOf since it is compatible with IE for lower versions. If .indexOf returns 0 then the string is in the first position of the string that calls that function, which can be usable when you are in this kind of situation that you can't use .startsWith().
const str = "Hey this is a sample string!"
console.log(str.indexOf("Hey") === 0)
console.log(str.indexOf("sample") === 0)
$scope.searchNationality = function (data) {
var thereIsData = data != "" && data != undefined;
var output = thereIsData
? $scope.nationalityList.filter(function (nationality) {
return nationality.content.toLowerCase().indexOf(data.toLowerCase())) == 0;
})
: [];
$scope.ShowNationalityDropDown = thereIsData;
}
I am trying to find all buttonitems. In chrome and modern browsers this works fine but in ie9 I am having the error above. I can't change the HTML on the page only the javascript on the page. In chrome I can use document.getElementsByClassName() but in ie 9 I can't even though I should be able to probably because the website has to run in comparability with Quirks. I have tried rewriting the code to work without this and believe I have got the elements with the code
if(navigator.userAgent.toLowerCase().indexOf('msie') != -1){
if (document.all) {
var allElements = document.all;
} else {
var allElements = document.getElementsByTagName("*");
}
// Empty placeholder to put in the found elements with the class name
var oldHrefs = [];
for (var i = 0, ii = allElements.length; i < ii; i++) {
if (allElements[i].className == 'ButtonItem') {
oldHrefs[oldHrefs.length] = allElements[i];
}
}
}
else
{
var oldHrefs = document.getElementsByClassName('ButtonItem');
}
But I then need to loop through the code and remove the href and add an onclick which is when I revive my next error. Object doesn't support property or method 'item'. Any ideas what I can do to correct the code below?
for (var i = 0; i < oldHrefs.length; i++) {
var thisHref = oldHrefs.item(i).getAttribute('href');
if (thisHref != null) {
if (thisHref.includes('Act=1468')) {
oldHrefs.item(i).removeAttribute("href");
oldHrefs.item(i).setAttribute('onclick', 'window.location.href="' + thisHref + '";this.removeAttribute("onclick");');
}
}
}
Thanks
This is my code. It works in Firefox and Chrome but not Safari. I get no errors.
<script>
var cleanData = new FormData();
cleanData.append("test", "test");
alert(cleanData.get("test"));
</script>
Does anyone know a workaround?
Apparently, Safari has no means of getting values stored in FormData objects at this time. There is no workaround at this time, and apparently it's not practical to polyfill.
Sorry :(
Notes:
https://developer.mozilla.org/en-US/docs/Web/API/FormData/get#Browser_compatibility
https://www.bountysource.com/issues/27573236-is-it-possible-to-polyfill-missing-formdata-methods
I solved this by conditionally (if Safari is the browser) iterating through the elements property of an actual form. For all other browser, my wrapper just iterates through FormData entries(). The end result of my function, in either case, is a simple javascript object (JSON) which amounts to name/value pairs.
function FormDataNameValuePairs(FormName)
{
var FormDaytaObject={};
var FormElement=$('#'+FormName).get(0);
if (IsSafariBrowser())
{
var FormElementCollection=FormElement.elements;
//console.log('namedItem='+FormElementCollection.namedItem('KEY'));
var JQEle,EleType;
for (ele=0; (ele < FormElementCollection.length); ele++)
{
JQEle=$(FormElementCollection.item(ele));
EleType=JQEle.attr('type');
// https://github.com/jimmywarting/FormData/blob/master/FormData.js
if ((! JQEle.attr('name')) ||
(((EleType == 'checkbox') || (EleType == 'radio')) &&
(! JQEle.prop('checked'))))
continue;
FormDaytaObject[JQEle.attr('name')]=JQEle.val();
}
}
else
{
var FormDayta=new FormData(FormElement);
for (var fld of FormDayta.entries())
FormDaytaObject[fld[0]]=fld[1];
}
return FormDaytaObject;
}
where IsSafariBrowser() is implemented by whatever your favorite method is, but I chose this:
function IsSafariBrowser()
{
var VendorName=window.navigator.vendor;
return ((VendorName.indexOf('Apple') > -1) &&
(window.navigator.userAgent.indexOf('Safari') > -1));
}
Example usage in OP's case, assuming that you have an actual form called CleanDataForm instead of creating a FormData from scratch:
var cleanData=FormDataNameValuePairs('CleanDataForm');
alert(cleanData.test);
I have the following code which is used for a mixitup filter, this code regulates the input from an input range and sets it to a checkbox which is checked it works in every browser except for internet explorer (tested in ie11). I think it has something to do with the initial function.
var p = document.getElementById("range"),
res = document.getElementById("output");
p.addEventListener("input", function () {
$("output").html(p.value);
var classes = "";
var minimal = 0;
var maximal = p.value;
$("input[type='range']").attr({'data-filter': "."+ maximal});
$("input[type=checkbox].budget").val('.'+maximal);
$( ".active" ).each(function( index ) {
var thisClass = $(this).attr("data-filter");
if (thisClass == '#mix.activiteiten') {
} else {
if (thisClass != 'undefined') {
classes += thisClass + ',';
}
}
});
if (classes.length > 0) {
var replaced = classes.replace('undefined', '');
var matching = 0;
var arrClasses = replaced.split(",")
}
}, true);
p.addEventListener("change", function() {
var $show = $('#FilterContainer').find('#mix.activiteiten').filter(function(){
var price = Number($(this).attr('data-budget'));
if (classes.length == 0) {
return price >= minimal && price <= maximal;
} else {
for (index = 0; index < arrClasses.length; index++) {
var thisValue = arrClasses[index].replace('.', '');
if ($(this).hasClass(thisValue) && price >= minimal && price <= maximal) {
matching = 1;
return (price >= minimal && price <= maximal);
}
}
}
});
$('#FilterContainer').mixItUp('filter', $show);
}, true);
`
Try this ... by using the jQuery On, you can ensure better response across browsers and versions.
var p = document.getElementById("range"),
res = document.getElementById("output");
$("#range").on("input", function () {
...
}, true);
$("#range").on("change", function() {
...
}, true);
In older IE attachEvent method works instead of addEventListner
see Docs
If you're interested in a cross-browser approach, try creating a function that handles the feature detection for you. Here's one way that might help as a starting point:
function registerEvent( sTargetID, sEventName, fnToBeRun )
{
var oTarget = document.getElementById( sTargetID );
if ( oTarget != null )
{
if ( oTarget.addEventListener ) {
oTarget.addEventListener( sEventName, fnToBeRun, false );
} else {
if ( oTarget.attachEvent )
{
oTarget.attachEvent( sOnEvent, fnToBeRun );
}
}
}
}
Note that this function makes a few assumptions that you may wish to expand in in order to incorporate this into production code, such as error checking, fallback to attribute based event handlers, and so on. Still, it may serve as a proof of concept.
Also, those claiming that IE predominately relies on attachEvent are referring to older versions of IE. Starting with IE9, addEventListener is not only supported, it's recommended for IE. To learn more, see:
How to detect features, rather than browsers
Use feature and behavior detection
IECookbook: Compatibility guidelines and best practices
The IE Blog is a good way to stay up-to-date on the latest news and best practices for IE. (For example, here's the entry talking about why you should use addEventListener instead of attachEvent.)
Hope this helps...
-- Lance
P.S. If 'addEventListener' doesn't seem to be working for you, trying adding <!DOCTYPE html> as the first line of your HTML file. To learn more, see How to enable standards support.
P.P.S. If you create a personal library of such functions, you can greatly reduce the amount of time it takes you to incorporate common tasks into new projects.
I have two frames, the expression running in first frame and calling highlightElements function in another frame. This expression works fine in Firefox:
parent.frames[0].highlightElements(lineNumbers, stringObj);
The highlightElements function (just for sure):
function highlightElements(lineNumbers, stringObj) {
// run through the cycle and highlight them
//for (var ln in lineNumbers) {
var length = lineNumbers.length;
for (var ln=0; ln<length; ln++) {
var elements = $('.no');
//for (var i in elements) {
var el_length = elements.length;
for (var i=0; i<el_length; i++) {
if (parseInt(elements[i].innerHTML) == lineNumbers[ln]) {
var badThing = "yes";
for (var nextElement = elements[i].next();
nextElement.className != '.no'; nextElement = elements[i].next()) {
if (nextElement.innerHTML == stringObj) {
badThing = "no";
nextElement.effect('highlight', {}, 'slow');
scrollIntoView(nextElement);
}
}
if (badThing == "yes") alert("Didn't find the object");
}
}
}
}
But in Chrome it produces the error "Uncaught TypeError: Property 'highlightElement' of object[objectDOMWindow] is not a function".
How to change the expression to make it runnable in Chrome? Thanks
Make sure both frames are under same domain and protocol. Chome blocks javascript access from frames to another if the domains/protocols don't match. If you are working locally, and not under a local domain (i.e. the url is something like file:///C:/etc/etc.html) then it won't work either.