How to simplify this code below? - javascript

I'd like to simplify this javascript code,
but I don't have ability to do this,
plz help me, I will really appreciate it, thank you very much!
$(function() {
$("#show1").click(function() {
$("#showmore1").toggle();
})
$("#show2").click(function() {
$("#showmore2").toggle();
})
$("#show3").click(function() {
$("#showmore3").toggle();
})
})
[2016/05/24] Here is my complete code, https://jsfiddle.net/o970b9cn/
sorry for my missing information.
I'd like to show many reviews, but it will hide the complete information first, when the user clicks on the button, to start the full text.
I tried the answer below yesterday, but it still can not run...sorry for my insufficient ability...

Give common class to each "show<your_id>". e.g. showmore
give some attribute to your element like data-showid, which contains id of toggle element.
For class "showmore", write click function
Like this
<a id="show1" class="showmore" data-showid="showmore1" >show more</a>
<a id="show2" class="showmore" data-showid="showmore2" >show more</a>
<a id="show3" class="showmore" data-showid="showmore3" >show more</a>
<script>
$(function() {
$(".showmore").click(function() {
var this_button = $(this);
$("#"+this_button.attr("data-showid")).toggle();
})
})
</script>

Use Attribute Starts With Selector [name^=”value”]
Selects elements that have the specified attribute with a value beginning exactly with a given string.
$(function() {
$("a[id^='show']").click(function() {
$(this).prev('div').find('span[id^="showmore"]').toggle();
});
});
$(function() {
$("a[id^='show']").click(function() {
$(this).prev('div').find('span[id^="showmore"]').toggle();
});
});
#import url(http://fonts.googleapis.com/earlyaccess/notosanstc.css);
#import url(http://fonts.googleapis.com/earlyaccess/cwtexyen.css);
#import url(https://fonts.googleapis.com/css?family=Nunito:300);
*,
html,
body {
/*font-family: 'Noto Sans TC', 'Nunito', sans-serif;
font-weight: 300;*/
font-family: 'cwTeXYen', 'Nunito', sans-serif;
font-weight: lighter;
font-size: 16px;
letter-spacing: .2pt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="parents_reviews" style="background: #fff; width: 300px; text-align: center; padding: 15px 20px; border-radius: 25px;">
<div style="color: #6bc4ea; font-size: 15px;">Two more earthquakes hit this month. They are not as bad, however. Only one person dies.Someone films the streets when the earthquakes hit. People are scared. They run in the streets.<span id="showmore1" style="display: none; font-size: 15px;">Difficult words: earthquake (when the ground moves), damage (to break), infrastructure (the roads, power supplies, and buildings that people need)</span>
</div>
(read more)
</div>
<div class="parents_reviews" style="background: #fff; width: 300px; text-align: center; padding: 15px 20px; border-radius: 25px; margin-top: 30px;">
<div style="color: #6bc4ea; font-size: 15px;">Two more earthquakes hit this month. They are not as bad, however. Only one person dies.Someone films the streets when the earthquakes hit. People are scared. They run in the streets.<span id="showmore2" style="display: none; font-size: 15px;">Difficult words: earthquake (when the ground moves), damage (to break), infrastructure (the roads, power supplies, and buildings that people need)</span>
</div>
(read more)
</div>
<div class="parents_reviews" style="background: #fff; width: 300px; text-align: center; padding: 15px 20px; border-radius: 25px; margin-top: 30px;">
<div style="color: #6bc4ea; font-size: 15px;">Two more earthquakes hit this month. They are not as bad, however. Only one person dies.Someone films the streets when the earthquakes hit. People are scared. They run in the streets.<span id="showmore3" style="display: none; font-size: 15px;">Difficult words: earthquake (when the ground moves), damage (to break), infrastructure (the roads, power supplies, and buildings that people need)</span>
</div>
(read more)
</div>
Fiddle Demo

You can use each, simply you will iterate the function on each element that has the same attribute, in this case we will use class because the id should be unique.
We will give to each container (#show1 #show2 ...) a class such show and make this function https://jsfiddle.net/sL3qk853/
$('.show').each(function (index, elem) {
$(elem).on('click', function () {
$(this).find('div[id^="showmore"]').toggle();
});
});
If you have more than a div in the container you can specify the selected div by using begin with selector ( div[attribute^="something"] ) with a find , or just use children if you have a one div or want to make this on all the divs inside the .show container $(this).children().toggle(); .
Edit: instead of using class and each you can do this
$('div[id^="showCont"]').on('click', function () {
$(this).children().toggle();
});
div {
width: 100px;
height: 100px;
background-color: #eee;
margin: 1px;
float: left
}
div[id^="showmore"] {
background-color: #3498db;
float: left
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="showCont1">
<div id="showmore1">
</div>
</div>
<div id="showCont2">
<div id="showmore2">
</div>
</div>
<div id="showCont3">
<div id="showmore3">
</div>
</div>

Related

radio button having multiple forms with style [duplicate]

Is it possible to apply a css(3) style to a label of a checked radio button?
I have the following markup:
<input type="radio" id="rad" name="radio"/>
<label for="rad">A Label</label>
What I was hoping is that
label:checked { font-weight: bold; }
would do something, but alas it does not (as I expected).
Is there a selector that can achieve this sort of functionality? You may surround with divs etc if that helps, but the best solution would be one that uses the label ''for'' attribute.
It should be noted that I am able to specify browsers for my application, so best of class css3 etc please.
try the + symbol:
It is Adjacent sibling combinator. It combines two sequences of simple selectors having the same parent and the second one must come IMMEDIATELY after the first.
As such:
input[type="radio"]:checked+label{ font-weight: bold; }
//a label that immediately follows an input of type radio that is checked
works very nicely for the following markup:
<input id="rad1" type="radio" name="rad"/><label for="rad1">Radio 1</label>
<input id="rad2" type="radio" name="rad"/><label for="rad2">Radio 2</label>
... and it will work for any structure, with or without divs etc as long as the label follows the radio input.
Example:
input[type="radio"]:checked+label { font-weight: bold; }
<input id="rad1" type="radio" name="rad"/><label for="rad1">Radio 1</label>
<input id="rad2" type="radio" name="rad"/><label for="rad2">Radio 2</label>
I know this is an old question, but if you would like to have the <input> be a child of <label> instead of having them separate, here is a pure CSS way that you could accomplish it:
:checked + span { font-weight: bold; }
Then just wrap the text with a <span>:
<label>
<input type="radio" name="test" />
<span>Radio number one</span>
</label>
See it on JSFiddle.
I forget where I first saw it mentioned but you can actually embed your labels in a container elsewhere as long as you have the for= attribute set. So, let's check out a sample on SO:
* {
padding: 0;
margin: 0;
background-color: #262626;
color: white;
}
.radio-button {
display: none;
}
#filter {
display: flex;
justify-content: center;
}
.filter-label {
display: inline-block;
border: 4px solid green;
padding: 10px 20px;
font-size: 1.4em;
text-align: center;
cursor: pointer;
}
main {
clear: left;
}
.content {
padding: 3% 10%;
display: none;
}
h1 {
font-size: 2em;
}
.date {
padding: 5px 30px;
font-style: italic;
}
.filter-label:hover {
background-color: #505050;
}
#featured-radio:checked~#filter .featured,
#personal-radio:checked~#filter .personal,
#tech-radio:checked~#filter .tech {
background-color: green;
}
#featured-radio:checked~main .featured {
display: block;
}
#personal-radio:checked~main .personal {
display: block;
}
#tech-radio:checked~main .tech {
display: block;
}
<input type="radio" id="featured-radio" class="radio-button" name="content-filter" checked="checked">
<input type="radio" id="personal-radio" class="radio-button" name="content-filter" value="Personal">
<input type="radio" id="tech-radio" class="radio-button" name="content-filter" value="Tech">
<header id="filter">
<label for="featured-radio" class="filter-label featured" id="feature-label">Featured</label>
<label for="personal-radio" class="filter-label personal" id="personal-label">Personal</label>
<label for="tech-radio" class="filter-label tech" id="tech-label">Tech</label>
</header>
<main>
<article class="content featured tech">
<header>
<h1>Cool Stuff</h1>
<h3 class="date">Today</h3>
</header>
<p>
I'm showing cool stuff in this article!
</p>
</article>
<article class="content personal">
<header>
<h1>Not As Cool</h1>
<h3 class="date">Tuesday</h3>
</header>
<p>
This stuff isn't nearly as cool for some reason :(;
</p>
</article>
<article class="content tech">
<header>
<h1>Cool Tech Article</h1>
<h3 class="date">Last Monday</h3>
</header>
<p>
This article has awesome stuff all over it!
</p>
</article>
<article class="content featured personal">
<header>
<h1>Cool Personal Article</h1>
<h3 class="date">Two Fridays Ago</h3>
</header>
<p>
This article talks about how I got a job at a cool startup because I rock!
</p>
</article>
</main>
Whew. That was a lot for a "sample" but I feel it really drives home the effect and point: we can certainly select a label for a checked input control without it being a sibling. The secret lies in keeping the input tags a child to only what they need to be (in this case - only the body element).
Since the label element doesn't actually utilize the :checked pseudo selector, it doesn't matter that the labels are stored in the header. It does have the added benefit that since the header is a sibling element we can use the ~ generic sibling selector to move from the input[type=radio]:checked DOM element to the header container and then use descendant/child selectors to access the labels themselves, allowing the ability to style them when their respective radio boxes/checkboxes are selected.
Not only can we style the labels, but also style other content that may be descendants of a sibling container relative to all of the inputs. And now for the moment you've all been waiting for, the JSFIDDLE! Go there, play with it, make it work for you, find out why it works, break it, do what you do!
Hopefully that all makes sense and fully answers the question and possibly any follow ups that may crop up.
If your input is a child element of the label and you have more than one labels, you can combine #Mike's trick with Flexbox + order.
label.switchLabel {
display: flex;
justify-content: space-between;
width: 150px;
}
.switchLabel .left { order: 1; }
.switchLabel .switch { order: 2; }
.switchLabel .right { order: 3; }
/* sibling selector ~ */
.switchLabel .switch:not(:checked) ~ span.left { color: lightblue }
.switchLabel .switch:checked ~ span.right { color: lightblue }
/* style the switch */
:root {
--radio-size: 14px;
}
.switchLabel input.switch {
width: var(--radio-size);
height: var(--radio-size);
border-radius: 50%;
border: 1px solid #999999;
box-sizing: border-box;
outline: none;
-webkit-appearance: inherit;
-moz-appearance: inherit;
appearance: inherit;
box-shadow: calc(var(--radio-size) / 2) 0 0 0 gray, calc(var(--radio-size) / 4) 0 0 0 gray;
margin: 0 calc(5px + var(--radio-size) / 2) 0 5px;
}
.switchLabel input.switch:checked {
box-shadow: calc(-1 * var(--radio-size) / 2) 0 0 0 gray, calc(-1 * var(--radio-size) / 4) 0 0 0 gray;
margin: 0 5px 0 calc(5px + var(--radio-size) / 2);
}
<label class="switchLabel">
<input type="checkbox" class="switch" />
<span class="left">Left</span>
<span class="right">Right</span>
</label>
asd
html
<label class="switchLabel">
<input type="checkbox" class="switch"/>
<span class="left">Left</span>
<span class="right">Right</span>
</label>
css
label.switchLabel {
display: flex;
justify-content: space-between;
width: 150px;
}
.switchLabel .left { order: 1; }
.switchLabel .switch { order: 2; }
.switchLabel .right { order: 3; }
/* sibling selector ~ */
.switchLabel .switch:not(:checked) ~ span.left { color: lightblue }
.switchLabel .switch:checked ~ span.right { color: lightblue }
See it on JSFiddle.
note: Sibling selector only works within the same parent. To work around this, you can make the input hidden at top-level using #Nathan Blair hack.
UPDATE:
This only worked for me because our existing generated html was wacky, generating labels along with radios and giving them both checked attribute.
Never mind, and big ups for Brilliand for bringing it up!
If your label is a sibling of a checkbox (which is usually the case), you can use the ~ sibling selector, and a label[for=your_checkbox_id] to address it... or give the label an id if you have multiple labels (like in this example where I use labels for buttons)
Came here looking for the same - but ended up finding my answer in the docs.
a label element with checked attribute can be selected like so:
label[checked] {
...
}
I know it's an old question, but maybe it helps someone out there :)

