2016-09-27 4 views
3

hoisting을 사용하면 문서가 준비되기 전에 ES6 모듈이로드됩니다. 콘솔의 예ES6 모듈에서 문서 준비가 완료 될 때까지 기다리십시오.

,

// module.js 
console.log('body', document.body); 
export let a = 1; 

// main.js 
import {a} from 'module' 

로그 body null.

DOM 조작을 사용하는 ES6 모듈은 어떻게 필요하며 document ready이 필요합니까?

나는 나의 모듈에
$(document).ready(function() { 
    var a = 1; 
}); 

export {a}; 

을 사용하려고하지만 바벨은 나에게 Unexpected token 오류를 반환했습니다.

는 또한
$(document).ready(function() { 
    export let a = 1; 
}); 

을 시도하고 나는 'import' and 'export' may only appear at the top level 오류가 발생했습니다.

업데이트 : a가 정의되어 있지 않기 때문에

나는

document.addEventListener("DOMContentLoaded",function(){ 
    var a = 1; 
} 

export {a}; 

과 같은 문제가 있습니다.

즉 내보낼 변수를 사용할 수 없습니다 (내 업데이트 참조).

업데이트 : 여기

이 @MaciejSikora 코드를 내 시도를 기반으로 : 내가 할 다른 파일에서

function Test() { 

    document.addEventListener("DOMContentLoaded",()=>{ 
     this.width = $(window).width(); 
    }); 

}; 

//example object method 
Test.prototype.getElement = function(el) { 
    return this[el]; 

}; 


export { Test }; 

var test = new Test(); 
var width = test.getElement('width'); 

그러나 width은 정의되지 않습니다.

답변

3

<script> 태그를 <body/> 하단에 놓으십시오. 이렇게하면 document.body을 사용할 수 있으며 오류가 발생하지 않습니다.

+0

고마워요! – hhh

+2

로드 된 DOM에서 이벤트를 사용하는 것이 좋습니다. 우리의 스크립트는 HTML의 모든 장소에있을 수 있습니다. –

+1

@MaciejSikora 동의하지만 작동하게 할 수는 없습니다. 내 업데이트를 참조하십시오. – hhh

9

DOM은 ES6에서 변경되지 않았으며 ES6은 JavaScript에 새로운 기능을 제공합니다 (모두). 순수 JS에서 (그것은 JQuery와 동등한에서 준비 문서이다)로드 DOM의 이벤트를 존재합니다

document.addEventListener("DOMContentLoaded",function(){ 

    //here code 
}); 

모듈 내부에 수신기를 가질 수 DOM 트리로 작업하거나 DOM을 준비 후 사용해야합니다.

var DomManipulate=function(selector){ 

    document.addEventListener("DOMContentLoaded",()=>{ 

     this.element=document.querySelector(selector); 

     if (typeof this.callback === 'function') 
     this.callback(); 

    }); 

}; 

//HERE WE HAVE CALLBACK WHEN OUR MODULE CAN BE USED 
DomManipulate.prototype.onReady=function(callback){ 

    this.callback=callback; 

}; 

DomManipulate.prototype.getElement=function(){ 
    //example object method 

    return this.element; 

}; 

DomManipulate.prototype.write=function(text){ 

    return this.element.innerText=text; 

}; 


export { DomManipulate }; 

은 그래서 더 나은 방법이고 우리는 성분을 캡슐화 한 : 나는 무슨 뜻인지 보여주기 위해 예를 DomManipulate 구성 요소를 만들었습니다.

사용 예 :

var d=new DomManipulate("#test"); 
d.onReady(()=>{d.write("Test text");}); 

모듈은 DOM 요소를 수출하는 DOM 독립, 생성 모듈은 직접 매우 잘못된 관행이다이어야한다. 따라서 두 가지 방법으로 수행 할 수 있습니다.

  1. 모듈은 속성의 선택기 DOM 객체를 가져와야하며 DOM 준비가 된 후에 호출해야합니다. 따라서 모듈은 어디에서 호출되는지는 모르지만 준비된 DOM 구조가 필요합니다. 이 상황에서 DOM 준비 콜백은 모듈을 사용하고있는 주 파일에만 있습니다.

  2. 모듈은 일부 DOM 준비 수신기를 가질 수 있지만 모듈을 사용할 수있을 때 약간의 정보가 필요합니다 (예제와 onReady 함수에서 보여준 상황).

+0

나는 아이디어를 본다. 그러나 나는 나의 경우에 효과가있을 수 없다. 문제는 내가'getElement'를 인스턴스화하고 호출 할 때, DOM이 반드시 준비가되어 있지 않고'this.element'이 비어 있다는 것입니다. 내 질문에 대한 새 업데이트를 확인하십시오. – hhh

+0

변경 사항을 확인하십시오 –

+0

문제를 해결하지 못합니다 – hhh

0

스크립트가 페이지 하단에 있으면 dom이 이미로드되어 있으므로 'DOMContentLoaded'가 필요하지 않습니다. 또는?

+0

html은 예이지만 다른 리소스는 원격 CDN에서로드되는 것과 같지 않을 수 있습니다. – Aaron

+0

잘 모르겠습니다. HTML은 브라우저에서 위에서 아래로 읽습니다. 그러나 script 태그 앞에있는 HTML을 읽었 기 때문에 반드시 script 태그가 실행되기 전에 HTML 용 DOM도 빌드되지는 않습니다. 그것은 효과가있는 것처럼 보이지만, 나는 이것에 의존 할 수 있는지 모르겠습니다. –