How do I toggle view/display of custom HTML elements? - javascript

thank you for taking the time to review my question! :-) I am attempting to write better, cleaner, more maintainable HTML using custom HTML elements as opposed to the traditional 'div' methods. I have a very simple example that works using a div and a class on it to map my link to the div that I want to show/hide and this does work. I include this as a working example of the kind of functionality I am trying to produce:
<html>
<head>
<style>
<!-- Not sure if display or visibility is the way to go so will look -->
<!-- that later, for now just setting both as that works -->
<!-- For some reason doing this does not seem to work -->
.hidden {
display: none;
visibility: hidden;
}
.unhidden {
display: block;
visibility: visible;
}
<!-- but, doing this does, anyone any idea why? -->
.hidden { display: none; }
.hidden { visibility: hidden; }
.unhidden { display: block; }
.unhidden { visibility: visible; }
</style>
<script type="text/javascript">
function toggle_view_div(divID) {
var item = document.getElementById(divID);
if (item) {
item.className=(item.className=='hidden')?'unhidden':'hidden';
}
}
</script>
</head>
<body>
<p>
This test shows or hides a div referenced by its class
</p>
Do the test
<div id="testToggleDivID" class="hidden">
<h3>Testing Toggling HTML</h3>
</div>
</body>
</html>
However, I am trying to provide this kind of functionality with multiple links to multiple sets/subsets of text, I have tried the following but am obviously doing something silly as I can't get it to work:
<html>
<head>
<script type="text/javascript">
function toggle_view_node(nodeID) {
nodeID.getAttribute('visibility')=('hidden')?item.setAttribute('visibility','visible'):item.setAttribute('visibility','hidden');
nodeID.getAttribute('display')=('none')?item.setAttribute('display','block'):item.setAttribute('display','none');
}
</script>
</head>
<body>
<p>
This test shows or hides Topic 1 custom element, (or at least attempts to
</p>
Topic 1
<p>
This test shows or hides Topic 2 custom element, (or at least attempts to
</p>
Topic 2
<p>
<p>
This test shows or hides the Intro custom element, (or at least attempts to
</p>
Introduction
<p>
This test shows or hides the Detail custom element, (or at least attempts to
</p>
Detail
<p>
<Intro>Some introduction text giving a more detailed overview that may want to be hidden by default, but able to be toggled into view with an always visible link such as at the top or on the side of the page</Intro>
<Detail>I may want to add detail with this ability both like this at the root of the document, but potentially inline with other text in custom elements as shown below</Detail>
</p>
<Topic1>
<h1>Topic 1</h1>
<p>
Some topics to be just simple nodes of text.
</p>
</Topic1>
<Topic2>
<h1>Topic 2</h1>
<p>
Other topics to be more detailed topics, <Topic1>potentially including aspects of that can share the toggle feature for the root level topic 1, as per all topic 1 nodes</Topic1> though generally referencing only topic 2 content. <Detail>However it would be nice to be able to toggle not directly relevant, but nice to have detail as well</Detail>
</p>
</Topic2>
<Topic3>
<h1>Topic 3</h1>
<p>
<Intro>Some topics might want an intro<Detail>, that may want further detail contained in them</Detail> that would also provide sufficient intro in itself.</Intro>
So, is this possible? I don't want specific control of sub custom elements, and can do it with div's and assigned classes if I really have to, but surly it is possible with a bit of special JS or CSS to do what I am looking for?</p>
</Topic3>
</body>
</html>
Please, can someone help me figure out what I am doing wrong. I really want to produce the aforementioned functionality with a simple bit of CSS or JS that is as dynamic as possible. Ideally I wont need to specify specific (especially repeated code for each topic or HTML tag that I want the ability to show/hide via a button/link. Obviously, I will probably have to set a few default assignments, maybe turning detail off by default, but if I can avoid required extra repetitive code for each "context" I wish to flip that would be amazing!!!
Any pointers in any direction that can help me achieve what I am attempting without having to use jQuery or a verbose library over and above JS and CSS would really make my day!
Many thanks in advance and apologies if I am doing something really stupid, I haven't done that much work with custom elements and so probably am.
Kind regards,
James
** Latest Attempt **
<html>
<head>
<style>
<!-- Not sure if display or visibility is the way to go so will look -->
<!-- that later, for now just setting both as that works -->
<!-- For some reason doing this does not seem to work -->
.hidden {
display: none;
visibility: hidden;
}
.unhidden {
display: block;
visibility: visible;
}
<!-- but, doing this does, anyone any idea why? -->
.hidden { display: none; }
.hidden { visibility: hidden; }
.unhidden { display: inline; }
.unhidden { visibility: visible; }
<!-- Playing with something like this, ideally I would -->
<!-- configure the show/hide state of my custom HTML tags -->
<!-- universally in a similar way? -->
Topic1.hide { display: none; }
Topic2.hide { display: none; }
Topic3.hide { display: none; }
Intro.hide { display: none; }
Detail.hide { display: none; }
<!-- Another attempt to configure switch state but does not work either -->
Topic1 { className: unhidden; }
Topic2 { className: unhidden; }
Topic3 { className: unhidden; }
Intro { className: unhidden; }
Detail { className: unhidden; }
</style>
<script type="text/javascript">
// This works, but is not clean
function toggle_view_div(divID) {
var item = document.getElementById(divID);
if (item) {
item.className=(item.className=='hidden')?'unhidden':'hidden';
}
}
// I am now attempting to use this on 'Topic1' as per the suggestion
// in the comments of this post, for some reason it does not work, wondering if
// I need to do a .forEach to parse the set of nodeID's of the 'Topic1' in this
// example, but if working whatever HTML tag name that I want to toggle in or
// out of view
function toggle_view_node_id(nodeID) {
var item = document.getElementById(nodeID);
if (item) {
item.className=(item.className=='hidden')?'unhidden':'hidden';
}
}
// This does not work but I have left to show what I tried that did not work
function toggle_view_node(nodeID) {
if (nodeID) {
nodeID.getAttribute('visibility')=('hidden')?item.setAttribute('visibility','visible'):item.setAttribute('visibility','hidden');
nodeID.getAttribute('display')=('none')?item.setAttribute('display','block'):item.setAttribute('display','none');
}
}
</script>
</head>
<body>
<p>
This test shows or hides a div referenced by its class
</p>
Do the test that works using extra layer of div with mapped class
<p>
This test shows or hides Topic 1 custom element,
(or at least attempts using the suggestion in this post
comments to try to make work without inline JS and call a
function to do it as with my working example, unfortunatly
however, this still does not seem to work :(
</p>
Topic 1
<p>
This test shows or hides Topic 2 custom element,
(or at least attempts to using existing method that doesn't work
</p>
Topic 2
<p>When I have it working I hope to be able to have: </p>Topic 3
<p>And... </p>Intro
<p>And this... </p>Detail
<div id="testToggleDivID" class="hidden">
<h3>Testing Toggling HTML into view using a div and associated class of hidden, can I not do this on a custom element?</h3>
</div>
<p>
<Intro>Some introduction text giving a more detailed overview that may want to be hidden by default, but able to be toggled into view with an always visible link such as at the top or on the side of the page</Intro>
<Detail>I may want to add detail with this ability both like this at the root of the document, but potentially inline with other text in custom elements as shown below</Detail>
</p>
<Topic1>
<h1>Topic 1</h1>
<p>
Some topics to be just simple nodes of text.
</p>
</Topic1>
<Topic2>
<h1>Topic 2</h1>
<p>
Other topics to be more detailed topics, <Topic1>potentially including aspects of that can share the toggle feature for the root level topic 1, as per all topic 1 nodes</Topic1> generally referencing only topic 2 content. <Detail>However it would be nice to be able to toggle not directly relevant, but nice to have detail as well</Detail>
</p>
</Topic2>
<Topic3>
<h1>Topic 3</h1>
<p>
<Intro>Some topics might want an intro<Detail>, that may want further detail contained in them</Detail> that would also provide sufficient intro without.</Intro>
So, is this possible? I don't want specific control of sub custom elements, and can do it with div's and assigned classes if I really have to, but surly it is possible with a bit of special JS or CSS to do what I am looking for?</p>
</Topic3>
</body>
</html>

you don't need a .unhidden class, only a .hidden class. It looks like:
.hidden{
display:none;
}
simply use classList like classList.toggle("hidden") or .add or .remove.

Related

Div's display: none gets overridden by user agent stylesheet, but works locally

I have this piece of code on my website:
<div class="test_section no_display" id="test_section_metric">
<div class="section_start_bar">
</div>
<div class="section_end_bar">
</div>
</div>
And this piece of css:
.test_section
{
width:70%;
margin-left:15%;
background-color: var(--color_main);
}
.no_display
{
display: none;
}
But the div with "no_display" class is displayed, because when I inspect the site in Chrome I see that it overrides it with user agent stylesheet like this:
div{
display:block;
}
However, when I open the site just as a file on my computer it is actually not displaying and is working as intended.
I've already searched for an answer, but I've mostly encountered people fixing it by putting a <!DOCTYPE html> before the <html> tag, which I've already done.
The .no_display class is a separate thing, because it'll be removed with javascript to show things on a button click.
Any ideas how to fix this?
using css property display: none !important; will override the user agent setting. bonus points for checking that your class name and css class selector are spelled the same 😅

Advanced sibling selector [duplicate]

This question already has answers here:
How do I select an element based on the state of another element in the page with CSS?
(3 answers)
Closed 7 years ago.
I can't quite get my head around this. I have the following construct:
<div class="container">
for n = 0 to ...
Link n
endfor
for each link in ".container"
<div class="poptip"></div>
endfor
</div>
And an example could be:
<div class="container">
Link 1
Link 2
Link 3
<div class="poptip">Some content related to link 1 retreived with ajax</div>
<div class="poptip">...</div>
<div class="poptip">...</div>
</div>
Now the hurdle, I am trying to show the .poptip on hover on the anchor tag, and this obviously works fine if there is one link (which is usually the case). In any case where there's >1 link, then the last one will work. Current css (sass style) which doesn't quite work in >1 cases:
.producttooltip {
position: relative;
}
.producttooltip a:hover + div {
display: block;
}
I cannot change the structure of the html, it will always be container > all links followed by all poptips. I can however mark the poptips and anchor tags up with unique identifiers e.g. Link 1<div class="poptip" rel="identifier"></div>, but I can't quite figure out if I in css can create a general selector which goes (pseudo):
a:hover + div[rel=a.rel] {
display: block
}
So my question is, can I get this construct marked up in pure CSS, or do I have to use some JS trickery (which I can, but I would really prefer CSS). Hope one of you guys are more clever than me.
Edit: just gonna clarify - I cannot change the structure of the html. The neatest solution would obviously be to wrap each element with it's equivalent poptip, but my entire conundrum is the fact that I cannot do this.
In your case, you can do this way:
$('a').on('hover', function() {
$('.poptip').eq($(this).index()).show();
}, function() {
$('.poptip:visible').hide();
});
It is tough to do this with CSS alone. But even then, I have provided a CSS solution below. Do have a look if you wanna consider a CSS only solution.
You can do this via CSS itself. Although there are lot of plugins, lets do something like this. First, you need a hovering element, say in this case, a link.
Hover Me!
Next should be the tool tip. We can have a <span> for now and put it inside the link.
Hover Me!<span class="tooltip">Hello, World!</span>
Now comes the real CSS part.
a span {display: none; position: absolute; color: #fff; background: #000; padding: 5px;}
a {position: relative;}
a:hover span {display: block; text-align: center;}
Snippet
a span {display: none; position: absolute; color: #fff; background: #000; padding: 5px;}
a {position: relative;}
a:hover span {display: block; text-align: center;}
Hover Me!<span class="tooltip">Hello, World!</span>
This is just one of a pure CSS solution. You can see the working fiddle here.
However, there are a lot of plugins, which keep this concept as base and work for hover-cards and tool tips. Some good examples include:
jQuery UI Tooltip
Tipsy
HoverCard
40+ Tooltips Scripts With AJAX, JavaScript & CSS
jQuery solution
You can use mouseenter/mouseleave event in order to show up the desired elements
$('a').on('mouseenter', function() {
var i = $(this).index();
$('.poptip').eq(i).show();
}).on('mouseleave', function() {
$('.poptip').hide();
});
.poptip {
width:100%;
float:left;
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
Link 1
Link 2
Link 3
<div class="poptip">Some content related to link 1 retreived with ajax</div>
<div class="poptip">Some content related to link 2 retreived with ajax</div>
<div class="poptip">Some content related to link 3 retreived with ajax</div>
</div>
Using jquery this can be achieved easily, just need to get the index of the current anchor element & display the respective div present at the index location.
HTML CODE:
<div class="container">
Link 1
Link 2
Link 3
<div class="poptip">Some content related to link 1 retreived with ajax</div>
<div class="poptip">...</div>
<div class="poptip">...</div>
</div>
JS CODE:
$(function(){
$('a').on('hover',function(){
var ind = $('a').index(this);
$('.poptip').eq(ind).css('display','block');
});
});
Live Demo # JSFiddle

How can I selectively change text using a CSS class?

I need to add a CSS/HTML 'fragment' to a page to change the text in the following:
<div>
<h3 class="category-heading">Keep this text:</h3>
</div>
<div>
<h3 class="category-heading">**Change this text**:</h3>
</div>
I have tried the following:
<style>
h3.category-heading {
text-indent: -9999px;
}
h3.category-heading::after {
content: “New and Featured Products”;
text-indent: 0;
display: block;
line –height: 120%;
}
</style>
But this changed both instances of the text.
Is it possible to specify the second instance of the css class to be changed? or is it possible to select and change the wording in the second css class by adding a html fragment?
Supposing you can use Javascript by including it an HTML fragment :
Depending on the inclusion mecanism (we need to know more about the tools you use), something containing :
<script>
window.onload = function(){
document.getElementsByClassName("category-heading")[1].innerHTML = "New and Featured Products";
}
</script>
If the first solution breaks some features of your website (because It could override defined behaviour), you should use :
<script>
document.getElementsByClassName("category-heading")[1].innerHTML = "New and Featured Products";
</script>
Why not to use an id attribute?
<h3 class="category-heading" id="itemThatShouldBeChanged">**Change this text**:</h3>
and than just
#itemThatShouldBeChanged {content:"other text"}
You should take a look at nth-child
Be aware that this is CSS3
this will give you the following css selector :
div:nth-child(2) h3.category-heading::after

JavaScript - tooltip div on hover

I'd like to implement this situation: user hovers link and on his screen appears div with additional information.
There is no problem, to generate div with absolute position, populate data and display it with jQuery, but the problem is with maintainability. I want to separate logic and view. What if I'd like to change page layout in the future? How programmer will know, that some part of page exist in JavaScript file?
Is it some elegant way to separate view (in my case HTML structure) and logic (data obtained from server in JSON using JS script) and combine them? Is it any ... templating engine or something like that in JavaScript?
You can generate your HTML entries like this
<a>
My Cool Link
<div class="tooltip">
This link is awesome!
</div>
</a>
And use CSS to style the tooltip:
(The important part is a:hover .tooltip and everything except background on .tooltip
a {
display: inline-block;
}
a:hover .tooltip {
visibility: visible;
}
.tooltip {
position: relative;
top: 20px;
left: -50%;
display: inline;
visibility: hidden;
background: #eee;
}
Example: http://jsfiddle.net/4K7sB/
Then you just need to populate the elements with the correct text using JS.
Bootstrap does all this and more: http://getbootstrap.com/javascript/#tooltips
To put it in:
$('#example').tooltip(options)
And the markup being:
<div class="tooltip">
<div class="tooltip-inner">
Tooltip text here!
</div>
<div class="tooltip-arrow"></div>
</div>
Go to the link for a more detailed explanation on how to implement it
You can alter the Title="information" dynamicaly by some program or script and use the following code to display it as a tool tip,found it on net
http://www.webdesignerdepot.com/2012/11/how-to-create-a-simple-css3-tooltip/
Just add title attribute in div tag like below code....
<div title="First Div">StackOverFlow StackOverFlow StackOverFlow
StackOverFlow StackOverFlow StackOverFlow StackOverFlow StackOverFlow
StackOverFlow </div>
</div>
<br /><br />
<div title="Second Div">StackOverFlow StackOverFlow StackOverFlow
StackOverFlow StackOverFlow StackOverFlow StackOverFlow StackOverFlow
StackOverFlow </div>
</div>
just copy paste and check.

CSS hidden text illegal for Search Engines? [duplicate]

This question already has answers here:
Is h1 tag that's hidden using display:none given prominence by search engines?
(10 answers)
Closed 9 years ago.
Here are basic example boxes, CSS and JS I created for jQuery Modal Box.
<!-- hidden boxes // -->
<div id="content_1" class="box">
<h1>First Box</h1>
<p>Content goes here...</p>
</div>
<div id="content_2" class="box">
<h1>Second Box</h1>
<p>Content goes here...</p>
</div>
.....
<!-- links for boxes // -->
Show First Box
Show Second Box
<!-- css // -->
<style>
.box {
display: none;
}
</style>
<!-- javascript // -->
<script type="text/javascript">
$(document).ready( function() {
$('.link').click( function() {
// process modal
});
});
</script>
So when User click on First/Second Box link, the jQuery modal popup with content. My Purpose is not to hide the text. I heard and read in some blogs, Google will take action with hidden text. Is my way illegal/bad for SEO? OR are there better way to do this without display:none?
You will find Google themselves actually use display:none; on their homepage - and considering the popularity of jQuery and other JavaScript libraries using these kinds of effects, I can't see how it will negatively impact your SEO if you use it in necessary circumstances.
I use following snippet to hide sub-menus on css3 navigation menus with some cool ease-in, ease-in-out transitions . And afaik this is valid css to hide elements when it comes to SEO.
opacity: 0;
visibility: hidden;
Already discussed at
Is there an alternative to conditional display:none
Instead of using display:none; you can use left: -9999px;position:absolute; it will still display the content for the search engine but it will be displayed somewhere not for the users.
http://css-tricks.com/snippets/css/accessibilityseo-friendly-css-hiding/

Categories

Resources