Javascript Skip hide/show divs - javascript

I am not that strong when it comes to JS. However I have written a little bit of code that does exactly what I want it to do.
function showDiv(divName)
{
var divnameids = new Array();
divnameids[0] = "accessories";
divnameids[1] = "connections";
divnameids[2] = "features";
divnameids[3] = "phones";
divnameids[4] = "services";
for (var i=0;i<divnameids.length;i++)
{
if (divnameids[i] == divName) divnameids.splice(i, 1);
}
for (var i=0;i<divnameids.length;i++)
{
document.getElementById(divnameids[i]).style.display='none';
document.getElementById('but' + divnameids[i]).className = "ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only";
}
document.getElementById('but' + divName).className = "quotebutton ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only";
document.getElementById(divName).style.display='block';
}
This works but the corresponding buttons triggering the opening and closing of divs like tabs.
However I now wish to use another button to skip through these divs in order (the same order as the JS array)
could somebody suggest the best approach to doing this?

This code should open each div, and then close the previous one:
var currentPos = 0;
$('#yourButtonId').on('click', function () {
if (currentPos > 0)
$('#' + divnameids[currentPos - 1]).hide();
if (currentPos == 0) // hide the last tab when coming back to the start
$('#' + divnameids[divnameids.length - 1]).hide();
$('#' + divnameids[currentPos]).show();
currentPos += 1;
// Reset the current position to 0
if (currentPos >= divnameids.length)
currentPos = 0;
});

Assuming that you wanted a pure Javascript solution, this works (assuming that I was in the ballpark on your HTML):
function nextDiv() {
var divnameids = new Array();
divnameids[0] = document.getElementById("accessories");
divnameids[1] = document.getElementById("connections");
divnameids[2] = document.getElementById("features");
divnameids[3] = document.getElementById("phones");
divnameids[4] = document.getElementById("services");
var len = divnameids.length;
for(var i=0; i < len; i++) {
if(i == (len - 1)) {
divnameids[len-1].style.display = 'none';
divnameids[0].style.display = '';
break;
}
else {
if(divnameids[i].style.display == '') {
divnameids[i].style.display = 'none';
divnameids[i+1].style.display = '';
break;
}
}
}
}
JSFiddle: http://jsfiddle.net/yjf8w/

$(document).ready(function(){
$(".content-box-front").click(function(){
$(".full-content-back").fadeIn("slow");
$(".full-content-front").fadeIn("slow");
$(".content-box-front").fadeOut("slow");
$(".content-box-back").fadeOut("slow");
});
});
$(document).ready(function(){
$(".full-content-front").click(function(){
$(".full-content-back").fadeOut("slow");
$(".full-content-front").fadeOut("slow");
$(".content-box-front").fadeIn("slow");
$(".content-box-back").fadeIn("slow");
});
});
this should help put the name of the divs in where full-content.... is

Related

Is it possible to use JavaScript element id Name as a variable in for loop

