300x250 AD TOP

adv1

Formulário de contato

21 de outubro de 2011

Tags: , , ,

Como acessar um iframe e seus elementos via jQuery?

Recentemente tive um problema no projeto pois sentiu a necessidade de acessar um valor de um input que estava dentro de um iframe. Esse tipo de situação não é tão comum, uma vez que geralmente acessamos os valores do iframe para fora.


Para acessar, de dentro de um iframe, um valor externo, utilizamos o seguinte código:
$('#idDoElementoExterno', parent.document).val();
Entretanto, nunca tínhamos passado pela situação contrária. Pesquisando um pouco descobrimos uma alternativa, porém em JavaScript. Para ficar melhor o entendimento, vamos simular uma situação aqui. Temos uma página html "A.html" e dentro da mesma existe um iframe que aponta (src) para uma página "B.html":

<!-- A.html -->
<html>
 <head>
  <title>Testando iframe - jQuery</title>
   <script language="JavaScript">
    function exibeValor() {
     // alert aqui!
    }
   </script>   
  </head>
  <body>
  <input type="button" value="Exibir valor de campo do iframe" onclick="exibeValor()"/>
  <br/>
  <iframe name="iframeTeste" id="iframeTeste" src="B.html" />
  </body>
</html>
<!-- B.html -->
<html>
 <head>
  <title>Testando iframe - jQuery</title>    
  </head>
  <body>
   Campo de teste: <input type="text" id="campoTeste" />
  </body>
</html>
Suponhamos que queremos buscar o valor digitado no campo de texto ('campoTeste') do iframe e exibir em um alert javascript o mesmo ao clicar no botão que está fora do iframe.
Para isso, precisamos implementar o seguinte código javascript na função "exibeValor()":
var valor = window.parent.iframeTeste.document.getElementById('campoTeste').value;

 alert(valor);
Entretanto, essa abordagem ainda não compreendia o que queríamos, uma vez que estávamos utilizando jQuery. Logo, encontramos a solução abaixo para o mesmo método:
var valor = $('#campoTeste', window.parent.iframeTeste.document).val();
 alert(valor);
Ainda assim, essa implementação ainda faz uso de chamada de atributos javascript bruta. Queríamos algo totalmente jQuery, e então chegamos a código:
var valor = $('#iframeTeste').contents().find('#campoTeste').val();
 alert(valor); 

Tudo ficou mais simples por causa da função contents() do jquery. Normalmente, a função retorna todos os nós filhos a partir dos elementos combinados, mas no caso de um iframe todo o documento é carregado no iframe. Agora você pode usar o find() para localizar os elementos que você precisa para trabalhar e é isso.

Update 15/01/2016


Se você estiver usando o Google Chrome como browser para efetuar os testes deste exemplo, provavelmente receberá um erro do tipo: 
Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match.
Isso acontece porque o Chrome tem uma política de restrição de segurança que não permite acesso a outros arquivos direto do disco rígido da sua máquina, mesmo que pertençam ao mesmo diretório/app de origem.

Existem algumas opções simples de resolver isso, vejamos:

  1. Você pode executar seus códigos via Firefox ou outro browser, uma vez que eles não impõem tais restrições;
  2. É possível ainda configurar a flag "--allow-file-access-from-files" no seu arquivo de inicialização do Chrome para habilitar tal recurso;
  3. Ou você pode hospedar suas páginas HTML em algum servidor (Apache, Tomcat, etc.) e executá-las via http://localhost/. A forma mais simples de fazer isso, se você não tiver conhecimentos avançados de servidor, é usando o módulo http-server do Node.js.

-->