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

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

新規登録して質問してみよう
ただいま回答率
85.51%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

3168閲覧

react 要素の高さの取得

cheche0830

総合スコア187

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

2クリップ

投稿2018/02/13 05:42

編集2018/02/14 02:44
componentDidMount() { var pElement = document.getElementById( "toph" ) ; var clientHeight = pElement.clientHeight ; console.log(clientHeight); }

普通にid="toph"の高さを取得したいのですが、
実寸と取得できる数値が違います。。

実寸は100px程度なのですが、
300ぐらいの値が帰ってきます。

何か対応方法はありますでしょうか?

推測ですが、cssが当たる前の要素が縦に並んだ上体の時の
高さを引っ張ってきてるようなきがしています・・


追記
やりたいことはtophの高さを取得してウィンドウ高さからマイナスします。
残ったエリア内をoverflow scrollでスクロールエリアにしたく、
ブラウザの高さが変更されても再計算して常に画面に吸着した状態にすることが目的です。


追記2
refsを使ったやり方に変えてみましたが帰ってくる数字はまだ変わりませんでした。念のため記します。

componentDidMount() { var test = this.refs.toph; console.log(test.clientHeight); } render() { return ( <section> <div ref="toph">a<br />b</div> <Contents /> </section> ); }

tophの部分はわかりやすいように省略しました。
実寸は42pxなのですが、帰ってくる数字は48です。。。
ここに要素が入れば入るほどその数字の乖離がはげしくなっていきます・・・


追記3

clicks() { var test = this.refs.toph; console.log(test.clientHeight); } render() { return ( <section> <div ref="toph" onClick={this.clicks}>a<br />b</div> <Contents /> </section> ); }

このようにクリックしてから高さを取得したらちゃんとした値が取得できました。
これを読み込んだ段階で取得できると良いのですが・・・


追記4

componentDidMount() { var test = this.refs.toph; setTimeout(function() { console.log(test.clientHeight); this.setState({hheight: test.clientHeight}) },0) }

setTimeout0秒で入れてみるとconsole.logの部分は正しい値が表示されました!
ただ、this.setStateの部分がUncaught TypeError: this.setState is not a functionというエラーになってしまいました・・・


追記5

constructor(props) { super(props); this.state = { topPartsHeight: null }; } componentDidMount() { process.nextTick(() => { const elem = this.topParts; this.setState({ topPartsHeight: elem.clientHeight }) }) } render() { return ( <div ref={(div) => {this.topParts = div }} style={{height:this.state.topPartsHeight}}>

上記で実現したいことができました!みなさんありがとうございました。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyabi-sun

2018/02/13 06:13

そもそもReactの設計思想として、手動でDOMを触ってほしくないからJSフレームワークを使うわけで、バッドノウハウに当たる事をやろうとしているように思えます。Reactらしいスマートな解決手段を提示出来るかもしれませんので動機に関しても記載お願いします。
mpyw

2018/02/13 06:19

少なくともDOMは `getElementById` 使わずに `ref` プロパティのコールバック関数で代入するほうが正解だというのは間違いないですね。
mpyw

2018/02/13 06:20

toph の中に height 属性を指定していない画像があったりしませんか?
cheche0830

2018/02/13 06:36

ありがとうございます。追記させていただきました。refプロパティ。触ったことがないので調べて見ます!画像などは今のところ使用しておりません!
miyabi-sun

2018/02/13 07:29

ううむ、このtophとやらは画面の幅をちょっと変更しただけですぐに高さが変更されて、毎回高さを測る必要があるものなのでしょうか?話を聞く限りフルスクリーンレイアウトだと思うのですがいかが?もしそうなら一見無理ゲーに見えますが「css3 calc」や「レスポンシブデザイン」なんかの合わせ技で実現出来ると思います。
miyabi-sun

2018/02/13 07:33

なるほど…tophの高さは可変でコロコロ変更される可能性があるのですね。だとすれば質問文のように逐一高さを取得する必要が出てきそうですね。
cheche0830

2018/02/13 07:34

はい、フルスクリーンレイアウトになります。tophはヘッダーにあたる部分なのですが、ここが実際は不確定文字数のテキストが入りまして、高さが一定でないものでして・・
cheche0830

2018/02/13 07:36

ウィンドウの高さをリサイズごとに取得する方は既にできているのですが、なぜかこのtophの高さがうまくとれず・・・ちなみにtophに直接styleでstyle={{height:"100px"}}とか指定してあげるとちゃんとその数値がそのまま帰ってきたりします・・
cheche0830

2018/02/13 08:37

変わらないようです・・・もう少し調べてみます・・
miyabi-sun

2018/02/13 09:01

setTimeoutで0ms遅延させてみたらどうなりますか?
cheche0830

2018/02/13 09:37

ありがとうございます!惜しいところまできているのですが・・・
miyabi-sun

2018/02/13 09:41

`function(){}`はスコープとthisを新たに作るので駄目になります。JSXなのでES2015の「アロー関数」が使えそうですね。`setTimeout(() => { /* 処理 */ }, 0)`に書き換えてみてください。こちらで作った関数はthisを作らないのでthis.setStateが利用出来ると思います。
cheche0830

2018/02/13 09:49

できました!!!このstateの値を実際にはこの後domにあてるのでrenderもsetTimeoutかけないとだめのようですがまぁしょうがないですね・・・
guest

回答2

0

ベストアンサー

setTimeoutの利用は気持ち悪くない?

よろしければ、下記のサイトごご覧ください。setTimeoutの代わりにMethodが存在しています。
http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/

VueJSの場合の 「this.$nextTick()」っていうMethodが使えます。
Reactの場合、process.nextTick()が使えると思います。試してみて:)

thisに関して、process.nextTick()を使うと、thisも使えます

componentDidMount() { process.nextTick(() => { var toph = document.getElementById('toph'); this.setState({ hheight: toph.clientHeight }) }) }

:)

