I have not been able to figure out why jQuery applies the desired new class to body making the first condion always true regarless of different conditions.
The HTML contains these different tags:
<h1 class="entry-title">Intro Audios</h1>
<h1 class="entry-title">Level 1 Audios</h1>
<h1 class="entry-title">Level 2 Audios</h1>
<h1 class="entry-title">Level 3 Audios</h1>
16 pages to be exact contain the h1 tag first aboeve, another 16 contain the h1 tag above and so on.
But no matter what page I visit the added class to the body tag is always "Level-1"
<script>
jQuery(document).ready(function($){
var level1 = $("h1.entry-title:contains(Level 1)");
var level2 = $("h1.entry-title:contains(Level 2)");
var level3 = $("h1.entry-title:contains(level 3)");
if ( level1)
{
$(document.body).addClass('level-1');
} else if (level2 )
{
$(document.body).addClass('level-2');
} else if (level3 )
{
$(document.body).addClass('level-3');
} else
{
$(document.body).addClass('intro');
}
});
</script>
What am I doing wrong?
Try this fiddle, https://jsfiddle.net/djkk8yrg/
Check the console where level1 and level2 vars are logged and there is no corresponding html code for level1
They return:
[prevObject: jQuery.fn.init[1]]
[h1.entry-title, prevObject: jQuery.fn.init[1]]
Even though level1 element is not there in the html, it just returns a prevObject. Add additional logic to confirm that it's not only prevObject which is returned.
What I was trying to do was to be able to add a class to the body tag depending on the condition that a particular wordpress category exists or not. If it exist add the class to body tag so I can stylize each of those pages differently according to new body class.
After trying and testing different answers and codes for a while I found a solution that woks and it is this:
<script>
jQuery(document).ready(function($){
var intro = $( "article" ).hasClass( "category-level-intro" );
var level_1 = $( "article" ).hasClass( "category-level-1" );
var level_2 = $( "article" ).hasClass( "category-level-2" );
var level_3 = $( "article" ).hasClass( "category-level-3" );
// check to see if the condition is true
if(intro === true)
{
$(document.body).addClass('intro');
} else if (level_1 === true)
{
$(document.body).addClass('level-1');
} else if (level_2 === true)
{
$(document.body).addClass('level-2');
} else if (level_3 === true )
{
$(document.body).addClass('level-3');
} else {
$(document.body).addClass('');
}
});
</script>
Thanks!
Related
this is my first post on StackOverflow. I hope it doesn't go horribly wrong.
<input type="Text" id="filterTextBox" placeholder="Filter by name"/>
<script type="text/javascript" src="/resources/events.js"></script>
<script>
$("#filterTextBox").on("keyup", function () {
var search = this.value;
$(".kurssikurssi").show().filter(function () {
return $(".course", this).text().indexOf(search) < 0;
}).hide();
});
</script>
I have a javascript snippet like this on my school project, which can be found here: http://www.cc.puv.fi/~e1301192/projekti/tulos.html
So the search bar at the bottom is supposed to filter divs and display only those, that contain certain keyword. (t.ex, if you type Digital Electronics, it will display only Divs that contain text "Digital Electronics II" and "Digital Electronics". Right now, if I type random gibberish, it hides everything like it's supposed to, but when I type in the beginning of a course name, it will not hide the courses that dont contain the certain text-string.
Here is an example that I used (which works fine): http://jsfiddle.net/Da4mX/
Hard to explain, but I hope you realize if you try the search-function on my page. Also, I'm pretty new to javascript, and I get the part where you set the searchbox's string as var search, the rest I'm not so sure about.
Please help me break down the script, and possibly point where I'm going wrong, and how to overcome the problem.
in your case I think you show and hide the parent of courses so you can try
$("#filterTextBox").on("keyup", function () {
var search = $(this).val().trim().toLowerCase();
$(".course").show().filter(function () {
return $(this).text().toLowerCase().indexOf(search) < 0;
}).hide();
});
Try this this is working now, paste this code in console and check, by searching.
$("#filterTextBox").on("keyup", function () {
var search = this.value; if( search == '') { return }
$( ".course" ).each(function() {
a = this; if (a.innerText.search(search) > 0 ) {this.hidden = false} else {this.hidden = true}
}); })
Check and the search is now working.
Your problem is there :
return $(".course", this)
From jquery doc: http://api.jquery.com/jQuery/#jQuery-selection
Internally, selector context is implemented with the .find() method,
so $( "span", this ) is equivalent to $( this ).find( "span" )
filter function already check each elements
then, when you try to put $(".course") in context, it will fetch all again...
Valid code :
$("#filterTextBox").on('keyup', function()
{
var search = $(this).val().toLowerCase();
$(".course").show().filter(function()
{
return $(this).text().toLowerCase().indexOf(search) < 0;
}).hide();
});
In fact, you can alternatively use :contains() CSS selector,
but, it is not optimized for a large list and not crossbrowser
http://caniuse.com/#search=contains
You were accessing the wrong elements. This should be working:
$(".kurssikurssi").find('.course').show().filter(function () {
var $this = $(this)
if($this.text().indexOf(search) < 0){
$this.hide()
}
})
If we have a collapsible panel initially defined like this
<div id="ContactDetails" class="panel-collapse collapse">
How can I test to see if it is open or closed via JavaScript?
Thanks
You can get the class list in that element (in your case div id = "ContactDetails").
var classList = document.getElementById('ContactDetails').className.split(/\s+/);
for (var i = 0; i < classList.length; i++) {
if (classList[i] === 'collapse') {
//do something
}
}
You can then browse through your classList[] if one of it is equal to "collapse".
Pure Javascript way:
var classList =$('#ContactDetails').attr('class').split(/\s+/);
$.each( classList, function(index, item){
if (item === 'collapse') {
//do something
}
});
With JQuery.hasClass:
$( "#ContactDetails" ).hasClass( "panel-collapse" )
#Jocksan was close, except that the panel will always have the "panel-collapse" class (as #gchq found). When it is opened the "in" class is added, and when it is closed the "in" class is removed. So this will return true for open, false for closed:
$( "#ContactDetails" ).hasClass( "in" )
Here is more about the classes and how it all works: http://getbootstrap.com/javascript/#collapse-example-accordion
I'm creating a site that has a status bar that updates its innerHTML depending on what is mouseovered by the user. The function that does this has a bunch of if statements in it but if the if statement finds that the conditions don't exist it throws alot of errors. For example: I have an if statement that checks what the id is of the element 3 parent elements above a child element like this: if( element.parentElement.parentElement.parentElement.id == 'body' ). But because i'm using one function this if statement throws the error 'Uncaught TypeError: Cannot read property 'parentElement' of null' when the element doesnt meet that condition. My question: Is there a way to first check if the if statement is even going to work before i use it? This might sound dumb but It seems thats the only way to avoid the errors unless I use multiple functions - which I don't want. My code is below and heres a JS BIN of a very simplified version of my program: http://jsbin.com/hefotifopo/1/edit ( open the console to see my errors ).
<html>
<body>
<header id = "header" onmouseover = "statusSet( this )">
<p>Header</p>
</header>
<section id = "body">
<div id = "area1">
<div>
<p id = "p1" onmouseover = "statusSet( this )">
paragraph
</p>
<p id = "p2" onmouseover = "statusSet( this )">
paragraph
</p>
<p id = "p3" onmouseover = "statusSet( this )">
paragraph
</p>
</div>
</div>
</section>
<footer><p id = "statusBar">Status Bar</p></footer>
<script>
document.body.addEventListener( 'mouseover', function( element ){
statusSet( element.target );
});
function statusSet( element ){
var elementId = element.id;
var elementInner = element.innerHTML;
if( elementId == 'body' || elementId == 'statusBar' ){
document.getElementById( 'statusBar' )
.innerHTML = 'hovering over body';
}
else if( element.parentElement.parentElement
.parentElement.id == 'body' ){
document.getElementById( 'statusBar' )
.innerHTML = 'hovering over paragraphs';
}
else if( element.id == 'header' ){
document.getElementById( 'statusBar' )
.innerHTML = 'hovering over header';
}
}
</script>
</body>
</html>
Just check each reference:
else if (element.parentElement && element.parentElement.parentElement && element.parentElement.parentElement && element.parentElement.parentElement.parentElement.id == "body")
It would really be better to work out a less fragile way of determining what's going on, for example by giving elements classes to distinguish their differing natures. Relying on the document structure like that means that you'll have to update your JavaScript if you make minor changes to the document.
I want to click all buttons on a page that have the attribute data-capture='noiseClicked'
This is my code so far:
javascript: (function() {
var followButtons = $("li.js-profile-card button[data-capture='noiseClicked']");
var index = followButtons.length - 1;
follow();
function follow() {
if (index >= 0) {
$(followButtons[index--]).click();
setTimeout(follow, 1);
}
}
})();
However I want to exclude buttons that have a parent of li.noise--active or li.friend--active
So the following would be clicked:
<li class="js-profile-card noise--active"><button data-capture="noiseClicked" type="button"></button></li>
but the following would not be clicked...
<li class="js-profile-card noise--active"><button data-capture="noiseClicked" type="button"></button></li>
or
<li class="js-profile-card friend--active"><button data-capture="noiseClicked" type="button"></button></li>
I thought that jquery's not selector would be helpful here, but I'm not sure how to use it to exclude a parent element with a specific attribute and I don't know how to exclude two different attributes (noise--active and friend--active)
Thanks.
You can use parent & hasClass methods for this:
var indexToSet = index--;
if( !$(followButtons[indexToSet]).parent().hasClass( 'noise--active' ) && !$(followButtons[indexToSet]).parent().hasClass( 'friend--active' )) {
$(followButtons[indexToSet]).click();
}
EDIT:
to travel up in the node list better to use closest() method:
var indexToSet = index--;
if( !$(followButtons[indexToSet]).closest( 'noise--active' ).length && !$(followButtons[indexToSet]).closest( 'friend--active' ).length ) {
$(followButtons[indexToSet]).click();
}
:not selector might come handy:
var followButtons = $("li.js-profile-card:not(.noise--active,.friend--active) button[data-capture='noiseClicked']");
Lets say I have a webpage, and all I'm interested is the div with id "content", i.e:
<div id="content"></div>
How do I remove all the other div elements, and just display the div I want?
var all_div_nodes = document.querySelectorAll('div'),
len = all_div_nodes.length,
current = null;
while( len-- ) {
current = all_div_nodes[len];
if( current.parentNode ) {
if( current .id !== 'content' )
current .parentNode.removeChild( current );
}
}
If you can afford using a library like jQuery, this would be even more trivial:
$('div').not('#content').remove();
If you want to remove the sibling DIVs, using jQuery, you can write:
$("#content").siblings("div").remove();