How can I get all the elements within a wrap to change color when mouse hovers on the cube in http://codepen.io/Feners4/pen/KggAwg? Currently, I can only get it to change on a single side the mouse hover on. I want to do this strictly with Angular for learning purposes.
This is my HTML:
<html>
<header>
Angularity
</header>
<h1>hjskl</hi>
<body ng-app="App">
<div class="wrap">
<div class="cube"change-background colorcode=¨#f45642¨>
<div class="front" change-background>AAA</div>
<div class="back" change-background></div>
<div class="top" change-background></div>
<div class="bottom" change-background></div>
<div class="left" change-background></div>
<div class="right" change-background></div>
</div>
</div>
<div class="wrap2">
<div class="cube2">
<div class="front2" change-background colorcode=¨#f45642¨>AAA</div>
<div class="back2" change-background ></div>
<div class="top2" change-background></div>
<div class="bottom2" change-background></div>
<div class="left2" change-background></div>
<div class="right2" change-background></div>
</div>
</div>
</body>
</html>
This is my JS:
angular.module('App', [])
.directive('changeBackground', ['$animate', function($animate) {
return {
restrict: 'EA',
scope: {
colorcode: '#?'
},
link: function($scope, element, attr) {
element.on('mouseenter', function() {
element.addClass('change-color');
element.css('background-color', $scope.colorcode);
});
element.on('mouseleave', function() {
element.removeClass('change-color');
element.css('background-color', '#red');
});
}
};
}])
One way to do this is add your directive to the parent of the cube sides, then inside use .children() to apply your function to each child item. Also you will want to have your class change-color to be general as in have not :foo, otherwise the CSS will still only apply to the hovered element even if they all have the class.
HTML
<div class="wrap">
<div class="cube" change-background colorcode=¨#f45642¨>
<div class="front" >AAA</div>
<div class="back" ></div>
<div class="top" ></div>
<div class="bottom" ></div>
<div class="left" ></div>
<div class="right" ></div>
</div>
</div>
<div class="wrap2">
<div class="cube2" change-background>
<div class="front2" colorcode=¨#f45642¨>AAA</div>
<div class="back2"></div>
<div class="top2"></div>
<div class="bottom2"></div>
<div class="left2"></div>
<div class="right2"></div>
</div>
</div>
JS
link: function($scope, element, attr) {
element.on('mouseenter', function() {
element.children().addClass('change-color');
element.children().css('background-color', $scope.colorcode);
});
element.on('mouseleave', function() {
element.children().removeClass('change-color');
element.children().css('background-color', '#red');
});
}
CSS
.change-color {
color: #fff;
background-color: #f45642;
cursor: pointer;
}
Pen Example
Related
I'm trying to refactor my jquery code to vanilla because I want to use js properly. But I'm having a problem. I cannot figure out how for example trigger event only on third element with specific class. Because querySelector always returns the first element with that class for example this is my half finished code
const box = document.querySelector('.media-page--box-container');
$(box).on('mouseenter', () => {
// $(this). => select hovered element and do something only on it
console.log('enter')
}).on('mouseleave', () => {
console.log('leave')
});
.media-page--box-container:not(:first-child){
margin-top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
You can find example in the snippet
Use the code below if you want to add a listener to one element.
const box = document.querySelector('.media-page--box-container');
box.addEventListener("click", function() {
console.log("Clicked!");
});
<div class="media-page--box-container">.media-page--box-container</div>
Or this code for few elements
const boxes = document.querySelectorAll('.media-page--box-container');
boxes.forEach(function(box){
box.addEventListener("click", function() {
console.log("Clicked!");
});
});
<div class="media-page--box-container">.media-page--box-container 1</div>
<div class="media-page--box-container">.media-page--box-container 2</div>
<div class="media-page--box-container">.media-page--box-container 3</div>
querySelector returns one object, querySelectorAll and getElementsByClassName return array of objects. Not getElementsByClassName require class name, not selector in parameters.
console.log("querySelector", document.querySelector('.media-page--box-container'));
console.log("querySelectorAll", document.querySelectorAll('.media-page--box-container'));
console.log("getElementsByClassName", document.getElementsByClassName('media-page--box-container'));
<div class="media-page--box-container">.media-page--box-container 1</div>
<div class="media-page--box-container">.media-page--box-container 2</div>
<div class="media-page--box-container">.media-page--box-container 3</div>
Note, if there will be no elements on the page, methods will return null. So, you should check this case. If box will null, the code will break with an error.
const box = document.querySelector('.media-page--box-container');
console.log("box value", box);
// Wrong:
box.addEventListener("click", function() {
console.log("Clicked!");
});
// Correct:
if (box !== null)
box.addEventListener("click", function() {
console.log("Clicked!");
});
<div class="media-page--box-container-A">.media-page--box-container-A</div>
<div class="media-page--box-container-B">.media-page--box-container-B</div>
This answer should highlight a few things. You may need to handle event bubbling differently. I added e.target to the hover message. Your target is a block element that will trigger the mouse events even where you can't see it so I highlighted it in red. querySelectorAll will grab all elements not just the first one the way querySelector works.
const boxes = document.querySelectorAll('.media-page--box-container');
boxes[2].addEventListener("mouseover", myMouseover );
boxes[2].addEventListener("mouseleave", myMouseout);
function myMouseover(e) {
console.log('enter' + e.target);
}
function myMouseout() {
console.log('leave');
}
.media-page--box-container:not(:first-child) {
margin-top: 50px;
}
.media-page--box-container {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
You can use querySelectorAll to retrieve all nodes matching your selector.
Because it returns a NodeList, which is an array-like object, you can traverse that by invoking array.prototype.foreach and passing through the nodelist.
From there you can add event listeners to each item in the node list, or any individual node based on the iterator.
const boxes = document.querySelectorAll('.media-page--box-container');
Array.prototype.forEach.call(boxes, (box, i) => {
if (i===2) {
box.addEventListener('mouseenter', () => {
console.log('enter')
});
box.addEventListener('mouseleave', () => {
console.log('leave')
});
}
});
.media-page--box-container:not(:first-child){
margin-top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
I want to launch a new page when a cube is clicked using Angular. My code is currently not doing anything when I click the boxes so I might have everything wrong.
My on-click function is:
$scope.clicked = function(){
console.log('pppp');
window.location = "#/test.html";
}
I call the function in my HTML like this:
<html>
<link href="https://fonts.googleapis.com/css?family=Bungee+Hairline" rel="stylesheet">
<header>
Angularity
</header>
<body ng-app="App">
<div ng-click="clicked()" class="wrap">
<div class="cube" change-background colorcode=¨#f45642¨>
<div class="front" ><span>E</span></div>
<div class="back" ></div>
<div class="top" ></div>
<div class="bottom" ></div>
<div class="left" ></div>
<div class="right" ></div>
</div>
</div>
<div class="wrap2">
<div class="cube" change-background>
<div class="front" colorcode=¨#f45642¨><span>S</span></div>
<div class="back"></div>
<div class="top"></div>
<div class="bottom"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</div>
<div class="wrap3">
<div class="cube" change-background>
<div class="front" colorcode=¨#f45642¨><span>C</span></div>
<div class="back"></div>
<div class="top"></div>
<div class="bottom"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</div>
</body>
</html>
What is wrong with my code that is not allowing a new link to launch when a box is clicked?
http://codepen.io/Feners4/pen/KggAwg
You need to define the ng-controller and define the clicked function there.
<body ng-app="App">
<div ng-controller="TestCtrl">
.....
</div>
</body>
Here's a fixed version. The problem in your original code pen was that the div element was outside your directive. You also defined $scope.clicked in the wrong spot. I've created a new directive myClick, so it now the HTML looks like
<div ng-click="clicked()" my-click class="wrap">
<div class="cube" change-background colorcode="#f45642">
</div>
</div>
And the directive definition is here:
angular.module('App', [])
.directive('changeBackground', () => {...})
.directive('myClick', () => {
return {
restrict: 'A',
link: (scope) => {
scope.clicked = () => {
console.log('pppp');
window.location = "#/test.html";
}
}
};
});
http://codepen.io/phillypham/pen/PbgXOE
If you don't want to create a new controller and you want just to redirect the user to that url, you can add the click event on your directive:
link: function($scope, element, attr) {
element.on('click', function() { window.location = "#/test.html"; });
[omissis]
enter code here
http://codepen.io/Feners4/pen/KggAwg
I want to get the cubes to change color with mouse hover using Angular. Ive managed to get it to work on one side of a cube, but I want the effect to change the whole cube color.
This is my HTML:
<header>
Angularity
</header>
<h1>hjskl</hi>
<body>
<div class="container" ng-controller="AppCtrl">
</div>
</header>
<div class="wrap">
<div ng-app="App" class="cube"change-background colorcode=¨#FE0883¨>
<div class="front">AAA</div>
<div class="back"></div>
<div class="top"></div>
<div class="bottom"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</div>
</header>
<div class="wrap2">
<div class="cube2">
<div ng-app="App" class="front2" change-background colorcode=¨#FE0883¨>AAA</div>
<div class="back2"></div>
<div class="top2"></div>
<div class="bottom2"></div>
<div class="left2"></div>
<div class="right2"></div>
</div>
</div>
My JS:
angular.module('App', [])
.directive('changeBackground', ['$animate', function($animate) {
return {
restrict: 'EA',
scope: {
colorcode: '#?'
},
link: function($scope, element, attr) {
element.on('mouseenter', function() {
element.addClass('change-color');
element.css('background-color', $scope.colorcode);
});
element.on('mouseleave', function() {
element.removeClass('change-color');
element.css('background-color', '#fff');
});
}
};
}])
How can I get the cubes to Change color on Mouse hover to work and when Mouse leaves it changes back?
One of the main problems here is how you defined ng-app, as I've stated in my comment this defines the root of the application to be used by Angular. Placing it in such a specific location would mean none of the other elements are connected to Angular. The first thing that needs to be done is your HTML should be cleaned up, there are duplicate closing header tags with no openings and there is not a closing body. Since you never defined a controller and it's not being used I removed it (otherwise it will throw an error) After that you can just define your ng-app on the body and that will allow to use your directive on any element:
<html>
<header>
Angularity
</header>
<h1>hjskl</hi>
<body ng-app="App">
<div class="wrap">
<div class="cube"change-background colorcode=¨#FE0883¨>
<div class="front">AAA</div>
<div class="back"></div>
<div class="top"></div>
<div class="bottom"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</div>
<div class="wrap2">
<div class="cube2">
<div class="front2" change-background colorcode=¨#FE0883¨>AAA</div>
<div class="back2" change-background ></div>
<div class="top2" change-background></div>
<div class="bottom2" change-background></div>
<div class="left2" change-background></div>
<div class="right2" change-background></div>
</div>
</div>
</body>
</html>
I'm making FAQ page with AngularJS and I want expand/collapse elements.
This is my HTML:
<div id="faq" class="">
<div class="faq-item" collapse>
<div class="expend-element">
<div class="question">
<div class="text">Question 1</div>
</div>
</div>
<div class="answer">ANSWER 1</div>
</div>
<div class="faq-item" collapse>
<div class="expend-element">
<div class="question">
<div class="text">Question 2</div>
</div>
</div>
<div class="answer">ANSWER 2</div>
</div>
<div class="faq-item" collapse>
<div class="expend-element">
<div class="question">
<div class="text">Question 3</div>
</div>
</div>
<div class="answer">ANSWER 3</div>
</div>
</div>
My Directive:
return {
scope: {},
template: "<div class='faq-item' ng-click='expend()' ng-class='{ expended: active }'><div ng-transclude></div></div>",
replace: true,
transclude: true,
link: function(scope) {
scope.active = false;
scope.expend = function() {
scope.active = !scope.active;
};
}
};
This works fine, but it has one problem.
My main aim was to expand was only one element, but this expands all the elements.
How can I make this?
i have a html like this
<div class="main" ng-controller="firstcontroller">
<div class="submain">
<div class="first" ng-show="display">displayed</div>
<div class="second" my-directive>click</div>
</div>
<div class="submain">
<div class="first" ng-show="display">displayed</div>
<div class="second" my-directive>click</div>
</div>
<div class="submain">
<div class="first" ng-show="display">displayed</div>
<div class="second" my-directive>click</div>
</div>
</div>
I have controller like this
app.controller('firstcontroller',function($scope)
{
$scope.display=false;
});
my directive coding like this
app.directive('myDirective',function(scope, element, attrs)
{
return function()
{
element.bind('click',function()
{
element.prev().show();
//alert(element.prev().attr('class'));
// element.parent().find('.main').append('<div>Some text</div>')
});
}
});
here initially div will be hidden if div has class name fist , only div having class name second will be displayed . so when we click on click div we have to show only previous div of that clicked div..... how to show previous div of clicked div in angular.js ?
I get the feeling that the question is missing information. E.g. are the .submain divs hardcoded, or created by iteration?
If however this is indeed the case, the directive is redundant. Change the HTML as:
<div class="main" ng-controller="firstcontroller">
<div class="submain">
<div class="first" ng-show="display[0]">displayed</div>
<div class="second" ng-click="display[0] = !display[0]">click</div>
</div>
<div class="submain">
<div class="first" ng-show="display[1]">displayed</div>
<div class="second" ng-click="display[1] = !display[1]">click</div>
</div>
<div class="submain">
<div class="first" ng-show="display[2]">displayed</div>
<div class="second" ng-click="display[2] = !display[2]">click</div>
</div>
</div>
And the controller:
app.controller('firstcontroller',function($scope) {
$scope.display=[false, false, false];
});