Mapbox.js - 单击列表中的项目并平移到标记并显示弹出窗口

时间:2015-06-08 23:39:58

标签: javascript jquery mapbox

我从一个.js文件开始并修改它以便: 1.过滤geoJSON中的数据(右上角按钮)
2.单击标记时显示包含相关数据的弹出窗口 3.根据入口标记或当前在地图上显示的标记显示商店列表。放大时,标记较少,左侧列出的项目也较少。

现在我无法让这两个人工作:

  1. Div class with' item'变化,以便它添加"活跃"到了 类名
  2. 当我单击左侧列表中的链接时列出项目,它不会平移到单击的标记并再显示弹出窗口。相反,它一次一个地显示列表中所有位置的标记,以最后一个结束。我确定它与locations.eachLayer有关,但我不知道如何修复它以便显示数据或选择我想要的数据。我有一种感觉,我可能也没有按正确的顺序使用事件处理程序。
  3. 视觉
    OLD FILE: When I click on an item in the list on the left, the map automatically pans to and opens up that marker and popup.
    NEW FILE (in progress): Trying to get it to work

    
    
    // *****This is the map
    L.mapbox.accessToken = 'pk.eyJ1IjoiamVubmlmZXJwaGFtIiwiYSI6Ijc3NmJkZWE1YjM0ZDc0MWU2Yzc0MWM0YWQ5NzRiNzliIn0.OaKjiklBTRs_Saoh1wSglw';
    var map = L.mapbox.map('map', 'glidewell.jno36i2l');
    // END of the map
    
    $( document ).ready(function() {
    
    
    // ******This code zooms to the country locations listed on the page
    document.getElementById('navigation').onclick = function(e) {
        e.preventDefault();
        var pos = e.target.getAttribute('data-position');
        var zoom = e.target.getAttribute('data-zoom');
        if (pos && zoom) {
            var loc = pos.split(',');
            var zoo = parseInt(zoom);
            map.setView(loc, zoo);
            return false;
        }
    }
    // END of that code
    
    
    //this calls the <div id="listings>
        var listings = document.getElementById('listings');
    // *****This brings in the locations or GEO JSON file
        var locations = L.mapbox.featureLayer().addTo(map);
        var listing = $('div.item');
        var link = $('a.title');
    
    //this is the file that the data comes from
    locations.loadURL('js/testingdummydata.geojson');
    // END of that code
    
    // ****** This code zooms to the point on hr map when a selection is made from the list
    function setActive(el) {
        var siblings = listings.getElementsByTagName('div');
        for (var i = 0; i < siblings.length; i++) {
            siblings[i].className = siblings[i].className
                    .replace(/active/, '').replace(/\s\s*$/, '');
        }
    
        el.className += ' active';
    }
    // END of that code
    
    
    // *****This code merges the Map and the list together
      locations.on('ready', makepopup).on('ready', showMarkersinBound)
              .on('ready', goToMarker);
    
    
    function makepopup() {
        locations.eachLayer(function (locale) {
    
            var prop = locale.feature.properties;
    // Shorten locale.feature.properties to just `prop` so we're not
    // writing this long form over and over again.
            var popup = '<h3>' + prop.title + '</h3><div>' + prop.address + '<br>' + prop.city + ', ' + prop.state + '<br>' + prop.phone + '<br>' + '<a href="http://' + prop.website + '" target="_blank">' + prop.website + '</a>';
    
            if (prop.crossStreet) {
            //    link.innerHTML += '<br /><small class="quiet">' + prop.crossStreet + '</small>';
                popup += '<br /><small class="quiet">' + prop.crossStreet + '</small>';
            };
    
         
    
            // Marker interaction
            locale.on('click', function (e) {
                // 1. center the map on the selected marker.
                map.panTo(locale.getLatLng());
    
                // 2. Set active the markers associated listing.
                setActive(listing);
            });
    
            popup += '</div>';
            locale.bindPopup(popup);
        });
    };
    
    function goToMarker(){
    
        locations.eachLayer(function (locale) {
    
            $("a[href='#'][class='title']").click(function () {
                  setActive(listing);
                    // When a menu item is clicked, animate the map to center
                    // its associated locale and open its popup.
                  map.setView(locale.getLatLng(), 16);
    
                    locale.openPopup();
                    return false;
            });
        });
    };
    
    
    // *****Filters
    
    $('.menu-ui-btn a').on('click', function() {
        //adds "active" class to the link being clicked on and removes active class from the other links in menu
        $(this).addClass('active').siblings().removeClass('active');
        // For each filter link, get the 'data-filter' attribute value and assign it to a variable called filter.
        var filter = $(this).data('filter');
        // The setFilter function takes a GeoJSON feature object
        // and returns true to show it or false to hide it.
        locations.setFilter(function(feature) {
            return (filter === 'all') ? true : feature.properties[filter] === true;
        });
        makepopup();
        showMarkersinBound();
        return false;
    });
    
    //*******LIST OF MARKERS INSIDE VIEW
    
    function showMarkersinBound() {
        // Construct an empty list to fill with onscreen markers.
        var inBounds = [];
    
        // Get the map bounds - the top-left and bottom-right locations.
        var bounds = map.getBounds();
    
        // For each marker, consider whether it is currently visible by comparing
        // with the current map bounds.
        locations.eachLayer(function (marker, locale) {
            if (bounds.contains(marker.getLatLng())) {
                var oneListing;
                var prop = marker.toGeoJSON().properties;
        
                oneListing= '<div class="item"><a href="#" class="title">' + prop.title + '</a>' + prop.city;
                if (prop.state) {
                    oneListing += ', ' + prop.state;
                };
                oneListing += '</div>';
              inBounds.push(oneListing);  //adds the oneListing item into inBounds array
            }  //closes if statement
        });
    
        // Display a list of markers in id="listings" on the DOM.
       listings.innerHTML = inBounds.join('');
    
    };
    
    
    //when map moves, trigger showMarkersinBound function
    map.on('move', showMarkersinBound);
    
    });
    &#13;
    /* google.com/fonts import files go above this line ^
    
    
    /* Nav / Menus
    ================= */
    .menu-ui-btn {
    background:#fff;
    position:absolute;
    top:10px;right:10px;
    z-index:1;
    border-radius:3px;
    width:120px;
    border:1px solid rgba(0,0,0,0.4);
    }
    .menu-ui-btn a {
    font-size:13px;
    color:#404040;
    display:block;
    margin:0;padding:0;
    padding:10px;
    text-decoration:none;
    border-bottom:1px solid rgba(0,0,0,0.25);
    text-align:center;
    }
    .menu-ui-btn a:first-child {
    border-radius:3px 3px 0 0;
    }
    .menu-ui-btn a:last-child {
    border:none;
    border-radius:0 0 3px 3px;
    }
    .menu-ui-btn a:hover {
    background:#f8f8f8;
    color:#404040;
    }
    .menu-ui-btn a.active,
    .menu-ui-btn a.active:hover {
    background:#3887BE;
    color:#FFF;
    }
    
    
    /* Content
    ================= */
    
    #marker-list {
            position:absolute;
            top:0; right:0;
            width:200px;
            bottom:0;
            overflow-x:auto;
            background:#fff;
            margin:0;
            padding:5px;
            height: 400px;
            z-index: 50;
            background-color: white;
    }
    #marker-list li {
            padding:5px;
            margin:0;
            list-style-type:none;
    }
    #marker-list li:hover {
            background:#eee;
    }
    
    
    .sidebar {
    position:absolute;
    width:25%;
    height:100%;
    top:0;left:0;
    overflow:hidden;
    border-right:1px solid rgba(0,0,0,0.25);
    }
    .pad2 {
    padding:20px;
    }
    .quiet {
    color:#888;
    }
    .map {
    position:absolute;
    left:25%;
    width:75%;
    top:0;bottom:0;
    }
    .heading {
    background:#fff;
    border-bottom:1px solid #eee;
    padding:0 10px;
    }
    .listings {
    height:100%;
    overflow:auto;
    padding-bottom:60px;
    }
    .listings .item {
    display:block;
    border-bottom:1px solid #eee;
    padding:10px;
    text-decoration:none;
    }
    .listings .item:last-child { border-bottom:none; }
    .listings .item .title {
    display:block;
    color:#BA222B;
    font-weight:700;
    }
    .listings .item .title small { font-weight:400; }
    .listings .item.active .title,
    .listings .item .title:hover { color:#bbb; }
    .listings .item.active {
      background-color:#f8f8f8;
      }
    
    ::-webkit-scrollbar {
    width:22px;
    height:3px;
    border-left:0;
    background:rgba(0,0,0,0.1);
    }
    ::-webkit-scrollbar-track {
    background:none;
    }
    ::-webkit-scrollbar-thumb {
    background:#BA222B;
    border-radius:0;
    height: 60px;
    }
    
    .clearfix { display:block; }
    .clearfix:after {
    content:'.';
    display:block;
    height:0;
    clear:both;
    visibility:hidden;
    }
    
    /* Marker tweaks
    ====================*/
    .leaflet-popup-close-button {
    display:none;
    }
    .leaflet-popup-content {
    font:400 15px/22px 'Source Sans Pro', 'Helvetica Neue', Sans-serif;
    padding:0;
    width: auto;
    }
    .leaflet-popup-content-wrapper {
    padding:0;
    }
    .leaflet-popup-content h3 {
    background:#BA222B;
    color:#fff;
    margin:0;
    display:block;
    border-radius:3px 3px 0 0;
    font-weight:700;
    margin-top:-15px;
    }
    .leaflet-popup-content div {
    padding:10px;
    }
    .leaflet-container .leaflet-marker-icon {
    	cursor:pointer;
    }
    /**********************************************************
    Media Querys (480px, 768px, 990px, 1200px, 1500px, 2000px)
    ***********************************************************/
    
    /* Smaller than
    ================= */
    
    /* Applied to resolutions less than 2000 (3x) */
    	@media (max-width: 2000px) {
    
    	}
    
    /* Applied to resolutions less than 1740 (2x) */
    	@media (max-width: 1740px) {
    
    	}
    
    /* Applied to resolutions less than 1500 (Xl) */
    	@media (max-width: 1500px) {
    
    	}
    
    /* Applied to resolutions less than 1200 (lg) */
    	@media (max-width: 1200px) {
    
    	}
    
    /* Applied to resolutions less than 990 (md) */
    	@media (max-width: 990px) {
    
    	}
    
    /* Applied to resolutions less than 768 (sm) */
    	@media (max-width: 768px) {
    
    	}
    	
    /* Applied to resolutions less than 568 (sm) */
    	@media only screen and (max-width: 568px) {
            .sidebar {
            position: absolute;
            width: 100%;
            height: 60%;
            bottom: 0;
            left: 0;
            overflow: hidden;
            border-right: 1px solid rgba(0,0,0,0.25);
            top: inherit;
            }
            .map {
            position: absolute;
            bottom: 60%;
            width: 100%;
            top: 0;
            left: 0;
            }
            .heading {
            background: #fff;
            border-bottom: 1px solid #eee;
            height: 60px;
            padding: 3px 10px;
            }
            .leaflet-container .leaflet-control-attribution {
              display: none;
            }
            .listings {
            height: 233px;
            }
          }     
    
    /* Applied to resolutions less than 480 (XS) */
    	@media (max-width: 480px) {
    
    	}
    
    /* Larger than
    ================= */
    
    /* Applied to resolutions larger than 2000 (3x) */
    	@media (min-width: 2001px) {
    
    	}
    
    /* Applied to resolutions larger than 1500 (2x) */
    	@media (min-width: 1501px) {
    
    	}
    
    /* Applied to resolutions larger than 1200 (xl) */
    	@media (min-width: 1201px) {
    
    	}
    
    /* Applied to resolutions larger than 990 (lg) */
    	@media (min-width: 991px) {
    
    	}
    
    /* Applied to resolutions larger than 768 (sm) */
    	@media (min-width: 769px) {
    
    	}
    
    /* Applied to resolutions larger than 480 (xs) */
    	@media (min-width: 481px) {
    
    	}
    
    /***************************************
    Default Style Sheet created as part of - The Maui Toolbox
    For more information visit: www.mauitoolbox.com
    pub-20150501
    ***************************************/
    
    #coordinates {
            height:450px;
            overflow:auto;
            padding-bottom:60px;
    }
    #coordinates .item {
            display:block;
            border-bottom:1px solid #eee;
            padding:10px;
            text-decoration:none;
    }
    #coordinates .item:last-child { border-bottom:none; }
    #coordinates .item .title {
            display:block;
            color:#BA222B;
            font-weight:700;
    }
    #coordinates .item .title small { font-weight:400; }
    #coordinates .item.active .title,
    #coordinates .item .title:hover { color:#bbb; }
    #coordinates .item.active {
            background-color:#f8f8f8;
    }
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <!DOCTYPE html>
    <html lang="en">
    	<head>
    		<meta charset="utf-8">
    		<meta name="viewport" content="width=device-width, initial-scale=1.0">
    		<meta name="Description" content="#"> <!-- (Example: Compelling description to be displayed on Search Engine) -->
    		<meta name="author" content="#"> <!-- (example: Developers Name) -->
    		<meta http-equiv="X-UA-Compatible" content="IE=edge">
    		<title>[PAGE TITLE]</title>
    <!-- (Extrenal) Default Style Sheets =========== -->
    		<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
    		<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    		<link rel="stylesheet" type="text/css" href="http://gl-dev-staticweb.s3.amazonaws.com/blimp.css">
    		<link rel="stylesheet" type="text/css" href="http://gl-dev-staticweb.s3.amazonaws.com/maui.css">	
    <!-- Style Sheets ============================== -->
    		<link rel="stylesheet" type="text/css" href="css/map-styles.css">
    <!-- Additional Style Sheets =================== -->
    		<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700' rel='stylesheet'>
    		<script src='https://api.tiles.mapbox.com/mapbox.js/v2.1.9/mapbox.js'></script>
    		<link href='https://api.tiles.mapbox.com/mapbox.js/v2.1.9/mapbox.css' rel='stylesheet' />
    
    	</head>
    	<body>
    
    <div class='sidebar'>
    	<div class='heading'>
    		<h1>ABC Company</h1>
    		<div class="dropdown">
    			<a id="dLabel" data-target="#" href="http://example.com" data-toggle="dropdown" aria-haspopup="true" role="button" aria-expanded="false">
    			Select Country
    			<span class="caret"></span>
    		 	</a>
    		 	<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel" id='navigation'>
    				<li><a href='#' data-zoom="5" data-position='37.0,-95.7'>USA</a></li>
    				<li><a href='#' data-zoom="8" data-position='56.1,9.5'>DNK</a></li>
    				<li><a href='#' data-zoom="8" data-position='55.3,-3.4'>GB</a></li>
    				<li><a href='#' data-zoom="6" data-position='46.2,2.2'>FRA</a></li>
    				<li><a href='#' data-zoom="7" data-position='41.8,12.5'>ITA</a></li>
    				<li><a href='#' data-zoom="6" data-position='-30.5,22.9'>ZAF</a></li>
    				<li><a href='#' data-zoom="6" data-position='20.5,78.9'>IN</a></li>
    				<li><a href='#' data-zoom="8" data-position='39.0,21.8'>GRC</a></li>
    				<li><a href='#' data-zoom="6" data-position='26.8,30.8'>EGY</a></li>
    				<li><a href='#' data-zoom="8" data-position='60.4,8.4'>NOR</a></li>
    				<li><a href='#' data-zoom="8" data-position='48.6,19.6'>SVK</a></li>
    				<li><a href='#' data-zoom="5" data-position='-25.3,133.7'>AUS</a></li>
    				<li><a href='#' data-zoom="8" data-position='-40.9,174.8'>NZ</a></li>
    				<li><a href='#' data-zoom="5" data-position='35.4,104.1'>CHN</a></li>
    				<li><a href='#' data-zoom="8" data-position='15.8,100.9'>THA</a></li>
    				<li><a href='#' data-zoom="8" data-position='52.1,5.2'>NLD</a></li>
    				<li><a href='#' data-zoom="8" data-position='9.7,-83.7'>CR</a></li>
    				<li><a href='#' data-zoom="6" data-position='23.6,-102.5'>MX</a></li>
    		 	</ul>
    		</div>
    	</div>
    	<div id='listings' class='listings'></div>
    </div>
    
    <!-- Filter buttons - filters markers on map-->
    <nav class='menu-ui-btn'>
    	<a href='#' class='active' data-filter='all' id="allfilter">Show all</a>
    	<a href='#' data-filter='mill' id="millfilter">Mills</a>
    	<a href='#' data-filter='lab' id="labfilter">Labs</a>
    </nav>
    <!-- Map is displayed here -->
    <div id='map' class='map'></div>
    
    <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
    &#13;
    &#13;
    &#13;

    关于Mapbox文档的2个相关示例:
    1.列出标记并平移到单击的项目
    2.在视图中列出标记

    我花了整整2天时间一遍又一遍地看着这个,我真的可以使用专家的帮助来获得专业的Javascript知识,甚至可能使用mapbox.js。

