0


I tried to use 'getelementbyclassname' in VUE methods. The reason why I tried to use this is that

instead of attaching information as :style, I want to change the width of the div I applied my class which is 'classon'. If I tie the style to the div, it wouldn't be interactive. So to achieve interactivity, I need to access to the DOM within VUE.

What shoudl I do if I want to access to the DOM element information in VUE?

Specifically, this part doesn't work

  methods: {
    growit(){
      let vueele=this.$el
      vueele.getElementsByClassName('classon').style.width='300px'
    },

Full code is as below.

-HTML-

<script src="https://npmcdn.com/vue/dist/vue.js"></script>

<div id="exercise">
  <!-- 1) Start the Effect with the Button. 
    The Effect should alternate the "highlight" or "shrink" class 
    on each new setInterval tick 
    (attach respective 
    class to the div 
    with id "effect" below) -->
  <div>
    <button @click="startEffect">Start Effect</button>
    <div id="effect" :class='{"highlight":classboolean, "shrink":!classboolean}'></div>
  </div>
  <!-- 2) Create a couple of CSS classes and attach them via the array syntax -->
  <div :style=[fclass,sclass]>I got no class :( but i think i just got it</div>
  <!-- 3) Let the user enter a class (create some example classes) and attach it -->
  <div>
    <label>Custom Class</label>
    <input type="text" v-model='newclass'>
    <div :style='this[newclass]'>{{newclass}}</div><br><br>
  </div>
  <!-- 4) Let the user enter a class and enter true/ false for another class (create some example classes) and attach the classes -->
  <div>
    <label>type another class</label>
    <input type="text" v-model='anotherclass'><br>
    <label>type true false for that</label>
    <input type="text" v-model='booleans'>
    <div :class='{"anotherclass":booleans}'>can't figure out this</div>
  </div>
  <!-- 5) Repeat 3) but now with values for styles (instead of class names). Attach the respective styles.  -->
  <div>
    <input type="text">
    <div></div>
  </div>
  <!-- 6) Create a simple progress bar with setInterval and style bindings. Start it by hitting the below button. -->
  <div>
    <label>What Rectangle do you want to grow?</label>
    <textarea v-model='rectselection'></textarea>
    <button @click="startProgress">Start Progress</button>
    <button class="btn-primary" @click='growit'>grow</button>
    <div class='options' :class='{classon:boolean1}'>{{rectselection}}</div>
    <div class='options' :class='{classon:boolean2}'>{{rectselection}}</div>
    <div class='options' :class='{classon:boolean3}'>{{rectselection}}</div>
    <div class='options' :class='{classon:boolean4}'>{{rectselection}}</div>
    <div class='options' :class='{classon:boolean5}'>{{rectselection}}</div>


  </div>
</div>
<script src='./app.js'></script>
<style>
  .highlight{
    background-color:yellow;
    border:solid black 1px;
    box-shadow:1px 2px 1px 1px;
    height:150px;
    width:150px;
  }
  .shrink{
    background-color:rgb(255, 255, 137);
    border:dashed grey 0.5px;
    box-shadow:0px;
    height:150px;
    width:50px;
  }
  .options{
    border:rgba(0, 0, 0, 0.564) solid 0.2px;
    width:200px;
    height:50px;
    margin:10px;
    display:block;
  }
  .classon{
    box-shadow: aquamarine 2px 2px;
    background-color: red;
  }

</style>

-JS-

new Vue({
  el: '#exercise',
  data: {
    classboolean:true,

    fclass:{
      'background-color':"red"
    },

    sclass:{
      'box-shadow':"grey 2px 2px 2px 2px",
      'margin':'50px',
    },
    newclass:'',
    anotherclass:'',
    booleans:'',
    width:'',
    rectselection:'',
    boolean1:false,
    boolean2:false,
    boolean3:false,
    boolean4:false,
    boolean5:false,




  },
  methods: {
    growit(){
      let vueele=this.$el
      vueele.getElementsByClassName('classon').style.width='300px'
    },
    startEffect() {
    this.classboolean=!this.classboolean
    },
    startProgress(){
      console.log

      if(this.rectselection==1){
        this.boolean1=true;

        this.boolean2=false; this.boolean3=false; this.boolean4=false; this.boolean5=false;
      } 
      else if(this.rectselection==2){
        this.boolean2=true;

        this.boolean1=false; this.boolean3=false; this.boolean4=false; this.boolean5=false;
      } 
      else if(this.rectselection==3){
        this.boolean3=true;

        this.boolean1=false; this.boolean2=false; this.boolean4=false; this.boolean5=false;
      } 
      else if(this.rectselection==4){
        this.boolean4=true;

        this.boolean1=false; this.boolean2=false; this.boolean3=false; this.boolean4=false;
      } 
      else if(this.rectselection==5){
        this.boolean5=true;

        this.boolean2=false; this.boolean3=false; this.boolean4=false; this.boolean1=false;
      } 

    },

  }
});