投稿2018/02/14 01:15

jerome.dupuis

総合スコア172

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cheche0830

2018/02/14 01:59

できました!ありがとうございます!そんな方法もあるのですね!getElementByIdの部分をrefに変えたものを最終解として追記させていただきます!
miyabi-sun

2018/02/14 02:46

> Reactの場合、process.nextTick()が使える おお、素晴らしい!勉強になりました!
guest

0

  • プロパティ名を参照するrefsは非推奨なので,コールバックを設定するrefを使ってください。Refs and the DOM - React
  • function () {} では this が束縛されないのでアロー関数 () => {} を使ってください。

(というか,クラス構文使ってるならアロー関数だけにとどまらずconst letなどのES.Nextの仕様バリバリ使いましょう。ReactでJSX使ってるならどうせBabel通すんだし…)

js

1import React, { Component } from 'react' 2 3class Example extends Component { 4 5 state = { height: null } 6 toph = null 7 8 componentDidMount() { 9 global.setTimeout(() => { 10 console.log(this.toph.clientHeight) 11 this.setState({ height: this.toph.clientHeight }) 12 }, 0) 13 } 14 15 clicks = () => { 16 /* ... */ 17 } 18 19 assignRefOfToph = (el) => { 20 this.toph = el 21 } 22 23 render() { 24 return ( 25 <section> 26 <div ref={this.assignRefOfToph} onClick={this.clicks}> 27 a<br />b 28 </div> 29 <Contents /> 30 </section> 31 ) 32 } 33}

投稿2018/02/13 09:50

編集2018/02/13 09:54
mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cheche0830

2018/02/13 10:02

ありがとうございます!refsだめなんですね・・・こちらの方法も試してみます!!ありがとうございます!こういう場合、setTimeoutを使うのは当たり前な感じなのですかね??
mpyw

2018/02/13 10:09

>> こういう場合、setTimeoutを使うのは当たり前な感じなのですかね?? あくまで最終手段という認識ですね。CSSを静的に指定していれば遅延させなくても一発で取れるはずなので,なんだかちょっとおかしいなぁとは思ってます…
cheche0830

2018/02/13 15:24

ありがとうございます!!
miyabi-sun

2018/02/14 02:54

> こういう場合、setTimeoutを使うのは当たり前な感じなのですかね?? 私もmpywさんと同意見ですね、あくまで最終手段です。 なんかcomponentDidMount後にも怪しげな事してる可能性があったので、念のため今積んである処理を先に流したらどう?という感じで勧めました。 ただ、ReactにはnextTickが用意されているようなので、そちらを使ったほうがかっこいいですね。 ただまぁ、これらの小手先対応で上手く行くのはReactの仕様的にどうなんだ?という感じはしますので、 バージョンアップでこの辺の挙動が改善される可能性があるかもしれませんね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問