transforming jquery to java script - javascript

I have this script made with jQuery which I am using to show / hide divs on my page.
I really need it to be made purely in JavaScript and I have no idea how to do this.
Could anyone help me ???
I think I need a converter or something . . .
$("#optiuni").children().click(function(){
$("#" + $(this).attr('name')).show().siblings().hide();
/*Gives the link-activ class to the link that i clicked an link-inactive to all others*/
$(this).attr('class','link-activ').siblings().attr('class','link-neactiv');
});
/*this makes shure that the first option from my list is active incarcarea paginii*/
$("#optiuni li.prima").children().click();
Sample markup:
<div id="lista">
<ul id="optiuni">
<li id="titlu-lista-p"> <p class="listname-t">Past Events </p></li>
<li name="opt-1" class="prima"><p class="listdata">28.02.2011</p><p class="listname">TABU Oscar Party</p> </li>
<li name="opt-2" ><p class="listdata">24.03.2011</p><p class="listname">Cheese & Wine</p></li>
<li name="opt-8"><p class="listdata">08.04.2011</p><p class="listname">George Baicea</p></li>
</ul>
</div>
<div class="centru">
<div id="continut" >
<div id="opt-2" class="galerie" style="background-color: black;">
<iframe id="gal" src="cheese/index.html"></iframe>
</div>
<div id="opt-1" class="galerie" style="background-color: black;">
<iframe src="tabu/index.html"></iframe>
</div>
<div id="opt-8" class="galerie" style="background-color: blue;">
<iframe src="no-ev/index.html"></iframe>
</div>
</div>
</div>

Here's an example of how you could do this based on the markup you linked to in your comment, as there are some assumptions you could make based on the jQuery version which don't hold when you see the markup.
jsFiddle with a live example.
// IE sucks
function addEvent(el, name, handler) {
if (el.addEventListener) {
el.addEventListener(name, handler, false);
} else if (el.attachEvent) {
// Make sure "this" references the element we're adding the event handler to
el.attachEvent('on' + name, function() { handler.call(el, window.event); });
}
}
function eachElementSibling(el, func) {
var childNodes = el.parentNode.childNodes;
for (var i = 0, sibling; sibling = childNodes[i]; i++) {
if (sibling.nodeType !== 1 || sibling === el) {
continue;
}
func(sibling);
}
}
function activateLink() {
var elToShow = document.getElementById(this.getAttribute('name'));
elToShow.style.display = '';
eachElementSibling(elToShow, function(s) { s.style.display = 'none'; });
this.className = 'link-active';
eachElementSibling(this, function(s) {
if (s.getAttribute('name')) { s.className = 'link-neactiv'; }
});
}
var items = document.getElementById('optiuni').getElementsByTagName('li');
var initialItem = null;
for (var i = 0, item; item = items[i]; i++) {
// Need to filter, as non-link items are also present in the list
if (item.getAttribute('name')) {
addEvent(item, 'click', activateLink);
if (item.className === 'prima') {
initialItem= item;
}
}
}
if (initialItem) {
activateLink.call(initialItem)
}

Related

How to display hidden div after mouse out or hover

Hi guys can someone help me here I want to make a hidden div being displayed after I trigger the event to display and I remove the mouse on that div here is my code
<div id='MainContainer'>
<div id='btn-img' onmouseover='DisplayHidden()'>content 1</div>
<div id='container2'>content 2</div>
</div>
function DisplayHidden()
{
$('#container2').show();
}
is it possible?
I preferred this way because if you want to add more attributes and comparisons parameters you may add it easily and attribute binding is dynamical.
$(document).ready(function(){
$("#MainContainer > div").on("click",function(e){
if(false === !!$(this).attr('data-click')){
$(this).attr("data-click", true);
alert('No');
}else{
alert('Clicking on same div');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='MainContainer'>
<div id='container1'>content 1</div>
<div id='container2'>content 2</div>
</div>
Here is what you could do, using pure javascript.
Bind the click event on the container element and use event.target attribute to check the previous click element and take appropriate action.
Event.target documentation on MDN
document.addEventListener("DOMContentLoaded", function() {
var prevElement = null;
document.querySelector("#MainContainer").addEventListener("click", function(event) {
if (prevElement === event.target) {
console.log("Yes")
} else {
console.log("No");
}
prevElement = event.target;
});
});
<div id='MainContainer'>
<div id='container1'>content 1</div>
<div id='container2'>content 2</div>
</div>
var lastClick = null;
$('div#MainContainer div').click(function() {
var clickedId = $(this).attr('id');
if (clickedId == lastClick) {
alert('Clicked the same div');
}
else {
alert('Clicked on a different div');
lastClick = clickedId;
}
});
Here a simple solution with plain javascript:
var g_lastTarget = null
var g_handleClick = function(e) {
var target = e.currentTarget
if (g_lastTarget === target) {
alert('You clicked the container twice. Container ID = ' + target.id)
}
g_lastTarget = target
}
var c1 = document.getElementById('container1')
var c2 = document.getElementById('container2')
c1.addEventListener('click', g_handleClick)
c2.addEventListener('click', g_handleClick)
Create a common class & use querySelectorAll to select the desirable elements.
Then loop through it attach eventListener method to it.Create a variable to store the id of the currently clicked element. On subsequent click check if the variable value and id is same. If it is same then throw an alert.
var getElements = document.querySelectorAll(".elem");
var clickedElem = "";
getElements.forEach(function(item) {
item.addEventListener('click', function() {
if (item.id === clickedElem) {
alert('Clicking on same div')
} else {
clickedElem = item.id
}
})
})
<div id='MainContainer'>
<div id='container1' class="elem">content 1</div>
<div id='container2' class="elem">content 2</div>
</div>

Multiple onclick button events Vanilla Javascript

I would like to change an inputs value whenever one of my many "li" tags are clicked (without using jQuery). I listed two of the list tags in my HTML below and I want to differentiate between them in my if statement. What would I put inside the if parameters to display buttons[0] being clicked or buttons[1]?
function myFunction() {
var input = document.getElementById('values');
var buttons = document.getElementsByTagName('li');
if(buttons[0]) {
input.value = 0;
}
else if(buttons[1]) {
input.value += 1;
}
};
HTML :
<div class="box">
<input id="values" type="text" placeholder="2017">
<ul>
<li onclick="myFunction()" id="1">C</li>
<li onclick="myFunction()" id="2">1</li>
</ul>
</div>
Two mistakes.
First, It is because of your if statement checks whether button[0] and button[1] are undefined.
Since button[0] is defined, it never goes to your second condition. So, your statement is just the same as:
function myFunction() {
var input = document.getElementById('values');
var buttons = document.getElementsByTagName('li');
if(buttons[0]) {
input.value = 0;
}
// the second if else is redundant because buttons[0] is not undefined
};
Second, input value is in string, so to increment, you need to parse it to integer. So for the fix:
function myFunction(e) {
var input = document.getElementById('values');
var buttons = document.getElementsByTagName('li');
if(buttons[0].id === e.target.id) {
input.value = 0;
}
else if(buttons[1].id === e.target.id) {
input.value = parseInt(input.value) + 1;
}
};
And your html needs to change a bit, because the function needs to capture the click event:
<div class="box">
<input id="values" type="text" placeholder="2017">
<ul>
<li onclick="myFunction(event)" id="1">C</li>
<li onclick="myFunction(event)" id="2">1</li>
</ul>
</div>
Given html at Question, if <li> elements have an id, you can pass this to myFunction, use id of li element
<li onclick="myFunction(this)" id="1">C</li>
<li onclick="myFunction(this)" id="2">1</li>
if(this.id === "1") {
input.value = 0;
}
else if(this.id === "2") {
input.value += 1;
}
I am somewhat confused as to what you want, but I think this should come pretty close? Let me know and I'm happy to help further.
EDIT: Just noticed you were calling this function from the element itself. Ignore this unless you want to abstract it, which I would usually suggest.
function myFunction() {
var input = document.getElementById('values');
var buttons = document.getElementsByTagName('li');
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function() {
if (i === 0) {
input.value = 0;
}
else if(i === 1) {
input.value += 1;
}
})
}
}
Instead of binding events to each <li>, use event delegation. Details are commented in Snippet.
SNIPPET
// Reference the <ul>
var list = document.querySelector('ul');
// When list is clicked call function delegator()
list.addEventListener('click', delegator, false);
/* This function uses a pattern called event...
||...delegation. Basically we register the event...
||...on the parent of multiple clickable elements...
||...In this case it would be <ul> and the children...
||...<li> would be the last in an event chain...
||...which would make that particular <li>...
||...the event.target (the one that's clicked)...
||...Any other elements above event.target are...
||...event.currentTarget. By knowing this, we can...
||...determine event.target by determining what is...
||...event.currentTarget.
*/
function delegator(event) {
// If it ain't event.currentTarget...
if (event.target !== event.currentTarget) {
/*...then it's gotta be event.target...
||...so let's store it's id in a var
*/
var tgt = event.target.id;
// Reference the id to as an DOM object
var target = document.getElementById(tgt);
// Get and store target's text
var value = target.textContent;
// Get and set textbox's value to the text of target
document.getElementById('values').value = value;
}
return false;
}
<div class="box">
<input id="values" type="text" placeholder="2017">
<ul>
<li id="i1">C</li>
<li id="i2">1</li>
</ul>
</div>

Issues with using classList to hide and show elements

I need to implement a feature where a div shows up when another div is clicked and should hide if the div is clicked again.
Here is the fiddle with a small portion of the code : https://jsfiddle.net/6dgL6zqb/1/
var portfolio = document.getElementById('portfolio');
EventUtil.addHandler(portfolio, 'click', function(event) {
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(target.id) {
case 'kk':
console.log('kk clicked');
var idName = target.id + 'Details',
doc = document,
currentProject = doc.getElementById(idName),
otherProjects = doc.getElementsByClassName('projectDetails');
console.log(currentProject);
for (var i = otherProjects.length - 1; i >= 0; i--) {
var projectClassList = otherProjects.item(i).classList;
if (projectClassList.contains('showMe')) {
projectClassList.remove('showMe');
projectClassList.add('hideMe');
}
};
var currentProjectClassList = currentProject.classList;
console.log(currentProjectClassList);
if (!currentProjectClassList.contains('showMe')) {
currentProjectClassList.remove('hideMe');
currentProjectClassList.add('showMe');
} else {
currentProjectClassList.remove('showMe');
currentProjectClassList.add('hideMe');
}
break;
}
});
I am using an EventUtil handler to handle events, along-with event delegation.
So, when I click on Section 1 with the id 'kk', another div with id 'kkDetails' displays. But, I expect the div with id 'kkDetails' to disappear when I click on the div with id 'kk'. How can I get that to happen?
As far as I can see, the currentProjectClassList object is not updating as I expect. Although, I don't understand why.
PS: I am new at programming, so please bear with any ignorance.
There problem that you are having is this section:
otherProjects = doc.getElementsByClassName('projectDetails');
for (var i = otherProjects.length - 1; i >= 0; i--) {
var projectClassList = otherProjects.item(i).classList;
if (projectClassList.contains('showMe')) {
projectClassList.remove('showMe');
projectClassList.add('hideMe');
}
};
You are actually hiding your element and then later showing it again, as an example modify this section to be something like:
otherProjects = doc.getElementsByClassName('projectDetails');
for (var i = otherProjects.length - 1; i >= 0; i--) {
if(otherProjects.item(i).id !== idName){
var projectClassList = otherProjects.item(i).classList;
if (projectClassList.contains('showMe')) {
projectClassList.remove('showMe');
projectClassList.add('hideMe');
}
}
};
In this section you are swapping the visible state of your selected div:
if (!currentProjectClassList.contains('showMe')) {
currentProjectClassList.remove('hideMe');
currentProjectClassList.add('showMe');
} else {
currentProjectClassList.remove('showMe');
currentProjectClassList.add('hideMe');
}
however in the previous section of code because your selected element also has the class projectDetails it gets its showMe removed and hideMe added. So when it gets to section of code above this if(!currentProjectClassList.contains('showMe')) will always be true.
I would use a single class to toggle visibility. It is a lot more manageable. Also I would link click element with the toggled element via an attribute of some kind (instead of using a switch statement in javascript).
EventUtil.addHandler(portfolio, 'click', function(event) {
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
var divId = target.getAttribute('href');
if (divId) {
event.preventDefault();
Array
.from(document.querySelectorAll('.projectDetails:not(.hideMe)'))
.forEach(function(a) {
a.classList.add('hideMe')
});
document.querySelector(divId).classList.remove('hideMe')
}
});
// Cross-browser event handler
var EventUtil = {
addHandler: function(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
getEvent: function(event) {
return event ? event : window.event;
},
getTarget: function(event) {
return event.target || event.srcElement;
},
preventDefault: function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
removeHandler: function(element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
},
stopPropagation: function(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
var portfolio = document.getElementById('portfolio');
EventUtil.addHandler(portfolio, 'click', function(event) {
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
var divId = target.getAttribute('href');
if (divId) {
event.preventDefault();
Array
.from(document.querySelectorAll('.projectDetails:not(.hideMe)'))
.forEach(function(a) {
a.classList.add('hideMe')
});
document.querySelector(divId).classList.remove('hideMe')
}
});
.projectDetails {
display: block;
}
.projectDetails.hideMe {
display: none;
}
<body>
<div class="container">
<section id="portfolio">
<div class="row">
<div class="col-sm-4">
Section 1
</div>
<div class="col-sm-4">
Section 2
</div>
<div class="col-sm-4">
Section 3
</div>
</div>
<div class="row">
<div id="kkDetails" class="hideMe projectDetails">
<p>Text</p>
</div>
<div id="arthDetails" class="hideMe projectDetails">
<p>Text 2</p>
</div>
<div id="bobyPinzDetails" class="hideMe projectDetails">
<p>Text 3</p>
</div>
</div>
</section>
</body>

Check whether a div or one of its children were clicked

I have a div as follows
<div class="parent">
<!--several child divs now-->
</div>
Now, I have registered a click handler on body using AngularJS as follows:
HTML:
<body ng-click="registerClick($event)">
</body>
Controller:
$scope.registerClick(e) {
//Here check if the parent div or one of its children were clicked
}
How, can use $event in my handler to determine if the div with class 'parent' or one of its children were clicked?
Change it to this:
$scope.registerClick(e) {
if (e.target.classList.contains('parent')){
// The .parent div is clicked
} else if (e.target.parentNode.classList.contains('parent')){
// Some child of the .parent div is clicked
} else {
var elem = e.target;
while(elem.tagName != 'body' || !elem.classList.contains('parent')){
elem = elem.parentNode;
}
if (elem.classList.contains('parent')){
console.log('DIV .parent')
} else {
console.log('Body tag reached. No .parent element found');
}
}
}
e.target is the clicked element. Use it to determine which element was clicked. This is a clean JavaScript solution. You wont even need the $scope.registerClick(e) { part if can attach the event like so:
someDiv.onclick = function(){/* Same code as above. */}
if you use the latter approach, 'this' points to the div, so you can that the validations a little bit.
You can do something like
var app = angular.module('my-app', [], function() {})
app.controller('AppController', function($scope) {
$scope.registerClick = function($event) {
//if has jQuery
if ($($event.target).closest('.parent').length) {
console.log('clicked parent');
$scope.jQuery = true;
} else {
$scope.jQuery = false;
}
var isParent = false;
if (angular.isFunction($event.target.closest)) {
isParent = !!$event.target.closest('.parent');
} else {
var tmp = $event.target;
do {
isParent = tmp.classList.contains('parent');
tmp = tmp.parentNode;
} while (tmp && tmp.classList && !isParent);
}
$scope.native = isParent;
};
})
.parent {
border: 1px solid grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="my-app">
<div ng-controller="AppController" ng-click="registerClick($event)">
<div>outside</div>
<div class="parent">
parent
<div>div</div>
<div>div</div>
</div>
<div>
jQuery: {{jQuery}}
</div>
<div>
native: {{native}}
</div>
</div>
</div>

javascript/Jquery improvement on a .hide() .show() div menu

i am super new to javascript and jquery self thought ....been working on this menu for a bit and i have finally "finished" but iv got some horrendous code and i am looking for ways to improve my code to make it more readable and functional any tips and hints would be helpful. the idea to save space on the page each div will have different parts of a form that the user will fill out
here is some of the code
<body>
<div class="content">
<div class="menu" id="menu"></div>
<div class="content" id="sort"></div>
<div class="menu"id="menu1"></div>
<div class="content" id="1sort"></div>
<div class="menu"id="menu2"></div>
<div class="content" id="sort2"></div>
</div>
<script>
var show = true;
var show2 = false;
var show3 = false;
$('#1sort').hide("fast");
$('#sort2').hide("fast");
$("#menu").click(function () {
if (show == true) {
$('#sort').hide("fast");
$('#1sort').show("fast");
show = false;
show2 = true;
} else if (show == false) {
$('#sort').show("fast");
$('#1sort').hide("fast");
$('#sort2').hide("fast");
show = true;
show2 = false;
show3 = false;
}
});
$("#menu1").click(function () {
if (show2 == true) {
$('#1sort').hide("fast");
$('#sort2').show("fast");
show2 = false;
show3 = true;
} else if (show2 == false) {
$('#1sort').show("fast");
$('#sort').hide("fast");
$('#sort2').hide("fast");
show = false;
show2 = true;
show3 = false;
}
});
$("#menu2").click(function () {
if (show3 == false) {
$('#1sort').hide("fast");
$('#sort').hide("fast");
$('#sort2').show("fast");
show = false;
show2 = false;
show3 = true;
}
});
</script>
You can use some basic traversal functions, and .is to determine visibility. You don't need boolean variables nor element IDs that way: http://jsfiddle.net/K2sqy/2/.
$(".menu").click(function() {
var $next = $(this).next(".content"); // corresponding .content element
var isVisible = $next.is(":visible"); // is it currently visible?
$(this).siblings(".content").hide("fast"); // hide all siblings
$next[isVisible ? "hide" : "show"]("fast"); // toggle the corresponding .content
if(isVisible) {
// it was visible, so now it's hidden. Show the other .content:
// the next or, if not available, the previous
var $second = $next.nextAll(".content").first();
if($second.length === 0) {
$second = $next.prevAll(".content").first();
}
$second.show("fast");
}
});
A useful technique here is to adorn some extra attributes (preferably html5 data-*) onto the links to indicate what it's associated content is.
<div class="menu" id="menu" data-content="sort"></div>
<div class="content" id="sort"></div>
<div class="menu"id="menu1" data-content="1sort"></div>
<div class="content" id="1sort"></div>
<div class="menu" id="menu2" data-content="sort2"></div>
<div class="content" id="sort2"></div>
You can then use this when an item is clicked to hide the currently visible one, and show the required one:
$('.menu').click(function(){
$('.content:visible').hide('fast');
$('#' + $(this).data('content')).show('fast');
});
Live example: http://jsfiddle.net/hAbPa/
You might also consider using jquery .toggle(). More info here.
$('#foo').toggle(showOrHide);
is equivalent to:
if ( showOrHide == true ) {
$('#foo').show();
} else if ( showOrHide == false ) {
$('#foo').hide();
}
I'm not 100% sure (untested)... but this is pretty close I think.
$(".menu").click(function (){
$(this).next('.content').toggle();
});

Categories