1 个答案:

答案 0 :(得分:1)

没关系我让它上班了:

我在DOM中显示的html中添加了data-name属性,这样我就可以获得列表中项目的唯一名称(将其添加到“oneListing”变量中)。

function showMarkersinBound() {
// Construct an empty list to fill with onscreen markers.
var inBounds = [];

// Get the map bounds - the top-left and bottom-right locations.
var bounds = map.getBounds();

// For each marker, consider whether it is currently visible by comparing
// with the current map bounds.
locations.eachLayer(function (marker) {
    if (bounds.contains(marker.getLatLng())) {
        var oneListing;
        var prop = marker.toGeoJSON().properties;
        //oneListing= '<div class="item"><a href="#" class="title">' + prop.title + '</a><br>' + prop.address + '<br>' + prop.city + ', ' + prop.state + '<br>' + prop.phone + '<br>' + '<a href="http://' + prop.website + '" target="_blank">' + prop.website + '</a></div>';
        oneListing= '<div class="item"><a href="#" class="title" data-name="' + prop.title + '">' + prop.title + '</a>' + prop.city;
        if (prop.state) {
            oneListing += ', ' + prop.state;
        };
        oneListing += '</div>';
      inBounds.push(oneListing);  //adds the oneListing item into inBounds array
    }  //closes if statement
});

   // Display a list of markers in id="listings" on the DOM.
   listings.innerHTML = inBounds.join('');
}; //closes function

然后函数遍历所有图层,并且我创建了一个if else语句,这样只有当点击链接的名称与该图层的标题相同时,它才会更改视图并平移到标记。

function goToMarker() {

locations.eachLayer(function (layer) {
    var itsTitle = layer.toGeoJSON().properties.title;

    // var prop = locale.feature.properties;
    $(".title").click(function () {
        if (($(this).data('name')) === itsTitle) {
            // When a menu item is clicked, animate the map to center
            // its associated locale and open its popup.
            map.setView(layer.getLatLng(), 16);
            layer.openPopup();
            return false;
        };
    });
   });
}

然后我在位置准备就绪时将它们添加为事件侦听器。

var locations = L.mapbox.featureLayer().addTo(map);
locations.loadURL('js/testingdummydata.geojson');
locations.on('ready', makepopup).on('ready', howMarkersinBound).on('ready', goToMarker);
//when map moves, trigger showMarkersinBound function
map.on('move', showMarkersinBound).on('move', goToMarker);