casperJS contentDocument selector hiddin in #document - javascript

I am having trouble clicking a selector in casperJS. If I am not mistaken the selector is hidden in a shadow-root.
this.waitForSelector('#tab > ul > li:nth-child(1) > a',function(){
//yields nothing - timeout
});
this.waitForSelector('#tab > ul > li:nth-child(1) > a',x[0].contentDocument,function(){
console.log("found"); //true
});
where var x is var x = this.evaluate(function(){
var selected = $('frameset>frame');
return selected;
});
When I try and click that. this.click('#tab > ul > li:nth-child(1) > a',x[0].contentDocument);nothing happens.
any help would be greatly appreciate it. thanks a lot!

Related

How to keep CSS changes made with Jquery after ajax call or form call

Im trying to hide a couple of payment options on our lightspeed Ecommerce site using Jquery during a set timeframe (Between 18.00 and 24.00) and only for people living in the Netherlands.
Since i cannot alter the file of the checkout page i use document.querySelector("#gui-checkout-shipment-methods > div:nth-child(1) > div") to then alter the css of mentioned div's "display:block" to be set as "display:none".
I tried wrapping the code in ajaxSuccess and ajaxComplete funtion, but it did not change anything.
$( document ).ajaxSuccess(function () {
$.get("https://freegeoip.app/json/", function (response) {
$("#ip").html("IP: " + response.ip);
$("#country_code").html(response.country_code);
var currentTime = new Date().getHours();
if(response.country_code=='NL' && 17 <= currentTime&&currentTime < 24){
document.querySelector("#gui-checkout-shipment-methods > div:nth-child(1) > div").style.display = 'none';
document.querySelector("#gui-checkout-shipment-methods > div:nth-child(2) > div").style.display = 'none';
document.querySelector("#gui-checkout-shipment-methods > div:nth-child(3) > div").style.display = 'none';
document.querySelector("#gui-checkout-shipment-methods > div:nth-child(4) > div").style.display = 'none';
document.querySelector("#gui-checkout-shipment-methods > div:nth-child(5) > div").style.display = 'none';
}
if(response.country_code=='NL' && 24 <= currentTime&&currentTime < 17){
document.querySelector("#gui-checkout-shipment-methods > div:nth-child(1) > div").style.display = 'block';
document.querySelector("#gui-checkout-shipment-methods > div:nth-child(2) > div").style.display = 'block';
document.querySelector("#gui-checkout-shipment-methods > div:nth-child(3) > div").style.display = 'block';
document.querySelector("#gui-checkout-shipment-methods > div:nth-child(4) > div").style.display = 'block';
document.querySelector("#gui-checkout-shipment-methods > div:nth-child(5) > div").style.display = 'block';
}
}, "jsonp");});
It works fine, but as soon as a Ajax form radio-button is clicked, my code stops working. Inspector says: css-change-by-time.js?20190925175433:8 Uncaught TypeError: Cannot read property 'style' of null
This makes sense, since i guess after the ajax call is made, the div that used to be display:block is no longer there, and so it conflicts and throws the error.
I searched the entire day on the internet, but could not find a working solution.
So my actual question is:
How do i apply these changes and how do i make them stick, no matter what happens.
You first see the .html whether it is pointing right div or not. I am using jquery for this.
$("#gui-checkout-shipment-methods > div:nth-child(1) > div").html()
Apply style display block if it is pointing right
$("#gui-checkout-shipment-methods > div:nth-child(1) > div").css('display','block');
apply display none as well
$("#gui-checkout-shipment-methods > div:nth-child(1) > div").css('display','none');
use this for all lines.

jQuery highlight menu item when scrolled over section

