How to search by classname and in element with style 'display='none'' - javascript

My code
I have a problem with searching in javascript.
I need to look up both throughout the document and only the CSS class.
<span class="ID">153</span>
<span class="keywords">pararell processing, evolutionary algorithm, linear algebra algorithm, FPGA</span>
<span class="author">Oleg Maslennikow, </span>
I want to search g in Oleg but not in processing.
If i search i want to show hide elements, and after hide it..
In this case, I would like to be able to look after the class = 'author'.
I would also like to be able to look at the elements that have style display = 'none' by showing that element and then keep it.
Can anybody help me?
I dont want to use jQuery!

If you are using Chrome browser it should support document.querySelector()
This is how you achieve what you need :
document.querySelector('span.author'); // to return span class="author"
It is supported in the below browsers:
https://developer.mozilla.org/en-US/docs/DOM/Element.querySelectorAll

You could do something like this. No worries about the while-loop it's just a short and revers version of a for loop.
var element_to_find;
var list = document.getElementsByClassName("author");
var len = list.length;
while (len--) {
if (list[len].style.display == "none") {
var element_to_find = list[len];
alert("do what you want");
}
}
Second: You cold create a class for "display:none"
So it woud be easier to find.
Style:
.hidden{ display:none }

Related

how to define html classes in javascript?

