javascript could not achieve the return - javascript

I had made this function, and this is new yet, and I don't really know how to handle this roughly.
var $;
(function() {
$ = function(e) {
return new query(e);
};
var query = function(e) {
var e = document.querySelectorAll(e), i;
for (i = 0; i < e.length; i++) {
this[i] = e[i];
}
this.length = e.length;
return this;
};
$.fn.prototype = {
hide: function() {
var i;
for (i = 0; i < this.length; i++) {
this[i].style.display = 'block';
}
return this;
},
hasClass: function (klass) {
var e = this, i;
var t = [];
for (i = 0; i < e.length; i++) {
var k = e[i].className;
var array = k.split(' ');
// If the element has the class, add it for return
if (array.indexOf(klass) > -1) {
t.push(e[i]);
}
}
// Return the list of matched elements
return t;
}
}
} ());
window.onload = function() {
$(".element").hasClass("someClass").hide();
}
So yeah, that's the code above. I think I have matched the class, but what the problem is, It's not returning the elements. I'm new to prototyping so please don't be harsh. I really need to fix this one. Please don't tell me to go and have jquery. I don't want to use that massive library just because I want some css selectors.

this inside the function isn't the current element.
hasClass: function (klass) {
var e = this, i;
var t = [];
for (i = 0; i < e.length; i++) {
var k = e[i].className;
var array = k.split(' ');
// If the element has the class, add it for return
if (array.indexOf(klass) > -1) {
t.push(e[i]);
}
}
// Return the list of matched elements
return t;
}
and that is why your script do not return the element.
ALSO:
You tried to use jQuery's method to add your own functions in library, but actually this will not work, as you're writing pure js, not jquery, and you need to do many thing to make it work like jQuery.
$.fn.prototype = {
hide: function() {
var i;
for (i = 0; i < this.length; i++) {
this[i].style.display = 'block';
}
return this;
},
hasClass: function (klass) {
var e = this, i;
var t = [];
for (i = 0; i < e.length; i++) {
var k = e[i].className;
var array = k.split(' ');
// If the element has the class, add it for return
if (array.indexOf(klass) > -1) {
t.push(e[i]);
}
}
// Return the list of matched elements
return t;
}
}
}