Scroll To a Location in HTML file - with Scrolling Animation

I am currently trying to have a part of the text one my website, when clicked scroll to a certain location in the website. I have this code which works, but just jumps, which takes away from the user interface.
The following is the code that I currently have:
Go to Part One!
<div id="part1">Hey Yeah!</div>
Please know that I don't code like that, It is just for the example.
Define a function as here:
function scrollToBox(element, offset) {
var destination = $(element).offset().top - (offset ? offset : 120);
$("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination }, 1500);
}
Then in onclick event you can call it like following code:
scrollToBox('#part1', 0);
Provided is a PLUNKER and a Snippet that uses jQuery animate(). The details are in the comments in the source.
SNIPPET
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1, maximum-scale=1, user-scalable=0" />
<link href='https://fonts.googleapis.com/css?family=Quicksand:300' rel='stylesheet' />
<style>
/* Core~~~~~~~~~~~~~~~*/
html {
box-sizing: border-box;
font: 300 16px/1.428'Quicksand';
height: 100vh;
width: 100vw;
}
*,
*:before,
*:after {
box-sizing: inherit;
margin: 0;
padding: 0;
}
body {
position: relative;
font-size: 1rem;
line-height: 1;
height: 100vh;
width: 100vw;
overflow-x: hidden;
overflow-y: scroll;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background: #000;
color: #eee;
display: table;
}
h1,
h2,
h3,
h4,
h5,
h6,
legend {
font-variant: small-caps;
margin-bottom: 15px;
color: #Fc3;
text-align: center;
}
h1 {
font-size: 1.5rem;
}
h2 {
font-size: 1.4rem;
}
h3 {
font-size: 1.3rem;
}
legend {
font-size: 1.35rem;
}
p {
margin: 0 5px 15px;
}
img {
display: block;
max-width: 100%;
height: auto;
margin: 20px auto;
}
a {
color: #Fc0;
text-decoration: none;
margin: 10px 20px;
display: inline-block;
font-size: 1.5rem;
font-weight: 700;
}
a:hover {
color: #CCC;
}
header {
position: relative;
top: 0;
left: 0;
right: 0;
width: 100%;
border-bottom: 3px outset #bbb;
height: 80px;
z-index: 11;
background: #000;
text-align: center;
}
footer {
position: relative;
bottom: 0;
left: 0;
right: 0;
width: 100%;
border-top: 3px outset #bbb;
text-align: center;
height: 80px;
z-index: 11;
background: #000;
margin: 0 auto;
}
.content {
width: 100%;
height: 100%;
margin: 0 auto;
position: relative;
padding: 20px;
}
.sec {
width: 92%;
height: auto;
border: 5px ridge #999;
border-radius: 12px;
margin: 20px auto;
}
</style>
</head>
<body>
<header>
<nav id="top">To End
</nav>
</header>
<section class="sec">
<article class="content">
<iframe src='http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_eff_animate_smoothscroll' scrolling='no' frameborder='0' width='100%'></iframe>
</article>
</section>
<main id='main'>
<article class="content">
"'I had NOT!' cried the Mouse, sharply and very angrily. 'A knot!' said Alice, always ready to make herself useful, and looking anxiously about her. 'Oh, do let me help to undo it!' 'I shall do nothing of the sort,' said the Mouse, getting up and walking
away. 'You insult me by talking such nonsense!' 'I didn't mean it!' pleaded poor Alice. 'But you're so easily offended, you know!' The Mouse only growled in reply. 'Please come back and finish your story!'
</article>
<article class="content">
Alice called after it; and the others all joined in chorus, 'Yes, please do!' but the Mouse only shook its head impatiently, and walked a little quicker. 'What a pity it wouldn't stay!' sighed the Lory, as soon as it was quite out of sight; and an old
Crab took the opportunity of saying to her daughter 'Ah, my dear! Let this be a lesson to you never to lose YOUR temper!' 'Hold your tongue, Ma!' said the young Crab, a little snappishly. 'You're enough to try the patience of an oyster!' 'I wish
I had our Dinah here, I know I do!' said Alice aloud, addressing nobody in particular.
</article>
<article class="content">
'She'd soon fetch it back!' 'And who is Dinah, if I might venture to ask the question?' said the Lory. Alice replied eagerly, for she was always ready to talk about her pet: 'Dinah's our cat. And she's such a capital one for catching mice you can't think!
And oh, I wish you could see her after the birds! Why, she'll eat a little bird as soon as look at it!' This speech caused a remarkable sensation among the party. Some of the birds hurried off at once: one old Magpie began wrapping itself up very
carefully, remarking, 'I really must be getting home; the night-air doesn't suit my throat!' and a Canary called out in a trembling voice to its children, 'Come away, my dears! It's high time you were all in bed!'"
</article>
<article class="content">
"Death!" I shouted. "Death is coming! Death!" and leaving him to digest that if he could, I hurried on after the artillery-man. At the corner I looked back. The soldier had left him, and he was still standing by his box, with the pots of orchids on the
lid of it, and staring vaguely over the trees. No one in Weybridge could tell us where the headquarters were established; the whole place was in such confusion as I had never seen in any town before. Carts, carriages everywhere, the most astonishing
miscellany of conveyances and horseflesh. The respectable inhabitants of the place, men in golf and boating costumes, wives prettily dressed, were packing, river-side loafers energetically helping, children excited, and, for the most part, highly
delighted at this astonishing variation of their Sunday experiences. In the midst of it all the worthy vicar was very pluckily holding an early celebration, and his bell was jangling out above the excitement.
</article>
<article class="content">
I and the artilleryman, seated on the step of the drinking fountain, made a very passable meal upon what we had brought with us. Patrols of soldiers--here no longer hussars, but grenadiers in white--were warning people to move now or to take refuge in
their cellars as soon as the firing began. We saw as we crossed the railway bridge that a growing crowd of people had assembled in and about the railway station, and the swarming platform was piled with boxes and packages. The ordinary traffic had
been stopped, I believe, in order to allow of the passage of troops and guns to Chertsey, and I have heard since that a savage struggle occurred for places in the special trains that were put on at a later hour.
</article>
<article class="content">
We remained at Weybridge until midday, and at that hour we found ourselves at the place near Shepperton Lock where the Wey and Thames join. Part of the time we spent helping two old women to pack a little cart. The Wey has a treble mouth, and at this
point boats are to be hired, and there was a ferry across the river. On the Shepperton side was an inn with a lawn, and beyond that the tower of Shepperton Church--it has been replaced by a spire--rose above the trees. Here we found an excited and
noisy crowd of fugitives. As yet the flight had not grown to a panic, but there were already far more people than all the boats going to and fro could enable to cross. People came panting along under heavy burdens; one husband
</article>
</main>
<section class="sec">
<article class="content">
<img src='https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png'>
</article>
</section>
<footer>
<nav id="end">To Top
</nav>
</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script>
$(document).ready(function() {
//Delagate: click event to all anchors
$("a").on('click', function(event) {
//Condition: If this anchor has "href=#" then...
if (this.hash !== "") {
//Inhibit: Default behavior of anchor
event.preventDefault();
//Store anchor's "#"
var hash = this.hash;
/*
||Target the root and parent of page content.
||.animate() scrolling from clicked anchor to
||location designated by the anchor's hash.
*/
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 800, function() {
//return anchor behavior to anchor
window.location.hash = hash;
});
}
});
});
</script>
</body>
</html>

