質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.61%

onsenUI switchのcheckedプロパティについて

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 880

score 18

onsenUIのswitchを作っているのですが、うまく動作しません。

スイッチ部分がこちらで、

<ons-switch id="pushswitch" checked></ons-switch>


それをcheckプロパティで判定するコードがこちらです。

if (document.getElementById("pushswitch").checked) {
   通知ON処理
  }else{
   通知OFF処理
  }

getElementByIdメソッドをつかって、スイッチがONかOFFかを判定したいのですが、
判定がうまく行っていないようなので、確認のためconsole.logで表示したところ、

console.log(document.getElementById("pushswitch").checked);
Type error: null is not an object (evalutating 'document.getElementById("pushswitch").checked')


とエラーが出てしまいます。

エラーの原因をご教授いただきたいです。
よろしくお願いいたします。

追記

回答いただきましたが、解決しませんでした、、、
javascriptをbodyタグの一番下に移したのですが更にもう一つのエラーが出てしまいました。

Type Error: null is not an object(evaluating 'this_input.checked')


unpkg.com/onsenui@2.10.6/js/onsenui.min.js:2 から起きているエラーのようですが、
よくわかりません、、、

もし原因がわかる方がいたらよろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • oikashinoa

    2019/02/27 16:30

    https://teratail.com/help#thanks-respondent
    にも書かれているように、コメントでお礼を記載しておきましょう。
    - 無償で2,3時間調べてると思います。
    - 私は”自分が調べたいことだけ”に調べて答えているんで問題ないんですが、他の人はどうなんでしょ?

    あまりに失礼が続くと次の質問が有った時、誰も助けてはもらえないですよ。
    - 回答する前にその人が過去どんな質問したのか見てから答えてます。
    - 変な人に回答すると後が大変なので、調べた後は自分のメモに残すだけにしてます。

    monacaは好きで触っているのでお互いがんばりましょう

    キャンセル

  • shunta71010

    2019/02/27 17:37

    アドバイスありがとうございます。
    参考にさせていただきます。

    キャンセル

回答 3

checkベストアンサー

+2

ons-pageのshowイベントでやれば取れるのがわかりました。
(ons.readyやwindow.onloadでは私が調べた限り無理なようです)

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsenui.css">
    <link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsen-css-components.min.css">
    <script src="https://unpkg.com/onsenui/js/onsenui.js"></script>
    <meta charset="UTF-8">
    <title>OnsenUI</title>
<script>
  ons.ready(function() {
    document.getElementById('pushswitch').addEventListener('change', function(e) {
      console.log(document.getElementById('pushswitch').checked);
      if(document.getElementById("pushswitch").checked) {
      }
      else{
      }
    });
    document.addEventListener('show', function(event) {
      if (event.target.matches('#main')) {
        console.log(document.getElementById('pushswitch').checked);
      }
    });
  });
</script>
</head>
<body>
<ons-page id="main">
  <ons-switch id="pushswitch" checked></ons-switch>
</ons-page>
</body>
</html>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/26 18:45

    いろいろロード時イベントでやってみましたが、ons-switchの初期処理終わった時のイベント取れないようです。
    jjj_aaaさんの記載されている通り、多少待つか、ロード直後に判定する必要がないのであれば私の回答の通り変更時にしたら良いと思います

    キャンセル

  • 2019/02/27 16:27

    ベストアンサーにする解答を間違えてしまったのですが、こちらのコードを構造にしたところ、
    無事にスイッチが機能しました。ありがとうございました。

    キャンセル

  • 2019/02/27 16:36

    ベストアンサーは変更可能ですよ。

    キャンセル

+2

onsオブジェクトready(callback)を読んで下さい。

  • 簡単に言うとons.ready()が呼ばれるとCordovaやUnsenUI関係の命令が使えるように準備が終わった状態になります。

ページのライフサイクル - Onsen UIも見て下さい。

  • 各ページの準備(init)ができてないと、CSSコンポーネント(Switchとか)の参照に失敗するようです。

OnsenUI V2 JS Splitter ベースにSwitch関係を追記。
Monaca のIDEでOnsenUI V2 JS Splitterをインポート後、index.htmlをこれで上が書いてみて下さい。
ons.ready()に実験コードを追加

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
  <script src="components/loader.js"></script>
  <script src="lib/onsenui/js/onsenui.min.js"></script>

  <link rel="stylesheet" href="components/loader.css">
  <link rel="stylesheet" href="lib/onsenui/css/onsenui.css">
  <link rel="stylesheet" href="lib/onsenui/css/onsen-css-components.css">
  <link rel="stylesheet" href="css/style.css">

  <script>
    ons.ready(function () {
      console.log("start");
      console.log(`ons.isReady() is ${ons.isReady()} は念の為確認`);
      // 正しくは別記codepenでの記載のようにinit()内で記載しないとタイミングによってはエラーとなる。
      // console.log(document.getElementById('pushswitch').checked);
      document.getElementById('pushswitch').addEventListener('change', function (e) {
        console.log(document.getElementById('pushswitch').checked);
      });
      console.log(document.getElementById('pushswitch').checked);
    });

    window.fn = {};
    window.fn.open = function() {
      var menu = document.getElementById('menu');
      menu.open();
    };
    window.fn.load = function(page) {
      var content = document.getElementById('content');
      var menu = document.getElementById('menu');
      content
        .load(page)
        .then(menu.close.bind(menu));
    };

  </script>
