I'm using jQuery 1.12.2 and sometimes I encoutered the error Unable to get property 'defaultView' of undefined or null reference.
The error occured at this line :
if (jQuery(event.target).is('[contenteditable]') ||
jQuery(event.target).css('position') == 'absolute' ||
jQuery(event.target).css('position') == 'fixed') {
return;
}
Edit
This is on document mousedown event.
jQuery(document).bind('mousedown', function (event) {
var $active_element;
if (jQuery(event.target).parents(".ui-draggable").length > 0) {
if (jQuery(event.target).parents(".ui-draggable").parent().data('contentbuilder')) {
$active_element = jQuery(event.target).parents(".ui-draggable").parent(); //Get current Builder element
}
}
//Remove Overlay on embedded object to enable the object.
if (jQuery(event.target).attr("class") == 'ovl') {
jQuery(event.target).css('z-index', '-1');
}
(...)
if (jQuery(event.target).is('[contenteditable]') ||
jQuery(event.target).css('position') == 'absolute' ||
jQuery(event.target).css('position') == 'fixed'
) {
return;
}
jQuery(event.target).parents().each(function (e) {
if (jQuery(this).is('[contenteditable]') ||
jQuery(this).css('position') == 'absolute' ||
jQuery(this).css('position') == 'fixed'
) {
return;
}
});
(...)
}
I think it isn't in the .each() function but maybe ?
It comes from getComputedStyle() fucnction...
Can you help me ?
Related
I am trying to add links eg <a> to the code from here, it is a treeview using JS and JSON.
It fully works and the children are already <a></a> with href="#", I have replaced the following code, to grab a href : "example.com" attribute from the JSON and set it to the href, which works. I have also made a change to the onclick, but that only does something if you click twice :/
I would like for it to instantly href, and not when you click twice on the child.
class SimpleTree extends Emitter {
constructor(parent, properties = {}) {
super();
// do not toggle with click
parent.addEventListener('click', e => {
// e.clientX to prevent stopping Enter key
// e.detail to prevent dbl-click
// e.offsetX to allow plus and minus clicking
if (e && e.clientX && e.detail === 1 && e.offsetX >= 0) {
if (parent.href != null) {
window.location.href = parent.href;
}
return e.preventDefault();
}
const active = this.active();
if (active && active.dataset.type === SimpleTree.FILE) {
e.preventDefault();
this.emit('action', active);
if (properties['no-focus-on-action'] === true) {
window.clearTimeout(this.id);
}
}
});
[...]
class SelectTree extends AsyncTree {
constructor(parent, options = {}) {
super(parent, options);
/* multiple clicks outside of elements */
parent.addEventListener('click', e => {
if (e.target.href !== '#' || e.target.href !== 'javascript:void(0)' || e.target.href !== undefined || e.target.href !== '' || e.target.href !== null) {
window.open(href, '_blank');
}
if (e.detail > 1) {
const active = this.active();
if (active && active !== e.target) {
if (e.target.tagName === 'A' || e.target.tagName === 'SUMMARY') {
return this.select(e.target, 'click');
}
}
if (active) {
this.focus(active);
}
}
});
The simplest answer to this, add an eventlistener for the <a> element and navigate if it's not empty, null, etc.
Solution below is using Jquery.
$("a").click(function(e) {
e.preventDefault();
var href = $(this).attr("href");
if (href !== '#' || href !== 'javascript:void(0)' || href !== undefined || href !== '' || href !== null) {
window.open(href, '_blank');
}
});
I have a script that I want to make more bulletproof. At the moment the page breaks because class box-tip is not found. To make this bulletproof and not throw an error how can I rewrote the below code to jquery getting the same results as js
function applyRecommendedSleeveLength(selectedVal) {
if (selectedVal !== undefined) {
var recommendedVal = map[selectedVal.trim()];
var selected = $('.attribute__swatch--selected:first div').text().trim();
if (recommendedVal === null || recommendedVal === undefined) {
selectedVal = $('.attribute__swatch--selected:first div').text().trim();
recommendedVal = map[selectedVal.trim()];
}
if (selected === null || selected === '' || selected === undefined) return;
var recommendedLis = document.querySelectorAll('[class*="attribute__swatch--length-' + recommendedVal + '"] div');
recommendedLis.forEach(function(recommendedLi, i) {
if (recommendedLi !== null && recommendedLi !== undefined) {
recommendedLi.classList.add('showBorder');
$('.box-tip').show();
var currentPosition = $('.showBorder').parent().position().left;
var sleeveRecom = document.getElementsByClassName('box-tip');
var info = sleeveRecom.length ? sleeveRecom[0] : false;
info.style.paddingLeft = currentPosition + -75 + 'px';
}
});
}
}
If you want to check if the div exists, you can use this (using JQuery):
if ( $('.box-tip').length != 0 ){
//do something
}
OR- since you've edited your post- without JQuery:
if ( document.getElementsByClassName('box-tip').length != 0 ){
//do something
}
Just use jQuery for all of this. If the class doesn't exist the jQuery methods won't cause errors
function applyRecommendedSleeveLength() {
$('.box-tip').show().first().css('paddingLeft', (currentPosition - 75) + 'px');
}
I have a drop down menu, and when I select the 'All' option, it gives me this error on the console:
TypeError: Cannot read property '0' of undefined
at n.$scope.onSearchByChanged (http://localhost:8080/js/jenkinsVersion/directives/assignment-filter.js:70:81)
So, I went to my script, function, line 70,character 81 :
$scope.onSearchByChanged = function () {
if ($scope.filter.list.searchBy == 'DEPARTMENT_CODE' && !$scope.filterScope.departments) {
$scope.loadDepartments();
} else if ($scope.filter.list.searchBy != 'DEPARTMENT_CODE') {
$scope.filter.list.departmentId = 0;
}
if ($scope.filter.list.searchBy == 'GROUP' && !$scope.filterScope.editorGroups) {
$scope.loadEditorGroups();
} else if ($scope.filter.list.searchBy != 'GROUP') {
$scope.filter.list.groupId = $scope.filterScope.editorGroups[0].id; //line 70
}
$scope.clearFilter('text');
};
if ($scope.filter.list.searchBy == 'GROUP' && !$scope.filterScope.editorGroups) {
$scope.loadEditorGroups();
}
if ($scope.filter.list.searchBy == 'DEPARTMENT_CODE' && !$scope.filterScope.departments) {
$scope.loadDepartments();
}
$scope.isStatusSelected = function (status) {
return _.indexOf($scope.filter.list.talentAssignmentStatuses, status) > -1;
};
$scope.selectTalentAssignmentStatus = function (status) {
$scope.clearFilter('text');
if ($scope.isStatusSelected(status)) {
_.remove($scope.filter.list.talentAssignmentStatuses, function (el) {
return status == el;
});
} else {
$scope.filter.list.talentAssignmentStatuses.push(status);
}
};
here is the loadEditorGroups function :
$scope.loadEditorGroups = function () {
Reference.getEditorGroups($scope, function (response) {
$scope.filterScope.editorGroups = response.list;
if ($scope.filterScope.editorGroups.length > 0) {
$scope.filter.list.groupId = $scope.filterScope.editorGroups[0].id
}
});
};
I'm still learning JS. Why is this error being thrown? When I change the value of the item I want to retrieve from that editorGroups list it just gives me the same error but with the corresponding number. Your help would be appreciated, please let me know if I can supply further information. Thank you!
Your logic for this if-else block is probably wrong:
if ($scope.filter.list.searchBy == 'GROUP' && !$scope.filterScope.editorGroups) {
$scope.loadEditorGroups();
} else if ($scope.filter.list.searchBy != 'GROUP') {
$scope.filter.list.groupId = $scope.filterScope.editorGroups[0].id; //line 70
}
The program will enter the else if block when both:
the if condition is false, that is: ($scope.filter.list.searchBy == 'GROUP' && !$scope.filterScope.editorGroups) == false
the else if condition is true, that is: ($scope.filter.list.searchBy != 'GROUP') == true
We can take these two statements and simplify them:
!($scope.filter.list.searchBy == 'GROUP' && !$scope.filterScope.editorGroups) && ($scope.filter.list.searchBy != 'GROUP')
($scope.filter.list.searchBy != 'GROUP' || $scope.filterScope.editorGroups) && ($scope.filter.list.searchBy != 'GROUP')
($scope.filter.list.searchBy != 'GROUP')
In step 2, I applied De Morgan's law to simplify !(A && B) to (!A || !B).
In step 3, I simplified the &&, since (A || B) && A is the same as just A.
So really, all we know when we enter the else if block is that searchBy != 'GROUP'. We do not know anything about editorGroups, and indeed, it may be undefined!
What you're probably looking for is:
if ($scope.filter.list.searchBy == 'GROUP' || !$scope.filterScope.editorGroups) {
$scope.loadEditorGroups();
} else if ($scope.filter.list.searchBy != 'GROUP') {
$scope.filter.list.groupId = $scope.filterScope.editorGroups[0].id;
}
Notice the || in the if condition. This ensures that the else if is executed only when ($scope.filter.list.searchBy != 'GROUP' && $scope.filterScope.editorGroups), so that editorGroups[0] will not give an error. I don't know enough if this is what you intended this code to do, so correct me when I'm wrong. :-)
70:81 means line 70, character 81.
The problem is at editorGroups[0]: If editorGroups is undefined, it cannot read editorGroups[0] because undefined has no property called 0.
Make sure that editorGroups isn't undefined and you'll be fine!
I need to pop-up alert when I use Middle Click and it must don't pop-up if I click it on a link but on any other element of page (or just on empty space).
var test = {
pageMiddleClickListener : function(e) {
if(e.which === 2) {
//if (!gContextMenu.onLink) {
alert('ok');
//}
}
}
window.addEventListener("click",test.pageMiddleClickListener,false);
Alert show-ups when I use Middle Click on a link, but I need to prevent this behavior to links
I need something like "!gContextMenu.onLink" but not for context menu (without)
There are multiple ways that you can test for the target of the click being a link. One way would be to check to see if the Element.tagName is A, another would be to test for the href property. As it turns out is is also necessary to test to see if any of the target's parentNodes are links.
var test = {
pageMiddleClickListener : function(e) {
if(e.button === 1) {
if (!test.isLinkOrAParentIsLink(e.target)) {
e.view.alert('ok');
}
}
},
isLinkOrAParentIsLink : function(el) {
if (el.tagName === "A") {
return true;
} //else
let parent= el.parentNode;
while (parent !== null && typeof parent.tagName !== "undefined") {
if (parent.tagName === "A") {
return true;
} //else
parent= parent.parentNode;
}
return false;
}
}
window.addEventListener("click",test.pageMiddleClickListener,false);
or
isLinkOrAParentIsLink : function(el) {
if (el.hasAttribute("href")) {
return true;
} //else
let parent= el.parentNode;
while (parent !== null && typeof parent.tagName !== "undefined") {
if (parent.hasAttribute("href")) {
return true;
} //else
parent= parent.parentNode;
}
return false;
}
Note: I changed e.which to e.button as that is what is in the specification for click events and MouseEvent.which is non-standard. Note this also required testing for e.button === 1 instead of 2.
You can check if you have clicked an <a> with the prop method.
$(this).prop("tagName") == "A"
In your event listener:
var test = {
pageMiddleClickListener : function(e) {
if(e.which === 2) {
// not an <a> ?
if ($(this).prop("tagName") !== "A") {
alert('ok');
}
}
}
window.addEventListener("click",test.pageMiddleClickListener,false);
I have to the following function that I would like to modify so that it only binds the click event to all href's that = /ShoppingCart.asp?ProductCode="whatever" (whatever = whatever is in there") but not if it is specifically /ShoppingCart.asp?ProductCode="GFT". It must also check or convert a gft or Gft to upper case to check for those as well. So basically it has to check for any variation of the case of GFT.
If it finds a "GFT" do not bind the click event.
function sacsoftaddtocart() {
if (location.pathname == "/SearchResults.asp" || location.pathname == "/Articles.asp" || location.pathname.indexOf("-s/") != -1 || location.pathname.indexOf("_s/") != -1) {
$("a[href^='/ShoppingCart.asp?ProductCode']").click(function () {
var href = $(this).attr('href');
addToCart3(href);
return false;
});
}
}
You can do it using .toUpperCase() and .filter(), like this:
function sacsoftaddtocart (){
if (location.pathname == "/SearchResults.asp" || location.pathname == "/Articles.asp" || location.pathname.indexOf("-s/") != -1 || location.pathname.indexOf("_s/") != -1) {
$("a[href^='/ShoppingCart.asp?ProductCode']").filter(function() {
return this.href.length - this.href.toUpperCase().indexOf('PRODUCTCODE=GFT') != 15;
}).click(function () {
var href = $(this).attr('href');
addToCart3(href);
return false;
});
}
}
You cant test it in a demo here. The this.href.length - matchPosition == 15 is checking that the ProductCode=GFT is both matched and there's nothing after the "GFT", so a product code like "GFT5" won't match.
using the filter in this post link text
function sacsoftaddtocart() {
if (location.pathname == "/SearchResults.asp" || location.pathname == "/Articles.asp" || location.pathname.indexOf("-s/") != -1 || location.pathname.indexOf("_s/") != -1) {
$("a:regex('href','*/ShoppingCart.asp\?ProductCode=(!?=GFT)*)").click(function () {
var href = $(this).attr('href');
addToCart3(href);
return false;
});
}
}
or if you don't want to use an exrat plugin:
function sacsoftaddtocart() {
if (location.pathname == "/SearchResults.asp" || location.pathname == "/Articles.asp" || location.pathname.indexOf("-s/") != -1 || location.pathname.indexOf("_s/") != -1) {
$("a['href^='/ShoppingCart.asp?ProductCode']")
.filter(function(){ return !/ProductCode=GTF/.test($(this).attr('href')) };
.click(function () {
var href = $(this).attr('href');
addToCart3(href);
return false;
});
}
}
Try them and see what happens ;)