0

I am working with a Bootstrap 3 template and built a little JavaScript app. I am wanting to add a certain amount of margin to an element in one of the phases I created based on how big the viewport is. I have some code that I'm trying to work with but I keep getting the message Uncaught TypeError: Cannot read property 'matches' of undefined at MediaQueryList.myFunction. I cannot figure out why because all my variables that I am passing into the function as a parameter have values. I can see that the first value works because 17em is being applied but the value isn't changing when the size of the window changes. Disclaimer: I am fairly new to Javascript.

var x = window.matchMedia("screen and (min-width: 1200px)"),
  y = window.matchMedia("screen and (min-width: 992px)"),
  z = window.matchMedia("screen and (min-width: 768px)");


function myFunction(x, y, z) {
  if (x.matches && phase === phases.crustType) {

    doughSpan.style.marginLeft = "17em";


  } else if (y.matches && phase === phases.crustType) {
    doughSpan.style.marginLeft = "13em";


  } else if (z.matches && phase === phases.crustType) {
    doughSpan.style.marginLeft = "12em";


  } else {
    doughSpan.style.marginLeft = "0em";
  }

}

myFunction(x, y, z);

x.addListener(myFunction);
y.addListener(myFunction);
z.addListener(myFunction);

3
  • 5
    Have you considered using media queries? Commented Jul 23, 2019 at 22:26
  • I have but I created phases in JS and since I need to target one specific phase, I need to modify it with JS. Commented Jul 23, 2019 at 22:33
  • You'd be better off setting a class based off the phase then let media queries handle the rest. You can target that specific class from within the media queries. Commented Jul 23, 2019 at 23:30

2 Answers 2

2

I'd handle this via media queries. It's what they are designed for.

Set a class on doughSpan based on the phase. You'd do this where you're setting phase. Let javascript handle the manipulation of the DOM and leave the styling of it to CSS.

Something along the lines of the following

/*JS*/
function setPhase(phase) {
  //Add the class "paseCrustType" to doughSpan if that is the active phase
  doughSpan.classList.togggle("phaseCrustType", phase === phases.crustType);
  
}
/*CSS*/
.phaseCrustType {
    margin-left: 0;
}

@media screen and (min-width: 1200px) {
  .phaseCrustType {
    margin-left: 17em;
  }
}

@media screen and (min-width: 992px) {
  .phaseCrustType {
    margin-left: 13em;
  }
}

@media screen and (min-width: 768px) {
  .phaseCrustType {
    margin-left: 17em;
  }
}

Sign up to request clarification or add additional context in comments.

1 Comment

Well, that makes sense! That didn't even cross my mind. I'll give it a whirl.
1

When you call: x.addListener(myFunction), myFunction is only being passed the MediaQueryListEvent for x when it expects all three. You should generalize the function to accept a single MediaQueryListEvent and a margin to apply, and call addListener for each of your media queries.

Here's an example:

var x = window.matchMedia("screen and (min-width: 1200px)");
// declare y and z

var handleQuery = function(e, margin) {
  if (e.matches && phase === phases.crustType) { 
    doughSpan.style.marginLeft = margin;
  }
};

handleQuery(x, "17em");
// call handleQuery for y and z, passing along their margins

x.addListener(function(e) {
  handleQuery(e, "17em");
});

// call addListener for y and z and handle them as you need

Check out the MediaQueryList.addListener docs for more details.

6 Comments

That kind of works. The changes don't appear right away and I have to resize the browser a few times and then the margin size kicks in.
Oh, sorry, didn't pick up on that. Check out my updated answer.
Thanks for trying, but for some reason it isn't working. Only the 17em is registering. It might have to do with my code?
If you could post a codepen I'd be happy to take a look :)
That's so strange. It works in Codepen but not for me in Brackets and viewing it in Chrome. Hmmm. In addition to that, I am only wanting to have the margin changes in one phase (crustType) that is under the H4 tag titled Build Your Order but it is being carried over to the doughType_Prices_Size phase.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.