Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
320 views
in Technique[技术] by (71.8m points)

html - How to update src of a img from javascript in a play framework project?

I have a image in my HTML file like this.

<img src="@routes.Assets.versioned("images/bell.png")" width="200", height="200" id = "symbolImg">

Image file is stored here.

enter image description here

Output

enter image description here

I was trying to change the image by having the following code in a typescript file.

document.getElementById("changeImageBtn").addEventListener("click", function () {
    document.getElementById("symbolImg").setAttribute("src", "@routes.Assets.versioned('images/cherry.png')" );
    document.getElementById("symbolImg").setAttribute("width", "300");
    document.getElementById("symbolImg").setAttribute("height", "300");
});

But the image doesn't change. This is the output.

enter image description here

Edit 1

Also tried these ways with escape characters. Had no effect.

 document.getElementById("symbolImg").setAttribute("src", "@routes.Assets.versioned("images/bell.png")" );

.

document.getElementById("symbolImg").setAttribute("src", "@routes.Assets.versioned("images/bell.png")" );
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Correct and long solution

All Play URLs are managed through the router, so you can easily find and change them if you need.

In Twirl templates, you can get URL as @routes.Assets.versioned("images/bell.png") because of the @... is a dynamic statement that will be replaced by the server, so it became /assets/images/cherry.png in the HTML output (well, if you will add sbt-digest plugin, as it must be with versioned, then, in production, you will get something like /assets/images/aaf512631818fb-cherry.png).

You can not use @ in the JavaScript client file just because it's a client and @ will not be dynamically replaced (yet, you can use it if you generate Javascript file dynamically as a Twirl template, then replacement will be done on the server in a moment of generation that JavaScript file)

The correct way to use Play routings on the client javascript is to generate them and load from the server. It's a special case described here: https://www.playframework.com/documentation/2.6.x/ScalaJavascriptRouting

In a short:

  1. create a javascriptRoutes action in a controller :

    def javascriptRoutes = Action { implicit request =>
      Ok(
        JavaScriptReverseRouter("jsRoutes")(
          routes.javascript.Assets.versioned
        )
      ).as("text/javascript")
    }
    
  2. Add correponding route:

    GET     /javascriptRoutes      controllers.Application.javascriptRoutes
    
  3. Load the javascript routers

    <script type="text/javascript" src="@routes.Application.javascriptRoutes"></script>
    
  4. Now you can use them in the client javascript

    document.getElementById("symbolImg").setAttribute("src",jsRoutes.controllers.Assets.versioned("images/favicon.png" ).url)
    

Incorrect and fast solution

Your solution is good only as a temporary fix

document.getElementById("symbolImg").setAttribute("src", "/assets/images/cherry.png" );

Be aware, in the case, if the project will run in a production environment with sbt-digest plugin then your /assets/images/cherry.png will be 404.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...