Really Appreciate always.

BS100
  • 823
  • 6
  • 22
  • This feels like an XY problem to me. What do you mean by using `v-bind:style` will make it "not interactive"? I would say using `v-bind:style` is a better solution, instead of trying to `v-bind:class` and then manually selecting the bound classes. Moreover, `getElementsByClassName` does not return a single element, but a `HTMLCollection`, so you will need to iterate over the collection to assign styles. – Terry May 07 '20 at 22:33
  • @Terry The reason why I think it wouldn't work is because, :style would be applied to a div once I assign the class to the div. so before assigning the class, I don't want the div to get the style information. – BS100 May 07 '20 at 22:35
  • Then you bind a method to `v-bind:style`. In the computed property, which returns a CSSStyleDeclaration object. you can then choose to assign a width of 300px or auto, depending on the value of the boolean you want to check. – Terry May 07 '20 at 23:01
  • @Terry I kind of get what you meant but not 100% sure, can you give me the code you are thinking if you don't mind?? my understanding from your comment is like adding :style to all the divs??? – BS100 May 07 '20 at 23:04

1 Answers1

2
let totalWidth = 0; 

new Vue({
  el: '#exercise',
  data: {
    classboolean:true,

    fclass:{
      'background-color':"red"
    },

    sclass:{
      'box-shadow':"grey 2px 2px 2px 2px",
      'margin':'50px',
    },
    newclass:'',
    anotherclass:'',
    booleans:'',
    width:'',
    rectselection:'',
    boolean1:false,
    boolean2:false,
    boolean3:false,
    boolean4:false,
    boolean5:false,




  },
  methods: {
    growit() {
      totalWidth += 50;
      document.querySelector(".btn-primary").style.width = totalWidth + "px";
    },
    startEffect() {
    this.classboolean=!this.classboolean
    },
    startProgress(){
      console.log

      if(this.rectselection==1){
        this.boolean1=true;

        this.boolean2=false; this.boolean3=false; this.boolean4=false; this.boolean5=false;
      } 
      else if(this.rectselection==2){
        this.boolean2=true;

        this.boolean1=false; this.boolean3=false; this.boolean4=false; this.boolean5=false;
      } 
      else if(this.rectselection==3){
        this.boolean3=true;

        this.boolean1=false; this.boolean2=false; this.boolean4=false; this.boolean5=false;
      } 
      else if(this.rectselection==4){
        this.boolean4=true;

        this.boolean1=false; this.boolean2=false; this.boolean3=false; this.boolean4=false;
      } 
      else if(this.rectselection==5){
        this.boolean5=true;

        this.boolean2=false; this.boolean3=false; this.boolean4=false; this.boolean1=false;
      } 

    },

  }
});

  • It works perfectly!!! Thank you so much. Why document.getElementbyClassName doesn't work while querySelector works?? And Why should I put if(window&& window.document)??? Really appreciate again – BS100 May 07 '20 at 22:39
  • @BS100 Nice to hear that it works. Cheers –  May 07 '20 at 22:40
  • but when I put 'document.getElementByClassName('classon).style.width='300px', it didn't work. – BS100 May 07 '20 at 22:47
  • And It doesn't allow me to increase the width after I set the value like, document.getElementsByClassName('classon').style.width=document.getElementsByClassName('classon').style.width+'50px' It ended up being onetime thing only... I know my approach is quite silly.. Thank you always. – BS100 May 07 '20 at 22:49
  • 1
    Sure thing!! really appreciate. I sent my link to your email. and this is my code if you can access right away. https://codepen.io/jotnajoa/pen/OJyvXQa – BS100 May 07 '20 at 22:53
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/213376/discussion-between-ci-boz-and-bs100). –  May 07 '20 at 22:58
  • 2
    Also, note that `querySelector()` only selects the **first** element that matches the query. If you have multiple element with the same class it will be a problem. – Terry May 07 '20 at 23:02
  • Thanks to all of you guys helps, I finally figured out to solve this problem and I wanna share the solution for those who would encounter a similar problem I have now for future. https://codepen.io/jotnajoa/pen/MWaVjge – BS100 May 07 '20 at 23:42