Нравится / не нравится гиперссылка не работает в объектно-ориентированной манере? - PullRequest
0 голосов
/ 27 февраля 2019

Я хотел бы иметь гиперссылку «нравится / не нравится» для отображения различного содержимого на моей странице: при нажатии «нравится» отображается «хорошо»;при нажатии «неприязнь» отображается «плохо».Мой код выглядит так:

<html>
<head>
<script>
function Homepage(){

    this.like = document.getElementById("like");
    this.dislike = document.getElementById("dislike");

    Homepage.prototype = {
        constructor: Homepage,
        likeGame: function(event){
            if(this.like.style.display == "none"){
                this.like.style.display = "block";
            }
            event.preventDefault();
            },
        dislikeGame: function(event){
            if(this.dislike.style.display == "none"){
                this.dislike.style.display = "block";
            }
            event.preventDefault();
            },
        setListeners: function(){
            console.log('in listen');
            document.getElementById("hyperLike").addEventListener("click", this.likeGame);
            document.getElementById("hyperDislike").addEventListener("click", this.dislikeGame);
        }
    }
}
</script>

</head>
<body>
<p style="display:block">
<a id="hyperLike" href="";>Like</a>/<a id="hyperDislike" href="";>Dislike</a> the game.
</p>
<p id="like" style="display:none">
good
</p>
<p id="dislike" style="display:none">
bad
</p>
<script>
var homepage = new Homepage();

window.onload = homepage.setListeners;
</script>
</body>
</html>

Однако это не работает.Нажатие гиперссылок не имеет никакой реакции.Я добавил console.log в setListeners, ничего не регистрировалось, поэтому он даже не входит в setListeners.В чем здесь проблема?

У меня есть еще одна версия без OO, которая в основном такая же, она работает.

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Следующая демонстрация может связать несколько элементов с любым применимым событием и функцией обратного вызова.Преимущество использования этого класса заключается в том, что параметры selector, event и callback могут быть любыми, и для нескольких слушателей не нужно предпринимать никаких дополнительных шагов.


Демо

Подробности прокомментированы в демо

Это модификация кода, представленного в этой статье .

// Define class
class Homepage {
  // Pass a CSS selector
  constructor(selector) {
    // Reference selector
    const elements = document.querySelectorAll(selector);
    // Get amount of elements
    this.length = elements.length;
    // Merge the constructor and elements
    Object.assign(this, elements);
  }
  // Pass a callback function
  each(callback) {
    // Iterate elements...
    for (let node of Array.from(this)) {
      // ...call callback function fore each element...
      callback.call(node);
    }
    // ...make the method chainable
    return this;
  }
  // Pass event and callback
  bind(event, callback) {
    // Iterate constructor...
    return this.each(function() {
      // ...regiter each element to the event and assign callback
      this.addEventListener(event, callback, false);
    });
  }
};

// Instantiate Homepage class
const likeHate = selector => new Homepage(selector);
// Callback rate()
const rate = e => {
  // Reference clicked element
  const tgt = e.target;
  // If the clicked has .btn class...
  if (tgt.matches('.btn')) {
    // ...get the clicked value...
    const val = e.target.value;
    // ...reference article#rate...
    const rate = document.getElementById('rate');
    // ...assign the value of clicked to [data-rate] of #rate
    rate.dataset.rate = val;
    // If the value of clicked is 'Superior' =  thumbs up/down
    let icon = val === 'Superior' ? '?' : '?';
    // Assign icon to [data-icon] of #rate
    rate.dataset.icon = icon;
  }
}
/*
Call the .bind() method on all .btn and register the click event
to each .btn. Assign rate() as callback function.
*/
likeHate('.btn').bind('click', rate);
html,
body {
  font: 700 16px/1.3 Raleway;
}

header {
  font-size: 1.5rem;
  margin: 10px 0;
}

.btn {
  border: 0 none transparent;
  background: none;
  cursor: pointer;
  font: inherit;
  margin: 0;
}

.btn:hover {
  color: blue;
  text-decoration: underline;
}

.btn:focus {
  outline: none;
}

#rate {
  font-size: 1.5rem;
}

#rate::before {
  content: attr(data-icon)'\a0';
}

#rate::after {
  content: attr(data-rate)'\a0';
}
<!DOCTYPE html>
<html>

<head>
  <link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
</head>

<body>
  <header>
    <button class='btn' value='Superior'>Like</button>/<button class='btn' value='Inferior'>Hate</button> the game.
  </header>
  <article id="rate" data-icon='' data-rate=''></article>
</body>

</html>
0 голосов
/ 27 февраля 2019

Проблема в том, что this.like внутри функции likeGame() отличается от this.like в функции Homepage(), потому что функция имеет свою собственную область видимости.Один из способов решить эту проблему - использовать функции-стрелки в качестве методов.Теперь this всегда будет означать Homepage.

function Homepage() {

  this.like = document.getElementById("like");
  this.dislike = document.getElementById("dislike");


  this.likeGame = (event) => {

    if (this.like.style.display == "none") {
      this.dislike.style.display = "none"
      this.like.style.display = "block";
    }
    event.preventDefault();
  };
  this.dislikeGame = (event) => {
    if (this.dislike.style.display == "none") {
      this.like.style.display = "none"
      this.dislike.style.display = "block";
    }
    event.preventDefault();
  };
  this.setListeners = () => {
    console.log('in listen');
    document.getElementById("hyperLike").addEventListener("click", this.likeGame);
    document.getElementById("hyperDislike").addEventListener("click", this.dislikeGame);
  }
}

var homepage = new Homepage();

window.addEventListener("load", () => {
  homepage.setListeners();
})
<html>

<body>
  <p style="display:block">
    <a id="hyperLike" href="">Like</a>/<a id="hyperDislike" href="" ;>Dislike</a> the game.
  </p>
  <p id="like" style="display:none">
    good
  </p>
  <p id="dislike" style="display:none">
    bad
  </p>

</body>

</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...