Any idea to make JavaScript id name as a variable.
var tblFruits2 = document.getElementById("table");
//Reference all the CheckBoxes in Table.
var chks2 = tblFruits2.getElementsByTagName("INPUT");
for (var i = 1; i < chks2.length+1; i++) {
var x = document.getElementById("table").rows[i].cells[2].innerHTML;
if (i == 1) { document.getElementById('HiddenField1').innerHTML = x; }
if (i == 2) { document.getElementById('HiddenField2').innerHTML = x; }
if (i == 3) { document.getElementById('HiddenField3').innerHTML = x; }
if (i == 4) { document.getElementById('HiddenField4').innerHTML = x; }
if (i == 5) { document.getElementById('HiddenField5').innerHTML = x; }
if (i == 6) { document.getElementById('HiddenField6').innerHTML = x; }
if (i == 7) { document.getElementById('HiddenField7').innerHTML = x; }
if (i == 8) { document.getElementById('HiddenField8').innerHTML = x; }
if (i == 9) { document.getElementById('HiddenField9').innerHTML = x; }
if (i == 9) { document.getElementById('HiddenField10').innerHTML = x; }
if (i == 10) { document.getElementById('HiddenField11').innerHTML = x; }
if (i == 11) { document.getElementById('HiddenField11').innerHTML = x; }
if (i == 12) { document.getElementById('HiddenField12').innerHTML = x; }
if (i == 13) { document.getElementById('HiddenField13').innerHTML = x; }
if (i == 14) { document.getElementById('HiddenField14').innerHTML = x; }
if (i == 15) { document.getElementById('HiddenField15').innerHTML = x; }
}
Why dont't you simply create your HiddenFields on demand like this:
You create a parent div in which you want to add your HiddenField:
<div id="collectionView">
<!-- items will be created here -->
</div>
Javscript would look like this:
var chks2 = tblFruits2.getElementsByTagName("INPUT");
for (var i = 1; i < chks2.length+1; i++) {
var x = document.getElementById("table").rows[i].cells[2].innerHTML;
var HiddenField = document.createElement("div");
var HiddenField.innerHTML = '<div id="HiddenField' + 'i' + '"></div>';
// deleteButton.setAttribute("hidden", "true");
var view = document.getElementById("collectionView");
view.appendChild(HiddenField);
}
If you want to add any other attributes to the div, you can do that with .setAttribute as I displayed or use the different pre-defined attributes html provides. Of course you can also append other divs or elements to your HiddenField using HiddenField.appendChild(new-div); underneath view.appendChild.
If you need to reverse your array (the HiddenFields are created the wrong way round) you can use var chks2 = chks2.slice().reverse();.
Using this method would allow you not to have useless code laying around in your html. I can also see the disadvantages, e. g. if the HiddenFields contain different code/information/attributes and are not similar.
Note: I used a different, more ugly js-code and have not tried the one in this example. Please let me know if this one does not work!

Count element clicks and define an max

I tried to count an element clicks, and, in the right number call some action.
var count = 0;
document.getElementById("rolarbaixo").onClick = function(e) {
if( count >= 3 ) {
var elem = document.getElementById("noticia");
elem.setAttribute("style","top: 0px;");
}
else {
count ++;
}
};
When i clicked 3 times in the link "rolarbaixo" the div "noticia" set the "top: 0px;", but this doesn't work.
Why?
count ++ should be count++. If you press F12, you will be able to get to the developer tools and debug the javascript.
It's onclick in lowercase
var count = 0;
document.getElementById("rolarbaixo").onclick = function (e) {
if (count >= 2) {
var elem = document.getElementById("noticia");
elem.style.top = "0px";
} else {
count++;
}
};
FIDDLE
And it's >= 2 for three clicks (zero based and all).
AS the question is tagged jQuery, this would be it
$('#rolarbaixo').on('click', function() {
var clicked = $(this).data('clicked') || 0;
if (clicked >= 2) $('#noticia').css('top', 0);
$(this).data('clicked', ++clicked);
});
FIDDLE
Misprint in else statement and change onclick to lowercase:
var count = 0;
document.getElementById("rolarbaixo").onclick = function(e) {
if( count >= 3 ) {
var elem = document.getElementById("noticia");
elem.setAttribute("style","top: 0px;");
} else {
count++;
}
};

Large list rendering in JavaScript

I am trying to render the list based on virtual rendering concept. I am facing some minor issues, but they are not blocking the behaviour. Here is the working fiddle http://jsfiddle.net/53N36/9/ and Here are my problems
Last items are not visible, I assume some where I missed indexing.(Fixed, Please see the edit)
How to calculate scrollPosition if I want to add custom scroll to this.
Is this the best method or any other?
I have tested it with 700000 items and 70 items in chrome. Below is the code
(function () {
var list = (function () {
var temp = [];
for (var i = 0, l = 70; i < l; i++) {
temp.push("list-item-" + (i + 1));
}
return temp;
}());
function listItem(text, id) {
var _div = document.createElement('div');
_div.innerHTML = text;
_div.className = "listItem";
_div.id = id;
return _div;
}
var listHold = document.getElementById('listHolder'),
ht = listHold.clientHeight,
wt = listHold.clientWidth,
ele = listItem(list[0], 'item0'),
frag = document.createDocumentFragment();
listHold.appendChild(ele);
var ht_ele = ele.clientHeight,
filled = ht_ele,
filledIn = [0];
for (var i = 1, l = list.length; i < l; i++) {
if (filled + ht_ele < ht) {
filled += ht_ele;
ele = listItem(list[i], 'item' + i);
frag.appendChild(ele);
} else {
filledIn.push(i);
break;
}
}
listHold.appendChild(frag.cloneNode(true));
var elements = document.querySelectorAll('#listHolder .listItem');
function MouseWheelHandler(e) {
var e = window.event || e;
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
console.log(delta);
//if(filledIn[0] != 0 && filledIn[0] != list.length){
if (delta == -1) {
var start = filledIn[0] + 1,
end = filledIn[1] + 1,
counter = 0;
if (list[start] && list[end]) {
for (var i = filledIn[0]; i < filledIn[1]; i++) {
if (list[i]) {
(function (a) {
elements[counter].innerHTML = list[a];
}(i));
counter++;
}
}
filledIn[0] = start;
filledIn[1] = end;
}
} else {
var start = filledIn[0] - 1,
end = filledIn[1] - 1,
counter = 0;
if (list[start] && list[end]) {
for (var i = start; i < end; i++) {
if (list[i]) {
(function (a) {
elements[counter].innerHTML = list[a];
}(i));
counter++;
}
}
filledIn[0] = start;
filledIn[1] = end;
}
}
//}
}
if (listHold.addEventListener) {
listHold.addEventListener("mousewheel", MouseWheelHandler, false);
listHold.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
} else listHold.attachEvent("onmousewheel", MouseWheelHandler);
}());
Please suggest me on this.
EDIT:
I have tried again and I am able to fix the indexing issue. http://jsfiddle.net/53N36/26/
But how can I calculate the scroll position based on the array list currently displayed.
Is this the best method or any other?
I think something that would make this much easier is not to try to handle scrolling yourself.
In this fiddle I show that you can let the browser handle scrolling for you, even though we are using virtual rendering.
Using .scrollTop I detect where the browser thinks the user is looking, and I draw in items based on that.
You'll note that if you set hidescrollbar to false and the user uses it to scroll, my method still runs fine.
Therefore, to calculate scroll position you can just use .scrollTop.
And as for custom scrolling, just make sure you influence the .scrollTop of #listHolder and recall refreshWindow()
CODE FROM FIDDLE
(function () {
//CHANGE THESE IF YOU WANT
var hidescrollbar = false;
var numberofitems = 700000;
//
var holder = document.getElementById('listHolder');
var view = null;
//get the height of a single item
var itemHeight = (function() {
//generate a fake item
var div = document.createElement('div');
div.className = 'listItem';
div.innerHTML = 'testing height';
holder.appendChild(div);
//get its height and remove it
var output = div.offsetHeight;
holder.removeChild(div);
return output;
})();
//faster to instantiate empty-celled array
var items = Array(numberofitems);
//fill it in with data
for (var index = 0; index < items.length; ++index)
items[index] = 'item-' + index;
//displays a suitable number of items
function refreshWindow() {
//remove old view
if (view != null)
holder.removeChild(view);
//create new view
view = holder.appendChild(document.createElement('div'));
var firstItem = Math.floor(holder.scrollTop / itemHeight);
var lastItem = firstItem + Math.ceil(holder.offsetHeight / itemHeight) + 1;
if (lastItem + 1 >= items.length)
lastItem = items.length - 1;
//position view in users face
view.id = 'view';
view.style.top = (firstItem * itemHeight) + 'px';
var div;
//add the items
for (var index = firstItem; index <= lastItem; ++index) {
div = document.createElement('div');
div.innerHTML = items[index];
div.className = "listItem";
view.appendChild(div);
}
console.log('viewing items ' + firstItem + ' to ' + lastItem);
}
refreshWindow();
document.getElementById('heightForcer').style.height = (items.length * itemHeight) + 'px';
if (hidescrollbar) {
//work around for non-chrome browsers, hides the scrollbar
holder.style.width = (holder.offsetWidth * 2 - view.offsetWidth) + 'px';
}
function delayingHandler() {
//wait for the scroll to finish
setTimeout(refreshWindow, 10);
}
if (holder.addEventListener)
holder.addEventListener("scroll", delayingHandler, false);
else
holder.attachEvent("onscroll", delayingHandler);
}());
<div id="listHolder">
<div id="heightForcer"></div>
</div>
html, body {
width:100%;
height:100%;
padding:0;
margin:0
}
body{
overflow:hidden;
}
.listItem {
border:1px solid gray;
padding:0 5px;
width: margin : 1px 0px;
}
#listHolder {
position:relative;
height:100%;
width:100%;
background-color:#CCC;
box-sizing:border-box;
overflow:auto;
}
/*chrome only
#listHolder::-webkit-scrollbar{
display:none;
}*/
#view{
position:absolute;
width:100%;
}

