简体   繁体   中英

<a> element doesn't redirect to another page and is not clickable

I created a web-component in which I declared method which creates a copyright string:

'<p>Copyright © 2020 Krzysztof Kaczyński<a href="https://www.google.com">. Policy terms</a></p>'

Then I am converting this string into HTMLParagraphElement and append to footer element. When I open web browser I do not see any errors and I can see my copyright element. If I inspect this element it also looks correct but if I click <a> part of this element nothing happens (but it should redirect to https://www.google.com ).

AppFooter component:

export class AppFooter extends KKWebComponent implements KKAppFooter {
    public static TAG: string = `${CONSTANTS.TAG_PREFIX}-app-footer`;

    public readonly shadowRoot!: ShadowRoot;

    private footer!: HTMLElement;

    constructor() {
        super(template);
        this.getElementsReferences();
    }

    protected getElementsReferences(): void {
        this.footer = <HTMLElement>this.shadowRoot.querySelector('footer');
    }

    public setCopyright({ year, author, termsReferenceUrl }: CopyrightProps): void {
        const copyrightText: string = AppFooter.formattedCopyrights`Copyright © ${year} ${author}. Policy terms${termsReferenceUrl}`;
        this.footer.appendChild(new StringElementConverter().toElement(copyrightText));
    }

    private static formattedCopyrights(strings: TemplateStringsArray, ...values: string[]): string {
        const policyTermsUrlText: string = `<a href="${values[values.length - 1]}">${strings[strings.length - 2]}</a>`;
        let formattedText: string = '<p>';
        for (let i = 0; i < values.length - 1; i++) {
            formattedText += `${strings[i]}${values[i]}`;
        }
        formattedText += `${policyTermsUrlText}</p>`;
        return formattedText;
    }
}

Element on website:

在此处输入图像描述

Inspected element:

在此处输入图像描述

Code snippet

 class StringElementConverter { constructor() { this.domParser = new DOMParser(); } toElement(xmlString) { const parsedString = this.domParser.parseFromString(xmlString, 'text/xml').firstElementChild; if (parsedString == null) { throw new Error(`This xml string ${xmlString} is not parsable to Node`); } return parsedString; } } const template = ` <footer> <slot name="prepend"></slot> <slot name="center"></slot> <slot name="append"></slot> </footer> `; class AppFooter extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = template; this.getElementsReferences(); this.setCopyright({ year: '2020', author: 'Krzysztof Kaczyński', termsReferenceUrl: 'https://www.google.com', }); } getElementsReferences() { this.footer = this.shadowRoot.querySelector('footer'); } setCopyright({ year, author, termsReferenceUrl }) { const copyrightText = this.formattedCopyrights`Copyright © ${year} ${author}. Policy terms${termsReferenceUrl}`; this.footer.appendChild(new StringElementConverter().toElement(copyrightText)); } formattedCopyrights(strings, ...values) { const policyTermsUrlText = `<a href="${values[values.length - 1]}">${strings[strings.length - 2]}</a>`; let formattedText = '<p>'; for (let i = 0; i < values.length - 1; i++) { formattedText += `${strings[i]}${values[i]}`; } formattedText += `${policyTermsUrlText}</p>`; return formattedText; } } customElements.define('kk-app-footer', AppFooter);
 <kk-app-footer></kk-app-footer>

If you need anything else let me know in comments

this.domParser.parseFromString(xmlString, 'text/xml')

You're not parsing your content as the right content type. You want:

this.domParser.parseFromString(xmlString, 'text/html')

I'm guessing that when you parse the content as XML instead of HTML, the browser doesn't think that <a> has any special meaning.


Working example:

 class StringElementConverter { constructor() { this.domParser = new DOMParser(); } toElement(xmlString) { const parsedString = this.domParser.parseFromString(xmlString, 'text/html').firstElementChild; if (parsedString == null) { throw new Error(`This xml string ${xmlString} is not parsable to Node`); } return parsedString; } } const template = ` <footer> <slot name="prepend"></slot> <slot name="center"></slot> <slot name="append"></slot> </footer> `; class AppFooter extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = template; this.getElementsReferences(); this.setCopyright({ year: '2020', author: 'Krzysztof Kaczyński', termsReferenceUrl: 'https://www.google.com', }); } getElementsReferences() { this.footer = this.shadowRoot.querySelector('footer'); } setCopyright({ year, author, termsReferenceUrl }) { const copyrightText = this.formattedCopyrights`Copyright © ${year} ${author}. Policy terms${termsReferenceUrl}`; this.footer.appendChild(new StringElementConverter().toElement(copyrightText)); } formattedCopyrights(strings, ...values) { const policyTermsUrlText = `<a href="${values[values.length - 1]}">${strings[strings.length - 2]}</a>`; let formattedText = '<p>'; for (let i = 0; i < values.length - 1; i++) { formattedText += `${strings[i]}${values[i]}`; } formattedText += `${policyTermsUrlText}</p>`; return formattedText; } } customElements.define('kk-app-footer', AppFooter);
 <kk-app-footer></kk-app-footer>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM