Reagieren: nicht bekommen Kann die richtige Breite des Elements nach dem Rendern
Ich versuche zu setup ein Zelt Reagieren, wenn ein Stück text ist größer als der container, aber ich kann nicht Holen Sie sich die richtige Breite des Containers ein, sogar nachdem die Komponente gerendert wurde.
Lese ich in einer anderen Antwort Reagieren "nach Rendern" code?, die Sie verwenden, requestAnimationFrame, die ich versuche und es immer noch nicht funktioniert.
Wenn ich das log der Breite des Containers zeigt Sie eine Breite von 147px gesetzt, die mit min-width in der CSS, aber die richtige Breite sollte 320px, die eingestellt ist mit einem media-query, wenn die Bildschirme min-width 600px.
Dies ist eine untergeordnete Komponente, die Eltern gerendert wird innerhalb eines iFrame, wenn es einen Unterschied macht, und die iFrame-Breite ist gut über 600px.
Der JS:
module.exports = React.createClass({
componentDidUpdate: function () {
//Setup marquee
this.initMarquee();
},
render: function () {
//Setup marquee
this.initMarquee();
var artistName = this.props.artist.artistName;
var trackName = this.props.track.trackName;
return (
<div className="MV-player-trackData no-select" ref="mvpTrackData">
<div className="MV-player-trackData-marquee-wrap" ref="mvpMarqueeWrap">
<div className="MV-player-trackData-marquee" ref="mvpMarquee">
<a className="MV-player-trackData-link no-select" href={this.props.storeUrl} target="_blank">
<span id="mvArtistName">{artistName}</span> – <span id="mvTrackName">{trackName}</span>
</a>
</div>
</div>
</div>
)
},
initMarquee: function () {
if ( typeof requestAnimationFrame !== 'undefined' ) {
//store a this ref, and
var self = this;
//wait for a paint to setup marquee
window.requestAnimationFrame(function() {
self.marquee();
});
}
else {
//Suport older browsers
window.setTimeout(this.marquee, 2000);
}
},
marquee: function () {
var marquee = React.findDOMNode(this.refs.mvpMarquee);
var marqueeWrap = React.findDOMNode(this.refs.mvpMarqueeWrap);
//If the marquee is greater than its container then animate it
if ( marquee.clientWidth > marqueeWrap.clientWidth ) {
marquee.className += ' is-animated';
}
else {
marquee.className = marquee.className.replace('is-animated', '');
}
}
});
Der CSS:
.MV-player-trackData-marquee-wrap {
height: 20px;
line-height: 20px;
min-width: 147px;
overflow: hidden;
position: relative;
width: 100%;
@media only screen and (min-width : 600px) {
min-width: 320px;
}
}
Habe ich versucht eine Reihe von verschiedenen Lösungen, einschließlich laidout und reagieren-Komponenten-Breite-mixin aber keiner von Ihnen arbeiten. Ich habe versucht, reagieren Komponente Breite mixin weil in einem anderen Teil von meiner app, ich werde versuchen, den Wert von window.innerWidth
aber, dass auch 0 zurück, nach dem Rendern, es sei denn, ich setze ein Zeitlimit für etwa 2 Sekunden, leider aber auch manchmal 2 Sekunden nicht lang genug durch, um das laden von Daten und andere Rückrufe, so kann diese Bremse leicht.
Jede Hilfe wird wirklich geschätzt. Danke.
Update:
Eine der Antworten richtig darauf hingewiesen, ich sollte anrufen this.initMarquee();
innen componentDidMount
denen ich dabei war, leider klebte ich den falschen code aus, wenn ich testen um zu sehen, ob es einen Unterschied gemacht, ruft es in render
. Der korrekte code sieht wie folgt aus:
componentDidMount: function () {
//Setup marquee
this.initMarquee();
},
Leider funktioniert das nicht, entweder, ich bekomme noch immer die falsche Breite für marqueeWrap.
Update: 24/06/2015
Nur um zu klären, dies ist die marquee-Effekt ich bin versucht zu erreichen, nur, wenn der text größer ist als seine container als sinnlos scrollen, wenn es nicht größer.
Auch hier ist ein link zu einem Github Issue aus dem team Reagieren sprechen darüber, warum Sie Reagieren, bevor der browser rendert die Farben. - So wie das der Fall ist, möchte ich wissen, wie kann ich zuverlässig erhalten die Breite des Elements in Frage.
- Ich bin mir nicht 100% klar, was Ihr Ziel ist. Möchten Sie, dass Ihre Inhalte von überquellenden container? Was ist das Problem, das Sie in läufst?
- Nein, ich will, dass mein Inhalt an horizontal scrollen innerhalb seines Containers automatisch, wenn es ist größer als sein container ist, wie ein marquee-Effekt, etwas ähnlich wie diese jsfiddle.net/jonathansampson/xxuxd
Du musst angemeldet sein, um einen Kommentar abzugeben.
Eines der möglichen Probleme, die auftreten können ist, dass dein CSS noch nicht geladen, wenn componentDidMount feuert. Dies kann passieren, mit webpack und darunter die css in Ihrem bundle, das enthält auch dein js auch wenn Sie inklusive der css-bevor Sie die Komponente in das Projekt.
js
geladen nachcss
hier ist, wie können Sie laden css vor js: stackoverflow.com/a/49228202/3632172Gibt es mehrere Probleme, wie haben Sie darauf hingewiesen, im Umgang mit der virtuellen DOM. Sie definitiv nicht wollen, um zu versuchen, um jQuery verwenden zu manipulieren, DOM-Knoten und Reagieren wahrscheinlich Schreien Ihre für versucht.
Gibt es eine Bibliothek namens Reagieren-Kontext, die würden genau das tun, was Sie gefragt haben. Sie würden aussetzen seine api in Ihre wrapper-Komponente und dann in der Lage sein zu hören auf Ereignisse, die auf den Komponenten innerhalb der virtuellen dom.
Diese Bibliothek ist ein wenig staubig, aber es sollte funktionieren mit dem code-Beispiel, das Sie teilten.
Ich bin verwirrt von dieser Frage, was Sie versuchen zu tun, mit der Breite?
Abgesehen davon, Reagieren, ist nur mit JavaScript, daher sollten Sie in der Lage sein, um das Feuer einige code auf Ihrer componentDidMount Funktion, die ausgeführt wird, nachdem das element in einem physikalischen Raum in Ihrem Browser-dom. Deshalb, wie der JavaScript-code, werden Sie in der Lage, Zugriff auf das div und erhalten es ist die Breite etc...
JavaScript Weg...
jQuery Weg...
Wenn das problem Sie versuchen zu lösen, ist dynamisch verändern der Breite eines div-weil es nicht gut aussieht, nachdem es gerendert etc... sollte dies wirklich getan werden, mithilfe von CSS.
Sollten Sie nicht nennen
this.initMarquee();
in der render () - Methode.In der Regel sollten Sie nicht arbeiten mit dem DOM an alle in der
render()
Methode.Versuchen, zu nennen
this.initMarquee();
imcomponentDidMount
Methode.(und ich verstehe wirklich nicht, die Verwendung von
requestAnimationFrame
in diesem Fall)