2016-07-07 10 views
0

注釈を付けてユーザーが編集できるインポートされたHTMLファイルを更新するAngular2コンポーネントがあります。これを行うには、プレーンHTML5を使用してDOMを直接更新しています。クリックすると、クリックされたDOM要素にクラスが追加されます。ブラウザ(FFとLinux on Chrome)では、一時的に追加されます。つまり、ノードをすぐに印刷すると、クラスが表示されますが、関数を終了して印刷すると、そのクラスは表示されません。要素を検査すると、要素がクリックされたときに値なしの要素が< .... class>に更新されたことが示されます。 これはAngularなしで実装したときに機能していました。 DOMManagerの操作(classList.addとx.className = y)、angleのレンダラー、NgZoneを使ってコードを実行しましたが、すべて同じ効果がありました。誰かがなぜこれが起こっているのか、それを解決するために何ができるのか教えてもらえますか? 注:これは簡単な内部ツールであるはずです(この時点で私は迅速な修正が必要ですが(追加のアドバイスも歓迎します)。 (まだ完全には実装されていないコードのいくつかの関係ない部分は省略した。)Angular2コンポーネントでDOMの変更が正しく実行されない

import { Component, OnInit, NgZone } from "@angular/core"; 
import { Http, Headers, RequestOptions } from "@angular/http"; 

@Component({ 
    selector: "editor", 
    templateUrl: `editor/starterDemo.html` 
}) 
export class EditorComponent implements OnInit { 

    ngOnInit() { 
     this.fixImagePaths(); 
     this.annotate(); 
    } 

    constructor(public http: Http, public zone: NgZone) { } 
    // constructor(public http: Http, public renderer: Renderer) { } 

    fixImagePaths =() => { 
     const els = document.querySelectorAll('img'); 
     for (let i: number = 0, el: any; (el = els[i]); i++) { 
      el.src = 'editor/' + el.getAttribute('src'); 
     } 

    } 

    annotate =() => { 
     document.body.addEventListener('dragover', this.drag_over); 
     document.body.addEventListener('click', this.selectNone); 
     document.body.addEventListener('keydown', this.keyDown); 

     const els = document.querySelectorAll('img, .box'); 
     for (let i: number = 0, el: any; (el = els[i]); i++) { 
      el.draggable = true; 
      el.addEventListener('dragstart', this.drag_start); 
      el.addEventListener('click', this.selectItem); 
     } 
    } 

    selectItem = (event) => { 
     console.log("select item!"); 
     this.selectNone(); 
//  this.zone.run(() => { 
      event.target.closest('[draggable]').classList.add('dragme'); 
//  }); 
     //  this.renderer.setElementClass(event.target.closest('[draggable]').nativeElement, 'dragme', true); 
     //  console.log(event.target.closest('[draggable]')); 
     //  console.log(event.target.closest('[draggable]').classList); 
     //  console.log(event.target.closest('[draggable]').classList.contains('dragme')); 
     console.log(this.selected()); 
     return false; 
    } 

    selectNone =() => { 
     this.selected() && this.selected().classList.remove('dragme'); 
    } 

    selected =(): any => document.getElementsByClassName('dragme')[0]; 
} 

HTML:

<div class='box' 
    style="background-color: white; position: absolute; top: 847px; left: 842px; z-index: 20; height: 118px; width: 351px"></div> 

<img src="Screenshot1.png" 
    style="position: absolute; top: 0px; left: -1px" /> 
<img src="Screenshot2.png" 
    style="position: absolute; top: 913px; left: 0px; z-index: 2"/> 
<img src="Screenshot3.png" 
    style="position: absolute; top: 1768px; left: 0px" /> 

<div style="height: 2000px">&nbsp;</div> 
+0

対応するHTMLを表示できますか? – rinukkusu

+0

私はHTMLを追加しました、そして私は既にx.className = yを試しました。 –

答えて

0

私はちょうど(苦悩の時間後に)問題を考え出しました。 linux chromeでは、falseを返すとイベントの伝播を防ぐことができず、clickイベントがaddClass呼び出しの前後に2回実行されていたようです。 clickイベントは最初にselectNone()があるため(既存の選択項目をクリアするため)、クラスを追加する前後にselectNone()が実行されました。私はevent.preventDefault()を追加しました。およびevent.stopPropagation();私のイベントハンドラに。 これが誰かを助けてくれることを願っています。

関連する問題