getElementsByClassName IE resolution issue

I am having issues figuring out how to resolve the getElementsByClassName issue in IE. How would I best implement the robert nyman (can't post the link to it since my rep is only 1) resolution into my code? Or would a jquery resolution be better? my code is
function showDesc(name) {
var e = document.getElementById(name);
//Get a list of elements that have a class name of service selected
var list = document.getElementsByClassName("description show");
//Loop through those items
for (var i = 0; i < list.length; ++i) {
//Reset all class names to description
list[i].className = "description";
}
if (e.className == "description"){
//Set the css class for the clicked element
e.className += " show";
}
else{
if (e.className == "description show"){
return;
}
}}
and I am using it on this page dev.msmnet.com/services/practice-management to show/hide the description for each service (works in Chrome and FF). Any tips would be greatly appreciated.
I was curious to see what a jQuery version of your function would look like, so I came up with this:
function showDesc(name) {
var e = $("#" + name);
$(".description.show").removeClass("show");
if(e.attr("class") == "description") {
e.addClass("show");
} else if(e.hasClass("description") && e.hasClass("show")) {
return;
}
}
This should support multiple classes.
function getElementsByClassName(findClass, parent) {
parent = parent || document;
var elements = parent.getElementsByTagName('*');
var matching = [];
for(var i = 0, elementsLength = elements.length; i < elementsLength; i++){
if ((' ' + elements[i].className + ' ').indexOf(findClass) > -1) {
matching.push(elements[i]);
}
}
return matching;
}
You can pass in a parent too, to make its searching the DOM a bit faster.
If you want getElementsByClassName('a c') to match HTML <div class="a b c" /> then try changing it like so...
var elementClasses = elements[i].className.split(/\s+/),
matchClasses = findClass.split(/\s+/), // Do this out of the loop :)
found = 0;
for (var j = 0, elementClassesLength = elementClasses.length; j < elementClassesLength; j++) {
if (matchClasses.indexOf(elementClasses[j]) > -1) {
found++;
}
}
if (found == matchClasses.length) {
// Push onto matching array
}
If you want this function to only be available if it doesn't already exist, wrap its definition with
if (typeof document.getElementsByClassName != 'function') { }
Even easier jQuery solution:
$('.service').click( function() {
var id = "#" + $(this).attr('id') + 'rt';
$('.description').not(id).hide();
$( id ).show();
}
Why bother with a show class if you are using jQuery?
Heres one I put together, reliable and possibly the fastest. Should work in any situation.
function $class(className) {
var children = document.getElementsByTagName('*') || document.all;
var i = children.length, e = [];
while (i--) {
var classNames = children[i].className.split(' ');
var j = classNames.length;
while (j--) {
if (classNames[j] == className) {
e.push(children[i]);
break;
}
}
}
return e;
}
I used to implement HTMLElement.getElementByClassName(), but at least Firefox and Chrome, only find the half of the elements when those elements are a lot, instead I use something like (actually it is a larger function):
getElmByClass(clm, parent){
// clm: Array of classes
if(typeof clm == "string"){ clm = [clm] }
var i, m = [], bcl, re, rm;
if (document.evaluate) { // Non MSIE browsers
v = "";
for(i=0; i < clm.length; i++){
v += "[contains(concat(' ', #"+clc+", ' '), ' " + base[i] + " ')]";
}
c = document.evaluate("./"+"/"+"*" + v, parent, null, 5, null);
while ((node = c.iterateNext())) {
m.push(node);
}
}else{ // MSIE which doesn't understand XPATH
v = elm.getElementsByTagName('*');
bcl = "";
for(i=0; i < clm.length; i++){
bcl += (i)? "|":"";
bcl += "\\b"+clm[i]+"\\b";
}
re = new RegExp(bcl, "gi");
for(i = 0; i < v.length; i++){
if(v.className){
rm = v[i].className.match(bcl);
if(rm && rm.length){ // sometimes .match returns an empty array so you cannot use just 'if(rm)'
m.push(v[i])
}
}
}
}
return m;
}
I think there would be a faster way to iterate without XPATH, because RegExp are slow (perhaps a function with .indexOf, it shuld be tested), but it is working well
You can replace getElementsByClassName() with the following:
function getbyclass(n){
var elements = document.getElementsByTagName("*");
var result = [];
for(z=0;z<elements.length;z++){
if(elements[z].getAttribute("class") == n){
result.push(elements[z]);
}
}
return result;
}
Then you can use it like this:
getbyclass("description") // Instead of document.getElementsByClassName("description")

removing html element styles via javascript

I'm trying to replace an element's inline style tag value. The current element looks like this:
`<tr class="row-even" style="background: red none repeat scroll 0% 0%; position: relative; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" id="0000ph2009-06-10s1s02">`
and I'd like to remove all that style stuff so that it's styled by it's class rather than it's inline style. I've tried delete element.style; and element.style = null; and element.style = ""; to no avail. My current code breaks at these statement. The whole function looks like:
function unSetHighlight(index){
if(index < 10)
index = "000" + (index);
else if (index < 100)
index = "000" + (index);
else if(index < 1000)
index = "0" + (index);
if(index >= 1000)
index = index;
var mainElm = document.getElementById('active_playlist');
var elmIndex = "";
for(var currElm = mainElm.firstChild; currElm !== null; currElm = currElm.nextSibling){
if(currElm.nodeType === 1){
var elementId = currElm.getAttribute("id");
if(elementId.match(/\b\d{4}/)){
elmIndex = elementId.substr(0,4);
if(elmIndex == index){
var that = currElm;
//that.style.background = position: relative;
}
}
}
}
clearInterval(highlight);
alert("cleared Interval");
that.style.background = null;
alert("unSet highlight called");
}
the clearInterval works but the alert never fires and the background stays the same. What's the problem?
function unSetHighlight(index){
alert(index);
if(index < 10)
index = "000" + (index);
else if (index < 100)
index = "000" + (index);
else if(index < 1000)
index = "0" + (index);
if(index >= 1000)
index = index;
var mainElm = document.getElementById('active_playlist');
var elmIndex = "";
for(var currElm = mainElm.firstChild; currElm !== null; currElm = currElm.nextSibling){
if(currElm.nodeType === 1){
var elementId = currElm.getAttribute("id");
if(elementId.match(/\b\d{4}/)){
elmIndex = elementId.substr(0,4);
alert("elmIndex = " + elmIndex + "index = " + index);
if(elmIndex === index){
var that = currElm;
alert("match found");
}
}
}
}
clearInterval(highlight);
alert("cleared Interval");
that.removeAttribute("style");
//that.style.position = "relative";
//reColor();
alert("unSet highlight called");
}
you can just do:
element.removeAttribute("style")
In JavaScript:
document.getElementById("id").style.display = null;
In jQuery:
$("#id").css('display',null);
getElementById("id").removeAttribute("style");
if you are using jQuery then
$("#id").removeClass("classname");
The class attribute can contain multiple styles, so you could specify it as
<tr class="row-even highlight">
and do string manipulation to remove 'highlight' from element.className
element.className=element.className.replace('hightlight','');
Using jQuery would make this simpler as you have the methods
$("#id").addClass("highlight");
$("#id").removeClass("hightlight");
that would enable you to toggle highlighting easily
Use
particular_node.classList.remove("<name-of-class>")
For native javascript
Remove removeProperty
var el=document.getElementById("id");
el.style.removeProperty('display')
console.log("display removed"+el.style["display"])
console.log("color "+el.style["color"])
<div id="id" style="display:block;color:red">s</div>
In jQuery, you can use
$(".className").attr("style","");
Completly removing style, not only set to NULL
document.getElementById("id").removeAttribute("style")

Categories