Show div when post has class

Update
I'd modded the CSS given by David Thomas a bit. Its now a banner.
.div.popular::before {
/* setting the default styles for
the generated content: */
display: block;
width: 10em;
height: 2em;
line-height: 2em;
text-align: center;
background: #F60;
color: #fff;
font-size: 1.4rem;
position: absolute;
top: 30px;
right: 0px;
z-index: 1;
}
I would like to make a folded corner sort of like in this post: Folded banner using css
--- Original post ---
Let me first explain what I'm trying to do. I'm trying to give some post some extra attention by making a little circle with some call-to-action text in it.
But I only want this to trigger when a div has a specific class.
So if the div the class populair or sale I would like to have a little circle show up on that post. This script what I am using right now.
$(document).ready(function($){
if($("#front-page-items").hasClass('populair')){
$(".populair-div").show();
}
if($("#front-page-items").hasClass('sale')){
$(".sale-div").show();
}
});
And this HTML:
<div class="populair-div" style="display:none;">
<strong>Populair</strong>
</div>
<div class="sale-div" style="display:none;">
<strong>Sale</strong>
</div>
But this only show's the populair-div and not the other one. I'm guessing my script is wrong. Should I use else for all the other call-to-action classes?
$(document).ready(function($){
if($("#front-page-items").hasClass('populair')){
$(".populair-div").show();
}
else($("#front-page-items").hasClass('sale')){
$(".sale-div").show();
}
else($("#front-page-items").hasClass('Free')){
$(".free-div").show();
} // and so on
});
Is there someone that could help me out? Also is it possible to echo the div so I don't have to write a whole div for every call-to-action div?
For something like this, where the displayed text is explicitly linked to the class-name of the element it's easiest to use CSS and the generated content available, effectively hiding the elements you don't wish to show by default and then explicitly allowing elements you want to show, along with the generated content of those elements (using the ::before and ::after pseudo-elements:
div {
/* preventing <div> elements
from showing by default: */
display: none;
}
div.populair-div,
div.sale-div {
/* ensuring that elements matching
the selectors above (<div>
elements with either the 'sale-div'
or 'populair-div' class-names
are shown: */
display: block;
}
div.populair-div::before,
div.sale-div::before {
/* setting the default styles for
the generated content: */
display: block;
width: 4em;
height: 4em;
line-height: 4em;
text-align: center;
border: 3px solid transparent;
border-radius: 50%;
}
div.populair-div::before {
/* setting the text with the
"content" property: */
content: "Popular";
/* providing a specific colour
for the generated contents'
border: */
border-color: #0c0;
}
div.sale-div::before {
content: "Sale";
border-color: #f90;
}
/* entirely irrelevant, just so you can
see a (slightly prettified) difference
should you remove the default display
property for the <div> elements: */
code {
background-color: #ddd;
}
em {
font-style: italic;
}
<div class="neither-popular-nor-sale">
<p>
This element should not be shown, it has neither a class of <code>"populair-div"</code> <em>or</em> <code>"sale-div"</code>.
</p>
</div>
<div class="populair-div">
</div>
<div>Also not to be shown.</div>
<div class="sale-div">
</div>
You can use toggle function for this. It will be shorter and clearer.
Display or hide the matched elements.
Note: The buttons is for tests.
$(document).ready(function($){
init();
});
function init() {
$(".populair-div").toggle($("#front-page-items").hasClass('populair'));
$(".sale-div").toggle($("#front-page-items").hasClass('sale'));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="front-page-items" class="populair sale"></div>
<div class="populair-div">populair-div</div>
<div class="sale-div">sale-div</div>
<hr />
<button onclick="document.getElementById('front-page-items').classList.toggle('populair');init()">toggle populair</button>
<button onclick="document.getElementById('front-page-items').classList.toggle('sale');init()">toggle sale</button>

"between" CSS/jQuery selector

The problem
Given a jQuery selection of one element (.context), how can I select into it:
the elements that are not child/grandchild of a specific class (e.g. .paragraph) [the class can have deeper nested levels of itself, like .paragraph .paragraph]
the child/grandchild elements with a certain set of tags (e.g. strong | i)
Notes
.context can be descendant of another .context or another .paragraph.
the elements I want to selects can be identified by [data-hint^="I want"] selector (obviously the data attribute is not present in the real scenario).
I don't want just the direct children of .context but also the descendants (obviously filtering away the elements contained in .context .paragraph.
The battle field
$selection = $('.context').first();
$formatting_elements = $selection.find('strong, i')
.not('.paragraph *');
.paragraph {
margin: 15px;
position: relative;
border: 1px solid black;
}
.paragraph .paragraph {
border: 1px solid #444;
}
.paragraph .paragraph .paragraph {
border: 1px solid #888;
}
.context {
margin: 15px;
position: relative;
background-color: limegreen;
}
[data-hint^="I want"] {
background-color: violet;
}
.paragraph:before {
content: '-paragraph-';
position: absolute;
bottom: 100%;
left: 200px;
}
.context:before {
content: '-context-';
position: absolute;
bottom: 100%;
left: 200px;
color: green;
}
.context .paragraph:before {
font-style: italic;
color: #444;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="paragraph">
<i>bar</i>
<div class="paragraph">
<strong>foo</strong>
<i>bar</i>
<div class="context" data-hint="Find elements relative to this element">
<i data-hint="I want to get this">foo</i>
<div class="paragraph">
<i>bar</i>
<div class="paragraph">
<strong>foo</strong>
<div class="paragraph">
<strong>foo</strong>
<i>bar</i>
</div>
<i>bar</i>
</div>
</div>
<strong data-hint="I want to get this">foo</strong>
<i data-hint="I want to get this">bar</i>
</div>
</div>
</div>
I tried the above script but it doesn't seem to work.
The goal
is being able to select and change yellow elements to be violet.
Edit
Sorry, misunderstood your question therefore re-writing the entire answer.
What you are trying to achieve here can be done using a custom filter function.
The theory is simple, you select all the elements that meet a specific criteria (including the one's that are children/grandchildren of some specific selector), then you filter your set out given the parent/grandparent criteria
var myElements = $('strong, i').filter(
function() {
return $(this).parents('.context').length < 1;
});
See working fiddle here
UPDATE
In light of your comment, I have made the following changes to the fiddle. I hope this is what you are looking for.
var myElements = $('strong, i', '.context').filter(
function() {
return $(this).parent('.context .paragraph').length < 1;
});
See updated fiddle here

I need these buttons to control which div is showing or "on top"

I have these buttons on the side of my page, and a main content area taking up the better part of the page.
What I am trying to do is get the button I click to change the main content to a div containing the corresponding information. This is very hard to find, perhaps because I am searching by the wrong terms, and I have covered a good portion of stackoverflow without much luck.
I have though about absolutely positioning the divs and using a script to change the z-index of the the divs to the highest amount using a "=+1" type situation, but I could see that getting messy.
I have considered adapting a script I have that replaces part of an image file name in order to change a main picture on a page to a larger version of the image corresponding to a thumb name, though this script targets file names so it isn't going well.
I have also tried something along the lines of:
"id of button" onclick function = "main content class" change id to "corresponding div"
only in javascript talk, and this isn't working at all so I can only assume that I am either looking at it wrong or I have some messed up in the code.
$('#tabhead1').click(function() {
document.getElementByClassName("maintab").id = "tabs1";
});
This is driving me crazy and I would really appreciate some ideas. I tried to leave it free formed so that noone gets hung up on anyone solution.
**** Just to clarify, I have 5 divs id'd at #tabhead1, #tabhead2, #tabhead3, etc. and 5 content divs classed as .maintab, and id'd as tabs1, tabs2, tabs3, etc. I need the first content div to show automatically, and for that div to change based on the button clicked. at the moment all content divs are set to display: none; except the first one.
For each button, add a data attribute related to the corresponding <div>
for example
<button id="tabhead1" data-content="tabs1" >first Tab</button>
apply a common class for the tabs, for example .tab
Then you can do the following
$('button').click(function(){
var contentId = $(this).data('content'); // get the id of corresponding tab
$('.tab').hide(); // hide all tabs
$('#'+contentId).show(); //show the corresponding tab
});
You are using getElementbyClassName which does not exists. Use:
document.getElementsByClassName("maintab")[0].id = "tabs1";
// Get all elements to match classname + get first element from array
And for the rest, I don't know why you want to add id with JS? Why not just add them to your HTML?
Try this
$('#tabhead1').click(function() {
// get element with class 'maintab' and replace its content with that of another tab
$(".maintab").html($(".tabs1").html());
});
To expand a little on the demo I posted in the comments earlier:
This uses a method very similar to #tilwin-joy, so I guess we were of like mindedness. There are a couple of small differences that I would point out:
jQuery:
$('button').on('click', function () {
var button = $(this);
var target = button.data('target');
button.prop('disabled', true).siblings().prop('disabled', false);
$(target).show('slow').siblings().hide();
});
This uses siblings to hide the other content (one less pass at the DOM).
I suggest just setting your data value with the id hash in the markup, I think it's a bit clearer to read and follow (IMHO) in both the script and markup.
This script also sets the current button to be disabled when clicked. The benefit of this is that you can use the disabled property to style up your buttons, and even if you don't style them it gives a visual cue to the user as to which tab content is currently displayed. Check out the demo to see how this can be used for styling purposes.
HTML: (I stripped some of the unneeded ids from what you described as your markup).
<div class="tabhead">
<button data-target="#tabs1" disabled="true">Content 1</button>
<button data-target="#tabs2">Content 2</button>
<button data-target="#tabs3">Content 3</button>
<button data-target="#tabs4">Content 4</button>
<button data-target="#tabs5">Content 5</button>
</div>
<div class="maintab">
<div id="tabs1">
<img src="http://placehold.it/350/e8117f/fff&text=Image+1" alt="Image 1" />
<p>This is the content of tabs1.</p>
</div>
<div id="tabs2">
<img src="http://placehold.it/350/9acd32/fff&text=Image+2" alt="Image 2" />
<p>This is the content of tabs2.</p>
</div>
<div id="tabs3">
<img src="http://placehold.it/350/9400d3/fff&text=Image+3" alt="Image 3" />
<p>This is the content of tabs3.</p>
</div>
<div id="tabs4">
<img src="http://placehold.it/350/ffd700/fff&text=Image+4" alt="Image 4" />
<p>This is the content of tabs4.</p>
</div>
<div id="tabs5">
<img src="http://placehold.it/350/1e90ff/fff&text=Image+5" alt="Image 5" />
<p>This is the content of tabs5.</p>
</div>
</div>
CSS: Not needed - just to give you an idea of how you can style the elements to look like tabs.
/*This sets all but the first tab to hidden when the page is loaded*/
.maintab>div:not(:first-child) {
display: none;
}
/*The rest is just to style the elements to look like tabs*/
body {
background-color: #eaeaea;
}
.maintab, .tabhead {
text-align: center;
margin:0 20px;
font-family: sans-serif;
}
.maintab {
border: 1px solid #1e90ff;
border-top: none;
padding-top: 20px;
background-color: #fff;
}
.tabhead {
border-bottom: 1px solid #1e90ff;
position: relative;
margin-top: 20px;
}
button {
background-color: #ccc;
padding: 10px;
border: 1px solid #999;
border-bottom: none;
-webkit-border-top-left-radius: 4px;
-webkit-border-top-right-radius: 4px;
-moz-border-radius-topleft: 4px;
-moz-border-radius-topright: 4px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
color: #999;
font-size: 14px;
cursor: pointer;
position: relative;
top: 2px;
}
button:disabled {
background-color: #fff;
border-color: #1e90ff;
color: #1e90ff;
top: 3px;
padding-top: 11px;
cursor: not-allowed;
z-index: 10;
}

Categories