WickyNilliams / enquire.js

Awesome Media Queries in JavaScript
http://wicky.nillia.ms/enquire.js/
MIT License
3.62k stars 269 forks source link

How to trigger match on initial pageload? #122

Open khromov opened 9 years ago

khromov commented 9 years ago

We want to trigger match() and unmatch() on initial pageload. The setup() function runs but it doesn't have any useful parameters and what we really want is to check whether the media queri matches or not so we can perform logic on the initial page load.

I'm not sure how such a common use case could be glossed over?

michaellopez commented 9 years ago

I am looking for this feature too.

It seems trivial to implement. Just pass along this.matches() to var qh = new QueryHandler(handler); and make ´QueryHandler#setup` take that argument and pass it to this.options.setup()

I can make up a pull request if this is a feature that would be merged into the project? @WickyNilliams

michaellopez commented 9 years ago

Looking through the code I see that it can be extended even further to make MediaQuery#addHandler also call qh.off() if the media query does not match. Currently it does call the match callback when the query matches on page load. This should probably go in another issue/PR? @WickyNilliams

But the setup function would be even more powerful if it could determine whether the query .matches or not as this issue feature requests.

michaellopez commented 9 years ago

@khromov In the meantime you can do something like this as a workaround:

var query = '(max-width: 767px)';
...
enquire.queries[query].matches() // returns true or undefined

Note that .matches() returns trueor undefined even though the API says it always returns bool. Well, it returns undefined depending on if you use the last paramter to register that is meant for legacy browser, internally called isUnconditional. Not setting it gives undefined, otherwise setting it returns the value that you set.

There is a bug in the API where a call to MediaQuery#matches returns undefined if it is not matching. The offending line is here. It should read more like return !!(this.mql.matches || this.isUnconditional); or the property should default to false if not defined by the user. @WickyNilliams

ThisNoName commented 9 years ago

I'm trying to do something similar, calling ajax for different parts during page load. If page loaded while matching, match triggered. But if page load while not matching, unmatch doesn't fire.

The workaround works. Tried the suggested code change, seems no effect.

riophae commented 9 years ago

Maybe an extra option can be added to set whether unmatch() should be triggered on initial pageload.

oceangravity commented 8 years ago

+1

landitus commented 7 years ago

+1

ronaldbarendse commented 7 years ago

@michaellopez has some valid arguments for adding an argument to the setup function (a boolean indicating whether the query matches or a reference to the MediaQuery instance to easily do this yourself - in case the matching has a significant performance impact).

In addition to that, it feels a bit wrong that currently only the match callback is fired (if it matches) after adding the handler. As @riophae noted, the unmatch should be triggered when it doesn't match. This would only require the following change in MediaQuery.addHandler: this.matches() && qh.on(); to this.matches() ? qh.on() : qh.off();. If this breaks backwards compatibility, an extra option could be created, eg. deferMatch: true or deferAssess: true.

ronaldbarendse commented 7 years ago

As workaround, you could also register an additional negated media query by prepending not to it and only using the match callbacks.

enquire.register('screen and (min-width: 45em)', function () {
});

enquire.register('not screen and (min-width: 45em)', function () {
});

See also: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#not

verrasse commented 7 years ago

enquire.js : v2.1.6

  1. Enquire always call setup callback synchronously on register.

  2. Enquire always call destroy callback synchronously on unregister.

  3. Enquire always call match callback synchronously on register if MediaQuery is matched.

  4. Enquire always call unmatch callback synchronously on unregister if MediaQuery is matched and destroy callback is not specified . If destroy callback is specified then unmatch callback does not fired on unregister.

  5. Enquire always call match callback asynchronously when MediaQuery is matched.

  6. Enquire always call unmatch callback asynchronously when MediaQuery is unmatched.

My questions are:

Can you please fix behavior 3 and 4!

Behaviors 1, 2, 5, 6 - are OK!