Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run unmatch before match on multiple queries #80

Open
thasmo opened this issue Oct 11, 2013 · 17 comments
Open

Run unmatch before match on multiple queries #80

thasmo opened this issue Oct 11, 2013 · 17 comments

Comments

@thasmo
Copy link

thasmo commented Oct 11, 2013

Hi there!

Would it be possible to run all defined unmatch handlers before any defined match handlers? In my case I have two registered media queries, and the unmatch handler of query 1 runs after the match handler of query 2.

In my scenario both media queries add javascript to the same element, but for different media queries. The Problem now is, that the unmatch handler of query 1 kills some stuff which was set up by the match handler of query 2, because imho the order is wrong.

I think it would make sense to run all neccessary unmatch handlers before any match handlers is executed.

Thoughts?

@MaxAIPlayground
Copy link

This is a very good idea.

@travm
Copy link

travm commented Oct 24, 2013

I believe this is by design, because there are scenarios where the unmatch shouldn't be fired immediately. Also, there is a chance that multiple unmatch handlers would be fired all at once.

I ran into similar issues with a project as well and ended up restructuring my code to include more match handlers and only used unmatch for minor cleanup and made sure that it wouldn't conflict with any other matches that may happen. I think we're all seeing unmatch as the opposite of match, but in the case of enquire it's really not. It seems to be more of a "cleanup" handler should we need to use it.

I put together a small write-up on my issue that may also help: http://travismaynard.com/writing/getting-started-with-enquirejs

I hope I'm understanding your issue correctly, and this helps you out!

@thasmo
Copy link
Author

thasmo commented Oct 24, 2013

Actually it's not about unmatch only firing after the viewport leaves a certain breakpoint or in other words, it's not about unmatch not firing if the media query does not match on page load.

I use this media-queries:

mobile:  'screen and (max-width: 767px)'
tablet:  'screen and (min-width: 768px) and (max-width: 991px)'

In my case if I resize the window from mobile towards tablet, the unmatch
function of the mobile query fires after the match function of the tablet query.

@travm
Copy link

travm commented Oct 24, 2013

I believe I understand the issue now. So, you need all the handlers to fire in sequence so that an unmatch always fires before a match can execute. Sounds very reasonable to me. I'd like to see this as well. +1

@WickyNilliams
Copy link
Owner

Travis, massive thanks for helping out :) very kind of you to offer your time.

This issue has been noted previously, see #38. Unfortunately, this is also the behaviour that the underlying matchMedia exhibits, I describe it in detail in that issue. This fiddle demonstrates that order is not guaranteed when listeners fire: http://jsfiddle.net/FmmTa/5/ You will also see that in that thread someone came up with a workaround which seemed to do what they want, so you could check that out.

However, I agree that it would be nice for enquire to guarantee order of matching/unmatching. I'll look at whether something can be done to neatly offer this functionality (I didn't like the implementation in the previous issue)

@thasmo
Copy link
Author

thasmo commented Oct 24, 2013

That would be a great feature imo!

@WickyNilliams
Copy link
Owner

Would you be happy using the workaround in the other issue until I get something in place? I'm super busy at the moment so it may be a little while before I get around to it? Unless of course you're happy to make a PR ;)

@thasmo
Copy link
Author

thasmo commented Oct 24, 2013

Sure, I'll have a look at the workaround! :)

@tgunz78
Copy link

tgunz78 commented Jun 3, 2014

I only recently noticed this problem too, but only when using Chrome (IE11 is fine for example).

I used enquire.js before when it was v1.x on a site that has 3 media queries. Unmatch was always done before match as I can resize browser from large to medium to small and vice versa without any problems. Even 'restore Down/Up' between large and small size (skipping the medium size) was fine. I updated to v.2 and subsequently v2.1.1 but didn't notice the problem until this past week. Hopefully a fix will come soon?

@renekoch
Copy link

i have this problem aswell ... but using the workaround calls unmatch immediately after match if more than one of the same media query is called.

@renekoch
Copy link

I've made an update the workaround from #38, to fix the problem I described above.

;(function(){
  var to_unmatch = null,to_unmatch_q = null;

  enquire.register2 = function (q, options, shouldDegrade) {
    if (typeof options === 'function') {
      options = {match: options};
    }

    var match = options.match, unmatch = options.unmatch;
    if (unmatch) delete options.unmatch;
    options.match = function () {
      if (to_unmatch && to_unmatch_q != q) {
        to_unmatch();
        to_unmatch = null;
      }
      if (unmatch) {
        if (to_unmatch_q == q){
          var old = to_unmatch;
          to_unmatch = function(){
            old.apply(this, arguments);
            unmatch.apply(this,arguments);
          }
        }
        else{
          to_unmatch = unmatch;
        }
        to_unmatch_q = q;
      }

      match();
    };

    return this.register(q, options, shouldDegrade)
  }
})()

@leepowelldev
Copy link

Just an update on this... been doing a bit of experimentation. It seems the order that mediaQueries are created has an impact on which gets fired first. After a bit of playing around I got a demo working that fires in the correct order - however this means that you have to register ALL your 'unmatch' handlers before any 'match' handlers. This obviously has many knock on issues to code structure.

http://codepen.io/anon/pen/PwEbaB (console needs to be open to see output)

@thasmo
Copy link
Author

thasmo commented Feb 10, 2015

But that still depends on how the browsers have implemented this, right?

@leepowelldev
Copy link

I only tried it on Chrome. Will have a look how the other browsers handle it.

On 10 Feb 2015, at 17:04, Thomas Deinhamer notifications@github.com wrote:

But that still depends on how the browsers have implemented this, right?


Reply to this email directly or view it on GitHub.

@leepowelldev
Copy link

Continuing to play with this - running unmatcher's before any match handlers is really important for me when transitioning between breakpoints to avoid DOM manipulation conflicts.
At the moment I've forked this repo and experimenting with adding a slim event emitter that will allow you to attach handlers to be run before/after a matching query/handler is executed.

@thasmo
Copy link
Author

thasmo commented Feb 13, 2015

Awesome, please share your results as soon as you see fit!

@verrasse
Copy link

verrasse commented Jul 29, 2017

This is not a browser bug. It follows the specifications. Javascript event queue is a simple FIFO, first registered — first fired. If you register event A and then register event B, it will guarantied that A will always run before B on a compliant browser.

Enquire follows the Javascript specifications and please don't change this behavior.

If you need to run unmatch before match on multiple queries then you should first register enquire event for unmatch callbacks only. Then you should register the same enquire event for match callbacks only. It will guarantied that all unmatch-callbacks will fire before all match-callbacks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants