I have a javascript error raised in IE11 that is disabling scrolling by mouse on the page. I'd like to know what the problem is with the code and if it can easily be modified to fix it.
The error is:
{exception} Unable to get property 'length' of undefined or null reference
It occurs in this block of code, in line 8 as shown handlers is a null reference:
return {
add: function(elem, event, handler) {
if(!elem.events) {
elem.events = {};
elem.handle = function(e) {
var ret, handlers = elem.events[e.type];
e = fixEvent(e);
for(var i = 0, len = handlers.length; i < len; i++) {
if(handlers[i]) {
ret = handlers[i].call(elem, e);
if(ret === false) {
e.preventDefault();
e.stopPropagaton();
}
}
}
};
}
if(!elem.events[event]) {
elem.events[event] = [];
if(elem.addEventListener) elem.addEventListener(event, elem.handle, false);
else if(elem.attachEvent) elem.attachEvent('on'+event, elem.handle);
}
elem.events[event].push(handler);
},
remove: function(elem, event, handler) {
var handlers = elem.events[event];
for(var i = handlers.length - 1; i >= 0; i--) {
if(handlers[i] === handler) {
handlers.splice(i,1);
}
}
if(!handlers.length) {
delete elem.events[event];
if(elem.removeEventListener) elem.removeEventListener(event, elem.handle, false);
else if(elem.detachEvent) elem.detachEvent('on'+event, elem.handle);
}
}
};
Related
I want to select element have no child.
This is js code
var elements = document.body.getElementsByTagName("*");
elements.each(function(element) {
if (element.childElementCount == 0) {
element.addEventListener(
"click",
function() {
makeBorder(selectedElement, false);
selectedElement = element;
makeBorder(element, true);
},
false
);
} else {
element.removeEventListener("click", null, false);
element.removeEventListener("onclick", null, false);
}
});
From link "m.naver.com", class["grid1 id_cui_cupid_news _MM_AIRS_CONTAINER"]'s real childElementCount is not 0.
But in code, childElementCount is 0.
I'm running this code in android webview.
How can I get the element that has no child?
reference : Select element inside WebView and get details
[[[[[[[ Edited ]]]]]]
Object.prototype.each = function(fn, bind) {
for (var i = 0; i < this.length; i++) {
if (i in this) {
fn.call(bind, this[i], i, this);
}
}
};
var selectedElement = null;
document.getElementsByTagName("*").addEventListener("click", function(e) {
if(e.target && e.target.childElementCount == 0) {
makeBorder(selectedElement, false);
selectedElement = element;
makeBorder(element, true);
}
});
// here
var makeBorder = function(element, selected) {
if (element) {
element.style.cssText = selected ? 'background: #CDEA90;' : '';
}
};
I recently learned a few ajax methods in jQuery and I stumbled upon this code and I cannot figure out what it's doing.
ajax: {
init: function() {
app.ajax._ctr = 1;
app.ajax._preloaded = {};
app.ajax.inProgress = false;
app.dom.$body.on('click', 'a:not(.no-ajax):not([hreflang])', function(e) {
var $a = $(e.currentTarget);
var href = $a.attr('href');
// what is indexOf
if (href.indexOf('mailto:') < 0
&& href != '#'
&& ((href.indexOf(app.baseUrl) >= 0 && href.indexOf(app.baseUrl) <= 7) || href.indexOf('://') < 0)
&& !$a.parents('.mejs-container').length) {
e.preventDefault();
app.ajax.loadPage(href, true, $a.attr('data-ajax-resolver'));
}
});
// below is load event
app.dom.$window.on('load', function() {
app.ajax.currentStateCtr = app.ajax._ctr;
history.replaceState({ internal: true, ctr: app.ajax._ctr++ }, null, document.URL);
});
// below is popstate event
app.dom.$window.on('popstate', function(e) {
if (e.originalEvent.state && e.originalEvent.state.internal) {
app.ajax.loadPage(location.href, false, null, e.originalEvent.state.ctr < app.ajax.currentStateCtr);
app.ajax.currentStateCtr = e.originalEvent.state.ctr;
}
});
}, // end of init
getResolver: function(resolverName) {
if (resolverName !== undefined && app.ajax._resolvers[resolverName] !== undefined) {
return app.ajax._resolvers[resolverName];
}
return app.ajax._defaultResolver;
},
I notice that it declares it within an App object with an empty DOM object. I also understand there are a few jQuery events being used here, but I don't understand exactly how the 'popstate' event and the getResolver function is being used with data.
I've got a page, on the page there is a button wrapped in an anchor tag:
This calls a function labeled as AddNewThread, now this function opens up a dialog Box using jQuery, and in the dialog box there is a text field that you enter text to, and this text is then pasted on the page using ajax.
The problem:
I want to remove the click event entirely; I want to have it on page load, it will load the text box, and the functionality is remaining the same, But I just don't know how to go about this.
Here's the code for the AddNewThread function:
function DiscussionViewModel() {
var self = this;
self.New = ko.mapping.fromJS(newDiscussion);
self.Threads = ko.mapping.fromJS(threads, mapping);
self.AddNewThread = function () {
$("#dvAddDiscussion").dialog('open');
ko.mapping.fromJS(newDiscussion, self.New);
if (CKEDITOR.instances["txtDiscussioinDescription"] != undefined) {
CKEDITOR.instances["txtDiscussioinDescription"].setData('');
}
};
self.AddReply = function (thread) {
$("#txtDiscussioinDescription").val('');
self.LastDiscussionId(thread.New.ParentId());
self.New.Title('');
self.New.DiscussionId(thread.New.DiscussionId());
self.New.Type(thread.New.Type());
self.New.TypeId(thread.New.TypeId());
self.New.Description('');
self.New.ParentId(thread.New.ParentId());
self.New.UserId(thread.New.UserId());
self.New.User(thread.New.User());
$("#dvAddDiscussion").dialog('open');
};
self.LastDiscussionId = ko.observable();
self.SubmitReply = function (form) {
var jForm = $(form);
$("#dvAddDiscussion").dialog('close');
var request = jForm.serialize();
var discussionId = $("#DiscussionID").val();
var parentId = $("#ParentId").val();
$.post(addDiscussionUrl, request, function (response) {
if (response) {
if ((discussionId == '' || discussionId == undefined) && parentId == '') {
$.post(summariesUrl, { type: type, objectId: objectId }, function (response) {
ko.mapping.fromJS(response, mapping, self.Threads);
$("abbr.timeago").timeago();
});
} else {
self.LoadReplies(self.LastDiscussionId());
}
} else {
alert("Error occured while adding discussion");
}
});
};
self.GetReplies = function (data) {
var thread;
if (data.IsMaximized() == true) {
for (var i = 0; i < self.Threads().length; i++) {
if (self.Threads()[i].DiscussionId() == data.DiscussionId()) {
self.Threads()[i].IsMaximized(false);
break;
}
}
} else {
for (var i = 0; i < self.Threads().length; i++) {
if (self.Threads()[i].DiscussionId() == data.DiscussionId()) {
self.Threads()[i].IsMaximized(true);
self.LoadReplies(data.DiscussionId());
break;
}
}
}
};
self.LoadReplies = function (discussionId) {
var request = {
discussionId: discussionId,
type: type,
objectId: objectId
};
$.post(threadsUrl, request, function (response) {
for (var i = 0; i < self.Threads().length; i++) {
if (self.Threads()[i].DiscussionId() == discussionId) {
self.Threads()[i].Replies.splice(0, self.Threads()[i].Replies().length);
for (var j = 0; j < response.length; j++) {
self.Threads()[i].Replies.push(new ReplyModel(response[j]));
}
break;
}
}
$("abbr.timeago").timeago();
});
};
self.EditReply = function (dicussion) {
self.New.Title(dicussion.Title());
self.New.DiscussionId(dicussion.DiscussionId());
self.New.Type(dicussion.Type());
self.New.TypeId(dicussion.TypeId());
self.New.Description(dicussion.Description());
self.New.ParentId(dicussion.ParentId());
self.New.UserId(dicussion.UserId());
self.New.User(dicussion.User());
self.LastDiscussionId(dicussion.DiscussionId());
$("#dvAddDiscussion").dialog('open');
};
self.ToggleView = function (data) {
for (var i = 0; i < self.Threads().length; i++) {
for (var j = 0; j < self.Threads()[i].Replies().length; j++) {
if (self.Threads()[i].Replies()[j].DiscussionId == data.DiscussionId) {
self.Threads()[i].Replies()[j].HasMore(!self.Threads()[i].Replies()[j].HasMore());
break;
}
}
}
};
}
var discussionViewmodel = new DiscussionViewModel();
ko.applyBindings(discussionViewmodel, document.getElementById("dvThreads"));
$(function () {
$("#accordion").accordion();
var dialog = $("#dvAddDiscussion").dialog({
autoOpen: false,
width: 720,
height: 500,
title: 'Discussion',
modal: true,
open: function () {
if (typeof DISABLE_FOR_DIALOG != 'undefined')
DISABLE_FOR_DIALOG = true;
CKEDITOR.replace('txtDiscussioinDescription');
},
close: function (parameters) {
if (typeof DISABLE_FOR_DIALOG != 'undefined')
DISABLE_FOR_DIALOG = false;
if (CKEDITOR.instances["txtDiscussioinDescription"] != undefined) {
CKEDITOR.instances.txtDiscussioinDescription.updateElement();
CKEDITOR.instances.txtDiscussioinDescription.destroy();
}
}
});
dialog.parent().appendTo($("#dvDialogs"));
$("#frmAddDiscussion").data("validator").settings.submitHandler = discussionViewmodel.SubmitReply;
$("#frmAddDiscussion").bind('click', function () {
CKEDITOR.instances.txtDiscussioinDescription.updateElement();
});
});
</script>
You just need to call the function at the appropriate time, which in this case is within your jQuery ready handler, right after this block:
$("#frmAddDiscussion").bind('click', function () {
CKEDITOR.instances.txtDiscussioinDescription.updateElement();
});
You should be able to just add:
discussionViewmodel.AddNewThread();
This will invoke the function the same way that knockout would have done through the click data binding.
So I've been following this tutorial here and it shows you how to validate dates compared with each other. I'm getting an error in the first block of code which I've commented and it says "Unable to get property 'element' of undefined or null reference" which originates from this line of code customValidation.formValidator = $(event.data.source).closest('form').data('validator') does anyone know of a work around for this so I don't get an error. I'm using the latest unobtrusive validation
window.customValidation = window.customValidation ||
{
relatedControlValidationCalled: function (event) {
if (!customValidation.activeValidator) {
customValidation.formValidator = $(event.data.source).closest('form').data('validator');
}
// code error below
customValidation.formValidator.element($(event.data.target));
},
relatedControlCollection: [],
formValidator: undefined,
addDependatControlValidaitonHandler: function (element, dependentPropertyName) {
var id = $(element).attr('id');
if ($.inArray(id, customValidation.relatedControlCollection) < 0) {
customValidation.relatedControlCollection.push(id);
$(element).on(
'blur',
{ source: $(element), target: $('#' + dependentPropertyName) },
customValidation.relatedControlValidationCalled);
}
}
};
adapter:
$.validator.unobtrusive.adapters.add('comparedates', ['otherpropertyname', 'allowequality'],
function (options) {
options.rules['comparedates'] = options.params;
if (options.message) {
options.messages['comparedates'] = options.message;
}
}
);
validator method:
$.validator.addMethod('comparedates', function (value, element, params) {
var otherFieldValue = $('input[name="' + params.otherpropertyname + '"]').val();
if (otherFieldValue && value) {
var currentValue = Date.parse(value);
var otherValue = Date.parse(otherFieldValue);
if ($(element).attr('name').toLowerCase().indexOf('begin') >= 0) {
if (params.allowequality) {
if (currentValue > otherValue) {
return false;
}
} else {
if (currentValue >= otherValue) {
return false;
}
}
} else {
if (params.allowequality) {
if (currentValue < otherValue) {
return false;
}
} else {
if (currentValue <= otherValue) {
return false;
}
}
}
}
customValidation.addDependatControlValidaitonHandler(element, params.otherpropertyname);
return true;
}, '');
Maybe you are loading this code too early, before the form is in the DOM. Make sure your code is protected by $(document).ready(your code here);
I've implemented the observer pattern in JS in a very universal way. Now I realized that there is a conceptional problem and I don't know how to solve it. Could you give me a tipp how to solve it? (particularly in a very smart way :-) )
This is the code:
var Oberserverable = function() {
var subscribers = { /* some delegated functions in here */ };
return {
attach: function (obj, fn) { subscribers[obj] = { src: obj, fn: fn }; },
detach: function (obj) { delete subscribers[obj]; },
notify: function (args) {
for(var o in subscribers) {
if(typeof args === "object") { args.target = subscribers[o].src; }
/* TODO return */ subscribers[o].fn.call(window, args);
}
},
count: function () { var size = 0; for(var o in subscribers) { size++; } return size; }
};
};
I'd like that each delegated function returns its value. But this would end the loop what I'd like to prevant.
Example case where I'm using it; workaround for crappy IE8 Eventhandeling:
window.addEvent = function (obj, type, fn, bub) {
if(obj.addEventListener) {
return obj.addEventListener(type, fn, bub ? bub : false);
}
if(obj.attachEvent && type == "DOMContentLoaded") type = "load";
// no use of attachEvent() 'cause of very buggy behaviour in IE<=8
// http://stackoverflow.com/questions/15952943/ie-attachevent-call-returns-true-but-handler-shows-null
if(!obj["e"+type]) obj["e"+type] = new Oberserverable();
obj["e"+type].attach("e"+obj+fn, fn);
if(!obj["on"+type]) {
obj["on"+type] = function(e) {
e = e || window.event;
e.cancelBubble = bub;
return obj["e"+type].notify(e) || (type != "contextmenu"); // suppressing context menu in IE8 as default
};
}
}
EUREKA!
I think I've got the solution. The actual problem is not the Oberserverable pattern but the example case itself. Maybe I should do sth. like this:
obj["on"+type] = function(e) {
e = e || window.event;
e.cancelBubble = bub;
obj["e"+type].notify(e);
if(typeof e.preventDefault == "function") {
return e.preventDefault();
}
};
And the other part simular to this:
addEvent(document, "contextmenu", function(e) {
document.defaultAction = false;
if (e.preventDefault)
e.preventDefault();
else
e.preventDefault = function() { return false; };
if (e.stopPropagation)
e.stopPropagation();
if (e.returnValue)
e.returnValue = false;
});
It seems to work this way but I'm not sure about compliance and side effects.