I am trying to highlight the menu item when you scroll down to the section.
The highlighting works but for some reason I can't remove the highlighting when scrolled to an other section
This is what my menu looks like:
<div id="navbar">
<ul class="nav navbar-nav">
<li class="active"><a data-id="home" href="#home">Home</a></li>
<li class="navbar-right"><a data-id="cont" href="#contact">Contact</a></li>
<li class="navbar-right"><a data-id="exp" href="#exp">Expertise</a></li>
<li class="navbar-right"><a data-id="wie2" href="#wie2">Wie</a></li>
</ul>
</div>
In the html for every section where I use the id anchor I added class="section"
This is my jQuery:
jQuery(window).scroll(function () {
var position = jQuery(this).scrollTop();
jQuery('.section').each(function() {
var target = jQuery(this).offset().top;
var id = jQuery(this).attr('id');
if (position >= target) {
jQuery('#navbar>ul>li>a').removeClass('clicked');
jQuery('#navbar ul li a[data-id=' + id + ']').addClass('clicked');
}
});
});
Anyone has any idea why the class get deleted everytime? becuase when I comment out jQuery('#navbar>ul>li>a').removeClass('clicked'); it works great. The classes are being added correctly. But removing them doesn't work :(
Havent tested this, but i think this should work
jQuery(window).scroll(function () {
var position = jQuery(this).scrollTop();
jQuery('.section').each(function() {
var target = jQuery(this).offset().top;
var id = jQuery(this).attr('id');
jQuery('#navbar ul li a[data-id=' + id + ']').removeClass('clicked');
if (position >= target) {
jQuery('#navbar ul li a[data-id=' + id + ']').addClass('clicked');
}
});
});
Hard for me to tell exactly what the issue is without being able to dig through the actual code, but you could try updating this line:
jQuery('#navbar>ul>li>a').removeClass('clicked');
to:
jQuery('#navbar').find('clicked').removeClass('clicked');
That way you are for sure going to be removing the class "clicked" from only link that already has the class "clicked" before reassignment.
I would also recommend checking out bootstrap's scrollspy feature. It sounds like it does what you are trying to achieve. You could either try implementing it instead, or digging into their code and see how they are approaching it and learn something new.
http://getbootstrap.com/javascript/#scrollspy
Hope this helps!
I think because: #navbar>ul>li>a is not the same as #navbar ul li a
The first is trying to find direct <ul> child to #navbar and the second is asking to find a <ul> child (at any level) under #navbar and the same goes for the rest of the selector.
Have a look here
The child combinator (E > F) can be thought of as a more specific form
of the descendant combinator (E F) in that it selects only first-level
descendants.
I think the problem is that position >= target only adds the active class if the user has scrolled below the top of the section, so this will add the class even if the user has scrolled beyond the entire section.
Change
if (position >= target)
to
if (position >= target && position < target + $(this).height())
appears to solve the problem.
hi with small change it worked without any issues
jQuery(window).scroll(function () {
var position = jQuery(this).scrollTop();
var classSet = 0;
jQuery('.section').each(function() {
var target = jQuery(this).offset().top;
var id = jQuery(this).attr('id');
if (classSet == 0)
jQuery('#navbar ul li a[data-id=' + id + ']').removeClass('clicked');
if (position >= (target - 200) && position < target + $(this).height()) {
jQuery('#navbar ul li a[data-id=' + id + ']').addClass('clicked');
classSet = 1;
}
});
});

Hide div if the ul is empty

