Bài 04: Google map events - UI Events - MVC State Changes

Javascript là một ngôn ngữ Client, có nghĩa là nó sẽ thao tác với người dùng  thông qua các sự kiện và ngôn ngữ này sẽ lắng nghe những thao tác của người dùng thông qua sự kiện đó. Trong bài này ta sẽ tìm hiểu hai loại sự kiện trong google map:

  • User evenets (như click, dbclick) được truyền từ DOM tới Google Map API, những sự kiện này nó riêng và không giống với DOM bình thường vì nó theo chuẩn của google map
  • MVC state change: đây là thông báo thay đổi trạng thái của bản đồ tới các đối tượng Google Map API với việc đặt tên theo một quy luật là property_changed, trong đó property thay đổi tùy theo sự kiện

Mỗi đối tượng của Google Map sẽ đưa ra những sự kiện có tên xác định, các chương trình viết thao tác với đối tượng API này thông qua hàm addListener(), hàm này nằm trong google.maps.event namespace. Bạn có thể tham khảo danh sách các sự kiện Google Map Events tại đây.

1. Google Map - UI Events

Các đối tượng Google Map có nhiệm vụ nhận diện các sự kiện của người dùng như Hover, Click hay những sự kiện trên bàn phím như keypress, uy keyup, ... Dưới đây là danh sách các sự kiện mà đối tượng google.maps.Marker có thể lắng nghe được:

  • 'click'
  • 'dblclick'
  • 'mouseup'
  • 'mousedown'
  • 'mouseover'
  • 'mouseout'

Để xem danh sách đầy đủ bạn có thể tham khảo danh sách sự kiện Marker class. Những sự kiện này có thể trông giống như các sự kiện của DOM nhưng trong thực tế có những sự kiện chỉ dành riêng cho Google API Map. Vì các trình duyệt có cách lắng nghe sự kiện khác nhau nên google API Map sẽ đáp ứng mà không cần phải check trình duyệt, những sự kiện này có thể sẽ có truyền tham số như những sự kiện bình thường.

2. Google Map - MVC State Changes

Đối tượng Google Map MVC thường lưu các trạng thái và nó sẽ thay đổi nếu lập trình viên thiết lập sự thay đổi đó khi nào (khi click, dbclick). Ví dụ khi load bản đồ google map TP HCM lên thì sự kiện zoom_changed sẽ thay đổi độ phóng to thu nhỏ theo tham số mà ta truyền vào. Như ở trên tôi có trình bày là ta có thể dùng hàm addListener()  để đăng ký xử lý cho sự kiện nào đó của Google API Map.

3. Google Map - Xử lý sự kiện

Để đăng ký thông báo với hệ thống Google Map là ta cần xử lý sự kiện gì thì dùng hàm addListener(), đây là phương thực của đối tượng google.maps.event.

Ví dụ: Map và Marker Events - Xem demo

Trong ví dụ này là sự kết hợp giữa người dùng và sự thay đổi trạng thái. Tôi sẽ đính kèm một hành động là phóng to bản đồ lên khi click vào biểu tượng của Marker Google Map, và tôi có thêm một hành động nữa đó là ở sự kiện center_changed, khi sự kiện này kích hoạt (nghĩa là người dùng kéo bản đồ) thì trong vòng 3 giây tôi sẽ đưa nó trở về vị trí cũ.

