2017-06-29 22 views
5

Tôi đang cố gắng viết một số javascript sẽ thay đổi một số giá trị được giữ trong một đối tượng cấu hình JS tại một số điểm ngắt trình duyệt nhất định.Trình nghe nhạc Windows.matchmedia kích hoạt hai lần

tôi đã lưu trữ các bài kiểm tra window.matchMedia trong đối tượng cấu hình và sau đó tôi đang Looping trên phím của đối tượng này để thêm một event listener với mỗi bài kiểm tra như sau:

Object.keys(config.mediaQueries).map((key) =>{ 
    config.mediaQueries[key].addListener(function(){ 
     console.log("breakpoint change"); 
    }); 
}); 

https://codepen.io/decodedcreative/pen/YQpNVO

Tuy nhiên khi trình duyệt được thay đổi kích thước và các hàm gọi lại của trình nghe này chạy, chúng xuất hiện để chạy hai lần. Kiểm tra CodePen ở trên với Console của bạn mở và bạn sẽ thấy những gì tôi có ý nghĩa.

Có ai biết tôi đã làm gì sai ở đây không?

Trả lời

4

Để trả lời câu hỏi trực tiếp của bạn, bạn đã không làm gì sai. Và JS đang làm chính xác những gì nó phải làm.

trld Có 2 sự kiện kích hoạt nhưng chỉ có một sự kiện chứa truy vấn phương tiện phù hợp.

Điều xảy ra là khi trình duyệt truy cập điểm ngắt có 2 sự kiện đang được ghi lại. Ví dụ, hãy xem xét trường hợp khi trình duyệt được thay đổi kích thước từ 1250px xuống còn 1150px. Khi cửa sổ có chiều rộng 1199px, chức năng của bạn:

Object.keys(config.mediaQueries).map((key) =>{ 
    config.mediaQueries[key].addListener(function(event){ 
    console.log("breakpoint change"); 
    }); 
}); 

sẽ ghi lại 2 sự kiện.Nếu bạn đi sâu vào vấn đề này và ghi lại các sự kiện với:

Object.keys(config.mediaQueries).map((key) =>{ 
    config.mediaQueries[key].addListener(function(event){ 
    console.log(event); 
    }); 
}); 

bạn sẽ thấy một số thông tin khác về truy vấn phương tiện. Tôi đã đun sôi đối tượng sự kiện xuống các đạo cụ quan trọng bên dưới.

// First event 
matches: true 
media: "(max-width: 1199px) and (min-width: 992px)" 

// Second event 
matches: false 
media: "(min-width: 1200px)" 

Điều đang xảy ra ở đây là 2 sự kiện đang được ghi lại nhưng chỉ một trong các sự kiện chứa truy vấn phù hợp.

Vì vậy, nếu chúng ta muốn cải thiện kịch bản của bạn để đăng nhập, bạn có thể kiểm tra matches tài sản:

Object.keys(config.mediaQueries).map((key) =>{ 
    config.mediaQueries[key].addListener(function(event){ 
    if (event.matches) { 
     console.log(event); 
    } 
    }); 
}); 

Với sự thay đổi nhỏ này chỉ truy vấn phương tiện truyền thông phù hợp sẽ được đăng nhập.

+0

Tuyệt vời. Cảm ơn bạn đã giúp đỡ. –

1

Dường như sự kiện đang kích hoạt ngay trước khi thay đổi kích thước và ngay sau khi thay đổi kích thước. Thêm câu lệnh if nếu bạn muốn ghi nhật ký "breakpoint" ngay sau khi thay đổi.

Chỉnh sửa: Noah Freitas có thể đúng về việc bắn sự kiện cho 2 khóa khi thay đổi kích thước. Vẫn e.matches trả về true nếu nó phù hợp với chính vì thế nó sẽ làm việc tốt

function(e) { 
     if(e.matches) { 
     console.log("breakpoint change"); 
     } 
    } 
2

Nếu bạn thay đổi console.log("breakpoint change");-console.log(key, "breakpoint change");, bạn sẽ thấy rằng cả xss truy vấn đang được kích hoạt khi bạn tự thay đổi kích thước cửa sổ trinh duyệt.

Nếu bạn chỉ muốn gọi lại để kích hoạt một lần trong một cửa sổ thời gian, bạn sẽ cần phải điều chỉnh các sự kiện hoặc đạt được hành vi theo một cách khác.

Chỉnh sửa: Tomasz BubałaBrett DeWoody câu trả lời của cả hai đều trỏ đến thuộc tính event.matches là giải pháp cụ thể và thích hợp hơn .matchMedia cho vấn đề này.

0

Không chắc chắn, nếu điều này đã là câu trả lời đầy đủ. Nhưng bạn đúng. Cuộc gọi lại đang kích hoạt hai lần - cho hai phím khác nhau.

tôi sửa đổi ví dụ của bạn, vì vậy nó xuất ra key:

Object.keys(config.mediaQueries).map((key) =>{ 
    console.log("register key: '" + key + "'"); 
    config.mediaQueries[key].addListener(function(){ 
     console.log("breakpoint change key:'" + key + "'"); 
    }); 
}); 

Kết quả là sản lượng khai thác gỗ luôn tạo ra hai dòng:

breakpoint change key:'m' 
breakpoint change key:'l' 

Hoặc cho chiều rộng giảm:

breakpoint change key:'s' 
breakpoint change key:'m' 
Các vấn đề liên quan