The problem here is this line: $.fn.prototype = {};. There is no $.fn in your code anywhere, so you cannot set a prototype property on it. (In jQuery, $.fn is set to jQuery.prototype, that's why you can set $.fn.someMethod.)
If you want the hasClass method to exists on your objects, you need to modify the prototype of query. Your $ function returns new query objects, so query is where the hasClass method should be.
Also, your hasClass method returns an array. Arrays do not have a method called hide. You need to have your hasClass method return a query object, so that you can continue to chain methods.
P.S. Shouldn't a hide method set the style.display to 'none'?
Anyway, your code should look like this:
var $;
(function() {
$ = function(e) {
return new query(e);
};
var query = function(e) {
var e = Array.isArray(e) ? e : document.querySelectorAll(e),
i;
for (i = 0; i < e.length; i++) {
this[i] = e[i];
}
this.length = e.length;
return this;
};
query.prototype = {
hide: function() {
var i;
for (i = 0; i < this.length; i++) {
this[i].style.display = 'none';
}
return this;
},
hasClass: function(klass) {
var e = this,
i;
var t = [];
for (i = 0; i < e.length; i++) {
var k = e[i].className;
var array = k.split(' ');
// If the element has the class, add it for return
if (array.indexOf(klass) > -1) {
t.push(e[i]);
}
}
// Return the list of matched elements
return new query(t);
}
}
}());
window.onload = function() {
$(".element").hasClass("someClass").hide();
}
<p class="someClass element">You can't see me!</p>
(Note: Array.isArray doesn't work in IE < 9.)

If all you want is to query for elements matching a condition and hide it based on element type, id or class name CSS query selectors along with querySelector() or querySelectorAll() api.
For your code sample the same can be rewritten as below
var elements = document.querySelectorAll("element.someClass");
for(var i = 0; i <elements.length; i++) {
elements[i].style.visibility = 'hidden';
}

Related

Cannot read property 'addEventListener' of undefined

function assign(id){
return document.getElementById(id) ;
}
var b = ['p','q','r','s','t','u','v'];
var a = ['fname','lname','email','password','r_password','g_m',"g_f"] ;
for (i=0;i<a.length;i++) {
var x = {} ;
x[b[i]] = assign(a[i]) ;
x[i].addEventListener('click', function() { alert(x[i].value) ;} ,false) ;
}
I want just array of variables and IDs assign with them in for loop .
You're expecting x[i] to return the DOM element you just stored, but you're storing the DOM element at x[b[i]], not x[i]. Be consistent, and that error will go away.
The code still won't work, though, because you're falling into the closure trap: When the click occurs, the event handler will use i as it is then, not as it was when the handler was created. So all the handlers will see i as a.length and fail.
I usually use a builder function to handle that:
for (i = 0; i < a.length; i++) {
var x = {};
x[b[i]] = asign(a[i]);
hookUp(i);
}
function hookUp(index) {
x[b[index]].addEventListener('click', function() {
alert(x[b[index]].value);
}, false);
}
hookUp uses index (which we don't change) rather than i. (I also took a guess at which to use, x[i] or x[b[i]].)
That said, if your goal is to alert the value of the element that was clicked, use this instead:
for (i = 0; i < a.length; i++) {
var x = {};
x[b[i]] = asign(a[i]);
x[b[i]].addEventListener('click', function() {
alert(this.value);
}, false);
}
or Event#currentTarget:
for (i = 0; i < a.length; i++) {
var x = {};
x[b[i]] = asign(a[i]);
x[b[i]].addEventListener('click', function(e) {
alert(e.currentTarget.value);
}, false);
}
function asign(id){
return document.getElementById(id) ;
}
var a = ['a','b','c'];
var b = ['fname','lname','email'] ;
for (i=0;i<a.length;i++) {
(function(i){
var x = {} ;
x[b[i]] = asign(a[i]) ;
x[b[i]].addEventListener('click', function() { alert(i+1) ;} ,false) ;
})(i);
}
<div id="a">Div 1</div>
<div id="b">Div 2</div>
<div id="c">Div 3</div>

How to check whether specific items inside an array have a value? Javascript

I have a function which gets values from elements:
function getTransactionValues() {
var o = {};
o.reservations = [];
$('#custom-headers option:selected').each(function (i, selected) {
o.reservations[i] = $(selected).val();
});
o.amount = $('input[name=amount-price]').val();
o.currency_value = $('input[name=currency-value]').val();
o.currency_name = $('.currency_appendto option:selected').html();
o.actual_amount = $('input[name=actual-amount]').val();
o.actual_remaining = $('input[name=actual-remaining]').val();
o.funds_arrival_date = $('input[name=funds-arrival]').val();
o.paid_to = $('.paidto option:selected').html();
o.checkbox = $('.multi-transaction:checked').map(function () {
return this.value
}).get();
return o;
}
Now i want to check whether amount, actual_amount and funds_arrival_date are filled. if they are i will release the disabled class from a button. i've tried
var check_review = function () {
var a = getTransactionValues();
var options = [a.amount, a.actual_amount, a.funds_arrival_date];
for(i = 0; i < options.length; i++) {
if(options[i].length > 0) {
$('a[name=review_button]').removeClass('disabled');
}
else{
//this array is empty
alert('There is a problem!');
}
}
}
$('.test').click(function() {
check_review();
});
But it doesn't seems to be working..
Remove disabled attribute using JQuery?
Can you please look at above link, I think we should use $('.inputDisabled').prop("disabled", false);
Even if a single array element will be non empty then your code will remove the class disabled from the a. To make sure that all the elements of array are non empty and then only you want to remove the class then the way is:
for(i = 0; i < options.length; i++) {
if(options[i].length > 0) {
$('a[name=review_button]').removeClass('disabled');
}
else{
$('a[name=review_button]').addClass('disabled');
}
}
Or the other way is
var check = true;
for(i = 0; i < options.length; i++) {
if(options[i].length == 0) {
check = false;
}
}
if(check ) $('a[name=review_button]').removeClass('disabled');
Try using Array.prototype.every()
if (options.every(Boolean)) {
$("a[name=review_button]").removeClass("disabled");
} else {
// do other stuff
}

Deleting from an array doesn't work

So, I'm trying to delete from an array if it's element value isn't equal to a value that I specified:
Code: http://pastebin.com/hUc3mVLv
$scope.enablePVR = function()
{
for (i = 0; i < $scope.new_epg.length; i++) {
start_time = convert_time($scope.new_epg[i].start);
$scope.new_epg[i].title = $scope.new_epg[i].title.replace(/<(?:.|\n)*?>/gm, '');
$scope.new_epg[i].description = "";
$scope.new_epg[i].time = start_time;
}
archiveEPG = [];
for(var i=0; i<archiveEPG.length; i++) {
var e = document.getElementById("dateSelect");
if($scope.new_epg[i].start.split(" ")[0] == e[e.selectedIndex].value) {
archiveEPG[archiveEPG.length+1] = $scope.new_epg[i];
}
}
document.getElementById("dateSelect").remove(0);
$scope.get_epg(null, true, archiveEPG);
}
.remove(0) isn't valid you can add this function to make it valid tho :
Array.prototype.remove = function(index) {
return this.splice(index, 1); // The second parameter is the number of elements to remove.
}

JavaScript: How to set a parent object as a parameter within an addEventListener function?

how can I set the object (which is part of the buttons array) as a parameter within the addEventListener function? buttons[i] is not working..
Here is a part of the code:
var buttonNames = ["canteen","locations","floorplan","guestbook","pictures"];
var buttonDivNames = ["btn1","btn2","btn3","btn4","btn5"];
var buttons = [];
window.onload = function() {
for(var i = 0; i<buttonNames.length; i++) {
var obj = new Object();
obj.targetLink = buttonNames[i] + ".html";
obj.defaultImage = "img/buttons/"+buttonNames[i]+"_default.jpg";
obj.hoverImage = "img/buttons/"+buttonNames[i]+"_hover.jpg";
obj.div = document.getElementById(buttonDivNames[i]);
obj.divPicture = obj.div.getElementsByClassName("thumbnailPicture")[0];
obj.divLink = obj.div.getElementsByClassName("thumbnailLink")[0];
buttons.push(obj);
}
for(var i = 0; i<buttons.length; i++) {
buttons[i].divPicture.addEventListener("mouseover",function() { anotherFunction(buttons[i]) },false)
}
}
function anotherFunction(arg) {
console.log(arg.targetLink);
}
Thanks guys, this way it works:
for(var i = 0; i<buttons.length; i++) {
initButton(buttons[i]);
}
}
function initButton(arg) {
arg.divPicture.addEventListener("mouseover",function() {anotherFunction(arg);},false)
}
function anotherFunction(arg) {
console.log(arg.targetLink);
}
As pointed out in the comment section, you could use an IIFE to create a new scope, that holds the value of the current i:
for(var i = 0; i<buttons.length; i++) {
(function (i) {
buttons[i].divPicture.addEventListener("mouseover",function() { anotherFunction(buttons[i]) },false)
}(i));
}
or, even better, create a seperate function that handles the adding of the eventlistener:
function addEventlistenerToButton(button) {
button.divPicture.addEventListener("mouseover",function() { anotherFunction(button) },false)
}
// ....
for(var i = 0; i<buttons.length; i++) {
addEventlistenerToButton(buttons[i]);
}
In addition to that, you could also omit sending the button to the eventlistener completely and get the button from the event object directly:
for(var i = 0; i<buttons.length; i++) {
buttons[i].divPicture.addEventListener("mouseover", anotherFunction, false);
}
function anotherFunction(ev) {
ev = ev || window.event;
var src = ev.target || ev.srcElement;
console.log(src.parentNode);
}

When I make a clone of the object shows me an error message

First the following is the code of my own javascript library.
(function() {
var lib = {
elems: [],
getElem: function() {
var tmpElem = [];
for (var i = 0; i < arguments.length; i++)
tmpElem.push(document.getElementById(arguments[i]));
this.elems = tmpElem;
tmpElem = null;
return this;
},
html: function(txt) {
for (var i = 0; i < this.elems.length; i++)
this.elems[i].innerHTML = txt;
return this;
},
style: function(prob, val) {
for (var i = 0; i < this.elems.length; i++)
this.elems[i].style[prob] = val;
return this;
},
addEvent: function(event, callback) {
if (this.elems[0].addEventListener) {
for (var i = 0; i < this.elems.length; i++)
this.elems[i].addEventListener(event, callback, false);
} else if (this.elems[0].attachEvent) {
for (var i = 0; i < this.elems.length; i++)
this.elems[i].attachEvent('on' + event, callback);
}
return this;
},
toggle: function() {
for (var i = 0; i < this.elems.length; i++)
this.elems[i].style.display = (this.elems[i].style.display === 'none' || '') ? 'block' : 'none';
return this;
},
domLoad: function(callback) {
var isLoaded = false;
var checkLoaded = setInterval(function() {
if (document.body && document.getElementById)
isLoaded = true;
}, 10);
var Loaded = setInterval(function() {
if (isLoaded) {
clearInterval(checkLoaded);
clearInterval(Loaded);
callback();
}
}, 10);
}
};
var fn = lib.getElem;
for(var i in lib)
fn[i] = lib[i];
window.lib = window.$ = fn;
})();
Previously, I have used this way to use my own library, and works fine .
$.getElem('box').html('Welcome to my computer.');
But when updated the code of my own library, and I added
var fn = lib.getElem;
for(var i in lib)
fn[i] = lib[i];
To be using the element selector like this way
$('box').html('Welcome to my computer.');
But the problem began appear when added the updated code to clone the lib object TypeError: $(...).html is not a function.
And now I want to use the element selector like that
$('box').html('Welcome to my computer.');
instead of
$.getElem('box').html('Welcome to my computer.');
You create a variable fn which has a reference to "getElem" but since fn is not a property on your lib object then it means that when getElem refers to "this" it will be you global object which is propbably window.
Remove all the following 3 lines
var fn = lib.getElem;
for(var i in lib)
fn[i] = lib[i];
and then do this
window.$ = function () { return lib.getElem.apply(lib, arguments); };
This will allow getElem to be called as $ but maintaining "lib" as context.
Although I don't know exactly what you are trying to achieve with those additional lines, just by reading the code, lib.getElem does not have a function called html
lib does.
Hence, just var fn = lib; should do just fine.
There more ways to achieve this but the root cause is in your getElem() function: return this;
$ is a reference to that function. If you call $() it is called as a function and not as a method. Therefore this refers to window and window has, of course, no html() function.
You could do return lib; to fix the problem.

Categories