I am moving from jQuery to MooTools (for the fun..) and I have this line of code :
$subMenus = $headMenu.find('li ul.sub_menu:visible');
How I can write this in mootools?
I know that I can use getElements but How I can check for visible ul?(I am using this(:visible) selector a lot).
Edit -
I implemented my own function :
function findVisibleElements(elementsCollection){
var returnArray = [];
elementsCollection.each(function(el){
if(el.getStyle('display') === 'block'){
returnArray.push(el);
}
});
return returnArray;
}
And what i want is to slide up all the visible sub menu, this is what I wrote :
// Sliding up the visible sub menus
if( visibleSubMenus.length > 0 ){
visibleSubMenus.each(function(el){
var slider = new Fx.Slide(el, {duration: 2000});
slider.slideOut();
});
}
Why my code isn`t working?My function is working, and the problem is with the Fx.Slide.
I added mootools more with Fx.Slide.
Just extend the selector functionality - it's MooTools!
$extend(Selectors.Pseudo, {
visible: function() {
if (this.getStyle('visibility') != 'hidden' && this.isVisible() && this.isDisplayed()) {
return this;
}
}
});
After that just do the usual $$('div:visible') which will return the elements that are visible.
Check out the example I've created: http://www.jsfiddle.net/oskar/zwFeV/
The $$() function in Mootools is mostly equivalent to JQuery's $() does-it-all selector.
// in MooTools
var elements = $$('.someSelector');
// natively in most newer browsers
elements = document.body.querySelectorAll('.someSelector');
However, for this specific case since :visible isn't a real pseudo class, you'll have to approximate it using an Array filter in Mootools.
var isItemVisible = function (item) {
return item.style.visibility != 'hidden' && item.style.display != 'none';
}
var elements = $$('ul').filter(isItemVisible);
There might be other things that you consider make an item 'invisible', in which case you can add them to the filtering function accordingly.
Related
I am trying to get this accordion style faq-sheet to work. So far I can only seem to get the first element to show the hidden content. Here is my js:
var arrowIcon = document.querySelector('.arrow-icon');
var hidden = document.querySelector('.hidden');
var answer = 'answer';
arrowIcon.addEventListener('click', function() {
if (answer === 'hidden') {
answer = 'answer';
hidden.setAttribute('class', 'answer');
}
else {
answer = 'hidden';
hidden.setAttribute('class', 'hidden');
}
});
You need to use querySelectorAll and then iterate through each element and add click listener. Keep in mind that querySelectorAll returns a nodeList not an array. So if you want to use all the array functionality make sure you convert it into array.
Something like this should work:
var arrowIcon = Array.from(document.querySelectorAll('.arrow-icon'));
arrowIcon.forEach(el => {
el.addEventListener("click", => (event) {
// Your Code Here
})
});
I have got a loop function that slides 2 divs over a 3rd. Working example can be found here: http://jsbin.com/OYebomEB/4/.
Main function:
var elements = ['#pointsbarDiv', '#hotlink1Div', '#pointsbarDiv', '#hotlink2Div'];
function hotlinks_loop(index) {
$(elements[index]).css({top: -75, display: 'block'}).animate({top: '+0'}, 3000, function () {
var $self = $(this);
var currentInstance = this;
setTimeout(function () {
$self.animate({top: $(window).height()}, 3000);
if(currentInstance.hotlinkStop !== true){
hotlinks_loop((index + 1) % elements.length);
}
}, 3000, currentInstance);
});
}
hotlinks_loop(0); // start with the first element
I have some code to disable onclick while hotlink divs are moving:
hotlink2BtnClick: function () {
if ($("#hotlink2Div").css("top") === "0px") {
//do stuff;
} else {
//do stuff;
}
},
However, for the stationary pointsbarDiv I cannot find a solution to disable onclick/mousedown while hotlink divs are sliding over it.
I have tried various 'If's like the the following example:
if (($("#hotlink1Div").css("top") < "76px" && $("#hotlink1Div").css("bottom") < "150px") || ($("#hotlink1Div").css("top") > "-75px" && $("#hotlink1Div").css("bottom") < "75px")))...
I am also wondering if there is way I can just disable onclick/mousedown while divs are moving within the main function provided.
I should mention that I am a newbie to javascript/jquery.
JQuery event functions get passed an event object - you can accept this in your function, and use it to stop propagation:
hotlink2BtnClick: function (ev) {
ev.stopPropagation();
http://api.jquery.com/event.stoppropagation/
Also, if you put your js examples on http://jsfiddle.net, then we can fork it and return it to you fixed.
I managed to do this by creating a an extra div giving it a z-index of -1 and setting visibility to hidden.
Then replacing the points div with this in array for the loop.
Followed by implementing a similar code solution hotlink2BtnClick().
I have this wizard step form that I simulated with <ul> list items by overlapping inactive <li> items with absolute positioning.
The wizard form is working as desired except that I want to hide next or previous button on a certain step.
This is my logic in jQuery but it doesn't do any good.
if (index === 0) {
$('#prev').addClass(invisible);
$('#prev').removeClass(visible);
} else if (index === 1) {
$('#prev').addClass(visible);
$('#prev').removeClass(invisible);
} else {
$('#next').addClass(invisible);
}
To get the index value I used eq() chained on a current step element like the following
var current;
var index = 0;
$(function () {
current = $('.pg-wrapper').find('.current');
$('#next').on('click', function() {
if (current.next().length===0) return;
current.next().addClass('current').show();
current.removeClass('current').hide();
navstep.next().addClass('active');
navstep.removeClass('active');
current = current.next();
navstep = navstep.next();
index = current.eq();
});
I tried to isolate it as much as possible but my full code will give you a better idea.
If you would care to assist please check my JS BIN
There were several issues
you used .eq instead of index
you were missing quotes around the class names
your navigation logic was flawed
no need to have two classes to change visibility
I believe the following is an improvement, but let me know if you have questions.
I added class="navBut" to the prev/next and rewrote the setting of the visibility
Live Demo
var current;
var navstep;
$(function () {
current = $('.pg-wrapper').find('.current');
navstep=$('.nav-step').find('.active');
$('.pg-wrapper div').not(current).hide();
setBut(current);
$('.navBut').on('click', function() {
var next = this.id=="next";
if (next) {
if (current.next().length===0) return;
current.next().addClass('current').show();
navstep.next().addClass('active');
}
else {
if (current.prev().length===0) return;
current.prev().addClass('current').show();
navstep.prev().addClass('active');
}
current.removeClass('current').hide();
navstep.removeClass('active');
current = (next)?current.next():current.prev();
navstep = (next)?navstep.next():navstep.prev();
setBut(current);
});
});
function setBut(current) {
var index=current.index();
var max = current.parent().children().length-1;
$('#prev').toggleClass("invisible",index<1);
$('#next').toggleClass("invisible",index>=max);
}
The eq function will not give you the index, for that you need to use the index() function.
I have not looked at the whole code but shouldn't your class assignemnts look like:
$('#prev').addClass('invisible');
$('#prev').removeClass('visible');
i.e. with quotes around the class names? And is it really necessary to have a class visible? Assigning and removing the class invisible should easily do the job (provided the right styles have been set for this class).
You should make 4 modifications.
1) Use .index() instead of .eq();
2) Add a function changeIndex which changes the class depends on the index and call it on click of prev and next.
3) add quotes to invisible and visible
4) There is a bug in your logic, try going to 3rd step and come back to 1st step. Both buttons will disappear. So you have to make next button visible if index = 0
Here is the demo :
http://jsfiddle.net/ChaitanyaMunipalle/9SzWB/
Use index() function instead of eq() because eq() will return object and index() will return the integer value.
DEMO HERE
var current;
var navstep;
var index = 0;
$(function () {
current = $('.pg-wrapper').find('.current');
navstep=$('.nav-step').find('.active');
$('.pg-wrapper div').not(current).hide();
}(jQuery));
$('#next').on('click', function() {
if (current.next().length===0) return;
current.next().addClass('current').show();
current.removeClass('current').hide();
navstep.next().addClass('active');
navstep.removeClass('active');
current = current.next();
navstep = navstep.next();
index = current.index();
change_step(index)
});
$('#prev').on('click', function() {
if (current.prev().length===0) return;
current.prev().addClass('current').show();
current.removeClass('current').hide();
navstep.prev().addClass('active');
navstep.removeClass('active');
current = current.prev();
navstep = navstep.prev();
index = current.index();
change_step(index)
});
function change_step(value)
{
if (value === 0) {
$('#prev').hide();
$('#next').show();
} else if (value === 1) {
$('#prev').show();
$('#next').show();
} else {
$('#next').hide();
$('#prev').show();
}
}
I want to remove and element from an each() loop inside a plugin so I will only return some specific itens. But so far I made many tests and I still cannot remove the item.
(function($){
$.fn.teste = function(parametro){
var parametro_padrao = {};
if (parametro){$.extend(parametro_padrao, parametro);}
return this.each(function(){
//if certain condition happens I want to remove an element so it will not be returned in the "return" clause above
});
};
})(jQuery);
EDIT:
the :hidden or :visible are not good cause they use offset which I believe is a bad idea.
After some time I found a great solution and I will share so others will not lose time as me:
(function($){
$.fn.visivel = function(parametro){
var parametro_padrao = {};
if (parametro){$.extend(parametro_padrao, parametro);}
elemento = this;
this.each(
function(index){
$(this).parents().andSelf().each(
function() {
if ( ($(this).css("display") == "none") || ($(this).css("visibility") == "hidden") ) {
delete elemento[index];
return false;
}
}
);
}
);
return elemento;
};
})(jQuery);
Use filter():
return this.filter(function(){
return mycondition?true:false;
});
Let's say I have many of these in my content div : <cite class="fn">blabla</cite>
How can I check every cite tag's content (in this case: blabla) with class fn to see if it equals to "sometext" then change it's color to red ?
Very simple.
$('cite.fn:contains(blabla)').css('color', 'red');
Edit: though that will match "blablablabla" as well.
$('cite.fn').each(function () {
if ($(this).text() == 'blabla') {
$(this).css('color', 'red');
}
});
That should be more accurate.
Edit: Actually, I think bazmegakapa's solution is more elegant:
$('cite.fn').filter(function () {
return $(this).text() == 'blabla';
}).css('color', 'red');;
You can make use of the amazing .filter() method. It can take a function as its parameter, which will reduce the jQuery collection's elements to those that pass its test (for which the function returns true). After that you can easily run commands on the remaining elements:
var searchText = 'blabla';
$('cite.fn').filter(function () {
return $(this).text() === searchText;
}).css('color', 'red');
jsFiddle Demo
You could potentially do something like:
$('cite.fn').each(function() {
var el = $(this);
if (el.text() === 'sometext') {
el.css({ 'color' : 'red' });
}
});
This fires a function against each cite that has the class fn. That function checks if the current cite's value is equal to 'sometext'.
If it is, then we change the CSS color (text-color) property to red.
Note I'm using jQuery in this example, as you've specifically tagged your question jQuery. Ignore the downvote, this was applied before I edited a typo that I'd made (el.val() rather than el.text())
Without jQuery:
var elms = document.querySelectorAll("cite.fn"), l = elms.length, i;
for( i=0; i<l; i++) {
if( (elms[i].innerText || elms[i].textContent) == "blabla") {
elms[i].style.color = "red";
}
}