<!DOCTYPE html>
<html>
    <head>
        <title>Simple click event</title>
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
        <meta charset="utf-8">
        <style>
            html, body, #map-canvas {
                height: 100%;
                margin: 0px;
                padding: 0px
            }
        </style>
        <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDfNk5eVWmQB9e6ApnWzICLNIY5lUXpOBw&language=vi"></script>
        <script>
            function initialize() 
            {
                // Thuộc tính map tại thành phố Hồ Chí Minh
                var mapOptions = {
                    zoom: 4,
                    center: new google.maps.LatLng(10.771971, 106.697845)
                };

                // Khởi tạo map
                var map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
                
                // Thuộc tính khởi tạo Marker 
                var marker = new google.maps.Marker({
                    position: map.getCenter(),
                    map: map,
                    title: 'Click to zoom'
                });
                
                // Khi thay đổi vị trí của bản đồ (center_changed events)
                // thì sẽ xử lý sau 3 giây đưa về vị trí cũ.
                google.maps.event.addListener(map, 'center_changed', function() {
                    // marker.getPosition() là lấy vị trí trung tâm của bản đồ
                    window.setTimeout(function() {
                        map.panTo(marker.getPosition());
                    }, 3000);
                });

                // Đưa sự kiện click vào marker vừa tạp trên
                // sẽ zoom lên 8 và đưa bản đồ về trạng thái nằm giữa
                google.maps.event.addListener(marker, 'click', function() {
                    map.setZoom(8);
                    map.setCenter(marker.getPosition());
                });
            }
            
            // Lúc laod các thẻ DOM thì chạy hàm initialize
            google.maps.event.addDomListener(window, 'load', initialize);

        </script>
    </head>
    <body>
        <div id="map-canvas"></div>
    </body>
</html>

4. Google Map - Xử lý tham số (Arguments) trong UI Events

Các sự kiện thao tác của người dùng thường sẽ có một tham số đại diện cho sự kiện đó, Google Map Events sẽ nhận diện sự kiện thông qua tham số này. Ví dụ khi nhấp chuột vào bản đồ google map sẽ kèm theo một sự kiện MouseEvent chứa một object tham số lưu thông tin vị trí nhấp chuột (latlng). Lứu ý với bạn rằng tham số của sự kiện chỉ dành cho UI Events, MVC State không hỗ trợ tham số này.

Bạn có thể truy cập các thuộc tính của sự kiện thông qua đối tượng truyền vào. Ví dụ dưới đây Google Map sẽ lắng nghe sự kiện click lên bản đồ và tạo ra một marker tại vị trí click đó.

Xem demo:

<!DOCTYPE html>
<html>
    <head>
        <title>Accessing arguments in UI events</title>
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
        <meta charset="utf-8">
        <style>
            html, body, #map-canvas {
                height: 100%;
                margin: 0px;
                padding: 0px
            }
        </style>
        <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDfNk5eVWmQB9e6ApnWzICLNIY5lUXpOBw&language=vi"></script>
        <script>
            // Hàm Chạy google map
            function initialize() 
            {
                // Thông số hiển thị
                var mapOptions = {
                    zoom: 4,
                    center: new google.maps.LatLng(10.771971, 106.697845)
                };
                
                // Khởi tạo bản đồ
                var map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);

                // Gắn sự kiện click vào bản đồ, khi click sẽ gọi hàm placeMarker
                // và tham số truyền vào là thông tin tung độ và vĩ độ và bản đồ đang hiển thị
                google.maps.event.addListener(map, 'click', function(e) {
                    placeMarker(e.latLng, map);
                });
            }
            
            // Hàm tạo marker theo vị trí position của bản đồ map
            function placeMarker(position, map) {
                // Tạo marker
                var marker = new google.maps.Marker({
                    position: position,
                    map: map
                });
                // Di chuyển trung tâm bản đồ tới vị trí position
                map.panTo(position);
            }
            
            // Chạy bản đồ khi load trang
            google.maps.event.addDomListener(window, 'load', initialize);

        </script>
    </head>
    <body>
        <div id="map-canvas"></div>
    </body>
</html>

5. Sử dụng Closures trong Event Listeners

Khi thực hiện một sự kiện trong Google Map sẽ nhận cả thông số private và public, tuy nhiên trong javascript không có khái niệm private, nhưng nó có hỗ trợ Closures cho phép các chức năng bên trong truy cập xử dụng các biến bên ngoài. Closures là một cách dùng khá hữu ích, nó cho phép các sự kiện sử dụng dữ liệu của nhau.