I have serval div's with classes and I want to define them in javascript.
Here is my jsfiddle script, It's only using DIV ID now but it has to be classes because I want to Add multiple blocks.
Can someone help?
var block = document.getElementById('block');
var minimizewindow = document.getElementById('minimizewindow');
block.style.height = "250px";
minimizewindow.style.display = "none";
//function minimize
minimize.onclick = function(){
if(block.style.height == "250px") {
block.style.display = "none";
} .........
http://jsfiddle.net/uVSyX/
click on the broken images for : minimize, maximze, close
Thank you!
EDIT : Think I don't get it, I wan't to show and hide multiple div's...
document.getElementsByClassName('myClass'); is the easiest way, however it is not supported by IE. Mozilla has great documentation on this.
If you need IE support, this page might be a good resource for you: http://robertnyman.com/2008/05/27/the-ultimate-getelementsbyclassname-anno-2008/
and I want to define them in javascript.
this is a bad idea. Styling instructions belong in CSS style sheets.
The right way to go here would be having classes, like .expanded and .contracted
They would contain rules like
.expanded { width: 800px; display: block }
you then just change the class property in JavaScript. jQuery makes this very easy because it has convenient methods for dealing with classes.
http://api.jquery.com/hasClass/
http://api.jquery.com/addClass/
http://api.jquery.com/toggleClass/
I don't remember where I found this function at but it's what I've used to find elements based on class.
var elems = document.getElementsByTagName('div'),i;
for (i in elems) {
if((" "+elems[i].className+" ").indexOf(" "+matchClass+" ") > -1) {
elems[i].style.display = "none";
}
}
with matchClass being the name of the class you are looking for.
I updated the above code to set all div with a specific class that is defined as matchClass to be set to display:none when the function is run.

Search for div classes with regex

Sounds simple, huh. Lot's of answers i found but all use jQuery or ProtoType. I want plain JavaScript. It shouldn't be that hard, but JavaScript is not my thing; no central documentation means searching for ages and not finding what i want.
Consider the following HTML code snippet:
<div class="central_0"> .. </div>
<div class="central_1"> .. </div>
<div class="central_2"> .. </div>
Now I want to use JavaScript to do things with those DIVs.
function processDivElements()
{
// search for relevant DIV classes
var divArray = document.getElementsByClass.regex('/^central_.*$/');
// do stuff with the DIV elements found
foreach (divArray as divElement)
{
divElement.style.background = '#f00';
};
}
Can anyone help me translate this to proper plain JavaScript? I use classes, not IDs. I prefer using a regular expression.
The jQuery solution is really nice:
var $divs = $('div[class^="central_"]');
If you only want to support newer browsers, you can use document.querySelectorAll() to do essentially the same thing:
var divs = document.querySelectorAll('div[class^="central_"]');
If you want to support older browsers, the code gets horrible:
var all_divs = document.getElementsByTagName('div');
var divs = [];
for (var i = 0; i < all_divs.length; i++) {
var div = all_divs[i];
if (div.className.match(/^central_\d+$/) {
divs.push(div);
}
}
Also:
I use classes, not IDs. I prefer using a regular expression.
Your classes are unique and are really functioning like IDs, which isn't really the intended use of classes. Structure your HTML like this instead:
<div id="central_0" class="central">...</div>
<div id="central_1" class="central">...</div>
<div id="central_2" class="central">...</div>
Now, the JavaScript becomes simpler:
var $divs = $('.central'); // jQuery
var divs = document.querySelectorAll('.central'); // Newer browsers
var divs = document.getElementsByClassName('central'); // Older browsers
As the others have mentioned you can't directly support a regex select on the getElementsByClassName method call.
But I will point out these other issues with your code, since you are new to javascript.
Using classes is fine, but your making more work for yourself by writing up your html like that.
Instead of the central_0....central_2 if they are all basically operating on the same css rules, you should write them like this central zero....central two then your central class can have identical rules, while you can assign any differences to the # classes. This way your also adhering to the DRY principle.
Also you should really consider sticking to the best practices for the language. If your not assigning css rules to your elements with those classes then you should be using id's, plus it makes your life much easier.
There is no way to get the matched elements by regex directly, the only thing you could do is to get all the elements by something (like: TagName, Name, etc..) and then filter the elements by regex.
With your html sample, you could only get all the element by TagName, and use regex to check the className by regex.
One quicker way to do so is to create a simple <style> as follows:
<style>
div[class^="central_"] {
background-color: #f00;
}
</style>
Therefore, as you look for plain javascript, useless to say that you can add <style> tags at will, by using javascript. A whole HTML example as follows:
<html>
<head>
</head>
<body>
<div class= "central_1">
central 1
</div>
<script>
var css = "<style>div[class^=\"central_\"] {background-color: #f00;}</style>";
var list = document.querySelector("head"); list.innerHTML += css;
</script>
</body>
</html>

Need Javascript syntax to reference a CSS class instead of HTML element

I searched online for the correct syntax to reference a CSS class, instead of an HTML element, but was unable to find anything helpful.
I would like to modify the code below to reference any DIV of class buy_content "div.buy_content" instead of the body element.
Small Text
Medium Text
Large Text
There is no "JavaScript syntax" for what you're asking for. Newer browsers support an API called "getElementsByClassName", so you could do this:
function setSize(sz) {
var elements = document.getElementsByClassName('buy_content');
for (var i = 0; i < elements.length; ++i) {
if (elements[i].tagName === 'DIV')
elements[i].style.fontSize = sz;
}
}
<a href='#' onclick='setSize("1em"); set_cookie(...);'>Small</a>
You can find a "patch" for "getElementsByClassName" support here.
<a href="#" class="clickie size-1" >Small text </a>
<a href="#" class="clickie size-2" >Medium text </a>
<a href="#" class="clickie size-3" >Large text </a>
You should change the markup not to rely on inline javascript.
// bind the event handler to all <a> tags
var as = document.getElementsByTagNames("a");
for (var i = 0, ii = as.length; i < ii; i++) {
as[i].onclick = setText;
}
function setText(ev) {
// get the em size from the class
var size = /[.]*text-([\d][.]*)/.exec(ev.target.className)[1]
var divs = document.querySelectorAll("div.buy_content");
// set the style on all divs.
for (var i = 0, ii = divs.length; i < ii; i++) {
divs[i].style.fontSize = size + "em";
}
}
There are issues with browser support (mainly IE7 and lower) so you need some more boilerplate to make it work.
You can't really do this (easily/readably/cleanly) with inline and stock JavaScript because the JavaScript DOM API doesn't provide a way to reference a CSS class since this isn't part of the DOM. You would have to populate an array or list with HTML elements that have that class applied to them and then iterate over the collection.
JQuery provides selectors and iterators to make this very simple, but if you can't use libraries then doing this inline isn't a good idea. Put it in a function in a script block or an external .js file.
EDIT:
A few people pointed out querySelectorAll, which will select by class but from what I have read isn't completely cross platform (doesn't work on IE below IE 8).
Further, to clarify on my original post, when I said that the DOM API doesn't allow you to access an element by class, what I meant was that it couldn't be done with DOM traversal. querySelectAll or the JQuery selectors perform DOM traversal with functions that inspect elements and their properties, retrieve the objects, and populate collections. Even getElementById performs attribute inspection. I suppose, in retrospect, it's a moot point, but since he wasn't using selectors or attribute queries in his original code I thought that he was asking if there was JS syntax that was as simple as what he was currently using. That's why I mentioned functions. In my head, even something like getElementById is a function since, well, it is a function.
I believe what you are looking for is insertRule (this is exactly what you asked for... kinda):
document.styleSheets[document.styleSheets.length-1].insertRule('div.buy_content {font-size: 1em}',document.styleSheets[document.styleSheets.length-1].length)
document.styleSheets[document.styleSheets.length-1] is your last stylesheet.
the new rule will go at index document.styleSheets[document.styleSheets.length].length
http://www.quirksmode.org/dom/w3c_css.html#t22
also... deleteRule:
http://www.quirksmode.org/dom/w3c_css.html#t21
BUT, a better way to go would be to getElementsByClassName, loop through em, check their nodeName for "DIV", then apply the styles the old fashioned way.
Leverage CSS to do the selection work for you:
body.smalltext .buy_content { font-size: 1em; }
body.mediumtext .buy_content { font-size: 2em; }
body.largetext .buy_content { font-size: 3em; }
...
<input type="button" value="Small text" id="smalltext"/>
<input type="button" value="Medium text" id="mediumtext"/>
<input type="button" value="Large text" id="largetext"/>
...
document.getElementById('smalltext').onclick= function() {
document.body.className= 'smalltext';
};
document.getElementById('mediumtext').onclick= function() {
document.body.className= 'mediumtext';
};
document.getElementById('largetext').onclick= function() {
document.body.className= 'largetext';
};
My first suggestion to answer your exact question:
If your project is bigger in scope than just this one thing:
Download jQuery
Use code:
$('div.buy_content')
Which returns a jQuery array object of all the divs which you can further manipulate.
My second suggestion based on thinking more deeply about what you're trying to do:
Either completely replace the stylesheet in script or modify the existing stylesheet to change the style. Don't loop through all the DIVs in the document and change their style assignment, instead change the meaning of their already-assigned style.

Is there a cross-browser css way to decorate only last word in a span block?

I need to show user's list which should look like in the example below:
Helen Burns Edward
Fairfax Rochester Bertha
Antoinetta Mason Adèle
Varens
Is there a way to achieve this without using javascript? Each row should be one span, i.e. <span>Helen</span><span>Burns</span> is not acceptable.
No, there is not. You are going to have to use some form of scripting to accomplish this if you don't want your last names to be in their own tags.
To the browser, each row is an element, and the "words" themselves have no separate meaning as far as CSS is concerned. You must place the words in different tags in order to do what you want.
The browser does not automagically know what part of the name is the last name so you have to add extra markup to achieve what you want.
There's no solution for common used browser for know using only CSS. You should use javascript or HTML + CSS as you already made.
without pure css this is impossible (as you don't want a separation in the markup)...
<span>Monty Burns</span><br />
<span>Bart Simpson</span>
<script type="text/javascript">
$(document).ready(function() {
var spans = $('span');
spans.each(function(index, element) {
var span = $(element);
var spanText = span.text();
var spanTextArray = spanText.split(' ');
var spanTextArrayLength = spanTextArray.length;
var lastName = spanTextArray[spanTextArrayLength -1];
spanTextArray.pop();
var firstName = spanTextArray.join(' ');
span.text(firstName);
var spanLastName = $('<span/>');
spanLastName.css('font-weight', 'bold');
spanLastName.css('margin-left', '5px');
spanLastName.appendTo(span);
spanLastName.text(lastName);
});
});
</script>
working demo.
edit: if you do not want an extra span-tag in there, just change
var spanLastName = $('<span/>');
spanLastName.css('font-weight', 'bold');
to
var spanLastName = $('<strong/>');
I don't think this is possible with CSS because your example doesn't show any order:
Helen Burns
Edward Fairfax Rochester
Bertha Antoinetta Mason
Adèle Varens
I don't know why you might desire not to have an extra tag surrounding the last name (as other answers and comments have suggested), but if you are looking simply for minimalist mark-up, this works (no span even used):
Html:
<body>
First Middle <strong>Last</strong>
First Middle <strong>Last</strong>
First Middle <strong>Last</strong>
</body>
Css:
strong:after {content:' '; display: block;}
Which creates "rows" with your desired styling without anything more than a single tag (which could be a span rather than a strong if you desired).
Edit: Of course, this will not work for IE7 or under.

How can I create an element that flips between two values on click?

Given two spans like this:
<span>Click for info</span>
<span style="display: none">Here is a big long string of info blah blah</span>
...I'd like to have an onclick function attached to each so that the visitor sees "Click for info", and then when they click it, the first span is hidden and the second is unhidden. And, of course, when the second is clicked, things go back to the way they were originally.
I don't have a way of easily generating unique IDs, so I'd prefer to avoid the getElementByID() route, and I'd rather not use jQuery or any other heavyweight dependency. Is there an elegant way to do this?
The best idea I have so far is to write a toggleAllSiblings() function, set onclick to that function for both elements in the pair, and then wrap each pair in a parent element.
Can it be done without the parent node?
If you really want to go without ids you could do something like this:
<script>
function togglePrevious(sender) {
sender.previousSibling.style.display = "inline";
sender.style.display = "none";
}
function toggleNext(sender) {
sender.nextSibling.style.display = "inline";
sender.style.display = "none";
}
</script>
<span onclick="javascript:toggleNext(this);">Click for info</span>
<span onclick="javascript:togglePrevious(this);" style="display:none">Info blablabla</span>
And please not that you should really use "inline" instead of "block" if you are using spans as they are inline elements. Setting their display style to block will force them to be divs.
Yet another version, a la progressive enhancement — will properly show the full info when JavaScript is off.
<span class="details">Here is a big long string of info blah blah</span>
<script type="text/javascript">
// Open/close span behaviour
//
function infoToggle(span) {
var ersatz= document.createElement('span');
ersatz.appendChild(document.createTextNode('Click for info...'));
span.parentNode.insertBefore(ersatz, span);
span.style.display= 'none';
span.onclick= function() {
ersatz.style.display= 'inline';
span.style.display= 'none';
};
ersatz.onclick= function() {
ersatz.style.display= 'none';
span.style.display= 'inline';
};
}
// Bind to all spans with class="details"
//
var spans= document.getElementsByTagName('span');
for (var i= spans.length; i-->0;)
if (spans[i].className=='details')
infoToggle(spans[i]);
</script>
I'm not sure of the implementation, but the logic will look similiar to
Get all spans
Hide adjacent spans
beneath (leave them visible for non
JS users by default)
Attach even
handler to first spans
Event handler
function - show next span if next
span invisible, otherwise hide it
This is off the top of my head & untested. It should get you going at least.
<script>
function toggle(id)
{
var display = document.getElementById(id).style.display;
if ( display == "block" )
document.getElementById(id).style.display = "none";
else
document.getElementById(id).style.display = "block";
}
</script>
<span onclick="javascript: toggle('span_to_toggle');" id="clickable_span">click here</span>
<span id='span_to_toggle' style="diplay:none">foooooooooooooooooooooo</span>
quick rework of #Jason:
<script>
function toggle(targetId, sender)
{
var show = document.getElementById(targetId);
show.style.display = "block";
sender.style.display = "none";
}
</script>
<span onclick="javascript: toggle('more', this);" id="less">click here</span>
<span style="display:none;" id="more" onclick="javascript: toggle('less', this);" >foooooooooooooooooooooo</span>
Just as a side note for when you're developing javascript stuff which involves creating elements in the DOM. If you're not going to use something like jQuery (I'm not a fan of frameworks, too heavy and non-specific) try and use a function to make your elements for you, that way you don't have too many redundant lines as it tends to make your scripts really heavy.
I personally use a code snippet i found here www.dev-explorer.com/articles/create-dom-object but you might find something that suits you better. If your site downloads quicker the user doesn't have to wait as long for onload events etc and generally doesn't get annoyed as easily.
Hope this made sense
Thanks,
Scarlet
I'd rather not use jQuery or any other heavyweight dependency.
I don't know if that is a good approach. Unless you can attribute any real performance problem to using jQuery or prototype.js (which are both not really that heavy), you should use them.
Otherwise you will just spend a lot of time with repetitive typing and on fixing nasty browser bugs and incompatibilites.
I don't have a way of easily generating unique IDs
Again, you really want $$('div span[someParam=something]'). And since the libraries dispatch this to native browser query functions where available, it is probably not even slower than a hand-coded solution. Definitely more maintainable.

Categories

Resources