Here is my html,
<div id="personaldetails">
<ul>
<li class="clear"></li>
</ul>
<ul>
<li class="clear"></li>
</ul>
</div>
I want to hide div personaldetails when all the ul inside in div is empty.
If the ul is having element <li class="clear"></li> then the ul is considered as to be empty.
How to do this using Jquery ?
You can try this:
$('#personaldetails').find('ul').each(function(){
var txt = $("li", this).text();
if(txt.length <= 0){
$(this).hide();
}
});
if(!$('#personaldetails').find('ul:visible').length){
$('#personaldetails').hide();
}
Updated Fiddle
And to me you should hide all ul, if no ul are visible then you can hide the #personaldetails div.
Even one of answer is already accepted, I think it can be simple as:
if($.trim($("#personaldetails").text()) == '') {
$("#personaldetails").hide();
}
:)
Take a look at that code:
function foo(){
var all_li_clear = true;
$("#personaldetails > ul > li").each(function(){
if(!$(this).hasClass("clear")){
all_li_clear = false;
break; // No need to continue now
}
});
if(all_li_clear){
$("#personaldetails").hide();
}
}
You can see a fiddle example there, just comment and discomment foo(); line.
Javascript solution:
This will only hide the div if all li have clear class
$(function() {
emptyLi = $('#personaldetails ul li').filter(function(){
/*if($(this).hasClass('clear')){
return true;
}else{
return false;
}*/
return $(this).hasClass('clear');
}).length;
if($('#personaldetails ul li').length == emptyLi){
$('#personaldetails').css('display','none');
}
});
CSS:
This will hide the li with class clear, so if you not fixed height of ul or li and don't have padding , margin given to ul,li your div personaldetails will get hidden automatically when all li element have class clear
#personaldetails ul li.clear{
display:none;
}
-UPDATED-
You can use following code if you are deciding empty class based on clear class.
if($("#personaldetails ul li:not(.clear)").length == 0) {
$("#personaldetails").hide();
}
Or if you are looking for the empty div then you can just use the shortest code given by #Samiul Amin Shanto Like:
if($.trim($("#personaldetails").text()) == '') {
$("#personaldetails").hide();
}
Explanations
Method1:
$("#personaldetails ul li:not(.clear)")
This code find all li without the clear class. Then if no such li found, just hide the div. Fiddle
Method2:
$("#personaldetails").text() this code return innerHTML text striping all html tags. So no meter what the div contain ul, li or anything else, this will return the plain text content of the div, then striping any white space we can determine if the div is empty. If your intention is to hide the empty div not hiding the div which contain empty Ul this should be your choice.
This asumes that if you have the same amount of li's with the class clear, as there are ul's, they're all empty
var $wrapper = $('#personaldetails');
if( $wrapper.find('ul').length=== $wrapper.find('li.clear').length){
$wrapper .hide();
}
Everybody's fiddling examples :)
$(function($) {
$cnt = 0;
$('.personalDetails ul li').each(function() {
if($(this).hasClass('clear')) $cnt++;
});
if($('.personalDetails ul li').length == $cnt) $('.personalDetails').hide();
});
$("ul li:empty").closest('div#personaldetails').hide();
Sample Code
#personaldetails ul li.clear{
visibility:hidden;
}

jQuery selecting top level element text

I have a menu that has the section Store this has a submenu of categories Printers Keyboards and under these categories they have their own sub categories.
What I am trying to do is select the top level categories that are Printers Keyboards just using jQuery into an Array.
When I use the following it prints out ["Printers", "Color", "Black/White", "Dual", "Keyboards", "Wired", "Wireless", "Touchscreen"] This is more than I need for now, could someone help me
Check out my jsFiddle
jQuery
var optionTexts = [];
$('.main-menu ul li a:contains("Store")').parent().find('.sub-menu > li a').each(function(){
optionTexts.push($(this).text());
});
console.log(optionTexts);
EDIT I looked at your fiddle a bit more closeley and changed the way the right "a" tag is found:
'.sub-menu > li > ul > li > a' will do it (I checked it in your jsfiddle):
$('.main-menu ul li a:contains("Store")').parent().find('.sub-menu > li > ul > li > a').each(function(){
optionTexts.push($(this).text());
});
The way you did it, every a underneath the "ul.sub-menu" is selected - also those that are nested in children and grandchildren of "ul.sub-menu".
Hope you are looking for something like this
var optionTexts = [];
$('.main-menu ul li a:contains("Store")').parent().find('.sub-menu').parent('li').each(function(){
optionTexts.push($(this).children('a').text());
});
console.log(optionTexts);
I Edit your code like this, its worked :
$(function () {
$(".check").on('click', function () {
var optionTexts = [];
$('.list > ul > li > a').each(function () {
optionTexts.push($(this).text());
});
c(optionTexts);
});
});
output : Printers, Keyboards
Check it FIDDLE : http://jsfiddle.net/mehmetakifalp/Mkv9q/16/

Determine if a UL has 1 or more LI within

How can I use JavaScript to determine if a UL contains 1 or more LI's within?
Pseudo code
if('ul#items' has >= 1 LI){
Thanks,
With jQuery:
$('ul#items li').length >= 1
Without jQuery:
document.getElementById('items').getElementsByTagName('li').length >= 1
With jQuery:
if( $('#items li').length >= 1 ){...
Use document.getElementById("items").childNodes.length and a number comparison operator. If your ul does contain other nodes than li, you will have to filter them.
In jQuery:
$("#items").children("li").length
I guess you only want direct children, so don't use find().
if ($('ul#items').children('li').length) {
// etc.
}
You can use:
$('ul#items li').length
If you're using jQuery
if($('ul > li').size()>0) {
}
That will check that the UL element has more than 0 direct child li elements.
if ($('ul#items > li').length >= 1)

Categories

Resources