</head>
<body>
  <ons-splitter>
    <ons-splitter-side id="menu" side="left" width="220px" collapse swipeable>
      <ons-page>
        <ons-list>
          <ons-list-item onclick="fn.load('home.html')" tappable>
            Home
          </ons-list-item>
          <ons-list-item onclick="fn.load('settings.html')" tappable>
            Settings
          </ons-list-item>
          <ons-list-item onclick="fn.load('about.html')" tappable>
            About
          </ons-list-item>
        </ons-list>
      </ons-page>
    </ons-splitter-side>
    <ons-splitter-content id="content" page="home.html"></ons-splitter-content>
  </ons-splitter>

  <ons-template id="home.html">
    <ons-page>
      <ons-toolbar>
        <div class="left">
          <ons-toolbar-button onclick="fn.open()">
            <ons-icon icon="ion-navicon, material:md-menu"></ons-icon>
          </ons-toolbar-button>
        </div>
        <div class="center">
          Main
        </div>
      </ons-toolbar>
      <p style="text-align: center; opacity: 0.6; padding-top: 20px;">
        Swipe right to open the menu!
      </p>
      <ons-switch id="pushswitch" checked></ons-switch>
      <ons-switch id="pushswitch2" ></ons-switch>
    </ons-page>
  </ons-template>

  <ons-template id="settings.html">
  <ons-page>
    <ons-toolbar>
      <div class="left">
        <ons-toolbar-button onclick="fn.open()">
          <ons-icon icon="ion-navicon, material:md-menu"></ons-icon>
        </ons-toolbar-button>
      </div>
      <div class="center">
        Settings
      </div>
    </ons-toolbar>
  </ons-page>
  </ons-template>

  <ons-template id="about.html">
  <ons-page>
    <ons-toolbar>
      <div class="left">
        <ons-toolbar-button onclick="fn.open()">
          <ons-icon icon="ion-navicon, material:md-menu"></ons-icon>
        </ons-toolbar-button>
      </div>
      <div class="center">
        About
      </div>
    </ons-toolbar>
  </ons-page>
  </ons-template>

</body>
</html>

codepenでのテストコードも追加。たぶんこれでOK

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsenui.css">
  <link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsen-css-components.min.css">
  <script src="https://unpkg.com/onsenui/js/onsenui.js"></script>
  <meta charset="UTF-8">
  <title>OnsenUI</title>
  <script>
    ons.ready(function () {
      console.log("start");
      console.log(`ons.isReady() is ${ons.isReady()} は念の為確認`);
      // 各ページの初期化が終わってない段階で[checked]は参照できないのでエラーになる。
      // console.log(document.getElementById('pushswitch').checked);

      document.getElementById('pushswitch').addEventListener('change', function (e) {
        console.log(document.getElementById('pushswitch').checked);
      });
      console.log("addEventListener end");
      // 各ページの初期化が終わってから値を参照すること。
      document.addEventListener('init', function (event) {
        if (event.target.matches('#main')) {
          console.log('#main');
          console.log(document.getElementById('pushswitch').checked);
        }
      }, false);
    });
  </script>
</head>

<body>
  <ons-page id="main">
    <ons-switch id="pushswitch" checked></ons-switch>
  </ons-page>
</body>
</html>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/27 10:19

    私も最初それで解決するだろうと思ったのですが、

    <!DOCTYPE html>
    <html>
    <head>
    <link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsenui.css">
    <link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsen-css-components.min.css">
    <script src="https://unpkg.com/onsenui/js/onsenui.js"></script>
    <meta charset="UTF-8">
    <title>OnsenUI</title>
    <script>
    ons.ready(function() {
    console.log(document.getElementById('pushswitch').checked);
    });
    </script>
    </head>
    <body>
    <ons-page id="main">
    <ons-switch id="pushswitch" checked></ons-switch>
    </ons-page>
    </body>
    </html>

    でやってみたらわかるかと思いますが、エラーになります
    (monaca ideとかでやるとエラーでないのかもしれませんか、このソースのhtmlをブラウザで開くとエラーになります)

    キャンセル

  • 2019/02/27 12:07 編集

    私はMonacaIDEでテストしてconsole.logにて値が取れています。
    - が、たまたまタイミングが良かっただけな気がしてます。

    rururu3さんのコードを元にcodepenで試してました。
    ons.ready() 内の
    console.log(document.getElementById('pushswitch').checked);`
    > Uncaught TypeError: Cannot read property 'checked' of null

    上記を有効にするとエラーで落ちてました。
    ons.ready()直後ではまだCSS component初期化中ってところなんですかね。
    - 各ページ内の準備はまだ出来ていない と理解しました。

    以下の処理内でCSS componentの値を参照すれば良いようです。
    document.addEventListener('init', function (event) {
    if (event.target.matches('#main')) {}
    }

    本質問をKNaitoさんが見たようなので補足があれば期待です。

    キャンセル

+1

とりあえずで良ければ

setTimeout(() => console.log(document.getElementById("pushswitch").checked), 10);

で解決すると思います。
onsenUIが非同期でUIコンポーネントを作成してるっぽいので、順番待ちすれば良いと思います。

実際は、イベントリスナーをきちんと実装して、状態変化を取得することになると思いますが。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る