Question

I have a question regarding custom elements in polymer.

I have acustom element that has a style nested inside it's template, for a div inside the template like so:

  <template>
    <style>    
       #navWrapper{
          height: auto;;
          color:red;
          position:fixed;
          background-color:black;
          width: 100%;
       }
    </style>
  <div id="navWrapper"><content></content></div>
</template>

Now, I'd like to change the color of navWrapper when I scroll down the page. I want to use jquery for that. Therefore I have a script inside of my custom element like so:

<script>
Polymer('responsive-nav',{ready: function() {
$(window).scroll (function () {
        var sT = $(this).scrollTop();
            if (sT >= 100) {    
                $(this.$.navWrapper).css({backgroundColor : 'rgba(0,0,0,0.0)' })
            }else {
                ...
            }
    })

     } });
</script>

Now sadly that does nothing. I have put an alert(test) before the $(this.$.navWrapper) to find out if I even get to that point and I do. Also when I want to change the background color or something else from an element that lives in my normal HTML file it works. For example $("#testDiv").css({...}) changes. So my question is: How do I access the css of my element properly?

Was it helpful?

Solution

Looks like your JQuery CSS call is wrong.

I think it should be:

.css("background-color", "rgba(0,0,0,0.0)")

rather than

.css({backgroundColor : 'rgba(0,0,0,0.0)' })

Cross referencing what you've done with the JQuery docs, you've definately missed the '-' out of 'backgroundColor', but also I don't see anything in the docs that states using a JSON object to make the change.

You can however use an array of property names and values (Which is what I suspect you may have been trying to do)

Update (Approx 1 hour later)

Since Iv'e been wrestling with a not too dissimilar problem today (but involving bootstrap rather than jquery) I was already investigating things around similar concepts.

As a result, I took the OP's original code and started playing with it.

What I present below is a partial JQuery solution (we still use JQ's scroll detection) where I also figured out an alternate way of changing the style using polymers conditional binding syntax.

http://www.polymer-project.org/docs/polymer/expressions.html

Essentially what i did was to pass a user data object into the scroll event at set-up time.

This user object contained a property that reflects the current polymer object (This is needed so that the JQ handler when it fires can update polymer properties)

When the window scroll event occurs, the handler extracts this property, then uses it to get at a local variable inside the polymer element, and thus updating it with the current scroll top value.

Since that locally scoped property is part of the actual polymer object, ANY polymer data-binding can read it, at this point it's simply just a matter of creating a couple of styles, then using the expression binding to pick the correct style.

Remember, styles cascade, so you can easily just make one master style for the whole thing, then 2 styles that simply just change the background color as appropriate.

Expression bindings work by using the text on the left side of the : only if the expression on the right evaluates to true eg:

{{ {frogs: a == 1} }}

would replace the expression binding with '' if property 'a' was NOT equal to 1 and set it to 'frogs' if property 'a' was equal to 1.

Expression bindings however are singular in nature, so in order to have more than 1 expression binding you need to pass the entire thing through one of polymers filters, specifically the 'tokenList' filter.

once you do this, you can build a whole object of different checks up, so expanding on our previous example:

{{ {frogs: a == 1, tadpoles: a == 2} | tokenList }}

will now make the result be equal to '' if property 'a' was NOT equal to 1 and NOT equal to 2 , while setting the result to 'frogs' if property 'a' was equal to 1 and setting the result to 'tadpoles' if property 'a' was equal to 2.

you can expand this to as many checks as you like, but the more you add in (I'm guessing anyway - iv'e not tested it) the slower performance is likely to be.

For now, the code below will do exactly what you need, well once you make a few alterations so that it targets your own elements and set's your own styles up anyway :-)

<link rel="import" href="polymer.html">

<polymer-element name="x-mypolymercomponent">
  <template>
    <style>
      .under100
      {
        background-color: green;
      }

      .over100
      {
        background-color: red;
      }

    </style>


    <h1 class="{{ {under100: scroll_top <= 100, over100: scroll_top > 100} | tokenList }}">This header has a dynamic class</h1>


  </template>

  <script>
    Polymer('x-mypolymercomponent', {

      ready: function ()
      {
        $(window).scroll({scope: this}, function(event) {
          var sT = $(this).scrollTop();
          event.data.scope.scroll_top = sT;
        })
      },

      scroll_top: 0,

    });
  </script>
</polymer-element>

Iv'e just tested this in the .NET project I'm currently working on, and it works fine in chrome 36, there are still problems in Firefox though, but this I think is possibly due to a bug I discovered last night so I wouldn't worry too much about it.

I have JQuery loaded at page level too, so it would appear that the component can pick up the page events just fine from it.

Give it a try see where you go from here, I'm about to adapt it for my specific issue, then turn it into a typescript module :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top