我是angularjs的新手。我正在尝试创建一个照片库,其中初始页面是一张来自twitter和Instagram的缩略图照片,使用angularjs ng-repeat循环创建。当用户将鼠标悬停在图像上时,图像会消失,并出现一个按钮供用户单击。我使用ng-mouseenter和ng-mouseleave创建了悬停效果。但出于某种原因,当我将鼠标悬停在图像上时,所有图像都会受到影响。只应将我悬停的单个图像作为目标。我不确定我做错了什么。请帮忙!代码如下。这里还有一个在线代码的链接: http://www.petermingione.com/my-demo/
<style>
* {
box-sizing: border-box;
font-family: sans-serif;
}
h1,
h2{
margin-left:10px;
}
.inner{
display:inline-block;
vertical-align:top;
padding:5px;
position:relative;
}
.inner img{
width:100%;
}
.inner .outer-caption{
color:black;
width:375px;
height:125px;
background-color:#fc7cab;
display:flex;
}
.inner .outer-caption .inner-caption{
font-size:14px;
font-family:sans-serif;
overflow:hidden;
width:320px;
height:70px;
margin:auto;
}
.inner .overlay-color{
position: absolute;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
background-color: #fff;
transition: all .5s;
}
.inner .overlay-text{
border: 2px solid #7e7e7e;
color:#7e7e7e;
font-size: 10px;
position: absolute;
top:0;
bottom:0;
left:0;
right:0;
width:70px;
height:35px;
line-height:35px;
margin:auto;
border-radius:1px;
text-align: center;
transition: all .5s;
</style>
<body>
<h1>{{title}}</h1>
<h2>{{myMessage}}</h2>
<div id="outer" class="outer">
<div class="inner" ng-mouseenter="makeVisibile()" ng-mouseleave="makeInVisibile()" ng-repeat="x in insideData">
<img ng-if="x.service=='Instagram'||(x.service=='Twitter' && x.mediaType=='image')" ng-src='{{x.thumbnails[0].url}}'>
<div ng-if="x.service=='Twitter'&& x.mediaType!='image'" class="outer-caption"><div class="inner-caption">{{x.caption}}</div></div>
<div class="overlay-color" ng-style="overlayColorStyles" ></div>
<div class="overlay-text" ng-style="overlayTextStyles">VIEW</div>
</div>
</div>
<script>
// Create the module
var appModule = angular.module('appName', []);
// Create rootScope variables
appModule.run(
function($rootScope){
$rootScope.title = "Taneleer Demonstration";
}
);
// Create the controller
appModule.controller('appCtrl', function($scope, $http) {
$scope.overlayColorStyles = {"opacity": 0};
$scope.overlayTextStyles = {"opacity": 0};
$scope.makeVisibile = function(){
//alert("test");
//document.getElementById("overlay-color").style.opacity = .75;
//document.getElementById("overlay-text").style.opacity = 1;
$scope.overlayColorStyles = {"opacity" : .75};
$scope.overlayTextStyles = {"opacity" : 1};
}
$scope.makeInVisibile = function(){
//alert("test");
//document.getElementById("overlay-color").style.opacity = 0;
//document.getElementById("overlay-text").style.opacity = 0;
$scope.overlayColorStyles = {"opacity" : 0};
$scope.overlayTextStyles = {"opacity" : 0};
}
$http({
method : "GET",
url : "https://taneleer.composedcreative.com/api/v1/feed/a0329f16-9225-11e6-89bb-296a97b9d609/bb0429f6-f0ca-11e7-8f5d-d92739a9a53f"
}).then(function mySucces(response) {
$scope.myMessage = "Success!";
$scope.response = response;
$scope.meta = response.data.meta;
$scope.outsideData = response.data;
$scope.insideData = response.data.data;
$scope.links = response.data.links;
$scope.selfLink = response.data.links.self;
$scope.firstLink = response.data.links.first;
$scope.lastLink = response.data.links.last;
$scope.nextLink = response.data.links.next;
$scope.prevLink = response.data.links.prev;
$scope.statuscode = response.status;
$scope.statustext = response.statusText;
$scope.statusheaders = response.headers();
$scope.statusconfig = response.config;
}, function myError(response) {
$scope.myMessage = "Error!";
$scope.response = response;
$scope.statuscode = response.status;
$scope.statustext = response.statusText;
$scope.statusheaders = response.headers();
$scope.statusconfig = response.config;
});
$scope.getNext = function() {
$http({
method : "GET",
url : $scope.nextLink
}).then(function mySucces(response) {
$scope.myMessage = "Success!";
$scope.response = response;
$scope.outsideData = response.data;
$scope.meta = response.data.meta;
$scope.insideData = $scope.insideData.concat(response.data.data);
$scope.links = response.data.links;
$scope.selfLink = response.data.links.self;
$scope.firstLink = response.data.links.first;
$scope.lastLink = response.data.links.last;
$scope.nextLink = response.data.links.next;
$scope.prevLink = response.data.links.prev;
$scope.statuscode = response.status;
$scope.statustext = response.statusText;
$scope.statusheaders = response.headers();
$scope.statusconfig = response.config;
}, function myError(response) {
$scope.myMessage = "Error!";
$scope.response = response;
$scope.statuscode = response.status;
$scope.statustext = response.statusText;
$scope.statusheaders = response.headers();
$scope.statusconfig = response.config;
});
}
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
$scope.getNext();
}
});
});
</script>
您好, 再次感谢Aaron的回答。我还有一个问题需要解决。我现在正在构建应用程序的灯箱部分。这是您单击视图按钮时看到的叠加层。我在网上放了最新版本: http://www.petermingione.com/my-demo/ 如您所见,无论您单击哪个图像,唯一出现的图像是该集合中的第一个图像。再次,这是ng-repeat的另一个问题。图像作为mainImage.url位于每个对象中,我通过ng-repeat循环中的x.mainImage.url访问它。我不确定为什么它不起作用。任何人都可以给我的任何帮助将不胜感激。代码在下面和在线:
<style>
* {
box-sizing: border-box;
font-family: sans-serif;
}
h1,
h2{
margin-left:10px;
}
.outer-wrapper{
overflow: hidden;
}
.inner-wrapper{
display:inline-block;
vertical-align:top;
padding:5px;
position:relative;
}
.inner-wrapper img{
width:100%;
}
.inner-wrapper .outer-caption{
color:black;
width:100%;
padding-top:35%;
background-color:#fc7cab;
position:relative;
}
.inner-wrapper .outer-caption .inner-caption{
font-size:14px;
font-family:sans-serif;
overflow:hidden;
width:75%;
height:70px;
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
margin:auto;
}
.inner-wrapper .item-overlay-color{
position: absolute;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
background-color: #fff;
transition: all .5s;
opacity: 0.0;
}
.inner-wrapper:hover .item-overlay-color {
opacity: 0.75;
}
.inner-wrapper .item-overlay-text{
border: 2px solid #7e7e7e;
color:#7e7e7e;
font-size: 10px;
position: absolute;
top:0;
bottom:0;
left:0;
right:0;
width:70px;
height:35px;
line-height:35px;
margin:auto;
border-radius:1px;
text-align: center;
transition: all .5s;
opacity: 0.0;
}
.inner-wrapper:hover .item-overlay-text {
opacity: 1.0;
}
.inner-wrapper .page-overlay {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(255,255,255,0.75);
z-index: 2;
cursor: pointer;
}
.inner-wrapper #page-overlay {
opacity:0;
transition: all .5s;
pointer-events:none;
}
.inner-wrapper .page-overlay .text{
position: absolute;
top: 50%;
left: 50%;
font-size: 50px;
color: white;
transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
}
.inner-wrapper .page-overlay .text .close{
position:absolute;
top:0;
right:0;
color:#000;
font-weight: lighter;
font-size: 30px;
line-height: 30px;
padding-top:5px;
padding-right:5px;
}
@media screen and (min-width: 1301px){
.inner-wrapper{
width:16.6666%;
}
}
@media screen and (max-width: 1300px){
.inner-wrapper{
width:20%;
}
}
@media screen and (max-width: 1024px){
.inner-wrapper{
width:25%;
}
}
@media screen and (max-width: 768px){
.inner-wrapper{
width:50%;
}
}
@media screen and (max-width: 480px){
.inner-wrapper{
width:100%;
}
}
</style>
<body>
<div id="outer-wrapper" class="outer-wrapper">
<div id="inner-wrapper" class="inner-wrapper" ng-repeat="x in insideData">
<img ng-if="x.service=='Instagram'||(x.service=='Twitter' && x.mediaType=='image')" ng-src='{{x.thumbnails[0].url}}'>
<div class="outer-caption" ng-if="x.service=='Twitter'&& x.mediaType!='image'">
<div class="inner-caption">{{x.caption}}</div>
</div>
<div class="item-overlay-color"></div>
<div class="item-overlay-text" ng-click="showOverlay()">VIEW</div>
<div id="page-overlay" class="page-overlay">
<div class="text">
<img ng-src='{{x.mainImage.url}}'>
<span class="close" ng-click="hideOverlay()">X</span>
</div>
</div>
</div>
</div>
</body>
<script>
// Create the module
var appModule = angular.module('appName', []);
// Create rootScope variables
appModule.run(
function($rootScope){
$rootScope.title = "Taneleer Demonstration";
}
);
// Create the controller
appModule.controller('appCtrl', function($scope, $http) {
$scope.showOverlay = function(){
document.getElementById("page-overlay").style.opacity = 1;
document.getElementById("page-overlay").style["pointer-events"] = "auto";
}
$scope.hideOverlay = function(){
document.getElementById("page-overlay").style.opacity = 0;
document.getElementById("page-overlay").style["pointer-events"] = "none";
}
$http({
method : "GET",
url : "https://taneleer.composedcreative.com/api/v1/feed/a0329f16-9225-11e6-89bb-296a97b9d609/bb0429f6-f0ca-11e7-8f5d-d92739a9a53f"
}).then(function mySucces(response) {
$scope.myMessage = "Success!";
$scope.response = response;
$scope.meta = response.data.meta;
$scope.outsideData = response.data;
$scope.insideData = response.data.data;
$scope.links = response.data.links;
$scope.selfLink = response.data.links.self;
$scope.firstLink = response.data.links.first;
$scope.lastLink = response.data.links.last;
$scope.nextLink = response.data.links.next;
$scope.prevLink = response.data.links.prev;
$scope.statuscode = response.status;
$scope.statustext = response.statusText;
$scope.statusheaders = response.headers();
$scope.statusconfig = response.config;
}, function myError(response) {
$scope.myMessage = "Error!";
$scope.response = response;
$scope.statuscode = response.status;
$scope.statustext = response.statusText;
$scope.statusheaders = response.headers();
$scope.statusconfig = response.config;
});
$scope.getNext = function() {
$http({
method : "GET",
url : $scope.nextLink
}).then(function mySucces(response) {
$scope.myMessage = "Success!";
$scope.response = response;
$scope.outsideData = response.data;
$scope.meta = response.data.meta;
$scope.insideData = $scope.insideData.concat(response.data.data);
$scope.links = response.data.links;
$scope.selfLink = response.data.links.self;
$scope.firstLink = response.data.links.first;
$scope.lastLink = response.data.links.last;
$scope.nextLink = response.data.links.next;
$scope.prevLink = response.data.links.prev;
$scope.statuscode = response.status;
$scope.statustext = response.statusText;
$scope.statusheaders = response.headers();
$scope.statusconfig = response.config;
}, function myError(response) {
$scope.myMessage = "Error!";
$scope.response = response;
$scope.statuscode = response.status;
$scope.statustext = response.statusText;
$scope.statusheaders = response.headers();
$scope.statusconfig = response.config;
});
}
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
$scope.getNext();
}
});
});
答案 0 :(得分:1)
我知道你问过如何以角度方式做到这一点,但ng-mouseenter和ng-mouseleave是非常高性能的,如果你打算在现实世界的应用程序中使用它,这应该用css完成。
我会继续向您展示如何修复您的版本,然后我会给您一个效率更高的CSS版本:)
对于这个用例,有一个非常有用的变量$ index,可以在ng-repeat
标记内的任何位置的角度模板中引用,以获取当前数据项的索引被迭代。您应该使用它来保存当前悬停到控制器范围的项目的索引。然后,当鼠标离开项目时,您可以丢弃已保存的索引。
然后,当您分配样式时,您可以使用三元组根据项目索引是否与范围上保存的活动索引变量匹配来分配活动或非活动样式。
此外,如果您不熟悉,则三元表达式是conditional_expression ? value_returned_if_true : value_returned_if_false
形式的条件语句的简写。在javascript中编写非常简洁的条件语句是好的(或者,在这种情况下,带有解释javascript的角度模板:))
因此,对于此示例,我使用三元表达式的组合并保存鼠标输入的最后一项的索引,以便为每个项目指定悬停或非悬停样式。
您的示例的缩写版本:
角度控制器:
app.controller('exampleController', function($scope) {
$scope.overlayColorStyles = {"opacity": 0};
$scope.overlayTextStyles = {"opacity": 0};
$scope.overlayTextStylesActive = {"opacity": 1};
$scope.overlayColorStylesActive = { "opacity": .75};
$scope.activeItemIndex = null;
});
模板:
<div id="outer" class="outer">
<div class="inner"
ng-mouseenter="$scope.activeItemIndex = $index"
ng-mouseleave="$scope.activeItemIndex = null"
ng-repeat="x in insideData">
<img ng-if="x.service=='Instagram'||(x.service=='Twitter' && x.mediaType=='image')" ng-src='{{x.thumbnails[0].url}}'>
<div ng-if="x.service=='Twitter'&& x.mediaType!='image'" class="outer-caption"><div class="inner-caption">{{x.caption}}</div></div>
<div class="overlay-color"
ng-style="$scope.activeItemIndex === $index ? overlayColorStylesActive : overlayColorStyles">
</div>
<div class="overlay-text"
ng-style="$scope.activeItemIndex === $index ? overlayTextStylesActive : overlayTextStyles">
VIEW
</div>
</div>
</div>
同样,这段代码只能用于学习练习。 Angular的工作不是基于用户交互应用样式,如果你尝试以这种方式使用它,那么当你开始添加更多项时,你的应用程序会变得非常慢。使用css执行此操作非常简单,可以显着提高性能:)
以下css版本:
HTML:
<div id="outer" class="outer">
<div class="inner"
ng-repeat="x in insideData">
<img ng-if="x.service=='Instagram'||(x.service=='Twitter' && x.mediaType=='image')" ng-src='{{x.thumbnails[0].url}}'>
<div ng-if="x.service=='Twitter'&& x.mediaType!='image'" class="outer-caption"><div class="inner-caption">{{x.caption}}</div></div>
<div class="overlay-color"></div>
<div class="overlay-text">VIEW</div>
</div>
</div>
CSS
.overlay-color {
opacity: 0.0;
}
.overlay-text {
opacity: 0.0;
}
.inner:hover .overlay-text {
opacity: 1.0;
}
.inner:hover .overlay-color {
opacity: 0.75;
}