I've run into a little something that I can't figure out and I was wondering if you could have a go at it.
First off, there's this code:
<li class="mc002">
<ul>
<li>
<div class="label-container">
<a class="btn">label 1</a>
<a class="btn">label 2</a>
</div>
<div class="main-container">
<div class="prj-title">
<h3>New design for my website</h3>
<div class="buttons">
<button data-role="none" class="btn smry">summary</button>
</div>
</div>
<div class="summary">
</div>
<div class="prj-footer">
<h6>filed under:</h6>
<span>webdesign, webdevelopment, UX design</span>
<h6>skills:</h6>
<span>html5, css3, javascript, php</span>
</div>
</div>
</li>
and the JavaScript to make "summary" slide down:
$('.main-container .smry').click(function () {
$(this).closest(".summary").slideToggle(100);
});
The problem with this is that it doesn't work. Can you help me out, please?
The .closest() method doesn't find siblings or cousins, it starts with the current element (.smry, in your case) and goes up through the ancestors, stopping when it finds a match (or returning an empty jQuery object if there is no match).
Try this instead:
$('.main-container .smry').click(function () {
$(this).closest(".main-container").find(".summary").slideToggle(100);
});
This navigates up to the closest containing .main-container element and then uses .find() to go back down to its associated .summary element.
Demo: http://jsfiddle.net/4a8JC/
Note that your code would need to be in a document ready handler and/or in a script block that appears after the elements in question.
(Note also that your summary div would need to have some actual content for this to make sense.)
I'll suggest to use just $(".main-container .summary") instead of closest. It's a little bit heavy operation. And do you have something in .summary. If it is an empty I don't think that you will see something.
Related
I have the following HTML code:
<div class="pack1">
<a class="optionButton">First option</a>
<a class="optionButton">Second option</a>
<a class="optionButton">Third option</a>
</div>
<div class="pack2">
<a class="optionButton">First option</a>
<a class="optionButton">Second option</a>
<a class="optionButton">Third option</a>
</div>
<div class="pack3">
<a class="optionButton">First option</a>
<a class="optionButton">Second option</a>
<a class="optionButton">Third option</a>
</div>
[...]
<div class="pack10">
<a class="optionButton">First option</a>
<a class="optionButton">Second option</a>
<a class="optionButton">Third option</a>
</div>
Using jQuery I would like to trigger an event on clicking the a tag with the optionButton class but I don't know how to limit the event to the div that the a tag resides in.
For example right now I have something like:
$(document).ready(function(){
$('.optionButton').click(function() {
$(".optionButton").removeClass('checked');
$(this).addClass('checked');
});
});
It works fine for the first selection, lets say when I click the First option in the pack1 div, but if I make another selection, lets say Third option in the pack3 div, the first one will disapear.
Also, there must be only one selected option for each pach.
You need to narrow down the selection of your removeClass, as right now it's selecting every occurrence of optionButton.
$(document).ready(function(){
$('.optionButton').click(function() {
$(this).siblings('.optionButton').removeClass('checked');
$(this).addClass('checked');
});
});
This will narrow it down by selecting siblings of the clicked element that have the class optionButton.
JSFiddle
EDIT: Woops, put the wrong class in there. Should be patched up now.
Because exact DOM structure is highly subject to change, your best bet is to almost always go to the parent and search your way down like so:
1) $(this).parent().find(".optionButton").removeClass("checked");
or you can simplify the selector results set (and make your code slightly more efficient) by saying:
2) $(this).parent().find(".checked").removeClass("checked");
You can also use the selector context parameter like so:
3) $(".checked", $(this).parent()).removeClass("checked");
The difference between 2 and 3 is purely syntactic. jQuery will convert 3 into 2 behind the scenes
I think this could work
$(document).ready(function(){
$('.optionButton').click(function() {
var parent = $(this).closest("div");//getting the parent content
parent.find(".optionButton").removeClass('checked');//remove the checked
$(this).addClass('checked');
});
});
I'm brand new to javascript/jquery, but have been going okay so far (though you'd hate to see my code), but I've hit a wall with trying to strip out style tags from some HTML I'm trying to clone.
The reason for cloning is that the CMS I'm forced to use (which I don't have access to code behind, only able to add code over the top) automatically builds a top nav, and I want to add a duplicate sticky nav once the user scrolls, but also add a couple of elements to the scrolled version.
The original HTML of the top nav looks a bit like like:
<nav id="mainNavigation" style="white-space: normal; display: block;">
<div class="index">
Participate
</div>
<div class="index" style="margin-right: 80px;">
News
</div>
<div class="index active" style="margin-left: 80px;">
<a class="active" href="/about/">About</a>
</div>
<div class="external">
Collection
</div>
<div class="index">
Contact
</div>
</nav>
I had mild success (other than those style tags I want to remove) with the following, even though it doesn't seem to make sense to me, as I expected some of the elements would be repeated (the whole < nav >…< /nav > tag should have been within the #mainNavigation clone, no?):
var originalNavItems = $('#mainNavigation').clone().html();
$("#site").prepend('
<div id="ScrollNavWrapper">
<div class="nav-wrapper show-on-scroll" id="mainNavWrapper">
<nav id="newScrolledNav" style="white-space: normal; display: block;">
<div class="index home">
Home
</div>
' + originalNavItems + '
<div class="newItem">
<a href="http://www.externalsite.com">
View on External Site
</a>
</div>
</nav>
</div>
</div>');
I've tried to use a few answers from related questions on here, but I keep getting incorrect results. Can you help me?
You can strip the style elements like so:
var el = $('#mainNavigation'); // or whatever
el.find('[style]').removeAttr('style');
You can use
var originalNavItems = $('#mainNavigation').clone().find("*").removeAttr("style");
Then you can use .append() to add that html elements
Fiddle
You can clone into an imaginary div and then fetch the mainNavigation also. You can also remove the style attributes along with that. Hope this works for you...
var temp = $('<div />').html($('#mainNavigation').clone());
temp.find('*').removeAttr('style');
originalNavItems = temp.html();
The nav is cloned but the html() function only returns the HTML for the contents and that's why it disappears. You can avoid some string manipulation by adding the cloned element directly before a target element.
$("#site").prepend('
<div id="ScrollNavWrapper">
<div class="nav-wrapper show-on-scroll" id="mainNavWrapper">
<nav id="newScrolledNav" style="white-space: normal; display: block;">
<div class="index home">
Home
</div>
<div class="newItem">
<a href="http://www.externalsite.com">
View on External Site
</a>
</div>
</nav>
</div>
</div>');
$('#mainNavigation').clone()
.find('[style]').removeAttr('style').end()
.insertBefore('#newScrolledNav .newItem');
In the previous case find('[style]') matches elements that have a style attribute.
I'm new to Stack Overflow (and js in general), so this might be really bad ettiquette, but I seem to have accidentally fixed it myself trying to debug my implementation of the first upvoted answer that #Anoop Joshi gave above. Please comment and let me know if it would have been better to just edit my question!
I decided to break the process down into separate steps – similar to #Kiran Reddy's response actually, but I hadn't got to trying his yet.
I tried:
var styledHTML = $('#mainNavigation').clone();
styledHTML.find("div[style]").removeAttr('style');
var originalNavItems = styledHTML.html();
$("#site").prepend('<div… etc.
with a console.log(styledHTML) etc under each line to check what I had at each stage – and it worked! (The code did, console.log didn't?)
I was just doing this to try and log the value of the variables at each stage, but whatever I did fixed it…
Now I need to figure out why I can't even make console.log(variable); work :-/
Try this code
$('#mainNavigation').children().removeAttr('style');
Hope this will help you.
<div class="base-view app-loaded" data-ng-class="cssClass.appState">
<div class="ng-scope" data-ng-view="">
<div class="ng-scope" data-ng-include="'partial/navigation/navigation.tpl.html'">
<div class="feedback-ball feedback-ball-show feedback-ball-big" data-ng-class="feedback.cls" data-ng-click="outside($event)" data-feedback-ball="">
<span class="close-button"></span>
<h2 class="ng-binding">Welcome to Garbo</h2>
<div class="ng-scope ng-binding" data-ng-bind-html="feedback.html" data-ng-if="feedback.html">
<p>Here you can play in style in a safe and secure environment.</p>
<p>
<a class="btn" href="/account">My Account</a>
<a class="btn" href="/deposit">Deposit</a>
</p>
</div>
</div>
</div>
I want to find and click /account button inside data-ng-bind-html="feedback.html", I can find data-ng-bind-html="feedback.html" but I could not find account button inside it. when I try to find account button, it gives me error that page has multiple account button so be more specific.
I tried element.().element() but it didnt work, please help
The problem is that webDriver is finding more than one element that matches. You have element for finding just one, and element.all for taking an array of elements, then you can use .get() and the index of the element, or first() or last(). You can do,
element(by.css('[data-ng-bind-html="feedback.html"]')
.element(by.cssContainingText('.btn', 'My account'));
If it doesn't work then you might have more than one, if so, you can use,
element(by.css('[data-ng-bind-html="feedback.html"]')
.all(by.cssContainingText('.btn', 'My account')).first();
But there you will have more than one button in your HTML, webDriver will get only one,
another thing, is to use the count() that gives you the length of the array of elements, and you can know how much you have.
element calls can be chained to find elements inside other elements, so your element().element() solution should work.
Alternatively, you can construct an xpath expression to reach the link inside the appropriate div:
element(by.xpath('//div[#data-ng-bind-html = "feedback.html"]//a[#href = "/account"]'))
I have a few elements flying around in an element that need to be altered when the window finishes loading ($(window).load...)
When the script loads, I've been struggling to find a more elegant way of finding a string.
Noticeably below, you can also see the rampant re-use of parent and next operators...
I've tried closest but it only goes up the dom tree once (from what I understand) and parents has never really worked for me, but I could be using it wrong.
Ex.
$(window).load( function(){
if($(".postmetadata:contains('Vancity Buzz')").length){
$(this).parent().parent().next().next().next().next('.articleImageThumb img').hide();
}
});
HTML output this runs through looks like this:
<div class="boxy">
<div class="read">
<div class="postmetadata">Vancity Buzz</div>
<div class="articleTitle"></div>
</div>
<div class="rightCtrls"></div>
<div class="initialPostLoad"></div>
<div class="ajaxBoxLoadSource"></div>
<div class="articleImageThumb">
<a href="#">
<img src="image.png" class="attachment-large wp-post-image" alt=""/>
</a>
</div>
</div>
I think you want to do this:
$(".postmetadata:contains('Vancity Buzz')")
.closest('.read') //Closest will get you to the parent with class .read
.siblings('.articleImageThumb').hide(); //this will get you all the siblings with class articleImageThumb
this refers to window there not the element you are checking in the if condition.
Fiddle
I don't know if your intention is to have the empty anchor tag just by hiding the image. if so just add a find to it.
You can just do this
$('.articleImageThumb img').toggle($(".postmetadata:contains('Vancity Buzz')").length)
If there are multiple divs and you do need to traverse then there are multiple ways
$(".boxy:has(.postmetadata:contains('Vancity Buzz'))").find('.articleImageThumb img').hide()
or
$('.postmetadata:contains("Vancity Buzz")').closest('.boxy').find('.articleImageThumb img').hide()
or
$(".boxy:has(.postmetadata:contains('Vancity Buzz')) .articleImageThumb img").hide()
Have you looked into parents http://api.jquery.com/parents/ you can pass a selector like so:
$(this).parents('.boxy').find(".articleImageThumb")
Careful though, If there is a parent boxy to that boxy, parents() will return it and thus you find multiple .articleImageThumb.
I can't figure out how to reach a nested div from the outer most element. Here is the html:
<li id="slide1">
<div id="video-container">
<div id=video-holder><div id="thumbnail"></div></div>
<div id=video-title></div>
<div id=video-desc></div>
</div>
</li>
I need jquery that will reach the id thumbnail from the starting id of the slide1
Use find to get the descendant.
$("#slide1").find("#thumbnail")
Basically since it is id you can just do: as id is supposed to be unique no matter where it appears.
$("#thumbnail");
For your scenario you want to use startswith selector to select the dynamic id starts with video_fake and in the 5th
slide.
$('#slide5fake').find('[id^=video_fake]').attr('id', 'newId')
$("#slide1").find("#thumbnail")
try this
<li id="slide1">
<div id="video-container">
<div id=video-holder><div class="thumbnail"></div></div>
<div id=video-title></div>
<div id=video-desc></div>
<div id="video-container">
<div id=video-holder><div class="thumbnail"></div></div>
<div id=video-title></div>
<div id=video-desc></div>
</div>
</li>
<script type="text/javascript">
$('#slide1').find('.thumbnail').each(function(){ });//you can get here two thumbnail
</script>
$("#thumbnail")
will find the thumbnail directly, but I suspect the id for your thumbnail will be repeated down the page, so you really need to be searchind for a class.
$("#slide1.thumbnail")
will do that if you change this line
<div id=video-holder><div id="thumbnail"></div></div>
to this
<div id=video-holder><div class="thumbnail"></div></div>
In case there are more "thumbnails" on your page, it would be better to give it a class. Ids should be unique.
In your given case, it would be sufficient to get it by ID
document.getElementById("#thumbnail")
If you gave it a class
document.querySelector("#slide1 .thumbnail")
would get you the element.
In jQuery the equivalent would be:
$("#slide1").find(".thumbnail");
There are many ways you can do this...
Single selector:
$('#slide1 #thumbnail');
If you already have the slide element:
var slide = document.getElementById("slide1");
// and then:
$('#thumbnail', slide);
Doing a .find() on the #slide1 element
$("slide1").find("#thumbnail");
But since you're using an ID it doesn't make sense to do anything else but finding that single ID, since you shouldn't have more than one element on a page with the same ID
$("#thumbnail");
There are probably more ways.. and what the best method is depends a lot on what you're doing and what the context is...
Good luck