Ví dụ dưới đây sử dụng chức năng Closures để hiển thị đúng dữ liệu, nghĩa là khi click vào marker google map  sẽ hiển thị thông tin thông điệp nào đó.

Xem demo:

<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
        <meta charset="utf-8">
        <title>Using closures in event listeners</title>
        <style>
            html, body, #map-canvas {
                height: 100%;
                margin: 0px;
                padding: 0px
            }
        </style>
        <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDfNk5eVWmQB9e6ApnWzICLNIY5lUXpOBw&language=vi"></script>
        <script>
            function initialize() 
            {
                // Thông số hiển thị bản đồ
                var mapOptions = {
                    zoom: 4,
                    center: new google.maps.LatLng(10.771971, 106.697845)
                };

                // Hiển thị bản đồ
                var map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);

                // Thêm 5 marker ngẫu nhiên trên bản đồ
                // Đây là hai thông số southWest và northEast của bản đồ
                var southWest = new google.maps.LatLng(12.771971, 104.244141);
                var northEast = new google.maps.LatLng(10.771971, 106.697845);
                
                // Khởi tạo một bounds của 2 vị trí trên
                var bounds = new google.maps.LatLngBounds(southWest, northEast);
                
                // Fill bound vào google map
                map.fitBounds(bounds);
                
                // Khoảng cách giữa các tọa độ northEast và northEast
                var lngSpan = northEast.lng() - southWest.lng();
                var latSpan = northEast.lat() - southWest.lat();
                
                // Lặp từ 0 đến 4 để hiển thị 5 marker ngẫu nhiên
                for (var i = 0; i < 5; i++) {
                    var position = new google.maps.LatLng(
                            southWest.lat() + latSpan * Math.random(),
                            southWest.lng() + lngSpan * Math.random());
                    var marker = new google.maps.Marker({
                        position: position,
                        map: map
                    });
                    
                    // Thiết lập tiêu đề cho marker
                    marker.setTitle((i + 1).toString());
                    
                    // Gọi hàm attachSecretMessage để hiển thị message cho từng marker
                    attachSecretMessage(marker, i);
                }
            }

            // Thêm message thông báo khi click vào marker
            // tham số là marker đang click và số thứ tự của message
            // như vậy nó sử dụng closure để thiết lập message cho  từng marker
            function attachSecretMessage(marker, num) 
            {
                // Danh sách message
                var message = ['Welcome', 'To', 'M', 'Website', 'Freetuts.net'];
                
                // Khởi tạo của sổ message
                var infowindow = new google.maps.InfoWindow({
                    content: message[num]
                });

                // Gắn của sổ vào sự kiện clic vào marker
                google.maps.event.addListener(marker, 'click', function() {
                    
                    // Hàm open có hai tham số đó là map nó đang được gắn vào và marker đó 
                    infowindow.open(marker.get('map'), marker);
                });
            }

            google.maps.event.addDomListener(window, 'load', initialize);

        </script>
    </head>
    <body>
        <div id="map-canvas"></div>
    </body>
</html>

6. Lời kết

Bài này hơi dài nên tôi sẽ chia làm 2 phần, ở phần này ta tìm hiểu một số khái niệm về sự kiện UI Events google map, MVC State google map và ba cách xử lý sự kiện thông dụng đó là xử lý Events Map, xử lý tham số arguments và các sử dụng kỹ thuật Closures trong google map.

Nguồn: freetuts.net

Profile photo of adminTheHalfHeart

TheHalfHeart

Có sở thích viết tuts nên đã từng tham gia viết ở một số diễn đàn, đến năm 2014 mới có điều kiện sáng lập ra freetuts.net. Sinh năm 90 và có 1 vợ 2 con, thích ca hát và lập trình.

ĐĂNG BÌNH LUẬN: Đăng câu hỏi trên Facebook để được hỗ trợ nhanh nhất.